zoukankan      html  css  js  c++  java
  • 最短路径算法

    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
  • 相关阅读:
    Data Base mysql备份与恢复
    java 乱码问题解决方案
    【知识强化】第二章 物理层 2.1 通信基础
    【知识强化】第二章 进程管理 2.2 处理机调度
    【知识强化】第二章 进程管理 2.1 进程与线程
    【知识强化】第一章 操作系统概述 1.3 操作系统的运行环境
    【知识强化】第一章 网络体系结构 1.1 数据结构的基本概念
    【知识强化】第一章 网络体系结构 1.2 计算机网络体系结构与参考模型
    【知识强化】第一章 网络体系结构 1.1 计算机网络概述
    【知识强化】第一章 操作系统概述 1.1 操作系统的基本概念
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/3195274.html
Copyright © 2011-2022 走看看