给定二维空间(网格)中的索引(x,y) 我可以通过von Neumann邻域推导出邻居指数:
http://en.wikipedia.org/wiki/Von_Neumann_neighborhood
我如何最好地将这个概念扩展到三维空间(运行时复杂度最小) 使用von Neumann邻域导出(x,y,z)的邻域索引?
有人可以用一些伪/ C代码帮我解释一下吗?
答案 0 :(得分:2)
如果您正在谈论6个直接邻居,最有效的方法是对其进行硬编码:
int neighbour_offsets[3][6] = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
{-1, 0, 0},
{0, -1, 0},
{0, 0, -1},
};
对于排名为< = r
的邻居,对于固定维度,嵌套for
循环将起作用:
for (x = -r; x <= r; ++x) {
r_x = r - abs(x);
for (y = -r_x; y <= r_x; ++y) {
r_y = r_x - abs(y);
for (z = -r_y; z <= r_y; ++z) {
printf("%d, %d, %d\n", x, y, z);
}
}
}
如果您希望距离为d == r
而不是d <= r
的邻居,请使用z := {-r_y, r_y}
。
对于任意低维,递归将起作用(并且相当清楚);对于高维度,您最好从递归解决方案开始并将其转换为循环。在高维度(D>&gt; r)中,无论如何,在大多数时间偏移将在大多数维度上为零。
答案 1 :(得分:0)
这看起来有点简单,所以我可能误解了你的问题,但对于三维中的任意r
,在C中,循环遍历相邻单元格并处理它们或存储索引将类似于:< / p>
for ( i = -r ; i <= r ; i++ )
for ( j = -r ; j <= r ; j++ )
for ( k = -r ; k <= r ; k++ )
if ( abs(i) + abs(j) + abs(k) <= r ) {
do whatever in the cell (x+i,y+j,z+k).
}
请注意,这不是最有效的方式,但可能是最直接的方式。
答案 2 :(得分:0)
如果您正在寻找特定点的索引,那么答案很简单:
让D为3D空间中2点的曼哈顿距离: D = abs(x1-x2) + abs (y1-y2) + abs (z1 - z2)
那将是你的索引。
如果您正在尝试构建von Neumann邻域的3D八面体,那么最简单的方法是使用递归。
事实上,很容易证明,如果 X 点在 Y 的 R 范围内且 Y < / strong>在 K 范围内 Z 然后 X 至少在 K + R 范围内 Z (在R步骤中从X到Y,然后在K其他步骤中从Y到Z)。
该解决方案需要O(n)时间,其中n是neighboorhood中的确切点数。 它可以很容易地优化,以避免冗余。
使用类似技术的算法示例是Dijkstra算法。 尽管它的主要目的是寻找路径,但它的原则是探索范围1的所有邻居,然后是2等等(在未加权图上)。