1. 程式人生 > >圖-最短路徑-Floyd演算法

圖-最短路徑-Floyd演算法

給定高鐵的規劃方案,如何求任意兩點的最短路呢?

方法是Floyd演算法。

演算法思想:

1、計算從i出發,跳點為空,直接到j 的最短路。記做D[i][j]。

2、可選跳點為1時,i到j的路徑分為兩種情況:

或者不經過1, 此時前者最短為D[i][j],

或者經過1,此時最短為D[i][1]+D[1][j]

所以D[i][j]=min{D[i][j,D[i][1] + D[1][j] }

3、可選跳點為{1,2}時i到j的路徑分為兩種情況。

或者不經過2,此時最短為D[i][j],

或者經過2,此時最短為D[i][2] + D[i][j]

所以所以D[i][j]=min{D[i][j,D[i][2] + D[2][j] }

遞推到可選跳點為{1..k}

D[i][j]=min{D[i][k],D[i][k] + D[k][j] }

可選跳點為{1..n}時,意味者對中間經過的頂點不加任何限制,此時所得的最短路就是全域性最短路。D[i][j]=min{D[i][j],D[i][n] + D[n][j] }

演算法複雜度O(G.vernum^3)

演算法實現:

typedef char   PathMatrix[50];
typedef int    DistancMatrix[MVNUM][MVNUM];
void ShortestPath_FLOYD(MGraph G,PathMatrix P[MVNUM][MVNUM],DistancMatrix &D){
	/*用Floyd演算法求有向網G中各頂點v和w之間的最短路徑P[v][w]及其帶權長度D[v][w]。
	計算得到跳點為空時的最短路D[i][j] 可選跳點為k時 或者不經過k 此時前者最短D
	[i][j] 經過1此時最短為D[i][1]+D[1][k] 可選跳點到n時 意味著對中間的頂點沒
	有限制 ,此時的最短路就是全域性最短路  */
    int i,j,k;
	char s[5],s1[50],s2[50];
    for(i=0;i<G.vexnum;i++)
		for(j=0;j<G.vexnum;j++)	{
		   D[i][j]=G.arcs[i][j].adj;
		   if(D[i][j]<INFINITY){
		      s[0]=G.vexs[i];
			  s[1]='-';
			  s[2]='>';
			  s[3]=G.vexs[j];
		      s[4]='\0';
			  strcpy(P[i][j],s);
		   }
		}
    for(k=0;k<G.vexnum;k++)
		for(i=0;i<G.vexnum;i++)
			for(j=0;j<G.vexnum;j++)
			  if(D[i][j]>D[i][k]+D[k][j]) {           //如果只關心兩點間是否有通路,則可以用1和0表示連通與不連通
			      D[i][j]=D[i][k]+D[k][j];            //改為:d[i][j] = d[i][j]||(d[i][k] && d[k][j]) 是為有向圖的傳遞閉包
			      strcpy(s1,P[i][k]);
                  strcpy(s2,P[k][j]);
				  strcpy(P[i][j],strcat(s1,Change(s2)));
			  }
	for(i=0;i<G.vexnum;i++)
        for(j=0;j<G.vexnum;j++)
			if(i!=j)
				printf("%s %d\n",P[i][j],D[i][j]);
}

修改字串 刪去s串第一個字母.

char *Change(char *s){
	//修改字串 刪去s串第一個字母
   int l=strlen(s);
   for(int i=0;i<l;i++)
      s[i]=s[i+1];
   return s;
}

鄰接表儲存:

void ShortestPath_FLOYD(ALGraph G,PathMatrix P[MVNUM][MVNUM],DistancMatrix &D){
	/*用Floyd演算法求有向網G中各頂點v和w之間的最短路徑P[v][w]及其帶權長度D[v][w]。
	計算得到跳點為空時的最短路D[i][j] 可選跳點為k時 或者不經過k 此時前者最短D
	[i][j] 經過1此時最短為D[i][k]+D[1][k] 可選跳點到n時 意味著對中間的頂點沒
	有限制 ,此時的最短路就是全域性最短路 */
	int i,j,k;
	char s[5],s1[50],s2[50];
	ArcNode *p;
    for(i=0;i<G.vexnum;i++)
		for(j=0;j<G.vexnum;j++)
			D[i][j]=INFINITY;
    for(i=0;i<G.vexnum;i++)
       for(p=G.vertices[i].firstarc;p!=NULL;p=p->nextarc) {
	      k=p->adjvex;
	      D[i][k]=p->adj;
          s[0]=G.vertices[i].data;
	      s[1]='-';
          s[2]='>';
          s[3]=G.vertices[k].data;
	      s[4]='\0';
	      strcpy(P[i][k],s);
	   }
    for(k=0;k<G.vexnum;k++)
		for(i=0;i<G.vexnum;i++)
			for(j=0;j<G.vexnum;j++){
                if(D[i][j]>D[i][k]+D[k][j]){
				   D[i][j]=D[i][k]+D[k][j];
				   strcpy(s1,P[i][k]);
                   strcpy(s2,P[k][j]);
				   strcpy(P[i][j],strcat(s1,Change(s2)));
				}
			}

	for(i=0;i<G.vexnum;i++)
        for(j=0;j<G.vexnum;j++)
			if(i!=j)
				printf("%s %d\n",P[i][j],D[i][j]);
}