我有一个矩阵:
var matrix = [
[0, 1, 0, 1, 0],
[0, 0, 1, 1, 0],
[0, 0, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 0, 1, 0]
];
我需要使用深度优先搜索算法找到从“开始”到“结束”的方式。
var start = [0,4],
end = [4,0];
我只能向四个方向移动。上,下,左,右。
我试图实现这个算法,但是我的函数找不到解决死锁的方法。该功能找不到其他路径。
也许我误解了算法的运作方式。
您可以在JSFiddle和此处找到我的代码:
let 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]
];
let start = [0,4];
let end = [4,0];
let way = [start];
function findWay(position, prevPosition){
prevPosition = prevPosition || [-1,-1];
let left = [ position[0], position[1] - 1 ];
let right = [ position[0], position[1] + 1 ];
let up = [ position[0] - 1, position[1] ];
let down = [ position[0] + 1, position[1] ];
if( position[0] == end[0] && position[1] == end[1] ) {
return way;
}
if(checkCondition(left, prevPosition)) {
way.push(left);
return findWay(left, position);
}
if(checkCondition(down, prevPosition)){
way.push(down);
return findWay(down, position);
}
if(checkCondition(right, prevPosition)){
way.push(right);
return findWay(right, position);
}
if(checkCondition(up, prevPosition)){
way.push(up);
return findWay(up, position);
}
way = 'No Way!';
return way;
}
function checkCondition(direction, prevPosition){
if(direction[0] > 4 || direction[0] < 0 || direction[1] > 4 || direction[1] < 0){
return false;
}
if(prevPosition[0] == direction[0] && prevPosition[1] == direction[1]){
return false;
}
if(matrix[direction[0]][direction[1]] == 0){
return true;
}
return false;
}
findWay(start);
请帮我正确编写功能。
答案 0 :(得分:2)
我发现您的实施存在两个问题:
1)检查访问过的节点。你确实有一张支票,确保你不会回到你刚来的节点,但这还不够。您需要检查是否未返回任何以前访问过的节点。
为此,我会保留一组访问过的节点。每次展开节点时,都将其添加到该阵列。每次您考虑扩展节点时,请检查它是否已存在于已访问的阵列中。所以像这样:
let visited = [];
function findWay(position) {
visited.push(position);
// Rest of function omitted.
}
checkCondition(position) {
// Code for checking out of bounds omitted
if (visited.find(v => v[0] == position[0] && v[1] == position[1]) {
return false;
}
// Code for checking passable vs unpassable omitted
}
2)扩展节点时,你只能进入最多一个方向;第一个方向恰好是可以通过的。这是因为无论findWay的结果如何,您都会返回。一个简单的解决方法是改变这个:
if(checkCondition(left, prevPosition)) {
way.push(left);
return findWay(left, position);
}
...到此
if(checkCondition(left, prevPosition)) {
way.push(left);
const result = findWay(left, position);
if (result !== 'No Way!') {
return result;
}
}
......以及其他案例的类似变化。
答案 1 :(得分:0)
您的代码存在一些问题:
null
表示没有找到路径,你可以轻松检查,因为它是一个假值。您只想在找到路径后返回。当你向左走并走向死胡同时,你仍然想要探索其他三个方向。您的代码会立即返回。null
。所以这是以下算法的有效实现:
null
。null
。null
。在Javascript中:
function findWay(pos, end, way)
{
if (way === undefined) way = [];
if (pos[0] < 0 || pos[0] >= matrix.length) return null;
if (pos[1] < 0 || pos[1] >= matrix[0].length) return null;
if (pos[0] == end[0] && pos[1] == end[1]) return way;
if (matrix[pos[0]][pos[1]] != 0) return null;
matrix[pos[0]][pos[1]] = 1;
way.push(pos);
let res = (findWay([pos[0] + 1, pos[1]], end, way)
|| findWay([pos[0], pos[1] + 1], end, way)
|| findWay([pos[0] - 1, pos[1]], end, way)
|| findWay([pos[0], pos[1] - 1], end, way));
if (res !== null) return res;
matrix[pos[0]][pos[1]] = 0;
way.pop();
return null;
}