我试图从一大堆职位中确定如何缩小我的名单。
现在我有大约3000个位置(x,y,z),我想基本上保持彼此相距最远的位置(我不需要保持100个半径都在2码范围内的位置彼此)。
除了做蛮力方法并且字面上进行3000 ^ 2比较之外,是否有人有任何想法如何进一步缩小此列表?
我对如何从数学角度处理这个问题感到困惑。
答案 0 :(得分:7)
好吧,我记不起这个算法的名字了,但我会告诉你一个有趣的技巧来处理这个问题。我假设在3D环境中存在点的半随机散射。
简单版本:分而治之
让我们节省一些内存
这将在一次通过中为您提供一个非常简化的数据集,但代价是可能存在大量内存。
那么,如何在不使用太多内存的情况下进行操作?
我在上面的示例中使用哈希表使得我的键是Grid-Cube坐标(5,8,9)。
If MyHashTable.contains({5,8,9}) then DoNothing else InsertCurrentVertex(...)
现在,您将拥有一个内存使用量最少的一次性解决方案(没有可能有大量空方块的巨大阵列。成本是多少?嗯,设置结构/类的编程时间,以便您可以在HashTable(或您的语言等效)
中执行.contains操作嘿,我的结果很粗糙!
这是对的,因为我们采用了适合任何立方体的第一个结果。平均而言,我们将实现顶点之间的X分离,但是现在你可以弄清楚,一些顶点仍然会彼此靠近(在立方体的边缘)。
那么,我们该如何处理呢?好吧,让我们回到顶部的数组方法(内存密集型!)。
除了仅检查顶点是否已存在于多维数据集中之外,还要执行此其他检查:
If Not ThisCubeIsTaken()
For each SurroundingCube
If not Is_Your_Vertex_Sufficiently_Far_Away_From_Me()
exit_loop_and_outer_if_statement()
end if
Next
//Ok, we got here, we can add the vertex to the current cube because the cube is not only available, but the neighbors are far enough away from me
End If
我认为你可能会看到它的美丽,因为如果你有一个3D阵列,很容易获得相邻的立方体。
如果你像这样进行一些平滑处理,你可以强制执行“如果它是0.25X的政策或其他东西则不添加”。您不必太严格,无法获得明显的平滑效果。
还是太粗,我希望它顺利
在此变体中,我们将更改允许顶点在多维数据集中驻留的限定操作。
If TheCube is empty OR if ThisVertex is closer to the center of TheCube than the Cube's current vertex
InsertVertex (overwrite any existing vertex in the cube
End If
注意,我们不必为此执行邻居检测。我们只是优化每个立方体的中心。
如果您愿意,可以将此变体与之前的变体合并。
作弊模式
对于这种情况下的某些人,您可以简单地随机选择10%的数据集,这将是一个很好的简化。然而,它会非常厚实,有些点非常接近。从好的方面来说,最多需要几分钟。除非你是原型,否则我不推荐它。