Dijkstra算法|单源最短路径|贪心算法

      单愿最短路径描述:给定带权有向图G=(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称之为(origin)。现在要计算从源到其他各顶点的最短路径的长度。这里的路径长度指的是到达路径各边权值之和。

      Dijkstra算法是解单源最短路径问题的贪心算法。Dijkstra算法的基本思想是:设置顶点集合S并不断地做贪心选择来扩充集合。一个顶点属于集合S当且仅当从源点到该顶点的最短路径长度已知。贪心扩充就是不断在集合S中添加新的元素(顶点)。
      初始时,集合S中仅含有源(origin)一个元素。设curr是G的某个顶点,把从源到curr且中间只经过集合S中顶点的路称之为从源到顶点curr的特殊路径,并且使用数组distance记录当前每个顶点所对应的最短路径的长度。Dijkstra算法每次从图G中的(V-S)的集合中选取具有最短路径的顶点curr,并将curr加入到集合S中,同时对数组distance进行必要的修改。一旦S包含了所有的V中元素,distance数组就记录了从源(origin)到其他顶点的最短路径长度。

算法演示 [演示素材来源于网络|点击下载]

核心代码:
      Dijkstra描述:带权有向图G=(V,E),V={1,2,3,...}。顶点origin是源。数组distance[index]表示当前源到顶点index的最短路径长度。数组prev[index]表示源点到达index顶点最短路径的前一个顶点[Dijkstra只能获取最短路径的长度,通过prev记录前驱顶点可以很方便的获取详细的最短路径]
      数据结构与代码:

public struct DIJGraph
        {
            public int[] vexs;
            public int[][] arcs;
            public int num;
        }

        public static bool DIJKSTRA(int origin,DIJGraph g,int[] distance,int[] prev)
        {
            if (origin < 0 || origin >= g.num)
                return false;
            bool[] s = new bool[g.num];

            for (int index = 0; index < g.num; ++index)
            {
                s[index] = false;
                distance[index] = g.arcs[origin][index];
                prev[index] = (distance[index] == Int32.MaxValue) ? -1 : origin;
            }
            distance[origin] = 0;
            s[origin] = true;
            for (int i = 0; i < g.num; ++i)
            {
                int temp = Int32.MaxValue;
                int curr = 0;
                for (int index = 0; index < g.num; ++index)
                {
                    if (!s[index] && distance[index] < temp)
                    {
                        curr = index;
                        temp = distance[index];
                    }
                }
                s[curr] = true;

                for (int index = 0; index < g.num; ++index)
                {
                    if (!s[index] && g.arcs[curr][index] < Int32.MaxValue)
                    {
                        int newDistance = distance[curr] + g.arcs[curr][index];
                        if (newDistance < distance[index])
                        {
                            distance[index] = newDistance;
                            prev[index] = curr;
                        }
                    }
                }
            }
            return true;
        }

      贪心选择性质|最优子结构性质是Dijkstra算法所具备的。不过,虽然Dijkstra算法是解决单源最短路径的一款很优秀的算法,但是如果在图中存在多条最短路径,Dijkstra算法只能获取路径的长度,而无法给出最短路径的详细情况。即使在代码中添加distance[index]表示当前源到顶点index的最短路径长度。数组prev[index]来记录前驱点,但是一旦存在多条最短路径,我们只能获取最先遇到的那条(或者最后遇到的那条路径)[往往,我们偏向于获取的是最短路线而非路长]。总之,Dijkstra算法还有许多改进的地方。
      本文提供的核心代码使用C#实现,您可以点击下载获取源代码[点击下载C语言实现代码]。

本文系个人学习笔记|转载请保留本文链接blog.iliyang.cn

转载于:https://my.oschina.net/sunshinedabby/blog/80443

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值