BFS 在第二个数组/unwighted 图上返回最短路径

问题描述

我知道以前有人问过这个问题,但我似乎无法从示例中找出解决方案并将它们转换为 javascript。即使在以下情况下也不行: https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

例如,我有一个未加权的图形或二维数组,如下所示:

const testMatrix = [
  [0,0],[0,1,0]
];

然后我使用 BFS 遍历它:(我目前对项目进行了硬编码以在数组中找到元素 2,2)。 并返回看到的列表项列表。但我不知道看到的列表是如何显示最短路径的。


const traversalBFS = function(matrix) {
  counter = 0;
  const seen = 
    new Array(matrix.length).fill(0).map(() => new Array(matrix[0].length).fill(false));

  const values = [];
  const queue = [[0,0]];

  while(queue.length) {
    const currentPos = queue.shift();
    const row = currentPos[0];
    const col = currentPos[1];
    
    if(row < 0 || row >= matrix.length || col < 0 || col >= matrix[0].length || seen[row][col] || matrix[row][col] === 1) {
      continue;
    }

 

    counter++;
    seen[row][col] = true;
    values.push(matrix[row][col]);
     if(row === 2 && col === 2) {
        return seen;
    }
    
    for(let i = 0; i < directions.length; i++) {
      const currentDir = directions[i];
      queue.push([row + currentDir[0],col + currentDir[1]]);
    }
  }

  return false;
}

即使我运行这段代码

temp = traversalBFS(testMatrix);
let path = [];
for(i = 0; i <= 2; i++) {
  for(j = 0; j <= 2; j++) {
       if(temp[i][j]) {
          path.push([i,j]);
       }
  }
}

它会返回:

0: (2) [0,0]
1: (2) [0,1]
2: (2) [0,2]
3: (2) [1,0]
4: (2) [1,1]
5: (2) [1,2]
6: (2) [2,0]
7: (2) [2,2]

这在任何方面都不是正确的路径,也不是最短的路径。

预期结果示例: 嗯,可以说终点是 1,1,起点是 0,0 预期的结果是一个具有最短路径的数组:

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

如果起点是 0,0 和终点是 2,2: 我认为结果应该是:

[[0,2],[2,2];

以我写的测试矩阵为例。因为没有 1 aka 墙挡在路上。

解决方法

要了解 Dijkstra's algorithm 是如何工作的,您可以采用给定链接的方法,开始时取大值,一旦邻居拥有它们,就取小值。

此示例使用(步长)值而不是索引,但可以将其替换为目标路径的坐标。

如果找到目标,这种方法使用避障和短路。

const
    travel = (array,from,to) => {
        const
            go = (i,j,smallest) => {
                if (array[i]?.[j] === 1) return;
                if (i === to[0] && j === to[1]) return;
                if (unvisited[i]?.[j] > smallest) {
                    unvisited[i][j] = smallest;
                    go(i + 1,smallest + 1);
                    go(i - 1,smallest + 1);
                    go(i,j + 1,j - 1,smallest + 1);
                }
            },unvisited = testMatrix.map(a => a.map(_ => Number.MAX_VALUE));

        go(from[0],from[1],0);
        return unvisited;
    },testMatrix = [[0,0],[0,1,0]],result = travel(testMatrix,[3,2]);

result.forEach(a => console.log(a.map(v => v === Number.MAX_VALUE ?'*': v).join(' ')));