最短路徑問題顧名思義,即求問題的最短路。
如有以下問題,圖中有1-5五個結點,求node1到node4的最短路徑。答案非常明顯,即1->2->4.
表示各個結點之間的路徑需要一個二元矩陣。假設\(t_{i,j}\)為路徑值,\(x_{i,j}\)用以表示是否選擇node i到node j的路徑,取值為0或1.
首先求解的目標函數是使得路徑上的數字和最小,即目標函數z為:
\[min z = \sum_{i,j}t_{i,j}*x_{i,j} \]
為了保證每一步的每個結點(除了起點和終點)都只有一個進路和一個出路,需要以下三個約束條件:
\(s.t.\hspace{1cm}\) $$\sum_{j} x_{o,j} = 1$$
\[\sum_{i}x_{i,d} = 1 \]
\[\sum_{i}x_{i,j} = \sum_{k}x_{j,k} ({\forall}j{\neq}o,d) \]
\[x_{i,j} = 0,1 \]
其中o為起點,d為終點。第一條限制了起點只有一個,第二條限制了終點只有一個,而第三條對其他結點做出了限制。確保i->j,j->k都只有一條線路,即中間結點j只有一條進路一條出路。
先創建一個Excel表格,命名為traveltime,用於存放結點路勁的二元矩陣,放入cplex模型的文件夾中,無路徑的值設置為一個較大的值:
CPLEX中.mod代碼如下:
range I=1..5;
int t[I][I]=...;
dvar boolean x[I][I];
constraint originNodeBalance;
constraint destinationNodeBalance;
constraint otherNodeBalance;
minimize sum(i in I,j in I) t[i][j]*x[i][j];
subject to
{
originNodeBalance=sum(j in I) x[1][j]==1;
destinationNodeBalance=sum(i in I) x[i][4]==1;
otherNodeBalance=forall(j in I:j!=1&&j!=4) sum(i in I) x[i][j]-sum(k in I) x[j][k]==0;
}
CPLEX中.dat代碼如下:
SheetConnection sheet("traveltime.xlsx");
t from SheetRead(sheet,"Sheet1! B2:F6");
這樣CPLEX中的模型就建好了,看看運行結果:
結果中的最短路徑為1->2->4,和肉眼判斷的結果一致。