線性規劃與單純形 學習筆記

2021-08-03 13:07:50 字數 3335 閱讀 4271

就是用於解決線性規劃問題的一般演算法。

時間複雜度比較玄學,不是多項式演算法,但是實際表現不錯。

線性規劃

在給定有限資源和競爭約束的情況下,要最大化或最小化某個目標,如果可以把目標描述為某些目標的線性函式,且約束為某些變數的不等式或等式,那我們就可以得到乙個線性規劃問題,如網路流問題就是特殊的線性規劃。

幾個經典問題的線性規劃表達:

最短路: 最大

化:dt

滿足約束:dv

<=du

+w(u

,v)

ds=0

,di≥

0 最大流: 最大

化:∑v

∈vfl

owsv

−∑v∈

vflo

wvs

滿足約束

:flo

wuv≤

cap(

u,v)

∑v∈vflo

wvu=

∑v∈v

flow

uv f

uv≥0

最小費用最大流: 最小

化:∑(

u,v)

cost

(u,v

)flo

wuv

滿足約束

:flo

wuv≤

cap(

u,v)

∑v∈vflo

wsv−

∑v∈v

flow

vs=m

axfl

ow ∑

v∈vf

lowv

u=∑v

∈vfl

owuv

fuv≥0

線性規劃表示方法

標準型: 最大

化:∑i

=1nc

ixi

滿足約束

:∑j=

1nai

j∗xj

≤bii

=1,2...,m

xi≥0i=1

,2,.

..,n

要把普通的式子轉化為標準型怎麼搞呢?很簡單:

若目標是要最小化,取個負號就變最大化了。

若有變數沒有非負約束,拆成xi

=x′i

−x′′i

,x′i

,x′′i

≥0。 若有等式,就變成大於等於和小於等於兩個約束。若有大於等於約束,就取反。

鬆弛型:

為了用單純形演算法,我們更喜歡將約束表示成等式,

對於 m

個標準型中的約束,我們加

m個變數,改為 滿足

約束:x

i+n=

bi−∑

j=1n

aijx

i xi

≥0其中左邊的

x 被稱為基本變數,右邊為非基本變數。我們記基本變數的集合為

b,非基本變數集合為

n 。這樣我們就能用乙個元組 (n

,b,a

,b,c

,v)表示乙個鬆弛形: 最大

化:z=

v+∑i

∈nci

xi 滿

足約束:

xi=b

i−∑j

∈nai

jxj,

i∈b

xi≥0

,i∈(

b∪n)

主要思想:大概可以理解成」不等式的高斯消元」。單純形通過不斷改變基本變數與非基本變數的集合,不斷重寫鬆弛形,直到變成最優解顯而易見的形式。

鬆弛形的基本解: 所有非基本變數xi

=0,得到基本變數 xi

+n=b

i ,這樣一組解,此時目標函式z=

v+∑i

∈nci

xi=v

。 主要步驟:

1.先找到一組初始的基本可行解。(下面會解釋)

2.找到乙個在目標函式中係數為正的非基本變數

e ,我們希望使他變大。若找不到說明已經到最優解了,結束演算法。

3.在m個約束中找到乙個限制e的值最緊的約束 l。

4.交換

e 與

l中的基本變數 的位置,即重寫約束

l ,使

e變為基本變數,原本

l 中的基本變數變為非基本變數。然後把其他的約束和目標函式中的

e替換掉。這個過程稱為一次轉動。

5.回到步驟2。

關於第乙個步驟,找基本解可行解:

由於一開始的 bi

不一定非負,所以基本解不合法,我們需要進行一些轉動使得bi

為正。

如何搞呢?

有一種玄學的簡單搞法是這樣的:每次瞎jb隨機選乙個負的bi,在對應的約束中瞎jb隨機選乙個係數負的

x , 然後轉動一下,這樣這個約束就負負得正了。不斷重複上述過程,直到找不到負的bi的為止。

這個搞法不能保證正確性,但是簡單一些。

正常的方法應該是建立乙個輔助線性規劃,不過好像用上面的玄學演算法的人更多。

輔助線性規劃:

(留坑…)

正確性證明什麼的不會。

下面是模板(uoj176),有很多細節,但理解步驟後都不是問題,各人有各人的寫法。

#include

#include

#include

#include

using

namespace

std;

const

int maxn=55;

const

double eps=1e-8;

int n,m,type;

double a[maxn][maxn],ans[maxn];

int id[maxn*2];

void pivot(int l,int e)

}bool init()

return

true;

}bool ******x()

if(!e) break;

for(int i=1;i<=m;i++)

if(-a[i][e]<-eps&&a[i][0]/a[i][e]<_min) _min=a[i][0]/a[i][e], l=i;

if(!l) return

printf("unbounded\n"),false;

pivot(l,e);

}return

true;

}int main()

for(int i=1;i<=n;i++) id[i]=i;

if(init()&&******x())

}return

0;}

單純形 學習筆記

想學好久了,這幾天終於看懂了,來寫一發。線性規劃是指具有以下形式的問題 max x ia i left forall i,sum a x i b i forall i,x i ge 0 end right.不過對於 le 的形式,我們可以通過鬆弛變數來實現,具體來說就是 max x ia i lef...

單純形法與線性規劃 學習筆記

很早以前學過理論,3個月前又學了一遍寫了一點筆記,現在覺得以 已 前 經 寫 完 的 全 太 忘 醜 記 於是重寫一遍 1.演算法導論 2.2016國家集訓隊 maximize quad sum limits c jx j satisfy quad constraint sum limits a x...

線性規劃 單純形演算法

作者 dylanfrank 滔滔 這裡簡要總結一下線性規劃的單純形演算法,做如下幾個方面的總結,其餘以後再來填坑.先看這樣乙個問題 我們很容易用下面的數學語言來描述這個問題ma xzs.t6x1 4x2 x1 2 x2 x 1 x2 x2xi 5x1 4x2 24 6 1 2 0如果我們用幾何來描述...