C ++代码设计中的多代理系统

时间:2010-08-30 19:15:41

标签: c++ design-patterns containers openmp multi-agent

我有一个用C ++编写的模拟,我需要维护可变数量的代理,而我在确定如何很好地实现它时遇到了麻烦。每个代理都看起来类似于:

class Agent{
public:
    Vector2f pos;
    float health;
    float data[DATASIZE];
    vector<Rule> rules;
}

我需要在模拟中维护可变数量的代理,以便:

  1. 优选地,代理数量没有上限
  2. 我可以轻松添加代理
  3. 我可以在某些条件下轻松删除任何代理(比如健康&lt; 0)
  4. 我可以轻松地迭代所有代理并执行某些操作(比如健康 - )
  5. 最好,我可以使用openMP并行化工作,因为许多更新都有些昂贵,但完全独立于其他代理。
  6. (编辑)代理的顺序根本不重要
  7. 我应该为代理商使用哪种容器或设计原则?直到现在我才使用矢量,但我认为很难从这个结构中抹去:我需要经常做的事情,因为事情总是在死。我应该看看有什么选择吗?我想到了像List这样的东西,但我不认为它们可以并行化,因为它们是作为带有迭代器对象的链表实现的?

    谢谢

4 个答案:

答案 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上搜索速度很快,删除也很快。 (另外,您可以跨子节点并行化)。