最短路径算法

using System;
using System.Collections.Generic;
using System.Text;
/*
new  DijkstraAlgCls
then SetMatrix
then Dijkstra
for function Dijkstra the return value is the list of idx (node sequence the start node not included) 
 * ref float dis is the total route distance
for the matrix 
is nodCount*nodeCount matrix the diagonal elements all set to zero matrix[i][j] represents the distance from node i to node j 
*/
namespace DijkstraImp
{
    class Dijkstragao
    {
        float[][] matrix;
        bool[] flags;
        List<int>[] routes;
        float[] Distance;
        int nodCount;
        public Dijkstragao()
        {
            
        }
        public bool SetMatrix(float[] matr)
        {
            int n = matr.Length;
            double dc = Math.Sqrt((double)n);
            nodCount = (int)dc;
            dc = dc - nodCount;
            if (dc > 0)
                return false;
            
            matrix = new float[nodCount][];
            for (int i = 0; i < nodCount; ++i)
            {
                matrix[i] = new float[nodCount];
            }
            int idx = 0;
            for (int i = 0; i < nodCount; ++i)
            {
                for (int j = 0; j < nodCount; ++j)
                {
                    matrix[i][j] = matr[idx];
                    idx++;
                }
            }
            Distance = new float[nodCount];
            for (int i = 1; i < nodCount; ++i)
                Distance[i] = -1;
            flags = new bool[nodCount];
            flags[0] = true;
            routes = new List<int>[nodCount];
            for (int i = 0; i < nodCount; ++i)
                routes[i] = new List<int>();
            return true;
        }
        void SetCurLeastFlag()
        {
            int idx = -1;
            float value=-1;
            //将路径距离值最小的U集合中的节点分配到S集合中
            for (int i = 0; i < nodCount; ++i)
            {
                if (flags[i] == false)
                {
                    if (value < 0 || (Distance[i]>0&&value > 0 && Distance[i] < value))
                    {
                        value = Distance[i];
                        idx = i;
                    }
                }
            }
            if (idx > 0)
                //将此节点放入S集合
                flags[idx] = true;
        }
        void CalculateLeastDis()
        {
            //将已经计算过的节点列为S集,未计算的节点列为U集
            //这一循环过程可理解为:每进行一次CalculateLeastDis函数运算即可向S集合中添加一个节点
            //添加节点意味着添加了一条新路径,在循环中遍历每一条路径以确定最短路径下一个节点
            for (int i = 0; i < nodCount; ++i)
            {
                //通过判断将i节点标志位S集,同时可以理解为i个已求得的路径
                if (flags[i] == true)
                {
                    for (int j = 0; j < nodCount; ++j)
                    {
                        //通过判断将j节点标志位U集
                        if (flags[j] == false)
                        {
                            //判断i,j节点是否连通
                            if (matrix[i][j] > 0)
                            {
                                float newVal = -1;
                                //Distance[i]代表S集合中的i节点已经具有的路径距离,大于0表示该节点不是起始节点
                                if (Distance[i]>0)
                                    newVal = matrix[i][j] + Distance[i];
                                else
                                    newVal = matrix[i][j];
                                //判断U集合中的当前j节点是否是第一次参与计算
                                if (Distance[j] < 0)
                                {
                                    Distance[j] = newVal;
                                    routes[j].Clear();
                                    if (Distance[i] > 0)
                                    {
                                        foreach (int iv in routes[i])
                                            routes[j].Add(iv);
                                    }
                                    routes[j].Add(j);
                                }
                                //若当前路径距离小于已有路径距离,为该节点重新分配路径
                                else
                                {
                                    if (newVal < Distance[j])
                                    {
                                        Distance[j] = newVal;
                                        routes[j].Clear();
                                        if (Distance[i] > 0)
                                        {
                                            foreach (int iv in routes[i])
                                                routes[j].Add(iv);
                                        }
                                        routes[j].Add(j);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //每生成一条新路径,对所有节点便利从而将新节点编制入S集合(通过flags判断)
            SetCurLeastFlag();
        }
        public float Dijkstra(List<int> retList)
        {
            Console.WriteLine("节点编号:0,1,2,3,4,5,6,7,8");
            float dis = -1;
            for (int i = 0; i < nodCount; ++i)
            {
                CalculateLeastDis();
                if (flags[nodCount-1] == true)
                {
                    dis = Distance[nodCount - 1];
                    foreach (int iv in routes[nodCount - 1])
                    {
                        retList.Add(iv);
                    }
                    break;
                }
            }
            int index = 0;
            Console.WriteLine();
                foreach (List<int> li in routes)
                {
                    
                    string list = "";
                    for (int ii = 0; ii < li.Count; ii++)
                    {
                        list += li[ii].ToString() + "  ";
                    }
                    Console.WriteLine();
                    Console.WriteLine(""+(index++).ToString()+"号节点路径:"+list);
                    
                    li.Clear();
                }
            routes = null;
            return dis;
        }
    }
}
View Code
原文地址:https://www.cnblogs.com/anbylau2130/p/3195274.html