/**
算法及其证明请访问http://www.math.ucsd.edu/~fan/teach/202/notes/04greed.pdf
*/
let max = Infinity;
function newGraph(){
return {
vertexs:['s','2','3','4','5','6','7','t'],
edges:[
[0,9,max,max,max,14,15,max],
[9,0,24,max,max,max,max,max],
[max,24,0,6,2,18,max,19],
[max,max,6,0,11,max,max,6],
[max,max,2,11,0,30,20,16],
[14,max,18,max,30,0,5,max],
[15,max,max,max,20,5,0,44],
[max,max,19,6,16,max,44,0]
]
};
return {
vertexs:['a','b','c','d','e','f','g'],
edges:[
[0,12,max,max,max,16,14],
[12,0,10,max,max,7,max],
[max,10,0,3,5,6,max],
[max,max,3,0,4,max,max],
[max,max,5,4,0,2,8],
[16,7,6,max,2,0,9],
[14,max,max,max,8,9,0]
]
};
return {
vertexs:['A','B','C','D','E'],
edges:[
[0,5,8,max,max],
[5,0,1,3,2],
[8,1,0,max,max],
[max,3,max,0,7],
[max,2,max,7,0]
]
};
}
function dijkstra(g,sv){
let edges = g.edges;
//let sv = 0;//
let u = edges[sv].map((item,index)=>index);//未遍历顶点
//console.info(u);
let s = [];//源顶点到各顶点的最短路径值以及路径
for(let i=0;i<u.length;i++){
s.push({
w:edges[sv][u[i]],
path:[sv],
visited:false
});
}
let pre = u.map(i=>sv);//各顶点上次更新最短路径时的源顶点
u.splice(sv,1);//未遍历的顶点中移除源顶点
s[0].visited = true;
while(u.length>0){
//寻找离当源顶点最近的顶点
let minI = 0;//离s最近的顶点在u中的下标
let min = u[minI];//最近顶点
let minW = s[min].w;//最近顶点权值
for(let i=1;i<u.length;i++){
if(!s[u[i]].visited && s[u[i]].w < minW){
minI = i;
min = u[i];
minW = s[min].w;
}
}
//console.info(`min=${min}`);
//更新最短路径,上次更新最短路径时的源顶点,用于记录路径信息
for(let i=0;i<u.length;i++){
if(s[min].w + edges[min][u[i]] < s[u[i]].w){
s[u[i]].w = s[min].w + edges[min][u[i]];
pre[u[i]] = min;
}
}
u.splice(minI,1);//
s[min].visited = true;
s[min].path = s[pre[min]].path.map(i=>i);//记录当前源顶点的最短路径信息到s。以上次更新最短路径时的源顶点的路径为基础。
s[min].path.push(min);//再加上当前顶点
//console.info(`pre=`);
//console.info(pre);
}
//console.info(s);
return s;
}
function test(){
let g = newGraph();
let res = dijkstra(g,0);
console.info(res);
}
test();
dijkstra算法(附带正确性证明)
最新推荐文章于 2024-08-13 17:15:43 发布