單純形演算法的原理和示例實現

作者簡介: @磊磊 本科河北工業大學電子科學與技術專業,現在中科院半導體研究所讀碩士,目前研一,方向NIRS或CV相關。自己本著興趣學習CS,ML和統計優化相關知識,寫一些自己的學習筆記為正在學習路上的小夥伴做做鋪墊,內容可能偏數學一點,因為本人算是半個數學愛好者,打的math基礎也更多是用在演算法理解方面。

歡迎原鏈接轉發,付費轉載請前往 @留德華叫獸 的主頁獲取信息,盜版必究

敬請關注和擴散本專欄及同名公眾號,會邀請全球知名學者陸續發布運籌學、人工智慧中優化理論等相關乾貨、知乎Live及行業動態:

『運籌OR帷幄』大數據人工智慧時代的運籌學--知乎專欄

寫作背景

大家都知道ML的基礎是統計和優化,作者本人這學期選了最優化計算(還沒開課),順道旁聽了一門組合優化,這次就寫寫組合優化的入門級演算法---單純形演算法,雖然這不是一個多項式演算法,但是它的應用面極為廣泛。本來沒想投入這麼多精力進去的,然後自己就淪陷了,都快拋棄主課了。數學專業上課講的東西更偏演算法設計的思想和主要流程,本人算是半個數學愛好者,除了學習數學的思維方式,也學一些CS知識敲代碼,所以追求一點細節以及代碼實現,寫出來分享一些我遇到的問題。

雖然本人不是一個數學專業的學生,但是這篇文章還是需要一些數學知識儲備的,同時也不準備舉例子,打算講清楚演算法原理和推導,害怕推導和公式者慎入。

1949年:G.B.Dantzig提出了單純形方法。關於歷史考究什麼的不想多提,可以自行搜索。

一 線性規劃問題的標準形式

線性規劃 (LP) 問題的標準型:

min z = c^T x\ s.t.egin{cases} Ax=b\ xge0 end{cases}

其中 xin R^n, cin R^n, bin R^m, Ain R^{m 	imes n}

一般總假設 bge0, (A,b,c) 的元素都為整數(線性規劃多應用在實際問題,所以要求為整數也可以理解), rank(A)=m

可行域: P = { xin R^n : Ax=b, xge0}

最優解集: P^*={xin P:x(LP) 的最優解 }

二 定理和推論

如果對仿射集,凸集,凸包和多胞形這些概念有一定的了解的話,看一些證明也有助於理解。如果對定理證明不理解也沒什麼關係,做為一名工科生,能夠理解大致意思和應用就是最好的結果。

定理1x 是可行域 P 的一個頂點 Leftrightarrow x 的正分量對應的 A 中的各列是線性獨立的。

  • 對矩陣 A 進行分解(可比對高斯消去法解方程組時,尋找主元變數的過程),移列使得前 m列線性不相關A=egin{bmatrix} B, Nend{bmatrix} , Bin R^{m 	imes m} 為滿秩矩陣,理解為矩陣 A 空間的一組基向量x=egin{bmatrix} x_B\ x_N end{bmatrix} 。則有:

egin{equation} Ax=b Leftrightarrow  Bx_B+Nx_N=b  Leftrightarrow  x_B+B^{-1}Nx_N=B^{-1}b end{equation}

Leftrightarrow  x_B=B^{-1}b-B^{-1}Nx_N ,令 x_N=0 ,若 x= egin{bmatrix} B^{-1}b\0 end{bmatrix} ge 0 ,稱之為 (LP) 的一個基可行解。

  • B 滿秩, A=egin{bmatrix} B, Nend{bmatrix} 中有 m 個基向量組成線性無關組, x=egin{bmatrix} x_B\ x_N end{bmatrix} 中有 m 個主元變數, n-m 個自由變數。通過上述分解可有以下推論:

推論1x(LP) 的一個基可行解 Leftrightarrow x in PP 的一個頂點。

推論2(LP) 的可行域至多有 C^m_n 個頂點。

如果 x_B >0, x_N=0 ,則稱一個基可行解 x=egin{bmatrix} x_B\ x_N end{bmatrix} 非退化。

由於可能有退化的情況,所以基可行解和頂點不是一一映射:任給一個基可行解,存在唯一的一個頂點與之對應;對於 P 的一個頂點,可能有多個基可行解與之對應。

如果它所對應的所有基可行解都是非退化的,則稱這個線性問題非退化。

考慮只有一個基變數不同的基可行解,可知這兩個基可行解對應的頂點相鄰。

三 單純形演算法框架

給定一個非退化的基可行解 ar x=egin{bmatrix} x_B\ x_N end{bmatrix}注意這裡沒有給出求基可行解方法,後面會說明怎麼求初始迭代的基可行解),對應的可行基為 B 則等式約束 Ax=b 變為:

x_B+B^{-1}Nx_N=B^{-1}b\ x_B=B^{-1}b-B^{-1}Nx_N

目標函數

egin{align} c^Tx &= c_B^Tx_B+c_N^Tx_N\ &=c_B^T(B^{-1}b-B^{-1}Nx_N)+c_N^Tx_N\ &= c_B^TB^{-1}b-(c_B^TB^{-1}N-c_N^T)x_N \ end{align}

規劃等價於

min c_B^TB^{-1}b-(c_B^TB^{-1}N-c_N^T)x_N\ s.t.egin{cases} x_B=B^{-1}b-B^{-1}Nx_N\ xge0 end{cases}

做以下記號:

B^{-1}b= egin{bmatrix} alpha_1\ vdots\ alpha_m end{bmatrix}B^{-1}N= egin{bmatrix} eta_{1,m+1} &eta_{1,m+2} &cdots &eta_{1,n} \ eta_{2,m+1} &eta_{2,m+2} &cdots &eta_{2,n}\ vdots & vdots & ddots & vdots \ eta_{m,m+1} &eta_{m,m+2} &cdots &eta_{m,n} end{bmatrix}

egin{bmatrix} lambda_{m+1} &lambda_{m+2} &cdots &lambda_n end{bmatrix} =c_B^TB^{-1}N-c_N^T , f_0=c_B^TB^{-1}b

則上述線性規劃問題就變成:

min f_0-(lambda_{m+1}x_{m+1}+lambda_{m+2}x_{m+2}+cdots+lambda_nx_n)\ s.t.egin{cases} x_1=alpha_1-(eta_{1,m+1}x_{m+1}+eta_{1,m+2}x_{m+2}+cdots +eta_{1,n}x_n\ x_2=alpha_2-(eta_{2,m+1}x_{m+1}+eta_{2,m+2}x_{m+2}+cdots +eta_{2,n}x_n\ cdots cdots\ x_m=alpha_m-(eta_{m,m+1}x_{m+1}+eta_{m,m+2}x_{m+2}+cdots +eta_{m,n}x_n\ x_ige0 (i=1,2,cdots,n) end{cases}

學數學的人為了表示方便,一般把上述問題轉換為一個單純形表去表示(其實就是寫成矩陣形式),但是我覺得就這樣看容易分析演算法,然後去用代碼迭代實現了。畢竟本人不是專門學數學的,怎麼方便理解怎麼來,圖也順道貼上,有點丑別見怪。

x_N= egin{bmatrix} x_{m+1}\ vdots\ x_n end{bmatrix}=0,對應的基可行解為 egin{bmatrix} B^{-1}b\ 0 end{bmatrix} ,目標函數值為 f_0

  1. 在當前給定基可行解 ar x 的情況下,若有一個 lambda_i >0 ,不妨設 lambda_{m+1} > 0 ,則可令 x_{m+1} 從0上升到某個 	heta>0 ,使得目標函數值下降。說明當前解非最優解。
  2. 如果檢驗數 lambda_{m+1} le 0,lambda_{m+2}le0,cdots,lambda_{m+n}le0,則基 egin{bmatrix} x_1,x_2,cdots,x_m end{bmatrix} 對應的基可行解 x_0 = egin{bmatrix} alpha_1,alpha_2,cdots,alpha_m,0,cdots,0 end{bmatrix}^T 是最優解。
  3. 如果目標函數有下界且存在一個檢驗數 lambda_{m+k} >0 ,則非基變數 x_{m+k} 對應的係數 eta_{1,m+k},eta_{2,m+k},cdots,eta_{m,m+k} 中至少有一個大於0.

(通俗一點就是如果當前解不是最優解,尋找入基變數和出基變數,即尋找其相鄰的頂點,在這裡就需要注意一點,為什麼要求問題非退化,退化的情況有多個基可行解對應一個頂點,迭代更新時會陷入循環出不去)

四 細節解釋

  • 求基可行解的方法

最開始聽完課就在想這怎麼劃分 A=egin{bmatrix} B, Nend{bmatrix} ,如何找一組線性無關的向量,進行高斯消去找線性無關組?可是程序化怎麼實現呢?

後來去搜了資料,簡單易行的方法就是在標準型上構造人工向量。

原始問題標準型

對約束構造人工變數

聰明的你們可能會發現約束已經變了,那目標問題求解也就變了。沒錯,所以兩種通用的方法就出來了---大M法和兩階段法。我只簡單介紹一種大M法,很容易看懂,兩階段法可以去搜資料看教材。

M是一個充分大的數,目標函數求最大就取減號,求最小就取加號。在這個問題中要有最優解,人工變數就必須取0,否則,原問題無解。這樣就很順利的得到了一個基可行解,然後代入單純形演算法進行迭代

  • 入基變數的選取:

最簡單的選取規則就是:目標函數求max,檢驗數大的為入基變數,目標函數求min,檢驗數小的為入基變數。當然還有別的選取方式,可以去搜搜相關的paper去看看。這裡只是一個簡單的科普。

  • 出基變數的選取:

最小比值法選取出基變數,當選取完入基變數 lambda_{m+k} 後,取 x_{m+k}=min  frac{alpha_i}{eta_{i,m+k}} ,相應的 x_i 做為出基變數置為0,取最小的原則是可以保證 x_ige0 (i=1,2,cdots,n) ,防止出現非負變數。

五 結語

這篇文章只是寫了單純形演算法的設計框架和原理,並沒有完全概括出來設計思想,算是入門型教學,後面我還會更新一篇文章,結合對偶單純形和原始對偶演算法來提煉出整體的設計思想,希望到時候讀者可以看得更清楚些,這篇是後面的基礎和鋪墊。

MATLAB code Demo

%匆忙之間寫的代碼,我也沒有測試有沒有問題,就是提供一個示例%大M法構造人工變數的個數可以考慮根據A有沒有單位列進行減少這個可以添加上function [x, f] = BigMsimplexmin(A, c, b)%A m*n%x n*1%b m*1%c n*1%大M法構造基可行解M=5000;[m,n] = size(A);A = [A, eye(m)];c = [c;repmat(M,m,1)];x = [zeros(n,1);b];while (1) %分離基變數和非基變數 index_B = find(x ~=0); index_N = find(x == 0); B = A(:, index_B); N = A(:, index_N);% x_B = x(index_B); x_N = x(index_N); c_B = c(index_B); c_N = c(index_N); %計算lambda,alpha,beta,f lambda = (c_B/B)*N-c_N; %1*(n-m) alpha = B; beta = BN; f = c_B*alpha; %lambda都小於0, 當前解為最優解,返回x和f if isempty(find(sign(lambda) > 0, 1)) x = x; return end % 選最大的正檢驗數作為進基變數 [~, k] = max(lambda); %更新入基變數 x_N(k) = min(alpha./beta(:, k)); %更新基變數,同時置出基變數為0 x_B = alpha - beta(:, k).*x_N; %新的x0 x = [x_B; x_N];endend

推薦閱讀:

TAG:凸優化 | 單純形法 | 機器學習 |