[小明学算法]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 }

时间: 2024-10-23 18:55:07

[小明学算法]4.Dijkstra(迪杰斯特拉)算法的相关文章

Dijkstra迪杰斯特拉算法

迪杰斯特拉算法是用于求解图的单元最短路径问题,即某个源点到达图中其余顶点的最短路径,其核心思想是每次从剩余未归入路径的顶点中找到一个到达当前路径距离最短的顶点,将其归入路径中,共执行n-1次.该算法需要三个辅助数组,s[ ]数组用来标记各个顶点有没有被归入当前路径中,dist[ ]数组用于表示当前源点到达各个顶点的最短路径长度,path[ ]数组用来存储该顶点在最短路径中的前驱结点. #include<stdio.h> //迪杰斯特拉算法,求带权图中某个源点到到达其余各个顶点的最短路劲,其需要

Dijkstra(迪杰斯特拉)算法求解最短路径

过程 首先需要记录每个点到原点的距离,这个距离会在每一轮遍历的过程中刷新.每一个节点到原点的最短路径是其上一个节点(前驱节点)到原点的最短路径加上前驱节点到该节点的距离.以这个原则,经过N轮计算就能得到每一个节点的最短距离. 第一轮,可以计算出,2.3.4.5.6到原点1的距离分别为:[7, 9, -1, -1, 14].-1表示无穷大.取其中最小的,为7,即可以确定1的最短路径为0,2为下一轮的前驱节点.同时确定2节点的最短路径为7,路线:1->2. 第二轮,取2节点为前驱节点,按照前驱节点的

hdu 2544 最短路 题解 (dijkstra/迪杰斯特拉算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544 这道题用dijkstra模板一套就出来了. 模板:http://blog.csdn.net/xdz78/article/details/47719849 需要注意的是,这里的边应该是双向边,所以在输入边的数据的时候应该这样写: for(i=0;i<m;i++){ scanf("%d%d%d",&a,&b,&c); g.map[a][b]=g.map[b]

C# 迪杰斯特拉算法 Dijkstra

什么也不想说,现在直接上封装的方法: using System; using System.Collections.Concurrent; using System.Collections.Generic; namespace 算法 { /// <summary> /// Dijkstra /// 迪杰斯特拉算法 /// </summary> public class Dijkstra : ICloneable { /// <summary>节点集合</summa

最短路径算法——迪杰斯特拉算法(Dijkstra)

图结构中应用的最多的就是最短路径的查找了,关于最短路径查找的算法主要有两种:迪杰斯特拉算法(Dijkstra)和Floyd算法. 其中迪杰斯特拉算法(Dijkstra)实现如下: 原理就是不断寻找当前的最优解: void main() { int V[Max][Max]={0,8,32,Infinity,Infinity, 12,0,16,15,Infinity, Infinity,29,0,Infinity,13, Infinity,21,Infinity,0,7, Infinity,Infi

最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现(C/C++)

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低. Dijkstra算法是很有代表性的最短路算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等. 其基本思想是,设置顶点集合S并不断地作贪心选择来扩充这个集合.一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知. 初始时,S

最短路径之迪杰斯特拉算法(Dijkstra)

1.迪杰斯特拉(dijkstra)算法简介 Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它应用了贪心算法模式, 是目前公认的最好的求解最短路径的方法.算法解决的是有向图中单个源点到其他顶点的最短 路径问题,其主要特点是每次迭代时选择的下一个顶点是标记点之外距离源点最近的顶点.但 由于dijkstra算法主要计算从源点到其他所有点的最短路径,所以算法的效率较低. 2.dijkstra算法基本过程 假设路网中每一个节点都有标号 是从出发点s到点t的最短路径长

普里姆算法,克鲁斯卡尔算法,迪杰斯特拉算法,弗洛里德算法

做数据结构的课程设计顺便总结一下这四大算法,本人小白学生一枚, 如果总结的有什么错误,希望能够告知指正 普里姆算法如图所示prim 找出最短的边,再以这条边构成的整体去寻找与之相邻的边,直至连接所有顶点,生成最小生成树,时间复杂度为O(n2) 克鲁斯卡尔算法如图所示kruskal 克鲁斯卡尔算法,假设连通网N=(N,{E}),则令最小生成树的初始状态为只有n个顶点而无边的非连通图T=(V,{}),图中每个顶点 自成一个连通分量.在E中选择代价最小的边,若该边依附的定顶点落在T中不同的连通分量上,

最短路之Dijkstra(迪杰斯特拉)

一般用法: Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.重点----->>>>注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径