有效地迭代和存储数千/数百万个对象

时间:2013-02-14 20:57:43

标签: loops iteration quadtree

我正在进行模拟,我需要能够处理数千个潜在的数百万个对象来更新每个循环。 所有对象都需要调用其逻辑函数(AI)。 但取决于对象的位置决定了逻辑的详细程度。例如:

[使用100个对象来保持简单]

  • 所有对象都有一个位置(x,y)
  • 20个对象距离500分 从“兴趣点”的位置。
  • 50个对象是500分 来自20个对象(1000点以外)。
  • 30个对象在100以内 从兴趣点开始。

现在说这是一个详细的城市模拟,对象是虚拟公民。 下午6点,每个人都可以从工作中回家睡觉。

所以我们遍历所有公民,但我希望他们做不同的事情。

  • 最远的物体(50)从工作中回家睡觉 直到早上。
  • 更近的物体(20)从工作回家,有一个 咬一口然后睡到早上。
  • 最近的物体(30)Go 从他们的工作回家,咬一口吃,刷牙再睡觉,直到 早晨。

正如您所看到的那样,它们越接近兴趣点,逻辑就越详细。

我正在尝试找出迭代所有对象的最佳和最高效的方法。 只需要一个装满物体的物品,这就相对容易了,但由于这需要有效地处理500,000个物体,我需要一些建议。

此外,我不确定是否应该遍历每个循环中的所有对象,或者最好是每个循环迭代最近的对象,但是每10个循环只迭代更远的对象?

由于需要对象在它们附近的其他对象之间进行交互的额外要求,我一直认为这样做的最佳方法可能是将它们组织成四叉树,但我不确定。似乎四棵树更多的是静态内容,但我正在处理的对象,如上所述有一个位置,需要移动到其他位置。 我是否正在思考正确的思路?还是有“更好”的方式?

如果有人认为它是相关的,我也在用c ++工作。

任何建议都将不胜感激。

注意:

  1. 兴趣点经常变化,将其视为相机 图。
  2. 动态创建和销毁对象

4 个答案:

答案 0 :(得分:1)

如果你想从特定的点快速选择特定半径的物体,那么四叉树或简单的方形网格将有所帮助。

如果您的问题是如何存储数百万个对象以使其有效迭代,那么您可能可以使用基于列的技术,而不是每个具有5个字段的100万个对象,而是每个有100个元素的5个数组。在这种情况下,每个对象只是范围0 ... 999999中的索引。因此,例如,您要存储以下结构的100万个对象:

struct resident
{
    int x;
    int y;
    int flags;
    int age;
    int health; // This is computer game, right?
}

然后,不是声明resident residents [1000000]而是声明5个数组:

int resident_x [1000000];
int resident_y [1000000];
int resident_flags [1000000];
int resident_age [1000000];
int resident_health [1000000];

然后,而不是residents [n].x,而是使用resident_x [n]。当你需要迭代相同类型的所有对象并在每个对象中使用几个字段(在每个对象中使用相同的字段集)时,这种存储对象的方式可能会更快。

答案 1 :(得分:0)

您需要将问题分解为“类”,就像在现实世界中一样。每个人的班级都是根据距离计算出来的。所以下层阶级的人很远,上层阶级也很近。或者更正确的“远程课程”,近似的课程和“这里的课程”或任何你想要命名的东西。

1)为每个类创建一个包含一个插槽的数组。此插槽将保存该类中每个人的“链接列表”。当一个人类改变者(社交登山者)时,将对象移动到另一个列表是非常迅速的。

2)所以把每个人都放到适当的类中,只迭代你附近的类。在适当的情况下,有些对象需要关注,因此您可以将这些对象放回磁盘,只有在距离较近时才会重新加载。

答案 2 :(得分:0)

其中嵌入了一些问题: - 如何处理大量物体?如果有固定数量的固定对象,只要你有足够的内存,你就可以简单地创建它们的数组。如果您需要动态创建和销毁它们,那么在不小心处理被破坏对象的情况下,您就会面临内存泄漏的风险。在某个时刻,您可能会问自己,使用其他应用程序(如数据库)来存储对象以及仅执行C ++代码中的逻辑是否更好。数据库将提供我将重点介绍的其他功能。

- 如何找到与他人相距给定距离的物体。这是地理信息系统(GIS)的经典问题;听起来您正在尝试操作一个简单的GIS来存储您的对象和属性,因此它是适用的。它需要计算能力来测试每个点上的SQRT((X-x)^ 2 +(Y-y)^ 2),即距离公式。相反,通常使用“窗口函数”来提取包含所需点的正方形,然后在其中搜索以找到特定于给定半径的点。某些数据库经过优化,可以执行各种GIS功能,包括返回给定半径内的点,或返回某些其他几何体(如多边形)内的点。否则你必须自己编写这个功能。

- 对象的三层存储。这可以提高速度,但如果对象不断移动,您将会进行权衡,其中树必须经常重组。这一切都取决于事物的移动频率与你想要对它们进行计算的频率。

-AI代码。如果您尝试在数百万个对象上执行AI,这可能是您对性能的最大用途,而不是用于存储和搜索对象的方法。你是对的,更简单的代码,更远的点将提高性能,因为在较远的点上执行逻辑的次数较少。这有时使用蒙特卡罗分析来处理,其中逻辑将在任何给定迭代期间在点的随机子集上执行,并且随着距兴趣点的距离增加,执行的概率可能降低。

答案 3 :(得分:0)

我会考虑使用带有Morton编码/ Z-Order索引的线性四叉树。您可以通过使用位数组来表示包含数据的节点并快速执行计算,从而进一步优化此结构。

我使用Javascript在浏览器中非常高效地完成了这项工作,我可以在亚秒内遍历6700万个节点。一旦我将其缩小到感兴趣的区域,我就会以不同的结构查找数据。所有这些仍然以毫秒为单位。我将它用于空间矢量动画。

相关问题