Javascript 从迷宫中找到最短路径(广度优先搜索)
晚上好。我有一个迷宫,以矩阵的形式表示。有一个起点和一个终点。我编写了一个函数,将可以访问的所有单元格添加到数组中。该函数还删除所有没有子体的单元格(死锁)。但该功能不会删除导致死胡同的单元格。请帮忙完成这个功能Javascript 从迷宫中找到最短路径(广度优先搜索),javascript,algorithm,Javascript,Algorithm,晚上好。我有一个迷宫,以矩阵的形式表示。有一个起点和一个终点。我编写了一个函数,将可以访问的所有单元格添加到数组中。该函数还删除所有没有子体的单元格(死锁)。但该功能不会删除导致死胡同的单元格。请帮忙完成这个功能 //maze 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
//maze
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 = [3, 4];
function findWay(position, end) {
var queue = [];
//an array that contains the cells that have already visited
var visited = [];
//An array that contains cells that can not be entered for this position
var invalidCells = [];
//mark the current cell with a unit so as not to visit it anymore.
matrix[position[0]][position[1]] = 1;
//add the current position to the queue
queue.push(position);
//until the queue is empty
while (queue.length > 0) {
//get the first element of the queue
var pos = queue.shift();
//we clear the array, because for each new position we will have our own array
invalidCells.length = 0;
//an array of motion directions
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++) {
//do a check for each direction
//if at least one cell does at least one of the conditions, the cell is
placed in an array of invalid cells
//then run a new iteration of the loop
if (direction[i][0] < 0 || direction[i][0] >= matrix[0].length || direction[i][1] < 0 || direction[i][1] >= matrix[0].length || matrix[direction[i][0]][direction[i][1]] != 0) {
invalidCells.push(direction[i]);
continue;
}
//If this direction turned out to be an end cell
//return the array of visited cells
if (direction[i][0] == end[0] && direction[i][1] == end[1]) return visited;
//if none of the conditions are met, mark this direction with one and add it to the end of the queue
matrix[direction[i][0]][direction[i][1]] = 1;
queue.push(direction[i]);
}
//add the current position to the array of visited cells
visited.push(pos);
//If no iteration of the loop returns anything, then this cell is a dead end
if (invalidCells.length == 4) {
//remove the deadlock from the array
visited.pop();
}
}
}
findWay(start, end);
//迷宫
矩阵=[
[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=[3,4];
功能findWay(位置,结束){
变量队列=[];
//包含已访问的单元格的数组
var=[];
//包含无法为此位置输入的单元格的数组
var invalidCells=[];
//用单元标记当前单元格,以便不再访问它。
矩阵[位置[0]][位置[1]]=1;
//将当前位置添加到队列中
排队推(位置);
//直到队列为空
while(queue.length>0){
//获取队列的第一个元素
var pos=queue.shift();
//我们清除阵列,因为对于每个新位置,我们都有自己的阵列
invalidCells.length=0;
//一系列运动方向
变量方向=[
[pos[0]+1,pos[1]],
[pos[0],pos[1]+1],
[pos[0]-1,pos[1]],
[位置[0],位置[1]-1]
];
对于(变量i=0;i=矩阵[0]。长度| |方向[i][1]<0 | | |方向[i][1]>=矩阵[0]。长度| |矩阵[i][0]][方向[i][1]!=0){
无效单元格。推(方向[i]);
继续;
}
//如果这个方向是一个终端单元
//返回已访问单元格的数组
如果(方向[i][0]==end[0]&方向[i][1]==end[1])返回访问;
//如果不满足任何条件,则用一个标记此方向,并将其添加到队列末尾
矩阵[方向[i][0]][方向[i][1]]=1;
排队推送(方向[i]);
}
//将当前位置添加到已访问单元格的数组中
访问推送(pos);
//如果循环的迭代没有返回任何结果,那么这个单元格就是一条死胡同
if(invalidCells.length==4){
//从阵列中移除死锁
pop();
}
}
}
findWay(开始、结束);
似乎没有必要跟踪访问的和无效单元格
:
已访问
包含所有已访问的单元格(在所有方向)。尽管您试图在到达死胡同后从中移除细胞,但没有简单的方法可以回溯并从中移除其他细胞,这些细胞会导致此死胡同,并且不涉及其他可能仍然成功的路径
invalidCells
仅用于检测死角,但由于前面的一点,我将不再使用它
我假设您的目标是获得一个已访问的
数组,该数组表示到最终单元的最短路径,并从中删除所有可能的变量迂回。使用BFS实现这一点的方法是,不仅使用队列存储位置,还使用通向这些位置的最短路径。然后,当您点击结束单元格时,可以返回该单一路径,忽略队列中可能仍然存在的所有其他路径
请注意,您的示例中存在一个问题:结束单元标记为1,您的代码将不会检测到这样一个单元作为结束单元,而是在它周围走动,并且永远找不到它。请确保末端单元格始终标记为0,或者在执行任何其他检查之前执行末端单元格测试
下面是对代码所做的更改--请参见注释的位置
var矩阵=[
[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=[3,4];
功能findWay(位置,结束){
变量队列=[];
矩阵[位置[0]][位置[1]]=1;
queue.push([position]);//存储路径,而不仅仅是位置
while(queue.length>0){
var path=queue.shift();//从队列中获取路径
var pos=path[path.length-1];/…然后是它的最后一个位置
变量方向=[
[pos[0]+1,pos[1]],
[pos[0],pos[1]+1],
[pos[0]-1,pos[1]],
[位置[0],位置[1]-1]
];
对于(变量i=0;i=矩阵[0]。长度
||方向[i][1]<0 | |方向[i][1]>=矩阵[0]。长度
||矩阵[direction[i][0]][direction[i][1]!=0{
继续;
}
矩阵[方向[i][0]][方向[i][1]]=1;
//扩展并推送队列上的路径
queue.push(path.concat([direction[i]]);
}
}
}
变量路径=findWay(开始、结束);
log(JSON.stringify(path))代码>我建议您对您的代码进行注释和记录,以帮助您了解到目前为止您所做的工作。如果目的是仅在中访问到终点的路径,那么使用DFS将更有用。有了BFS,就不会有回溯,所以你将无法删除最终导致死胡同的单元格。注意:在您的示例中,结束单元格标记为1,因此您永远找不到它。