如何使用von Neumann邻域来设置3D空间中的索引?

时间:2012-06-26 15:20:22

标签: c++ c algorithm

给定二维空间(网格)中的索引(x,y) 我可以通过von Neumann邻域推导出邻居指数:

http://en.wikipedia.org/wiki/Von_Neumann_neighborhood

我如何最好地将这个概念扩展到三维空间(运行时复杂度最小) 使用von Neumann邻域导出(x,y,z)的邻域索引?

有人可以用一些伪/ C代码帮我解释一下吗?

3 个答案:

答案 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等等(在未加权图上)。