1

我正在研究包含细胞自动机方法的项目。我想弄清楚的是如何编写函数来帮助找到二维数组中的所有邻居。例如,我有 size x size 2d array [size = 4 here]

[x][n][ ][n]
[n][n][ ][n]
[ ][ ][ ][ ]
[n][n][ ][n]

标记为 x [0,0 索引] 的字段具有标记为 [n] -> 8 个邻居的邻居。我想做的是编写一个函数,该函数可以找到编写大量 if 语句的邻居

有人知道怎么做吗?谢谢

4

3 回答 3

2

对于 NxM 矩阵中元素 (i,j) 的邻居:

int above = (i-1) % N;
int below = (i+1) % N;
int left = (j-1) % M;
int right = (j+1) % M;

decltype(matrix[0][0]) *indices[8]; 
indices[0] = & matrix[above][left];
indices[1] = & matrix[above][j];
indices[2] = & matrix[above][right];
indices[3] = & matrix[i][left];
// Skip matrix[i][j]
indices[4] = & matrix[i][right];
indices[5] = & matrix[below][left];
indices[6] = & matrix[below][j];
indices[7] = & matrix[below][right];
于 2013-09-23T16:58:26.170 回答
1

在所有可能的排列中,从坐标中加减一。边界外的结果环绕(例如-1变成34变成0)。基本上只需要几个简单的循环。

就像是

// Find the closest neighbours (one step) from the coordinates [x,y]
// The max coordinates is max_x,max_y
// Note: Does not contain any error checking (for valid coordinates)
std::vector<std::pair<int, int>> getNeighbours(int x, int y, int max_x, int max_y)
{
    std::vector<std::pair<int, int>> neighbours;

    for (int dx = -1; dx <= 1; ++dx)
    {
        for (int dy = -1; dy <= 1; ++dy)
        {
            // Skip the coordinates [x,y]
            if (dx == 0 && dy == 0)
                continue;

            int nx = x + dx;
            int ny = y + dy;

            // If the new coordinates goes out of bounds, wrap them around
            if (nx < 0)
                nx = max_x;
            else if (nx > max_x)
                nx = 0;

            if (ny < 0)
                ny = max_y;
            else if (ny > max_y)
                ny = 0;

            // Add neighbouring coordinates to result
            neighbours.push_back(std::make_pair(nx, ny));
        }
    }

    return neighbours;
}

为您使用示例:

auto n = getNeighbours(0, 0, 3, 3);
for (const auto& p : n)
    std::cout << '[' << p.first << ',' << p.second << "]\n";

打印出来

[3,3]
[3,0]
[3,1]
[0,3]
[0,1]
[1,3]
[1,0]
[1,1]

这是正确的答案。

于 2013-09-23T16:50:25.103 回答
1

假设你在 cell 中(i, j)。然后,在无限网格上,你的邻居应该是[(i-1, j-1), (i-1,j), (i-1, j+1), (i, j-1), (i, j+1), (i+1, j-1), (i+1, j), (i+1, j+1)]

然而,由于网格是有限的,上述一些值将超出范围。但是我们知道模运算:4 % 3 = 1-1 % 3 = 2. 所以,如果网格的大小n, m你只需要%n, %m在上面的列表上应用就可以获得正确的邻居列表:[((i-1) % n, (j-1) % m), ((i-1) % n,j), ((i-1) % n, (j+1) % m), (i, (j-1) % m), (i, (j+1) % m), ((i+1) % n, (j-1) % m), ((i+1) % n, j), ((i+1) % n, (j+1) % m)]

如果您的坐标在0andn和 between 0and之间,则此方法有效m。如果您开始,那么您需要通过在某处执行 a和 a1来调整上述内容。-1+1

对于您的情况n=m=4(i, j) = (0, 0). 第一个列表是[(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]。应用您得到的模数运算,[(3, 3), (3, 0), (3, 1), (0, 3), (0, 1), (1, 3), (1, 0), (1, 1)]这正是[n]您图片中标记的正方形。

于 2013-09-23T16:50:57.793 回答