多段圖的最短路徑問題-----動態規劃法
阿新 • • 發佈:2019-01-25
對多段圖,求最短路徑,如圖:
對其使用動態規劃法:
階段:將圖中的頂點劃分5個階段,k
狀態:每個階段有幾種供選擇的點s
決策:當前狀態應在前一個狀態的基礎上獲得。決策需要滿足規劃方程
規劃方程:f(k)表示狀態k到終點狀態的最短距離。
初始條件:f(k)=0;
方程:f(k-1)=min{f(k)+W(k-1,k)}其中W(k-1,k)表示狀態k-1到狀態k的距離
程式碼如下:
#include<limits.h> #include<iostream> using namespace std; void Init_Graph(int N,int k,int** S, int **C) { int X; int i,j; int temp=N; cout<<"輸入邊的長度:輸入1 2 4 表示點1 與 2的邊的長度為 4:首數字為0表示結束輸入"<<endl; cin>>i; while (i!=0) { cin>>j; cin>>C[i][j]; cin>>i; } cout<<"輸入每個階段有哪些點:輸入:X 1 2 3表示該階段有X個點,分別為1,2,3:"<<endl; for (i=1;i<=k;i++) { cout<<"輸入第"<<i<<"階段的狀態的點數:"; cin>>X; cout<<"這些點分別為:"; for (j=0;j<X;j++) { cin>>S[i][j]; } } } void Plan(int N,int k,int **S,int **F,int** C,int *result) { int i,j,t=N; int m; int point; //cout<<S[k][0]<<" "; point=S[k][0]; for (i=k-1;i>=1;i--)//階段 { j=0;//i階段的狀態 while (S[i][j]!=0)//狀態 { m=0;//i+1階段的狀態 F[i][j]=INT_MAX; if (C[S[i][j]][point]==INT_MAX) { while (S[i+1][m]!=0) { if (C[S[i][j]][S[i+1][m]]!=INT_MAX) { if (F[i][j]>(F[i+1][m]+C[S[i][j]][S[i+1][m]])) { F[i][j] = F[i+1][m] + C[S[i][j]][S[i+1][m]]; result[S[i][j]]=S[i+1][m]; t--; } } m++; } } else { while (S[i+1][m]!=0) { if (F[i][j]>(F[i+1][m]+C[S[i][j]][S[i+1][m]])) { F[i][j] = F[i+1][m] + C[S[i][j]][S[i+1][m]]; result[S[i][j]]=S[i+1][m]; t--; } m++; } } j++; } } cout<<"符合條件的點為:"<<endl; t=0; result[t]=1; cout<<result[t]<<" "; t=result[t]; while (t<N) { cout<<result[t]<<" "; t=result[t]; } cout<<endl<<"最短距離為:"; cout<<F[i+1][0]<<endl; } int main(int argc,char *argv[]) { int N,k; int i,j; int **C,**S,**F;//C:邊的長度,S;每個階段的狀態;F:記錄每個階段的狀態中的點到終點的距離 int *result;//輸出點 cout<<"輸入點的個數:"; cin>>N; cout<<"輸入階段數:"; cin>>k; C=new int*[N+1]; //C=(int **)malloc(sizeof(int*)*(N+1)); for (i=0;i<N+1;i++) { //C[i]=(int *)malloc(sizeof(int)*(N+1)); C[i]=new int[N+1]; for (j=0;j<N+1;j++) { C[i][j]=INT_MAX; } } S= new int*[N+1]; for (i=0;i<N+1;i++) { S[i]=new int[N+1]; memset(S[i],0,sizeof(int)*(N+1)); } F=new int *[N+1]; for (i=0;i<N+1;i++) { F[i]=new int [N+1]; for (j=0;j<N+1;j++) { F[i][j]=0; } } result=new int[N+1]; memset(result,0,sizeof(int)*(k+1)); Init_Graph(N,k,S,C); /* 多段圖的動態規劃方法 階段:k 狀態:Sk:即每個階段可供選擇的點的位置 決策:u 規劃方程:f(k)=min(f(k+1)+邊u的長度。 f(k)表示:k點到終點的最短路徑長度 初始值:F(k)=0; */ Plan(N,k,S,F,C,result); delete []result; for (i=0;i<N+1;i++) { delete []C[i]; } delete []C; for (i=0;i<N+1;i++) { delete []S[i]; } delete []S; for (i=0;i<N+1;i++) { delete []F[i]; } delete []F; return 0; }
執行結果如下: