給定乙個帶權重的有向圖g=(v,e),v為頂點集,e為有向邊集,每一條有向邊均有乙個權重。對於給定的頂點s、t,以及v的子集v』,尋找從s到t的不成環有向路徑p,使得p經過v』中所有的頂點(對經過v』中節點的順序不做要求)。記邊的變數為ei
對應權重為ci
, 點記為vi
, 其出邊記為vo
ji, 其入邊記為vi
ji, 必經點記為dj
i 可以建立如下規劃方程 mi
n∑ci
ei e
i為整數
,取值0
或1必經點出邊和為1 ∑j
doji
=1所有點出邊和等於入邊和 ∑j
viji
=∑jv
oji
普通點 出邊和小於等於1 ∑j
viji
≤1起點 出邊和為1, 入邊和為0 ∑j
vijs
=0 ∑
jvoj
s=1
終點 入邊和為1, 出邊和為0 ∑j
vijs
=1 ∑
jvoj
s=0
這樣使用支援整數規劃或混合整數規劃的求解器的求解器即可以求解。這樣,就將路徑問題轉化為了線性規劃問題。
如下的拓撲中,邊上的紅色數字表示邊的id, 綠色為對應的權重。
起點為0, 終點為1, 必經點為2,3。
可行路徑為
0 -> 2 -> 3 -> 1, 權重為4
0 -> 3 -> 2 -> 1, 權重為5
但如果使用上面的模型求解,就會求出如下的結果
這樣也符合以上的模型,但很明顯,並不是起點到終點的有效路徑。
必經點之間出現了環路。但在使用模型求解之前,是無法知道哪些邊會組成環路的。
所以,最簡單的思路就是,求解一次,檢測是否出現了環路。如果有環路,就對組成環路的邊加上限制。然後重新計算。但這樣的效率明顯不高。
這裡介紹另一種防止環路的方法。
對所有邊的起點和終點,新增如下約束方程: ei
s−ei
t+ne
i≤n−
1 其中 eis
eit分別表示邊ei
的起點和終點。
如果部分邊組成了環路,則環路部分的不等式相加,左側的起點和終點恰好全部約去,就會出現n≤
n−1 的矛盾情況。
通過新增這樣的方程,即可以防止環路。
用於求解線性規劃問題的求解器有很多。我們使用的是lp_solve。之前沒有接觸過這個領域,使用之後,發現很方便。
建立模型,將模型表示為求解器的輸入格式,直接輸出結果。
使用線性規劃問題,求解路徑問題,不同於搜尋的方法。自己接觸之後,感覺思路很新穎,很神奇,彷彿開啟了另乙個世界。
而建立模型,使用求解器求解。自己感覺是不是所謂的函式式程式設計。
求解器求解之前,對應的結果其實已經被模型確定了。求解過程只是找出這個解而已。
如果模型沒有準確的描述問題,那得到的結果必然不正確。
函式式程式設計,還是得學習乙個。
python求解線性規劃問題
最近在做最優化的作業,涉及到線性規劃問題,之前運籌學也學過相關問題,都是通過手寫單純性表來進行求解的,但學了python之後感覺太麻煩了,不如利用python來幫我們求解。線性規劃求解主要弄清楚兩個部分,目標函式 max,min 和約束條件 s.t.我們求解時一般要化為python的標準形式 在此用...
linprog線性規劃求解
linprog 四要素 min quad c tx s.t.quad begin a cdot x leq b aeq cdot x beq lb leq x leq ub end 其中,c 和 x 為 n 維向量,a aeq為適當維數的矩陣,b beq為適當維數的列向量。matlab 中求解線性規...
非線性規劃問題的matlab求解
函式 x,fval fmincon fun,x0,a,b,aeq,beq,lb,ub,nonlcon 返回的x 是乙個向量 在取得目標函式最小時各個xi的取值 返回的fval 目標函式的最小值 引數fun 目標函式 引數x0 向量x的初始值 引數a 線性不等式約束的係數矩陣,若沒有線性不等式約束,則...