根据位置和半径快速查询对象

Posted

技术标签:

【中文标题】根据位置和半径快速查询对象【英文标题】:Fast query of objects based on location and radius 【发布时间】:2014-03-19 20:15:45 【问题描述】:

我正在开发一个简单的生态系统模拟,但我一直在为这些生物选择最佳数据结构。

我基本上拥有的是我当前世界中所有动物的列表,其中包含有关动物类型和位置的信息。此列表可能会变得非常大 - 可能接近数百万。

所以,为了实现一些简单的 AI,我需要让这个操作尽可能快: 给定地图上的一个点和一个半径,给我一个按距中心点的距离排序的半径内所有动物的列表。

世界将是二维的,因此我们仅限于平面坐标。 我还需要支持的一些操作:

改变动物的位置 创造新动物 移除动物

我了解了 kd 树以及它们快速计算最近邻的能力。

问题: 你认为它会在我的情况下工作吗?如果不是,我应该使用什么数据结构来满足要求?

编辑:

以下是 cmets 中要求的更多详细信息。 世界不会太大——可以容纳一个小圆圈的动物屏幕。我还应该支持世界可能变得相当密集的情况。 最后,我希望每个查询返回不超过几十个,但因为我将有大量的这些查询(每个动物一个,这应该以某种方式缓存,但为了简单起见,我们暂时忘记这一点)这是尽可能快速高效。

【问题讨论】:

kd 树应该可以相当容易地获得最近的动物,我认为需要进行一些修改才能获得给定半径内的所有动物...... 您能否提供有关该问题的更多详细信息?二维平面的大小是多少?它的预期密度是多少? (您希望每次查询返回多少只动物?几只?几十只?几千只?...?) 【参考方案1】:

考虑到您的限制条件(大量移动对象和可能固定大小的小世界),简单的grid 可能比 kd-tree 更适合。

见:Trees or Grids? Indexing Moving Objects in Main Memory

【讨论】:

这看起来很有趣,我会研究网格。你知道我在哪里可以找到一个示例实现吗?欢迎任何语言。 @korhner:也许this article 会有所帮助。此外,如果您的对象明显小于查询距离,您可以使用索引来存储它们的中心而不是边界框。这使得实现更简单,并且可能会提高性能。 谢谢,我认为这足以让我朝着正确的方向前进。【参考方案2】:

如果在位置改变之前有很多查询(例如,每只动物一个),kd-trees 应该可以正常工作。增量更新可能也很好,但是在必要时完全重建的不可变 kd 树的优点是可以用数组简洁地表示树结构。要查找搜索盘内的所有点,请遍历树,同时修剪半平面完全排除搜索盘的节点。您必须在最后按距离对结果进行排序。

【讨论】:

所以基本上动作顺序是这样的 - 对于每一帧重建树,处理动物(创建/删除,移动一点)?每次移动后重新创建树会不会太多? @korhner 也许,也许不是。 AI 多久运行一次? 动物需要能够对事件做出快速反应 - 即食草动物看到植物并开始向它移动以吃掉它,同时它发现有肉食动物追逐它,它需要更新状态并尝试逃跑。动物的位置可以在每一帧更新,但幅度很小。

以上是关于根据位置和半径快速查询对象的主要内容,如果未能解决你的问题,请参考以下文章

在 mongodb 地理位置查询中使用对象属性作为 $maxDistance 参数

如何根据用户位置查询 mySQL [关闭]

Android快速获取联系人

教你根据情况快速导入单号查询快递单号物流

Twitter - 查询特定地理位置半径内的推文

[SDOI2019]快速查询