zoukankan      html  css  js  c++  java
  • Dijstra(C#)

    支持有向与无向图

    DijistraSeach.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Dijistra
    {
        public static class DijistraSeach
        {
            public class SearchResult
            {
                public int Distance { get; private set; }
                public int[] Route { get; set; }
                public SearchResult(int distance, int[] route)
                {
                    Distance = distance;
                    Route = route;
                }
            }
    
            /// <summary>
            /// 获取正确的顺序<para/>
            /// 比如footPrint为<para/>
            /// [0] = 0<para/>
            /// [1] = 0<para/>
            /// [2] = 3<para/>
            /// [3] = 0<para/>
            /// [4] = 2<para/>
            /// 从最后一行开始,[4] = 2,意味着[4]的前一个节点为[2],然后看[2] = 3这一行,2的前节点为3,如此循环直到起点。
            /// </summary>
            /// <param name="footPrint">value -> index</param>
            /// <param name="startPoint"></param>
            /// <returns></returns>
            private static int[] findRoute(int[] footPrint, int startPoint = 0)
            {
                var mapSize = footPrint.Length;
                // 反向路径
                var reversedRoute = new int[mapSize];
                // 反向路径中的当前操作序号
                int routeIndex = 0;
    
                // 添加终点
                reversedRoute[routeIndex] = mapSize - 1;
    
                routeIndex++;
    
                // 找到最末节点的前节点
                int previousIndex = footPrint[mapSize - 1];
    
                // 如果不是起点的话
                while (previousIndex != startPoint)
                {
                    // 路径不存在
                    if (previousIndex == -1)
                        return null;
    
                    // 记录此节点并继续查找前节点
                    reversedRoute[routeIndex] = previousIndex;
                    routeIndex++;
                    previousIndex = footPrint[previousIndex];
                }
    
                // 添加起点
                reversedRoute[routeIndex] = startPoint;
    
                // 将反向路径反向
                var route = new List<int>(mapSize);
                for (int i = routeIndex; i >= 0; i--)
                {
                    route.Add(reversedRoute[i]);
                }
                return route.ToArray();
            }
    
            /// <summary>
            /// search for the shortest route.
            /// </summary>
            /// <param name="routes">an array which contains {pointA, pointB, distance}
            /// <para/>e.g.
            /// <para/>var map = new[] {
            /// <para/>    new []{0,1,10},
            /// <para/>    new []{0,3,30},
            /// <para/>    new []{0,4,100},
            /// <para/>    new []{1,2,50},
            /// <para/>    new []{2,4,10},
            /// <para/>    new []{3,2,20},
            /// <para/>    new []{3,4,60},
            /// <para/>};
            /// </param>
            /// <param name="mapSize">size</param>
            /// <param name="startPoint"></param>
            /// <param name="directional"></param>
            /// <returns></returns>
            public static SearchResult Search(int[][] routes, int mapSize, int startPoint , bool directional)
            {
                // record all minIndex found during the searching progress.
                var footPrint = new int[mapSize];
                // to avoid dead searching loop.
                var visted = new bool[mapSize];
                // accumulated distance from startPoint to each index.
                var milestones = new int[mapSize];
    
                // initialize map.
                var map = new int[mapSize, mapSize];
                for (int i = 0; i < mapSize; i++)
                {
                    for (int j = 0; j < mapSize; j++)
                    {
                        map[i, j] = i == j? 0 : int.MaxValue;
                    }
                }
    
                // build map.
                foreach (var route in routes)
                {
                    map[route[0], route[1]] = route[2];
    
                    if (!directional)
                    {
                        // make the map non-directional.
                        map[route[1], route[0]] = route[2];
                    }
                }
    
                // initialize milestones by distance between each node and startPoint.
                for (int i = 0; i < mapSize; i++)
                {
                    milestones[i] = map[startPoint, i];
                    // wether i is connected to startPoint or not;
                    if (milestones[i] != int.MaxValue)
                    {
                        footPrint[i] = startPoint;
                    }
                    else
                    {
                        footPrint[i] = -1;
                    }
                }
    
                // start searching.
                for (int j = 0; j < mapSize; j++)
                {
                    // find the nearest from this index.
                    // milestones has already been updated to fit the minIndex.
                    int localMin = int.MaxValue, minIndex = startPoint;
                    for (int i = 0; i < mapSize; i++)
                    {
                        if (!visted[i] && milestones[i] < localMin)
                        {
                            minIndex = i;
                            localMin = milestones[i];
                        }
                    }
    
                    visted[minIndex] = true;
    
                    // update milestones.
                    for (int i = 0; i < mapSize; i++)
                    {
                        // index not connected to minIndex is not connected to 
                        if (map[minIndex, i] == int.MaxValue) continue;
                        if (visted[i]) continue;
    
                        // accumulate distance from startPoint to minIndex;
                        var newDis = milestones[minIndex] + map[minIndex, i];
                        if ((newDis < milestones[i]))
                        {
                            milestones[i] = newDis;
                            footPrint[i] = minIndex;
                        }
                    }
                }
    
                // the end is beyond reach.
                if (milestones[mapSize - 1] == int.MaxValue)
                    return null;
    
                var resultRoute = findRoute(footPrint, startPoint);
                var result = new SearchResult(milestones[mapSize - 1], resultRoute);
                return result;
            }
        }
    }
    View Code

    Main.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Dijistra
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 无向图
                // 使用此外图时,需将DijistraSeach.Search的directional参数设为false,mapSize=5
                var nonDirectionalMap = new[] {
                    new []{0,1,10},
                    new []{0,3,30},
                    new []{0,4,100},
                    new []{1,2,50},
                    new []{2,4,10},
                    new []{3,2,20},
                    new []{3,4,60},
                };
    
                // 有向图
                // 使用此外图时,需将DijistraSeach.Search的directional参数设为true,mapSize=2
                var directionalMap = new[]{
                    new []{1, 0, 10},
                    new []{0, 1, 11},
                };
    
                var result = DijistraSeach.Search(
                    routes: nonDirectionalMap,
                    mapSize: 5,
                    startPoint: 0,
                    directional: false
                    );
    
                if (result == null)
                {
                    Console.WriteLine("Can't find the route.");
                }
                else
                {
                    Console.WriteLine(
                    "Shortest distance is {0}
    route : {1}
    ",
                    result.Distance,
                    String.Join("->", result.Route)
                    );
                }
                
            }
        }
    }
    View Code
  • 相关阅读:
    三大主流负载均衡软件对比(LVS+Nginx+HAproxy)
    nginx 提示the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
    centos安装nginx并配置SSL证书
    hadoop创建目录文件失败
    The server time zone value 'EDT' is unrecognized or represents more than one time zone.
    脚本启动SpringBoot(jar)
    centos做免密登录
    数据库远程连接配置
    Bash 快捷键
    TCP三次握手四次断开
  • 原文地址:https://www.cnblogs.com/ornithopter/p/3791389.html
Copyright © 2011-2022 走看看