1. 程式人生 > >無向圖求最短路徑 迪傑斯特拉(dijkstra)演算法實現

無向圖求最短路徑 迪傑斯特拉(dijkstra)演算法實現

Dijkstra演算法說明  http://ibupu.link/?id=29
namespace ConsoleApp14
{
    class Program
    {
        public static  int M = -1;
        static void Main(string[] args)
        {

            //源點
            int start = 0;
            int sVertet= start;
            int vCount = 6;
    //圖的鄰接矩陣
            int[,] map = new int[6,6] {
                {0,7,9,M,M,14 }, //0點到其它點距離
                {7,0,10,15,M,M}, 
                {9,10,0,11,M,2 },
                {M,15,11,0,6,M },
                {M,M,M,6,0,9 },
                {14,M,2,M,9,0 }
            };
            //上一次最短距離 
            int[] lastMinEdge = new int[vCount];
            //當前最短距離
            int[] currentMinEdge= new int[vCount];
            //已經求得的最短距離
            int[] tColle = new int[vCount];

            //置為M ,M標記未記錄的結點
            for (int i = 0; i < tColle.Length; i++)
            {
                tColle[i] = M;
            }
            //置為M ,M代表未使用
            for (int i = 0; i < lastMinEdge.Length; i++)
            {
                lastMinEdge[i] = M;
            }

            //將源點加入已記錄的節點
            tColle[sVertet] = 0;
          
            while (true)
            {
                for (int i = 0; i < 6; i++)
                {
                    currentMinEdge[i] = M;
                    //未處理的頂點,
                    if (tColle[sVertet] != M && i != sVertet && tColle[i]==M)
                    {
                        //領接邊距離
                        if (map[sVertet, i] != M)
                        {
                            currentMinEdge[i] = tColle[sVertet] + map[sVertet, i];
                        }
                        else

                        {
                            //非領接邊 距離為M
                            currentMinEdge[i] = M;
                        }
                    }
                }
          
                //與上一輪比較
                for (int i = 0; i < 6; i++)
                {
                    if (lastMinEdge[i]!=M && tColle[i]==M)
                    {
                        if (currentMinEdge[i]!=M)
                        {
                            currentMinEdge[i] = lastMinEdge[i] < currentMinEdge[i] ? lastMinEdge[i] : currentMinEdge[i];
                        }
                        else
                        {
                            currentMinEdge[i] = lastMinEdge[i];
                        }
                    }
                  
                }


                //取得新結點最小路徑
                sVertet = FindMinVertetIndex(currentMinEdge);
                tColle[sVertet] = currentMinEdge[sVertet];
                //儲存當前記錄
                for (int i = 0; i < currentMinEdge.Length; i++)
                {
                    if (tColle[i]==M)
                    {
                        lastMinEdge[i] = currentMinEdge[i];
                    }
                    else
                    {
                        lastMinEdge[i] = M;
                    }
                }

                Console.WriteLine("{0}到{1}的最短路徑:{2}", start+1, sVertet + 1,tColle[sVertet]);


                if (tColle.Count(temp => temp == M) == 0)
                {
                    break;
                }
            }

            Console.ReadKey();
            Console.WriteLine();

        }


        private static int FindMinVertetIndex(int[] a)
        {

            int min = a.Where(temp=>temp!=M && temp>0).Min();
            int index = 0;

            for (int i = 0; i < a.Length; i++)
            {
                if (a[i]==min)
                {
                    index = i;
                }
            }
            return index;
        }
    }
}