[小明学算法]4.Dijkstra(迪杰斯特拉)算法

1.定义概念

  Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。值得注意的是,该算法要求图中不存在负权边.

2.基本思想

  设置顶点集合S,初始时,S中仅含有起始点,把从起始点到u且中间只经过S中顶点的路称为从起始点到u的特殊路径,并用数组dist记录当前每个顶点所对应的最短特殊路径的长度.Dijkstra算法每次从S外取出对应dist值最小的节点u,将其添加到S中,并对所有与u点直接相连的点重新计算dist值,若变小,则修改.一旦S中包含了所有的顶点,则dist中就记录了从起始点到所有其它顶点的最短路径长度.

  例如,对下图中的有向图,应用Dijkstra算法计算从源顶点1到其它顶点间最短路径的过程列在下表中。

  Dijkstra算法的迭代过程:

迭代

s

u

dist[2]

dist[3]

dist[4]

dist[5]

初始

{1}

-

10

maxint

30

100

1

{1,2}

2

10

60

30

100

2

{1,2,4}

4

10

50

30

90

3

{1,2,4,3}

3

10

50

30

60

4

{1,2,4,3,5}

5

10

50

30

60

 

 

 3.代码实现:

  1 using System;
  2 using System.Collections.Generic;
  3 
  4 
  5 namespace 动态规划
  6 {
  7     internal class Graphic
  8     {
  9         public List<Node> Nodes;
 10 
 11 
 12         public int[] Dijkstra()
 13         {
 14             //1.一个集合S记录了所有的找到最短路径的数据
 15             var S = new List<Node>();
 16             //2.一个数组dist记录了所有点当前的最短路径
 17             var dist = new int[Nodes.Count];
 18             for (int i = 0; i < dist.Length; i++)
 19             {
 20                 dist[i] = int.MaxValue;
 21             }
 22             //3.先加进去起点
 23             var curNode = Nodes[0];
 24             dist[0] = 0;
 25             S.Add(curNode);
 26 
 27             while (true)
 28             {
 29                 //当前节点没有边,则应该结束了把?
 30                 if (curNode.Edges == null || curNode.Edges.Count == 0)
 31                     break;
 32 
 33                 //遍历当前节点直接相连的点,更新dist值
 34                 foreach (var edge in curNode.Edges)
 35                 {
 36                     var nextNode = edge.Next;
 37                     //1.重新估值
 38                     if (dist[curNode.Id] + edge.Value < dist[nextNode.Id])
 39                         dist[nextNode.Id] = dist[curNode.Id] + edge.Value;
 40                 }
 41 
 42                 //选择dist中最小的值加入到S中
 43                 curNode = curNode.Edges[0].Next;
 44                 for (int i = 0; i < dist.Length; i++)
 45                 {
 46                     //不在S中且比当前节点的dist值小,则替换
 47                     if (!S.Contains(Nodes[i]) &&
 48                         dist[i] < dist[curNode.Id])
 49                         curNode = Nodes[i];
 50                 }
 51                 S.Add(curNode);
 52                 //所有元素都加入到S中之后,则结束
 53                 if (S.Count == Nodes.Count)
 54                     break;
 55             }
 56 
 57             return dist;
 58         }
 59 
 60         private static void Main(string[] args)
 61         {
 62             Graphic graphic = new Graphic()
 63             {
 64                 Nodes = new List<Node>()
 65                 {
 66                     new Node(0),
 67                     new Node(1),
 68                     new Node(2),
 69                     new Node(3),
 70                     new Node(4),
 71                 }
 72             };
 73 
 74             graphic.Nodes[0].Edges = new List<Edge>()
 75             {
 76                 new Edge() {Value = 10, Next = graphic.Nodes[1]},
 77                 new Edge() {Value = 100, Next = graphic.Nodes[4]},
 78                 new Edge() {Value = 30, Next = graphic.Nodes[3]},
 79             };
 80 
 81             graphic.Nodes[1].Edges = new List<Edge>()
 82             {
 83                 new Edge() {Value = 50, Next = graphic.Nodes[2]},
 84             };
 85 
 86             graphic.Nodes[2].Edges = new List<Edge>()
 87             {
 88                 new Edge() {Value = 10, Next = graphic.Nodes[4]},
 89             };
 90 
 91             graphic.Nodes[3].Edges = new List<Edge>()
 92             {
 93                 new Edge() {Value = 20, Next = graphic.Nodes[2]},
 94                 new Edge() {Value = 60, Next = graphic.Nodes[4]},
 95             };
 96 
 97             graphic.Nodes[4].Edges = new List<Edge>();
 98 
 99             var arr = graphic.Dijkstra();
100 
101             for (int i = 0; i < arr.Length; i++)
102             {
103                 Console.Write((i + 1) + ":" + arr[i].ToString() + " ");
104             }
105 
106             Console.WriteLine();
107             Console.Read();
108         }
109     }
110 
111 
112     internal class Node
113     {
114         public List<Edge> Edges;
115         public int Id;
116 
117         public Node(int id)
118         {
119             Id = id;
120         }
121     }
122 
123     internal class Edge
124     {
125         public Node Next;
126         public int Value;
127     }
128 }
View Code

 

posted @ 2015-12-14 16:45  WongSiuming  阅读(429)  评论(0编辑  收藏  举报