【问题标题】:Getting the shortest path for chess pieces on n*m board获取 n*m 棋盘上棋子的最短路径
【发布时间】:2012-06-15 11:50:53
【问题描述】:

我在解决一项任务时遇到了困难,该任务要求我计算从 A 点到 B 点所需的最小步数,在 n*m 棋盘上使用不同的棋子,该棋盘也有障碍物并输出所走的路径。

我正在研究 A* 算法,但它需要我得到一个很好的启发式估计,我不知道如何得到一个像骑士这样的棋子

我一直在尝试做的是首先使用广度优先搜索找到从 A 点无障碍到达 B 点所需的最少步数,然后使用 A* 算法

public void AllPaths(int[,] chessBoard, int startX, int startY, int dimension) {
  // All the moves a knight can make
  int[] movementX = new int[8]{-2, -2, -1, -1,  1,  1,  2,  2};
  int[] movementY = new int[8]{-1,  1, -2,  2, -2,  2, -1,  1};
  chessBoard[startX, startY] = 0;

  for (int step = 0; step < dimension-1; step++) {
    for (int x = 0; x < dimension; x++) {
      for (int j = 0; j < dimension; j++) {
        if (chessBoard[x, j] == step) {
          for (int k = 0; k < 8; k++) {
            if (movementY[k] + x>= 0 && movementY[k] + x < dimension && movementX[k] + j >= 0 && movementX[k]+j < dimension) {
              if (chessBoard[movementY[k]+x,movementX[k]+j] == -1) {
                chessBoard[movementY[k]+x,movementX[k]+j] = step + 1;
              }
            }
          }
        }
      }
    }
  }
}

骑士动作的输入输出如下:

-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1

- starting from the top left
0 3 2 3 2 3 4 5
3 4 1 2 3 4 3 4
2 1 4 3 2 3 4 5
3 2 3 2 3 4 3 4
2 3 2 3 4 3 4 5
3 4 3 4 3 4 5 4
4 3 4 3 4 5 4 5
5 4 5 4 5 4 5 6

这适用于 n*n 板,但我也需要它适用于 n*m 板。 我是朝着正确的方向前进还是应该完全使用其他东西? 我必须改变什么才能让它适用于 n*m 板? 感谢您对解决我遇到的问题提出的任何建议。

【问题讨论】:

  • math.stackexchange.commath.stackexchange.com 上的这个问题你可能会更幸运
  • 您在编码算法时遇到问题,或者在建立算法时遇到问题?我还没有计算过,但是蛮力方法需要太多时间吗?
  • 我得到了直接问题的答案,但我担心我是否做对了。用 DFS 找到启发式然后使用 A* 是否合理,还是我做了很多无意义的工作?
  • 没有必要使用 A*/DFS,条件是 A) Guffa's Answer 足够快并且 B) 这不是作为学习练习。

标签: c# a-star breadth-first-search


【解决方案1】:

您需要两个参数来描述 n*m 板。

不要循环到理论上的最大步数,而是循环直到你填满棋盘:

public void AllPaths(int[,] chessBoard, int startX, int startY, int dimensionX, int dimensionY) {
  // All the moves a knight can make
  int[] movementY = { -2, -2, -1, -1,  1,  1,  2,  2 };
  int[] movementX = { -1,  1, -2,  2, -2,  2, -1,  1 };
  chessBoard[startX, startY] = 0;
  int cnt = dimensionX * dimensionY - 1:
  int step = 0;

  while (cnt > 0) {
    for (int x = 0; x < dimension; x++) {
      for (int y = 0; y < dimension; y++) {
        if (chessBoard[x, y] == step) {
          for (int k = 0; k < 8; k++) {
            int dx = movementX[k] + x, dy = movementY[k] + y;
            if (dx >= 0 && dx < dimensionX && dy >= 0 && dy < dimensionY) {
              if (chessBoard[dx, dy] == -1) {
                chessBoard[dx, dy] = step + 1;
                cnt--;
              }
            }
          }
        }
      }
    }
    step++;
  }
}

【讨论】:

  • 也许你也可以回答我的新问题 :)
  • @JoonasL:您应该将新问题作为新问题发布。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-28
相关资源
最近更新 更多