我找不到迷宫中的最短路径(广度优先搜索)

时间:2017-09-23 13:04:47

标签: javascript algorithm

我有一个以矩阵形式表示的迷宫。有一个起点和终点。我只能在包含零的单元格周围移动。我写了一个找到所有可用路径的函数。但该功能找不到最短路径。请帮助完成这项功能。

matrix = [
    [0, 1, 0, 1, 0],
    [0, 0, 1, 0, 0],
    [0, 0, 1, 1, 0],
    [0, 0, 0, 0, 0],
    [0, 1, 0, 1, 0]
 ];

 var start = [4,0];
 var end = [1,1];


function findWay(position, end)
{

	var queue = [];

	var visited = [];

	matrix[position[0]][position[1]] = 1;
        visited.push(position);
   	queue.push(position);

    while(queue.length > 0){

    	var pos = queue.shift();

		var direction = [ [ pos[0] + 1, pos[1] ], [ pos[0], pos[1] + 1 ], 
	                [ pos[0] - 1, pos[1] ], [ pos[0], pos[1] - 1 ] ];

    	for(var i = 0; i < direction.length; i++){

		    if (direction[i][0] < 0 || direction[i][0] >= matrix[0].length) continue;
		    if (direction[i][1] < 0 || direction[i][1] >= matrix[0].length) continue;

		    if (direction[i][0] == end[0] && direction[i][1] == end[1]) return visited;
		    if (matrix[direction[i][0]][direction[i][1]] != 0) continue;

		    matrix[direction[i][0]][direction[i][1]] = 1;
		    visited.push(direction[i]);
		    queue.push(direction[i]);

    	}

    }

    return visited;

}

findWay(start, end);

1 个答案:

答案 0 :(得分:0)

这些变化背后的想法是,您记得您采取的每个步骤路径。向队列添加新点时,请使用它添加路径。

使用此路径,您可以检查在进行下一步时是否已经访问过某个点。然后你不必操纵矩阵/迷宫来记住被访问的点。

如果找到新点,请将新点和路径添加到队列中。如果该点包含在您的路径中,则会遇到死胡同,并且不会将其添加到队列中。

如果您采取步骤并点击结束,请将带有结束点的相应路径添加到“有效路径”列表中。如果您只对最短路径感兴趣,则第一个有效路径应该是(最短的)最短路径。

如果你想要所有,请在队列为空时中断,因为最终你将访问每条路径中的每个点。

function findWay(position, end)
{
   var queue = [];
   var validpaths = [];

   // New points, where we did not check the surroundings:
   // remember the position and how we got there
   // initially our starting point and a path containing only this point
   queue.push({pos: position, path: [position]});

    // as long as we have unchecked points
    while(queue.length > 0){

      // get next position to check viable directions
      var obj = queue.shift();
      var pos = obj.pos;
      var path = obj.path;

      // all points in each direction
      var direction = [ [ pos[0] + 1, pos[1] ], [ pos[0], pos[1] + 1 ],
                   [ pos[0] - 1, pos[1] ], [ pos[0], pos[1] - 1 ] ];

      for(var i = 0; i < direction.length; i++){

          // check if out of bounds or in a "wall"
          if (direction[i][0] < 0 || direction[i][0] >= matrix[0].length) continue;
          if (direction[i][1] < 0 || direction[i][1] >= matrix[0].length) continue;
          if (matrix[direction[i][0]][direction[i][1]] != 0) continue;

          // check if we were at this point with this path already:
          var visited = false;
          for (var j = 0; j < path.length; j ++) {
               if ((path[j][0] == direction[i][0] && path[j][1] == direction[i][1])) {
                   visited = true;
                   break;
              }
          }
          if (visited) continue;

          // copy path
          var newpath = path.slice(0);
          // add new point
          newpath.push(direction[i]);

          // check if we are at end
          if (direction[i][0] != end[0] || direction[i][1] != end[1]) {
             // remember position and the path to it
             queue.push({pos: direction[i], path: newpath});
          } else {
            // remember this path from start to end
            validpaths.push(newpath);
            // break here if you want only one shortest path
          }

      }
    }
    return validpaths;
}

var paths = findWay(start, end);