我想在下面的图表中找到没有周期的所有不同路径:
从这张图中,我编写了邻接列表,从节点0开始,向右移动(如上图所示):
var rightAdjacent = [[1,7],[2],[3,9],[4],[5],[6,10],[8],[2],[5],[11],[12]];
由于我是图表中的菜鸟,我从BFS的规范算法开始,在我看来,这是获得我需要的最便宜的方式:
...
var paths = []
queue.push(0); // Starting node
parents[0] = null;
while (queue.length > 0) {
u = queue.splice(0, 1)[0];
for (i = 0, l= rightAdjacent.length; i < l; i++) { // Explore edge(u, v).
v = rightAdjacent[u][i];
if (rightAdjacent[v]) {
if(rightAdjacent[v].status === 'unexplored') {
rightAdjacent[v].status = 'exploring'; // Node u has been discovered
queue.push(v);
parents[v] = u;
}
} else {
paths.push(collectPath(parents));
}
}
rightAdjacent[u].status = 'explored';
}
...但是在我的第一次尝试中,我只能收集连接组件的列表,在此之后,直到现在,只有垃圾。
我还编写了左邻接列表,不知道这对于加速搜索或回溯跟踪发现的路径是否有用。关于这个的任何线索?
对于图中的图表,我期待以下结果(如果我错了,请纠正我):
[0,1,2,3,4,5,6],
[0,1,2,9,5,6],
[0,1,2,9,5,10,11,12],
[0,7,8,2,3,4,5,6],
[0,7,8,2,9,5,10,11,12]
其中每个单一路径都有从起始节点开始排序的节点,通过第一个遇到的节点,直到最后一个节点。
从邻接列表开始,并且不使用递归,这不是收集所有这些路径的最简单方法,(所有父路径的有序父节点 < / em>)在我的例子中,从节点0开始到节点6和12结束?
这段代码有什么问题?
答案 0 :(得分:2)
你的rightAdjacent缺少节点6的邻居,它应该是一个空数组。一个简单的实现方法是执行bfs,但是在向路径添加节点时深度复制访问路径和当前路径。如果没有邻居,可以输出/保存当前路径
var rightAdjacent = [[1,7],[2],[3,9],[4],[5],[6,10],[],[8],[2],[5],[11],[12]];
var queue = [{visited:{0:true},path:[0]}] // start with node 0
function bfs(){
while(queue.length){
obj = queue.pop() // get last added path
node = obj.path[obj.path.length-1] // get last visited node from that path
visited = obj.visited
if(node >= rightAdjacent.length || rightAdjacent[node].length == 0){ // we reached a leaf node
console.log(obj.path)
}else{
for(var i=0;i<rightAdjacent[node].length;i++){ // we need to add the neighbours not visited
if(!visited[rightAdjacent[node][i]]){
visited[rightAdjacent[node][i]] = true
arr = obj.path.slice(0);
arr.push(rightAdjacent[node][i]); queue.push({visited:JSON.parse(JSON.stringify(visited)),path:arr}) // deep copy of both
}
}
}
}
}
bfs()