最短路径搜索算法中Dijkstra的原理

一:简介

  这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点,求图中其它节点到此源节点的最短路径。如下图所示:给定源节点a,求节点b到a的最短距离。

《最短路径搜索算法中Dijkstra的原理》

(图来自于参考资料2)

那么如何寻找?还是以上图为例:

1)初始化:设定除源节点以外的其它所有节点到源节点的距离为INFINITE(一个很大的数),且这些节点都没被处理过。

2)从源节点出发,更新相邻节点(图中为2,3,6)到源节点的距离。然后在所有节点中选择一个最段距离的点作为当前节点。

3)标记当前节点为done(表示已经被处理过),与步骤2类似,更新其相邻节点的距离。(这些相邻节点的距离更新也叫松弛,目的是让它们与源节点的距离最小。因为你是在当前最小距离的基础上进行更新的,由于当前节点到源节点的距离已经是最小的了,那么如果这些节点之前得到的距离比这个距离大的话,我们就更新它)。

4)步骤3做完以后,设置这个当前节点已被done,然后寻找下一个具有最小代价(cost)的点,作为新的当前节点,重复步骤3.

5)如果最后检测到目标节点时,其周围所有的节点都已被处理,那么目标节点与源节点的距离就是最小距离了。如果想看这个最小距离所经过的路径,可以回溯,前提是你在步骤3里面加入了当前节点的最优路径前驱节点信息。

 看文字描述显得苍白无力,你可以结合上图,看下这个视频:http://v.youku.com/v_show/id_XMjQyOTY1NDQw.html (dijkstra演示),然后就清楚了。

《最短路径搜索算法中Dijkstra的原理》

二:源代码

  直接给源代码,注释很清楚,不解释。

 

《最短路径搜索算法中Dijkstra的原理》
Dijkstra.h
《最短路径搜索算法中Dijkstra的原理》
Dijkstra.c
《最短路径搜索算法中Dijkstra的原理》
main.c

demo:

输入文件内容:

1:2-2:3-4:5-4;
2:1-2:3-3;
3:1-4:2-3:5-6:6-7;
4:6-8;
5:1-4:3-6;
6:3-7:4-8;

格式说明:

起始节点:连接节点1-权值:连接节点2-权值:连接节点3-权值…..

图的结构:

《最短路径搜索算法中Dijkstra的原理》

运行结果:

《最短路径搜索算法中Dijkstra的原理》

 

三:总结

  Dijkstra最短路径搜索属于广度优先搜索(BFS, Breadth-First-Search),即不断去搜索当前节点的所有相邻节点,并更新它们的cost。更新的前提是认为:当前节点是目前与起始节点之间cost最小的节点,它认为自己是最优解,要想到达目的节点,经过我这里必然错不了,接着在此基础上不断去寻找其它最优路径,运用的是一种贪婪算法的思想。但是有时候并不是最优解,典型的例子就是:最小数目找零的例子,现有10元,5元,1元的纸币,如果要找15块钱,贪婪算法的结果是-10元+5元。但是如果现在假设银行发行了12元一张的纸币(银行闲的蛋疼),还用贪婪算法,结果是12+1+1+1(坑爹的,找这么多硬币!!)。但是实际上最优解仍然是10元+5元。所以有时候,具体问题要具体分析。另外,最优路径搜素还有带有启发性的A*搜索,双向广度优先搜索(BFS),它们比Dijkstra算法的搜索效率要高。改天再续。

  再说一下,我的代码中,在寻找下一个当前节点时,用了全局搜索,这显然是一个很笨的方法,复杂度太高。一般的方法都是定义一个开集,一个闭集,用来存储未处理过的节点和已被处理的节点,所以我们可以用FIFO队列去优化。参考资料1。

  

参考资料:

1,《数据结构与算法分析-c++描述》,weiss

2,http://en.wikipedia.org/wiki/Dijkstra’s_algorithm

3,http://blog.chinaunix.net/uid-20662820-id-142445.html

4,http://www.rawbytes.com/dijkstras-algorithm-in-c/

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/blakegao/article/details/20043443
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞