可扩展3D阵列的数据结构?

时间:2012-02-25 21:43:41

标签: c# data-structures

我正在寻找类似于T[,,](3D数组)的数据结构,除了我不知道预先确定的维度(也没有合理的上限),随着时间的推移会向外扩展。我也想使用负面索引。

唯一想到的是字典,以某种Point3结构为关键字。还有其他选择吗?我想尽可能快地查找。数据将始终聚集在0,0,0周围。它可以向任何方向扩展,但点之间永远不会有任何“差距”。


我想我现在要继续使用Dictionary<Point3, T>,看看它是如何表现的。如果这是性能问题,我将尝试在T[,,]周围构建一个包装器,以便我可以使用负索引。

4 个答案:

答案 0 :(得分:2)

显然,您需要将其存储在类似于稀疏数组的数据结构中,因为您不知道数据集的大小。所以字典似乎是合理的。

我在这里有点疯狂,但我认为你的指数应该在Spherical Coordinates。随着您的数据向外扩展,这对我来说很有意义。它还可以非常容易地在(0,0,0)的特定范围内找到元素。

答案 1 :(得分:2)

如果您可能需要范围查询,我会想到KD-Trees。它们是树状结构,在每个层面上,沿着一个轴将宇宙分成两个。它们提供O(logN)查找时间(对于常数维度),其可能或者可能不够快,但它们也为范围查询提供O(logN + S)时间,其中S是找到的项目的大小,通常非常好。它们可以处理动态数据(插入和删除以及查找),但树可能会因此而变得不平衡。你也可以从一个给定的点做最近的邻居搜索(即得到最近的10个对象到点(7,8,9))维基百科一如既往地是一个很好的起点:http://en.wikipedia.org/wiki/Kd-tree

如果世界上有大量的东西,如果世界是非常动态的(事物一直在移动,被创造/破坏),那么kd-tree可能就不够好了。如果大多数情况下你只会问“给我(7,8,9)的东西”,你可以使用你在问题中提到的散列或类似List<List<List<T>>>的东西。我只是在界面中实现哪个更容易,并且稍后会担心性能。

答案 2 :(得分:1)

我有点假设您需要动态方面,因为数组可能很大。在这种情况下,您可以尝试将数组分配为一组3d“tile”。在顶层,您有一个存储指向瓷砖的指针的3d数据结构。随着时间的推移,您可以扩展并分配它。

每个单独的图块可以包含32x32x32体素。或任何适合您目标的金额。 通过将坐标索引除以32(当然是通过位移)来查找平铺,并通过屏蔽高位来计算平铺中的索引。

像这样的查找相当便宜,可能与.net字典相提并论,但它会使用更少的内存,这对性能也有好处。

但是,生成的数组将会很粗糙:数组边界是平铺大小的倍数。

答案 3 :(得分:1)

数组访问是一种非常快速的线性查找 - 如果查找速度是您的首选,那么它可能是最佳选择,具体取决于您需要修改数组的频率。

如果您的目标是维护玩家周围的块,您可能希望在玩家周围安排“当前世界”阵列结构,这样它就是一个三维数组,其中心块位于9,9,9大小为[20,20,20]。每次玩家离开中心块时,你都会重新索引数组以丢弃旧的块并继续前进。

最终,你要求选择如何优化你的游戏引擎,但几乎不可能说出哪些对你来说是正确的。尽管游戏往往比其他应用程序更优化性能,但不要被引诱进行微优化;首先优化可读性,然后在您认为必要时优化性能。

如果您怀疑这个特定的数据结构将成为引擎的瓶颈,请进行一些性能跟踪,以便在引擎运行后很容易确定一种方式。