我有一个用C ++编写的模拟,我需要维护可变数量的代理,而我在确定如何很好地实现它时遇到了麻烦。每个代理都看起来类似于:
class Agent{
public:
Vector2f pos;
float health;
float data[DATASIZE];
vector<Rule> rules;
}
我需要在模拟中维护可变数量的代理,以便:
我应该为代理商使用哪种容器或设计原则?直到现在我才使用矢量,但我认为很难从这个结构中抹去:我需要经常做的事情,因为事情总是在死。我应该看看有什么选择吗?我想到了像List这样的东西,但我不认为它们可以并行化,因为它们是作为带有迭代器对象的链表实现的?
谢谢
答案 0 :(得分:5)
您可以在停止时将代理留在列表中,准备重新使用。不用担心缩小容器,而是保留了矢量的好处。您可以保留一个指向死/可重用代理的单独指针堆栈,只需在代理程序死亡时将其推入,弹出一个以回收新代理程序。
foreach Agent {
if (agent.health > 0) // skip dead agents
process rules
答案 1 :(得分:3)
直到现在我才使用矢量,但我认为很难从这个结构中删除:我需要经常做的事情,因为事情总是在死。
每次模拟的每一步,你实际上有多少人会死?对于人来说似乎“一直”的东西对于计算机来说仍然很少被认为是罕见的。例如,如果您的模拟的每个步骤处理数千个代理,但平均每1个步骤只有1个代理程序死亡,那么代理程序死亡是一个小事件。有了这些数字,你的程序花在处理实时代理上的时间远远超过处理死代理的时间,因此担心删除死代理的性能可能根本不值得。如果更有效地移除代理将最终使正常的代理迭代和处理效率降低(但代理移除相对较少),那么这可能是一个糟糕的权衡。
另一方面,如果在每个模拟步骤中出现大量代理并死亡,那么您可能希望确保可以有效地处理这些事件。所以这取决于你期望处理的数字种类。
我的一般建议是继续使用std :: vector(只要它适合你的设计的其余部分),除非你真的期望每一步的代理人死亡人数与总数中的代理人数相比。 / p>
答案 2 :(得分:0)
列表应该可以很好地工作。它可以并行化,因为插入或删除元素不会使其他迭代器无效(当然除了指向要删除的元素的迭代器)。
如果你不需要向后遍历,slist就像list一样好,而且速度要快一点。
如果您不关心元素的顺序,请使用set。
答案 3 :(得分:0)
像在视频游戏中一样使用四叉树。然后在pos
上搜索速度很快,删除也很快。 (另外,您可以跨子节点并行化)。