zoukankan      html  css  js  c++  java
  • 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());
                }
            }
        }
    }
  • 相关阅读:
    [LC] 270. Closest Binary Search Tree Value
    [LC] 452. Minimum Number of Arrows to Burst Balloons
    [LC] 494. Target Sum
    [LC] 350. Intersection of Two Arrays II
    [LC] 349. Intersection of Two Arrays
    [LC] 322. Coin Change
    scala--函数和闭包
    scala-- 内建控制结构
    scala--函数式对象
    scala --操作符和运算
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/2862459.html
Copyright © 2011-2022 走看看