在半径增加的2D网格中查找相邻单元

时间:2018-07-01 12:31:44

标签: algorithm search

让我们有一个二维网格,其中X是要检查的单元格,T是满足给定单元格X的检查标准的单元格。

+---+---+---+---+---+
| T |   |   |   |   |
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+
|   |   | X |   |   |
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+

现在,我想通过以下方式搜索找到最接近X的,满足条件(在此示例中为T)的单元格,其中数字表示要检查的单元格按升序排列:

+---+---+---+---+---+
| 11|   |   |   |   |
+---+---+---+---+---+
| 10| 1 | 2 | 3 |   |
+---+---+---+---+---+
| 9 | 0 | X | 4 |   |
+---+---+---+---+---+
| 8 | 7 | 6 | 5 |   |
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+

对X单元的偏移量进行硬编码的简单方法不起作用,因为T和X之间的距离是任意的。那么,如果没有前一种方法,我该如何归档呢?

2 个答案:

答案 0 :(得分:1)

如果您想结识邻居,可以使用下面显示的简单算法。半径将指定您将获得多少个邻居,并且可以非常简单地增加它。它将从上到下从左到右。有了数据,循环就可以把每个邻居扔掉,并让相邻的小区相距-1。

 List<Node> neighbours = new List<Node>();

  iint currentRadius = 1;
  for(int x = -currentRadius; x <= concurrent; x++)
  {
    for(int y = -currentRadius; y <= concurrent; y++)
    {
      if(x == 0 && y == 0)
        continue; //Dont check itself

      int checkX = pos.x + x;
      int checkY = pos.y + y;

      if(checkX >= 0 && checkX < gridSizeX && checkY >= 0 checkY < gridSizeY) //Check if current pos is not out of bounds
      {
        neighbours.Add(nodes(checkX, checkY));
      }
    }
  }

答案 1 :(得分:1)

尚未指定半径测试,在循环上方没有标记任何内容,仅填充了一个正方形。 “半径”一词仅适用于圆形区域。

如果要枚举圆内或圆附近的点,请使用欧氏距离

第二个选项是最快的-我在过去的美好时光中使用了-您会更快地找到点。.但是它给您带来象限和边界问题,并且如果您要存储点,则在运行时从整数获得的收益比较将无关紧要。

现在,我将使用第一个选项。对于相对较小的网格,请使用循环,添加R * R> V的测试,其中V是X和T之间的平方欧几里得距离,即V =(TX-X)*(TX-X)+(TY-Y )*(TY-Y)。