图论:最短路径搜索--Dijkstra算法(c代码实现)
2013-03-12 11:46
579 查看
最近因为辞职,有不少闲功夫,重温下数据结构,顺便练练手。今天说说最短路径搜索算法中的Dijkstra原理和实现。
一:简介
这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点,求图中其它节点到此源节点的最短路径。如下图所示:给定源节点a,求节点b到a的最短距离。
main.c
demo:
输入文件内容:
格式说明:
起始节点:连接节点1-权值:连接节点2-权值:连接节点3-权值.....
图的结构:
![](http://images.cnitblog.com/blog/360827/201303/12115002-3b87922c56dd414f9f9a70404e7bd81d.jpg)
运行结果:
![](http://images.cnitblog.com/blog/360827/201303/12110920-2dd84e6691454b0e89dc4dc909b7eb75.jpg)
三:总结
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/
一:简介
这个算法用于解决图中单源最短路径问题。所谓单源节点是指给定源节点,求图中其它节点到此源节点的最短路径。如下图所示:给定源节点a,求节点b到a的最短距离。
main.c
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "Dijkstra.h" int main(int argc, char *argv[]) { char filepath[MAX_STRLEN];//图的信息文件 node graphic[MAX_VERTEX_NUM] = {0};//图的数组 int sid, did; int selnum; if(argc < 2) { printf("usage:*.exe input\n"); exit(1); } strcpy(filepath, argv[1]); /***********初始化图***************/ if(!InitGraphic(filepath, graphic, MAX_VERTEX_NUM)) { UnitGraphic(graphic); exit(1); } printf("**** Print The Graphic information ****"); ViewGraphic(graphic);//打印图 /************dijkstra运算***********/ if(!Dijkstra(graphic)) { UnitGraphic(graphic); exit(1); } printf("\n****Find the shortest path between nodes****"); printf("\n1.View minimum route between nodes."); printf("\n2.Exit."); for(;;) { printf("\nEnter Your Selection:"); scanf("%d",&selnum); switch(selnum) { case 1: { printf("\nEnter source node ID:"); scanf("%d",&sid); printf("\nEnter destination node ID:"); scanf("%d",&did); MinRoute(graphic, sid, did);//打印最优路径 break; } case 2: exit(1); default: { printf("\nEnter proper choice.\n"); break; } } } UnitGraphic(graphic); return 0; }
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-权值.....
图的结构:
![](http://images.cnitblog.com/blog/360827/201303/12115002-3b87922c56dd414f9f9a70404e7bd81d.jpg)
运行结果:
![](http://images.cnitblog.com/blog/360827/201303/12110920-2dd84e6691454b0e89dc4dc909b7eb75.jpg)
三:总结
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算法(c代码实现)
- 图论:最短路径搜索--Dijkstra算法(c代码实现)
- 图论:最短路径搜索--Dijkstra算法(c代码实现)
- Dijkstra算法----单源最短路径的贪心算法Java具体代码实现
- 图论最短路径算法-Floyd算法-JAVA代码实现
- 有向图某顶点到其他顶点最短路径的C程序实现代码(Dijkstra算法)
- 最短路径算法—Dijkstra(迪杰斯特拉)算法分析与实现代码(C/C++)
- 单源最短路径问题(dijkstra算法 及其 优化算法(优先队列实现))
- 迪杰斯特拉算法求最短路径 C++代码实现
- HDU 2544-最短路(Dijkstra算法 Floyd算法 SPFA算法,3种实现代码,包含路径)
- 在SQL Server实现最短路径的搜索
- 最短路径之Dijkstra算法的概念与实现
- HDOJ 2544 最短路(最短路径 dijkstra算法,SPFA邻接表实现,floyd算法)
- CUGB图论专场:A - Domino Effect(最短路径:dijkstra算法)
- 最短路径实现(Dijkstra算法)
- 单源最短路径---贪心法实现(Dijkstra算法)
- 图论中最短路径问题C++实现
- Dijkstra算法实现非负权值最短路径的求解(另用小根堆进行优化)
- 【算法——Python实现】有权图求单源最短路径Dijkstra算法
- 数据结构与算法——最短路径Dijkstra算法的C++实现