定义:
1.找出加权图中前往X的最短路经。
2.只适用于无向图。

image.png

步骤
1.找出最短时间可以到达的节点。
2.更新该点相邻点的开销。
3.重复这个过程。
4.计算最终路经。

术语

狄克斯特拉算法用于每条边都有关数字的图,这些数组称为权重。带权重的图称为加权图,不带权重为非加权图。不能使用于有向图中,有向图中可能存在环,导致死循环。

image.png

负权边

如果有负权边不能使用狄克斯特拉算法,例如以物换物的时候就会出现负权边。
狄克斯特拉算法基于一定会前往最低权重路径,这种假设仅在没有负权变边时成立。
在负权边的图中,要找出最短路径,可以使用另一种算法(贝尔曼-福德算法)。

实现

解决这个问题需要三个散列表
1.表示每一步的权重
2.存储开销权重
3.存储父节点

  1. let graph = {};
  2. //表示了每一步的权重
  3. //第一个散列表
  4. graph['start']={};
  5. graph['start']['a']=6;
  6. graph['start']['b']=6;
  7. //第二个散列表
  8. graph['a']={};
  9. graph['a']['fin']=1;
  10. graph['a']['b']=3;
  11. //第三个散列表
  12. graph['b']={};
  13. graph['b']['fin']=5;
  14. graph['b']['a']=3;
  15. //存储到达某节点需要权重
  16. let costst={};
  17. costst['a']=6;
  18. costst['b']=2;
  19. costst['fin']= Number.POSITIVE_INFINITY;//无穷大
  20. let parents={};
  21. parents['a']='start';
  22. parents['b']='start';
  23. parents['fin']= null;//未知
  24. /**
  25. 1.只要还有要处理的节点
  26. 2.获取离起点最近的节点
  27. 3.更新其邻近点的开销
  28. 4.如有邻近点开销被更新,同时更新其父节点
  29. */
  30. //循环遍历花费找出最低权重元素并返回
  31. function find_lowest_cost_node(json_obj, arr) {
  32. let lowest_cost = Infinity
  33. let lowest_cost_node = null
  34. for (let json_obj_node in json_obj) {
  35. /**
  36. 判断当前key值对应的值是否小于当前最小开销
  37. 且不没有被处理过
  38. */
  39. if (json_obj[json_obj_node] < lowest_cost && arr.indexOf(json_obj_node) == -1) {
  40. lowest_cost = json_obj[json_obj_node]
  41. lowest_cost_node = json_obj_node
  42. }
  43. }
  44. return lowest_cost_node
  45. }
  46. // 狄克斯特拉算法
  47. function dekesitela(json_obj, json_cost, json_parent, arr) {
  48. let node = find_lowest_cost_node(json_cost, arr)
  49. //仍有需要处理的节点
  50. while (node != null) {
  51. for (let json_obj_node in json_obj[node]) {
  52. //到达当前节点开销+邻近节点开销 < 之前记录的开销
  53. if (json_cost[node] + json_obj[node][json_obj_node] < json_cost[json_obj_node]) {
  54. costs[json_obj_node] = json_cost[node] + json_obj[node][json_obj_node]
  55. json_parent[json_obj_node] = node
  56. }
  57. }
  58. // 已经检查过的最低权重元素放在数组
  59. arr.push(node)
  60. node = find_lowest_cost_node(json_cost, arr)
  61. }
  62. }
  63. dekesitela(graph, costs, parents, processed)
  64. console.log(processed)//