【问题标题】:How can I store a 3d map allowing O(1) random access? (C++)如何存储允许 O(1) 随机访问的 3d 地图? (C++)
【发布时间】:2015-04-05 20:10:23
【问题描述】:

我目前正在为 Minecraft 制作 C++ 客户端/机器人,我想知道是否有一种方法可以使用允许有效随机访问的数据结构(使用 STL 或 Qt 库)来存储世界地图。

世界总是 256 高,但在 x 和 z 坐标上可以无限大。它以包含 16x256x16 块的数据包的形式发送。 现在我将 16x256x16 部分中的块存储到数组中,因为大小永远不会改变,并且我使用 x 和 z 作为键将这些部分存储到 stl 映射中。

问题是我目前在做AI,我需要访问地图很多,所以我想知道是否有更好的我可以存储它以提高访问效率。我不关心添加或删除元素的效率。也不需要排序。

【问题讨论】:

  • Minecraft API 确实可以让您访问世界几何(我不知道是不是这样)?那么为什么需要存储自己的副本呢?

标签: c++ qt


【解决方案1】:

你想使用 STL std::unordered_map,这会给你 O(1)

【讨论】:

  • 应该注意那是平均的情况。最坏的情况是 O(N)。
  • 好的,我试试。我认为它不适用于一对整数,我需要找到一种方法让它工作!
【解决方案2】:

如果您采用 Qt 方式,您可以使用 QHash 作为 std::unordered_map 的替代品,并使用更方便的 API。此外,QMultiHash 如果在给定坐标上可能有多个对象。

您可以QHasht<Coord3d, Data> 并编写uint qHash(Coord3d) 函数,这是QHash 所需要的:

struct Coord3d {
  uint x, y, z;
};

uint qHash(Coord3d & c) {
  uint h = 0;
  uchar * p = (uchar*)&c;
  for (uint i = 0; i < sizeof(Coord3d); ++i)
    h = 31 * h + p[i];
  return h;
}

此外,如果您必须遍历相邻的块,则可能值得额外的内存来保存指向所有相邻块的指针,这样您就不必查找它们。您可以使用每个块的相邻块指针轻松实现自己的查找。它可能比哈希图对 AI 更有利,并且在执行路径查找等典型任务时会更快。

【讨论】:

  • 为了给你一个更新,我已将我的地图转换为 QHash,并且我的寻路算法找到相同测试路径的时间从 630 毫秒变为 6 毫秒。谢谢!
  • 这很好,它足够低,可以将其保留在主线程中,而不是使用另一个来防止 gui 冻结。
猜你喜欢
  • 2011-07-17
  • 2022-01-15
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 2017-09-15
  • 1970-01-01
  • 1970-01-01
  • 2013-04-04
相关资源
最近更新 更多