DijkstraImp最短路径算法

cs类
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;
            //初始化一个float类型的二维数组
            matrix = new float[nodCount][];
            for (int i = 0; i < nodCount; ++i)
            {
                //二维数组赋null
                matrix[i] = new float[nodCount];
            }
            int idx = 0;
            //将martr中的值一一赋给matrix二位数组
            for (int i = 0; i < nodCount; ++i)
            {
                for (int j = 0; j < nodCount; ++j)
                {
                    matrix[i][j] = matr[idx];
                    idx++;
                }
            }
            //距离数组Distance
            Distance = new float[nodCount];
            //将数组中的值全部赋值-1,默认为0
            for (int i = 1; i < nodCount; ++i)
                Distance[i] = -1;
            //定义布尔型数组
            flags = new bool[nodCount];
            //给第一个起点赋值为true
            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;
        }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace DijkstraImp
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Dijkstragao dij = new Dijkstragao();
                float[] matr = { 0, 2,-1, 9, 6,-1,-1,-1,-1,
                                -1, 0, 1,-1, 3,-1,-1,-1,-1,
                                -1,-1, 0,-1, 1,-1, 6,-1,-1,
                                -1,-1,-1, 0,-1,-1,-1, 4,-1,
                                -1,-1,-1, 2, 0, 9,-1, 7,-1,
                                -1,-1,-1,-1,-1, 0, 5,-1, 1,
                                -1,-1,-1,-1,-1,-1, 0,-1, 5,
                                -1,-1,-1,-1,-1, 1,-1, 0, 5,
                                -1,-1,-1,-1,-1,-1,-1,-1, 0};
                if (dij.SetMatrix(matr))
                {
                    List<int> route = new List<int>();
                    float dis = dij.Dijkstra(route);
                    dij = null;
                    Console.ReadLine();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}

 

posted @ 2013-01-16 11:36  尼姑哪里跑  阅读(145)  评论(0编辑  收藏  举报