C# 迪傑斯特拉(Dijkstra)算法


Dijkstra(迪傑斯特拉)算法是典型的最短路徑路由算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴展,直到擴展到終點為止。

其基本思想是,設置頂點集合S並不斷地作貪心選擇來擴充這個集合。一個頂點屬於集合S當且僅當從源到該頂點的最短路徑長度已知。

初始時,S中僅含有源。設u是G的某一個頂點,把從源到u且中間只經過S中頂點的路稱為從源到u的特殊路徑,並用數組dist記錄當前每個頂點所對應的最短特殊路徑長度。Dijkstra算法每次從V-S中取出具有最短特殊路長度的頂點u,將u添加到S中,同時對數組dist作必要的修改。一旦S包含了所有V中頂點,dist就記錄了從源到所有其它頂點之間的最短路徑長度。

 using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConAppDijkstra
{
     class Program
    {

         private  const  int MaxSize =  6;
         private  const  int INF =  32767;     // INF表示∞
         private  const  int MAXV =  4;     // 最大頂點個數
        
// 結構體的成員定義里不能直接賦值,也就是等號后的應該移除,在你后面實例化整個結構體以后,
        
// 再對Study_Data[n].input=new double[50] 其他成員類似。順便說下其實用class簡單得多。

         struct VertexType
        {
             public  string VexNo;         // 頂點編號
             public  string VexName;         // 頂點名稱
             public  string otherInfo;      // 頂點其他信息     
        } ;                                // 頂點類型
         struct MGraph                     // 圖的定義
        {
             public  int[,] edges;        // 鄰接矩陣
             public  int n, e;              // 頂點數,弧數
             public VertexType[] vexs;  // 存放頂點信息
        } ;                                // 圖的鄰接矩陣類型

         static  void Ppath( int[] path,  int i,  int v)   // 前向遞歸查找路徑上的頂點
        {
             int k;
            k = path[i];
             if (k == v)  return;     // 找到了起點則返回
            Ppath(path, k, v);     // 找頂點k的前一個頂點v

            Console.Write( " {0}, ", k);     // 輸出路徑上的終點
           
//  Ppath(path, k, j);     // 找頂點k的前一個頂點j
        }

         static  void Ppath(MGraph g, int[] path,  int i,  int v)   // 前向遞歸查找路徑上的頂點
        {
             int k;
            k = path[i];
             if (k == v)  return;     // 找到了起點則返回
            Ppath(path, k, v);     // 找頂點k的前一個頂點v

            Console.Write( " {0}, ", g.vexs[k].VexName);     // 輸出路徑上的終點
            
//  Ppath(path, k, j);     // 找頂點k的前一個頂點j
        }

         static  void Dispath( int[] dist,  int[] path,  int[] s,  int n,  int v)
        {
             int i;
             for (i =  0; i < n; i++)
            {
                 if (s[i] ==  1)
                {
                    Console.Write( "  從{0}到{1}的最短路徑長度為:{2}\t路徑為: ", v, i, dist[i]);
                    Console.Write( " {0}, ", v);     // 輸出路徑上的起點
                    Ppath(path, i, v);     // 輸出路徑上的中間點
                    Console.WriteLine( " {0} ", i);     // 輸出路徑上的終點
                }
                 else 
                    Console.WriteLine( " 從{0}到{1}不存在路徑\n ", v, i);
            }
        }

         static  void PutBothpath(MGraph g,  int[] dist,  int[] path,  int[] s,  int n,  int v,  int m)
        {
             int i;
             for (i =  0; i < n; i++)
            {
                 if (s[i] ==  1)
                {
                     // Console.Write(" 從{0}到{1}的最短路徑長度為:{2}\t路徑為:", v, i, dist[i]);
                    
// Console.Write("{0},", v);     // 輸出路徑上的起點
                    
// Ppath(path, i, v);     // 輸出路徑上的中間點
                    
// Console.WriteLine("{0}", i);     // 輸出路徑上的終點
                     if (i == m && dist[i] < INF)
                    {
                        Console.Write( "  從{0}到{1}的最短路徑長度為:{2}\t路徑為: ", g.vexs[v].VexName, g.vexs[i].VexName, dist[i]);
                        Console.Write( " {0}, ", g.vexs[v].VexName);     // 輸出路徑上的起點
                        
// Ppath(path, i, v);     // 輸出路徑上的中間點
                        Ppath(g, path, i, v);
                        Console.WriteLine( " {0} ", g.vexs[i].VexName);     // 輸出路徑上的終點
                    }
                }
                 else
                    Console.WriteLine( " 從{0}到{1}不存在路徑\n ", v, i);
            }
        }

         static  void Dijkstra(MGraph g,  int v)
        {
             int[] dist =  new  int[MAXV]; // 從原點v到其他的各定點當前的最短路徑長度
             int[] path =  new  int[MAXV]; // path[i]表示從原點到定點i之間最短路徑的前驅節點
             int[] s =  new  int[MAXV];    // 選定的頂點的集合
             int mindis, i, j, u;
            u =  0;
             for (i =  0; i < g.n; i++)
            {
                dist[i] = g.edges[v, i];        // 距離初始化
                s[i] =  0;                         // s[]置空  0表示i不在s集合中
                 if (g.edges[v, i] < INF)         // 路徑初始化
                    path[i] = v;
                 else
                    path[i] = - 1;
            }
            s[v] =  1;                   // 源點編號v放入s中
            path[v] =  0;                
             for (i =  0; i < g.n; i++)                 // 循環直到所有頂點的最短路徑都求出
            {
                mindis = INF;                     // mindis置最小長度初值
                 for (j =  0; j < g.n; j++)          // 選取不在s中且具有最小距離的頂點u
                     if (s[j] ==  0 && dist[j] < mindis)
                    {
                        u = j;
                        mindis = dist[j];
                    }
                s[u] =  1;                        // 頂點u加入s中
                 for (j =  0; j < g.n; j++)          // 修改不在s中的頂點的距離
                     if (s[j] ==  0)
                         if (g.edges[u, j] < INF && dist[u] + g.edges[u, j] < dist[j])
                        {
                            dist[j] = dist[u] + g.edges[u, j];
                            path[j] = u;
                        }
            }
           Dispath(dist, path, s, g.n, v);       // 輸出最短路徑
           
// PutBothpath(g, dist, path, s, g.n, v, 3);
        }

         static  void initdata()
        {
             int i, j;
            MGraph g;
            g.n =  4; g.e =  8;
            g.edges =  new  int[MAXV, MAXV];
            g.vexs =  new VertexType[MAXV];
             // int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
             int[,] a =  new  int[MAXV, MAXV] {
            { 0,   5,INF, 7},
            {INF, 0,   4, 2},
            { 3,   3,   0, 2},
            {INF,INF, 1, 0}
            };

             for (i =  0; i < g.n; i++)         // 建立圖的圖的鄰接矩陣
            {
                 for (j =  0; j < g.n; j++)
                {
                    g.edges[i, j] = a[i, j]; ///////////////////////////////////////////// //
                }
            }
            Console.WriteLine( " 各頂點的最短路徑: ");
        }

         static  void initialVexInfo(MGraph g)
        {
            g.vexs[ 0].VexNo =  " 0361 ";
            g.vexs[ 0].VexName =  " 西安 ";

            g.vexs[ 1].VexNo =  " 010 ";
            g.vexs[ 1].VexName =  " 北京 ";

            g.vexs[ 2].VexNo =  " 0681 ";
            g.vexs[ 2].VexName =  " 武漢 ";

            g.vexs[ 3].VexNo =  " 0571 ";
            g.vexs[ 3].VexName =  " 杭州 ";
        }
         static  void Main( string[] args)
        {
             int i, j;
            MGraph g;
            g.n =  4; g.e =  8;
            g.edges =  new  int[MAXV, MAXV];
            g.vexs =  new VertexType[MAXV];

            initialVexInfo(g);
             // int [,] anArray = new int [2, 4] {{1,2,3,4},{5,6,7,8}};
             int[,] a =  new  int[MAXV, MAXV] {
            { 05,INF, 7},
            { 50,   4, 1},
            {INF,  40,INF},
            { 7, 1,INF, 0}
            };

             for (i =  0; i < g.n; i++)         // 建立圖的圖的鄰接矩陣
            {
                 for (j =  0; j < g.n; j++)
                {
                    g.edges[i, j] = a[i, j];
                }
            }
            Console.WriteLine( " 最小生成樹構成: ");
            Dijkstra(g,  0);

            Console.ReadKey();
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM