【发布时间】:2010-08-23 09:54:04
【问题描述】:
我的问题最好用一个代码示例来说明,所以让我们开始吧:
class Game
{
// All this vector does is establish ownership over the Card objects
// It is initialized with data when Game is created and then is never
// changed.
vector<shared_ptr<Card> > m_cards;
// And then we have a bunch of pointers to the Cards.
// All these pointers point to Cards from m_cards.
// These could have been weak_ptrs, but at the moment, they aren't
vector<Card*> m_ptrs;
// Note: In my application, m_ptrs isn't there, instead there are
// pointers all over the place (in objects that are stored in member
// variables of Game.
// Also, in my application, each Card in m_cards will have a pointer
// in m_ptrs (or as I said, really just somewhere), while sometimes
// there is more than one pointer to a Card.
}
现在我想做的是制作这个 Game 类的深层副本。我创建了一个新向量,其中包含新的 shared_ptrs,它指向新的 Card 对象,它们是原始 Card 对象的副本。这部分很简单。
那么麻烦就来了,要更新m_ptrs的指针指向m_cards中的卡片,这可不是一件简单的事。
我能想到的唯一方法是创建一个映射并在复制 m_cards 期间填充它(使用map[oldPtr] = newPtr),然后使用它来更新 m_ptrs。但是,这只是O(m * log(n)) (m = m_ptrs.size(); n = m_cards.size())。由于这将是一个非常常规的操作* 我想有效地执行此操作,并且我觉得在 O(m) 中使用自定义指针应该是可能的。但是,我似乎无法找到一种有效的方法来做到这一点。有谁做过吗?
*它用于为 AI 创建一个测试平台,让它“尝试”不同的动作
编辑:我想补充一点关于接受答案的信息,因为我还没有。我一直在等到我回到这个项目(我在这个项目上工作了太多,所以我走上了旁道——如果你这样做是为了好玩,那就必须保持乐趣),所以在我接受之前可能需要一段时间答案。不过,我会在一段时间内接受答案,所以不要担心:P
编辑 nr 2:我还没有回到这个项目。现在,我正在考虑采取O(m * log(n)) 的方式而不是抱怨,然后再看看它是否需要更快。然而,由于我最近花了一些时间来学习我的模式,我也认为我真的需要一些时间来重构这个项目。哦,我可能会花一些时间利用我掌握的所有新知识来解决这个问题。由于没有答案说“只需坚持使用哈希图,稍后再看看它是否真的需要更快”(如果有的话,我实际上会非常失望,因为这不是我问题的答案),我是在我回到这个项目之前再推迟选择答案。
编辑 nr 3:我仍然没有回到这个项目。更准确地说,它已被无限期搁置。我很确定我现在不会把头放在O(m * log(n)) 上,如果结果证明是个问题,也许以后再看看。但是,这并不是我的问题的好答案,因为我明确要求更好的性能。不想再让答案不被接受,我选择了最有帮助的答案并接受了它。
【问题讨论】:
-
我不确定我是否理解您为什么认为您需要 2 个具有相同数据的向量。对我来说,这听起来像是数据缺陷的重复。请解释您为什么需要/想要这个?
-
@John Dibling:请做阅读。指针数组是使问题更容易的简化。实际上它并不存在——而是指针分布在 Game 拥有的多个类中。那是问题所在。此外,它(更详细地)在此页面的其他地方。
-
在做类似的事情时,我使用了一个映射来将 oldptrs 映射到 newptrs,尽管在我的情况下这并不重要,因为该映射仅在复制时使用,因此没有必要进行优化。你认为你可以重构你的项目以帮助你的改变更容易引入吗?
-
@n1ck:问题是复制是人工智能的核心部分,在这样的应用程序中,这绝对是一个瓶颈。基本上,即使是打出单张牌的效果,AI 也不知道,所以它必须复制游戏才能找到它。那么,打出一连串的牌,也需要一份游戏副本才能看到效果。最后,要再次看到预期计划的可能结果,还需要复制游戏。基本上,复制游戏将是 AI 的核心。
-
@n1ck:当您希望我重构项目时,我不完全理解您的意思。但是,使用不同的指针类将最大限度地减少我必须对代码进行的更改次数。这是一个不错的奖励,尽管这并不是建议这种方法的真正理由——这是由对我来说似乎是正确的设计所引发的(因为该软件仍处于早期 alpha 阶段,我没有最后期限,并且因为我有点理想主义,我更喜欢适当的设计)。