定义:
1.找出加权图中前往X的最短路经。
2.只适用于无向图。
步骤
1.找出最短时间可以到达的节点。
2.更新该点相邻点的开销。
3.重复这个过程。
4.计算最终路经。
术语
狄克斯特拉算法用于每条边都有关数字的图,这些数组称为权重。带权重的图称为加权图,不带权重为非加权图。不能使用于有向图中,有向图中可能存在环,导致死循环。
负权边
如果有负权边不能使用狄克斯特拉算法,例如以物换物的时候就会出现负权边。
狄克斯特拉算法基于一定会前往最低权重路径,这种假设仅在没有负权变边时成立。
在负权边的图中,要找出最短路径,可以使用另一种算法(贝尔曼-福德算法)。
实现
解决这个问题需要三个散列表
1.表示每一步的权重
2.存储开销权重
3.存储父节点
let graph = {};
//表示了每一步的权重
//第一个散列表
graph['start']={};
graph['start']['a']=6;
graph['start']['b']=6;
//第二个散列表
graph['a']={};
graph['a']['fin']=1;
graph['a']['b']=3;
//第三个散列表
graph['b']={};
graph['b']['fin']=5;
graph['b']['a']=3;
//存储到达某节点需要权重
let costst={};
costst['a']=6;
costst['b']=2;
costst['fin']= Number.POSITIVE_INFINITY;//无穷大
let parents={};
parents['a']='start';
parents['b']='start';
parents['fin']= null;//未知
/**
1.只要还有要处理的节点
2.获取离起点最近的节点
3.更新其邻近点的开销
4.如有邻近点开销被更新,同时更新其父节点
*/
//循环遍历花费找出最低权重元素并返回
function find_lowest_cost_node(json_obj, arr) {
let lowest_cost = Infinity
let lowest_cost_node = null
for (let json_obj_node in json_obj) {
/**
判断当前key值对应的值是否小于当前最小开销
且不没有被处理过
*/
if (json_obj[json_obj_node] < lowest_cost && arr.indexOf(json_obj_node) == -1) {
lowest_cost = json_obj[json_obj_node]
lowest_cost_node = json_obj_node
}
}
return lowest_cost_node
}
// 狄克斯特拉算法
function dekesitela(json_obj, json_cost, json_parent, arr) {
let node = find_lowest_cost_node(json_cost, arr)
//仍有需要处理的节点
while (node != null) {
for (let json_obj_node in json_obj[node]) {
//到达当前节点开销+邻近节点开销 < 之前记录的开销
if (json_cost[node] + json_obj[node][json_obj_node] < json_cost[json_obj_node]) {
costs[json_obj_node] = json_cost[node] + json_obj[node][json_obj_node]
json_parent[json_obj_node] = node
}
}
// 已经检查过的最低权重元素放在数组
arr.push(node)
node = find_lowest_cost_node(json_cost, arr)
}
}
dekesitela(graph, costs, parents, processed)
console.log(processed)//