1. 程式人生 > >·完整·單純形演算法(Simplex Algorithm),附C原始碼

·完整·單純形演算法(Simplex Algorithm),附C原始碼

前段時間參加了華為的2017軟體精英挑戰賽,用到了單純形演算法求解線性規劃問題,學習了正單純形,對偶單純形以及割平面法並用C語言實現了完整的simplex演算法。

單純形演算法是用來求解線性規劃問題的,其被用在了眾多SMT Solver中,如Yices, Z3等,都是基於的單純形演算法,其演算法效率在最壞情況下為指數級別,不過實現證明其效率在大多數情況下都是令人滿意的。

標準形式

max{b+1knckxk}

1knA1xkb1

1knAmxkbm
x1,...,xn0

對於b1,...,bm0的情況,可使用正單純形演算法求解,對於存在bi<0的情況,則需要使用對偶單純形求解

。這裡求出來的解都是非整數解,若要得到目標式的整數最優解,在前面的基礎上還需要使用割平面法,即引入Gomory(高莫雷)約束。

一些特殊情況的處理

1.對於不滿足xi0的情況,可將xi化為兩個非負數的差值,即
xi=xjxk, 其中xj,xk0
2.如果限制式子為等式,可將其化為一個大於等於和小於等於,如
a+b=c(a+bca+bc)
3.如果要求的目標式Z的最小值,則可轉化為先求Z的最大值

正單純形演算法

首先將標準形式寫為如下形式(Slack Form)
Z=b+1knckxk

y1=b11knA1xk

ym=bm1k

nAmxk

這裡引入了新的鬆弛變數y1,...,ym0,不難證明,新的形式跟原不等式等價。xk稱為basic variable(基變數), ym稱為non-basic variable(非基變數)。因為b0,所以所有的非基變數為0為一組可行解,我們就是從這個初始可行解觸發,一步一步找到最優解。下面是具體的步驟:
1.查詢ckck>0,若不存在(目標式已經無法再繼續增大),跳轉到第4步
2.找到minbiAi,即限制條件最強的一組式子
3.交換xkyi, xk變為新的基變數,yi變為新的非基變數,將其他式子中的xk替換為新的值,然後回到第1步
4.將所有的非基變數取0值,即可算出所有的基變數的值以及目標式的最大值,演算法結束

單純形的物理意義

A polyhedron dened by seven inequalities.
如上圖所示,為7個限制不等式所構成的凸多面體,每個限制條件可看成正凸多面體的一個面,凸多面體的內部(包括表面)即為可行解區域。可以證明,最優解如果存在,則一定在凸多面體的頂點上。對於三維空間來說(更高維空間可類似推廣),某個頂點比為三個或以上的平面的交點,這個交點滿足對應相交平面的限制不等式。如點A,同時滿足式子②③⑦。
演算法中第3步中的交換因子(pivot),可以看成是從凸多面體的一個頂點走向另一個頂點。

對偶單純形

在標準形式(Slack Form)中,如果bm<0,則不能直接用正單純形求解,需要使用對偶單純形,先將標準型化為正單純形的標準形式,即bm0,然後再使用正單純形進行求解。
對偶單純形的求解步驟如下:
1.引入新的鬆弛變數z0,得到如下新的標準型
Z=b+1knckxkz
y1=b11kn