【问题标题】:BFS algorithm for maze not looping - Javascript迷宫不循环的 BFS 算法 - Javascript
【发布时间】:2020-09-14 09:39:22
【问题描述】:

我正在尝试使用 BFS 算法来解决一个迷宫,我在一个数组中表示该迷宫,其中所有元素都以 999 开头,但中心(目标)为 0。我试图让代码从 0 开始并分支出四种方式(北/南/东/西),如果数字大于父级,则将父级数加 1。初始循环中间应该有一个 0,四个相邻的单元格应该从 999 更新为 1。这应该循环直到算法到达位置 0,0。不幸的是,我似乎无法让循环运行——我可以将前四个元素更新为 1,然后它就停止了。我认为这与我的队列如何/没有被拾取为下一个循环的 (y,x) 输入有关,但我似乎无法改变这一点。 这是一项任务,因此不寻找解决方案,但任何帮助我了解我在循环中缺少什么的帮助将不胜感激。我在下面展示了数组代码 (mazeD) 和 BFS/洪水代码

// maze array showing numerical distance
let mazeD = [];
for (let y = 0; y < 10; y++) {
  let row = [];
  for (let x = 0; x < 10; x++) {
    row[x] = 999;
  }
  mazeD[y] = row;
}

mazeD[5][5] = 0;

// BFS function
function flood(x, y, d) {
  let queue = []
  queue.push([y, x]);
  while (queue.length > 0) {
    queue.shift();
    let fillArr = [
      [+y - 1, +x],
      [+y, +x - 1],
      [+y, +x + 1],
      [+y + 1, +x],
    ];
    if ((x < 10) && (y < 10)) {
      d++;
      for (let [yy, xx] of fillArr) {
      if (mazeD[yy][xx] > d) {
        queue.push([yy, xx]);
        mazeD[yy][xx] = d;
        console.log("queue =" +queue)
      }
    } 
  }
 }
}
flood(5, 5, 0);
console.log(mazeD);

【问题讨论】:

    标签: javascript breadth-first-search maze


    【解决方案1】:

    就这样做吧:

    let mazeD = [];
    for (let y = 0; y < 10; y++) {
      let row = [];
      for (let x = 0; x < 10; x++) {
        row[x] = 999;
      }
      mazeD[y] = row;
    }
    
    mazeD[5][5] = 0;
    
    // BFS function
    function flood(x, y, d) {
      let queue = [];
      let i = 0;
      queue.push([y, x]);
    
      while (i < queue.length) {
        
        [x,y] = queue[i,i];
        let fillArr = [
          [+y - 1, +x],
          [+y, +x - 1],
          [+y, +x + 1],
          [+y + 1, +x],
        ];
        if ((x < 10) && (y < 10) && x >=0 && y>=0) 
        {
          for (let [yy, xx] of fillArr) 
          {
            
          if(yy >=0 && yy < 10 && xx>=0 && xx<10)
          {
              if (mazeD[yy][xx] == 999) 
              {
                queue.push([yy, xx]);
                mazeD[yy][xx] = mazeD[y][x]+1;
                console.log(xx,yy,mazeD[y][x]+1);
              }
              if(xx == 0 && yy == 0){
                return;
              }
          }
          
        } 
      
       }
       i++;
      }
    }
    flood(5, 5, 0);
    console.log(mazeD);
    

    【讨论】:

    • 感谢 Nao!我仍在努力进行正确的故障排除,所以这给了我一个很好的比较,非常感谢它
    【解决方案2】:

    我认为你可能在这行有问题:

    queue.shift()
    

    您似乎从未读取存储在队列中的值,因此循环中的坐标永远不会更新,这意味着您始终检查相同的位置。您可能希望将 queue.shift() 的值分配给变量并使用这些坐标继续搜索。

    【讨论】:

    • 谢谢 :) 我可以看到我没有引用队列,所以将尝试在 while 循环的末尾添加一行。我认为 queue.shift() 删除了队列数组中的第 0 个项,然后应该将下一个循环的坐标移动到第 0 个位置。这是错误的方法吗?
    • 您是正确的,queue.shift() 删除了队列的第 0 个位置并允许您访问队列中的下一个项目。但是,您没有做的是检查您刚刚删除的特定节点的相邻节点 - 并将它们添加到队列中。这意味着一旦您访问了起点的所有相邻节点,您的队列将为空并且循环将停止。
    • 看看这个实现gist.github.com/keif/96c49cae3bd62dc9651cc66f8561672e 以供参考;特别是第 41 行以后
    • 再次感谢 Danilo - 这个参考非常有帮助:)
    猜你喜欢
    • 1970-01-01
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 2021-06-25
    • 2015-06-02
    相关资源
    最近更新 更多