【问题标题】:Multi-agent system in C++ code designC++代码设计中的多智能体系统
【发布时间】:2010-08-30 19:15:41
【问题描述】:

我有一个用 C++ 编写的模拟,我需要在其中维护可变数量的代理,但我无法决定如何很好地实现它。每个代理看起来都类似于:

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

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

  1. 最好对代理的数量没有上限
  2. 我可以轻松添加代理
  3. 我可以在某些情况下轻松移除任何代理(比如健康
  4. 我可以轻松地迭代所有代理并做一些事情(比如健康--)
  5. 最好我可以使用 openMP 并行化工作,因为许多更新有点昂贵,但完全独立于其他代理。
  6. (编辑)代理的顺序根本不重要

我应该为代理使用什么样的容器或设计原则?到目前为止,我一直在使用矢量,但我认为很难从这个结构中删除:我需要经常做的事情,因为事情总是会死掉。有什么我应该看的替代品吗?我想到了 List 之类的东西,但我不认为它们可以并行化,因为它们是作为带有迭代器对象的链表实现的?

谢谢

【问题讨论】:

  • 你分析过你的代码吗?如果没有,我还不会指责std::vector

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


【解决方案1】:

您可以在代理死亡时将其留在列表中,以供重新使用。不用担心缩小容器,并且保留向量的好处。您可以保留一个指向死亡/可重用代理的单独堆栈,只需在代理死亡时将其推入,弹出一个以回收新代理。

foreach Agent {
    if (agent.health > 0) // skip dead agents
        process rules

【讨论】:

  • 谢谢,我考虑过这个解决方案,但我在代码中的很多地方都为每个代理循环做了一个,而且很多时候我还为距离检查等做了嵌套代理循环,所以这个解决方案是将来可能很容易出现错误,我可能会不小心在各种计算中涉及死代理。
  • +1 用于指针堆栈的想法。我已经非常有效地使用了这种“模式”来处理高吞吐量遥测系统中的通信数据包。一堆可重用的代理会比一个队列更好,因为您更有可能重用缓存中仍然“热”的代理。
  • 我喜欢单独堆栈指针的想法,我也可以试试,谢谢!
  • ...当然,就我而言,我的数据包的生命周期非常短,内存分配/释放时间可能会令人望而却步。
【解决方案2】:

到目前为止,我一直在使用矢量,但我认为很难从这个结构中删除:我需要经常做的事情,因为事情总是会死掉。

在模拟的每个步骤中,您实际预计会死多少人?对人类来说似乎“一直”的事情对于计算机来说仍然是非常罕见的。例如,如果您的模拟的每个步骤都处理数千个代理,但平均每几步只有 1 个代理死亡,那么代理死亡是一个小事件。有了这些数字,您的程序处理活动代理所花费的时间远远多于处理死代理所花费的时间,因此担心删除死代理的性能可能根本不值得。如果提高代理移除效率最终会降低正常的代理迭代和处理效率(但代理移除相对较少),那么这可能是一个糟糕的权衡。

另一方面,如果每个模拟步骤都有大量代理出生和死亡,那么您可能希望确保这些事件能够得到有效处理。因此,这实际上取决于您希望处理的数字类型。

我的一般建议是继续使用 std::vector(只要它适合您的设计的其余部分),除非您真的预计与总代理数量相比,每一步有大量代理死亡。

【讨论】:

  • 你是对的,有时一次死亡可能需要数百次迭代
【解决方案3】:

列表应该工作得很好。它可以并行化,因为插入或移除元素不会使其他迭代器失效(当然,指向被移除元素的迭代器除外)。

如果不需要后向遍历,slist 和 list 一样好,而且快一点。

如果你不关心元素的顺序,使用 set。

【讨论】:

    【解决方案4】:

    像在视频游戏中一样使用四叉树。然后搜索pos 很快,删除也很快。 (此外,您可以跨子节点并行化)。

    【讨论】:

      猜你喜欢
      • 2017-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      • 2010-11-05
      • 2014-01-30
      • 2012-03-08
      • 1970-01-01
      相关资源
      最近更新 更多