圖-最短路徑-Floyd演算法
阿新 • • 發佈:2018-12-15
給定高鐵的規劃方案,如何求任意兩點的最短路呢?
方法是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]); }