• [小明学算法]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
  • 相关阅读:
    WCF 路由功能
    ado.net2.0的SqlTransaction使用方法
    IIS7、IIS8添加net.tcp协议报错 "未将对象引用设置到对象的实例。"
    windows phone 7 调用 wcf
    kettle连接mssql(Driver class 'net.sourceforge.jtds.jdbc.Driver' could not be found, make sure the 'MS SQL Server' driver (jar file) is installed)
    hive源码编译
    传奇1.76版本私服物品过滤单(去除祖玛级别)
    中国电信摘机系统xml
    初中英语
    视频播放器
  • 原文地址:https://www.cnblogs.com/WongSiuming/p/5045733.html
Copyright © 2020-2023  润新知