Javascript 我的Dijkstra';s算法实现不返回最短路径

Javascript 我的Dijkstra';s算法实现不返回最短路径,javascript,graph-algorithm,shortest-path,Javascript,Graph Algorithm,Shortest Path,我试图用JavaScript实现Dijkstra的最短路径算法,并用多个示例对其进行了测试 我用这个图表来观察它的行为: 如果我想找到从A到I的最短路径,结果应该是[A,D,C,F,G,H,I],距离等于10 但我的实现将路径返回为[A,B,E,J,F,G,H,I],距离为14 以下是我的JavaScript代码: const图={ A:{B:3,C:4,D:2}, B:{A:3,D:6,E:1}, C:{A:4,D:1,F:3}, D:{A:2,B:6,C:1,E:5}, E:{B:1,D

我试图用JavaScript实现Dijkstra的最短路径算法,并用多个示例对其进行了测试

我用这个图表来观察它的行为:

如果我想找到从A到I的最短路径,结果应该是[A,D,C,F,G,H,I],距离等于10

但我的实现将路径返回为[A,B,E,J,F,G,H,I],距离为14

以下是我的JavaScript代码:

const图={
A:{B:3,C:4,D:2},
B:{A:3,D:6,E:1},
C:{A:4,D:1,F:3},
D:{A:2,B:6,C:1,E:5},
E:{B:1,D:5,J:1},
F:{C:3,G:2,J:5},
G:{F:2,H:1,I:3},
H:{G:1,I:1,X:2},
I:{G:3,H:1,X:8},
J:{E:1,F:5,X:6},
X:{H:2,I:8,J:6},
};
//Dsp类:
类Dsp{
构造函数(){
//更新距离后的上一个节点
this.prev={};
//每个节点的距离
这个.distance={};
//未访问邻居数组
this.unvisitedn=[];
//访问的节点从第一个节点到最后一个节点的路径
this.path=[];
}
findsp(图形、开始、结束){
//寄存器图形数据
这个.registerGraphData(图,开始);
//将起始节点设置为当前节点
让cn=开始;
//而存在未访问的节点
而(this.unvisitedn.length>0){
//将当前节点标记为已访问
本网站为markAsVisited(cn);
//比较从当前节点到未访问邻居的距离
设nodes=this.compareNodeDistances(图,cn);
//更新邻居距离
this.updateNodeDistances(节点,cn);
//比较每个未访问的邻居并选择距离最小的邻居
//将所选节点设置为新的当前节点
cn=this。选择nextnode(图形,cn);
}
返回此.generatePath(开始、结束);
}
registerGraphData(图形,开始){
//设置所有节点的起始权重
恒高重量=10000;
//对于图中的每个节点
for(图中的let节点){
//如果该节点是起始节点
如果(节点==开始)
//将起始重量设置为0
这个。距离[节点]=0;
//否则就定高了
其他的
这个。距离[节点]=更高的重量;
//添加到未访问的节点
此.unvisitedn.push(节点);
}
console.log(这是距离);
console.log(this.unvisitedn);
}
马克斯(中国){
console.log('访问',cn);
设index=this.unvisitedn.indexOf(cn);
这是一个未经检查的拼接(索引1);
}
GetUnvisitedNeights(图,cn){
//所有当前节点邻居
设nbs=图[cn];
设unbs=[];
对于(让nb进入nbs){
如果(未访问的,包括(nb))
推压(nb);
}
log(cn,‘未访问的邻居:’,unbs);
返回unbs;
}
比较距离(图表,cn){
设unbs=this.getUnvisitedNeights(图,cn);
//新距离
设newdistance={};
//对于所有currentNode邻居
对于(unbs的let nb){//替换的unbs
//邻域权重
设nbw=图[cn][nb];
//console.log(“邻居重量”,nbw);
//邻域距离
设nbd=这个。距离[nb];
//console.log('邻居距离',nbd);
//当前节点距离
设cnd=this.distance[cn];
//console.log('当前节点距离',cnd);
//如果邻居距离>当前节点距离+邻居权重
如果(nbd>cnd+nbw)
新距离[nb]=cnd+nbw;
}
console.log('新距离:',新距离);
返回新距离;
}
updateNodeDistances(节点,cn){
//更新已比较的每个邻居的距离
for(让节点进入节点){
console.log(节点);
这个。距离[节点]=节点[节点];
this.prev[node]=cn;
}
log(“更新后的节点距离”,this.distance);
log(“更新后的节点之前的节点”,this.prev);
}
选择下一个节点(图形,cn){
设unbs=this.getUnvisitedNeights(图,cn);
让心灵=100000;
设nextn=null;
//如果有未访问的邻居
如果(unbs.length>0){
对于(让nb代表unbs){
如果(这个距离[nb]log(shp.findsp(图'A','I')问题在于您没有执行最佳优先搜索。您的代码实际上执行深度优先搜索,您只需优化将从当前节点中选择的未访问邻居。但是,您应该在所有未访问的节点之间选择距离最小的节点,而不仅仅是在当前节点的邻居之间

另请参见算法说明的步骤6:

  • 否则,选择标有最小暂定距离的未访问节点,将其设置为新的“当前节点”
  • 所以问题出在
    选择nextnode
    中。可以更正为:

    selectNextNode(graph, cn) {
        let mindist = Infinity;
        let best;
        for (let node of this.unvisitedn) {
            if (this.distances[node] < mindist) {
                mindist = this.distances[node];
                best = node;
            }
        }
        return best;
    }