标签:
最短路径:对于网图来说,最短路径是指两个顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点式源点,最后一个顶点是终点。以下图为例,
寻找v0到v8的最短距离。
对应解决思路:现在比较成熟的有Dijkstra(迪杰斯特拉)算法和Flord算法算法。
Dijkstra求源节点S到终结点D的最短距离的过程中,循环过程中每次确定一个源节点到其它节点T的最短距离。该距离确定后,遍历判断该节点T到其它节点的距离是否比现在S到其它节点距离短,更短的话则修改为相应长度,并将对应的路径记录。。这种求最短路径的方式与图最小生成树算法之Kruskal(克鲁斯卡尔)算法有异曲同工之妙。该算法的时间复杂度度是O(N^2),N是节点的个数。
代码如下:
int dist[MAXNUM];
int prevT[MAXNUM];
int final[MAXNUM];
int MIN;
int G[9][9]={0,1, 5, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT, MAXINT,//对应的权值矩阵
1, 0, 3, 7, 5, MAXINT ,MAXINT, MAXINT ,MAXINT,
5 ,3, 0, MAXINT ,1 ,7, MAXINT ,MAXINT ,MAXINT,
MAXINT, 7, MAXINT ,0, 2, MAXINT, 3 ,MAXINT, MAXINT,
MAXINT ,5, 1, 2, 0, 3 ,6, 9, MAXINT,
MAXINT, MAXINT ,7, MAXINT, 3, 0, MAXINT, 5, MAXINT,
MAXINT ,MAXINT ,MAXINT, 3, 6, MAXINT, 0 ,2 ,7,
MAXINT, MAXINT ,MAXINT, MAXINT, 9 ,5 ,2, 0, 4,
MAXINT, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT ,7, 4, 0};
void Short_Dijkstra() { //初始化dist和prevT int min_num; for(int i=0;i<MAXNUM;i++) { final[i]=0;//标记是否是最短路径 dist[i]=G[0][i];//对应权值 prevT[i]=0; } final[0]=1;//对v0本身就是最短的 dist[0]=G[0][0]; for(int i=1;i<MAXNUM;i++)//每次遍历v0到某个顶点最短距离 { MIN=MAXINT;//最小值 min_num=0; for(int j=1;j<MAXNUM;j++) { if(!final[j] && dist[j]<MIN) { min_num=j; MIN=dist[j];//最小值 } } final[min_num]=1;//找到最小值 for(int k=0;k<MAXNUM;k++) { if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的点上找到距离V0更短的距离 { prevT[k]=min_num;//记录经过的前驱点 dist[k]=G[min_num][k]+dist[min_num];//更新距离 } } } }
Floyd算法是一个经典的动态规划算法,它适用于寻找各个顶点之间的最短距离。从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从点i到点j,这种方法最直接,但是距离比一定最短。2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点i到节点j的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),同时记录我们走过的路径。这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。算法时间复杂度:O(n3)。
代码如下
void Short_Dijkstra() { //初始化dist和prevTT int min_num; for(int i=0;i<MAXNUM;i++) { final[i]=0; dist[i]=G[0][i]; prevT[i]=0; } final[0]=1;//对v0本身就是最短的 dist[0]=G[0][0]; for(int i=1;i<MAXNUM;i++)//每次遍历v0到某个顶点最短距离 { MIN=MAXINT;//最小值 min_num=0; for(int j=1;j<MAXNUM;j++) { if(!final[j] && dist[j]<MIN) { min_num=j; MIN=dist[j];//最小值 } } final[min_num]=1;//找到最小值 for(int k=0;k<MAXNUM;k++) { if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的点上找到距离V0更短的距离 { prevT[k]=min_num;//记录经过的前驱点 dist[k]=G[min_num][k]+dist[min_num];//更新距离 } } } }
图这两种算法最核心的思想就是:利用已有的最短的距离路径,通过这路径来不断扩充,最终实现从原点S到终点D的寻找过程。
标签:
原文地址:http://www.cnblogs.com/zhanjxcom/p/5665879.html