以下內容全是口胡,請謹慎觀看 ——From ATP
參見高中數學必修五第三章
根據ATP的理解。。。線性規劃就是設出一些變量,給出一些對于變量取值的限制,同時給出一個與這些變量相關的目標函數,要求在滿足限制的前提下最大化或最小化目標函數。
舉個例子:設有變量
就是一個線性規劃啦。。(上面那一坨東西是ATP隨便打上去的有沒有解就不一定了= =)
形式化地,設
我們在這里僅討論線性規劃的標準型。線性規劃的標準型表示如下:
但是很多時候好像遇到的線性規劃并不是標準型?難道它們不能做嗎。。。其實并不是,在大多數情況下,不是標準型的線性規劃都可以通過做一些適當的轉化表示成標準型。比如……
目標函數要求最小化(
首先線性規劃的限制應該都是大于等于或者小于等于這種形式的(不然計算機怎么搞出“無限接近”這種類型的答案來= =),但是在標準型里面限制都要求是小于等于,如果遇到別的符號? 如果是帶“
總之通過類似這樣的變換我們可以把任意的線性規劃轉化為標準型,并且它們的最優解都是不變的。
求解線性規劃最常用的算法是單純形算法。它的理論時間復雜度是指數級別的。。但是跑得奇快無比啊并且也基本上卡不掉。。所以放心大膽用就是了。。
單純形算法的幾何意義很多地方都有解釋。。但是這里ATP主要解釋它在代數方面的原理。
首先,為了對線性規劃使用單純形算法,我們需要把線性規劃轉化為“松弛型”,也就是說把所有的不等式變為等式。以下都用m來表示限制個數,n來表示變量個數。
為了做到這一點,我們對于每一個形如
相對的那我們就把所有
那么我們把所有的
先貼代碼,在下面解釋:
double Simplex(){ int l,e; double t; while (true){ e=n+1; for (int i=1;i<=n;i++) if (C[i]>eps){e=i;break;} if (e==n+1) break; t=inf;l=0; for (int i=1;i<=m;i++) if (A[i][e]>eps&&t>B[i]/A[i][e]){ t=B[i]/A[i][e];l=i; } if (t==inf) return inf; pivot(l,e); } return v;}上面的Simplex過程是單純形算法的主過程。首先每次先找到第一個系數大于0的非基變量。這里有一個叫做Bland法則的東西,就是說一定要選第一個系數大于0的,不然容易被特殊數據卡成死循環。。然而ATP并沒有試過= =
選中的這個非基變量就是上面的e。如果沒有找到這樣的變量,說明算法已經完成了,目標函數中的所有系數都變成負數了,就可以退出了。否則我們要把目標函數中
不同的約束條件產生的
否則我們能夠找到一個約束條件
基變量
于是上面的pivot過程就是來做這樣的變形的。這玩意兒好像學名叫“轉軸”操作,好像來源于單純形算法的幾何意義。。不管它不管它。
pivot過程是這樣的:
void pivot(int l,int e){ B[l]/=A[l][e]; for (int i=1;i<=n;i++) if (i!=e) A[l][i]/=A[l][e]; A[l][e]=1/A[l][e]; for (int i=1;i<=m;i++) if (i!=l&&fabs(A[i][e])>eps){ B[i]-=B[l]*A[i][e]; for (int j=1;j<=n;j++) if (j!=e) A[i][j]-=A[l][j]*A[i][e]; A[i][e]=-A[l][e]*A[i][e]; } v+=C[e]*B[l]; for (int i=1;i<=n;i++) if (i!=e) C[i]-=C[e]*A[l][i]; C[e]=-C[e]*A[l][e];}這里的
為了替換方便我們要把
這樣我們就完成了過程的第一步,也就是上面代碼里前4行的內容。
接下來我們要對所有除了約束條件
很容易發現替換以后約束條件
最后是對于目標函數的處理,同樣是把
最后當目標函數中所有系數都變成負數的時候,記錄的v就是線性規劃的最優解啦。
前面我們所有的討論都基于一個假設:所有非基變量取0是一組可行解。
但是很多時候我們會碰到這樣的線性規劃:
把所有系數取反?但是取反這種操作是不會改變約束條件的本質的。這個時候我們就會用到對偶原理了
形式化的,對偶原理就是說:
這兩個線性規劃是等價的。
顯然,如果我們遇到了一個這種所有非基變量取0不是可行解的線性規劃,我們可以用對偶原理把它“轉”一下,就會變成一個所有非基變量取0是可行解的線性規劃,就可以用單純形求解了。
證明?好像不大會用到,ATP也不會。。。
不過想要理解一下對偶原理的話,這篇文章還是不錯的[戳這里]。。。
參考曹欽翔《線性規劃與網絡流》。。。
ATP其實沒怎么看那個。。。
主要問題是感覺里面說的基本上就是如何把現成的網絡流模型改造成線性規劃。。。
但是既然都有了網絡流模型干嘛還要改線性規劃啊。。。(?Д?*)?
這種方法是ATP一開始看線性規劃的時候稀里糊涂學過來的。。也沒大用過。。在這里提一句吧。。
例:BZOJ1061 志愿者招募
用費用流做線性規劃的時候,我們要做的第一步仍然是列出不等式并且把它們轉化成松弛型。接下來以這個題的樣例來舉例說明操作過程。
首先設每一種志愿者的招募人數為
添加兩個約束條件
我們把它們化成這種形式是有原因的,因為我們求解的方法是網絡流,而這組等式滿足一個十分關鍵的性質——它們相加的和等于0。這可以和網絡流中的流量平衡結合起來。那么我們可以把上面的每個等式看成一個點并且按照變量的正負進行連邊,并且設定“流出為正,流入為負”,那么源點S作為唯一只有流出流量的點,它流出的流量可以看成等式右邊那些正數;匯點T作為唯一只有流入流量的點,它流入的流量可以看成等式右邊那些負數。然后我們找到每個變量
其實這個過程就是將費用流問題轉線性規劃問題的逆過程。。
新聞熱點
疑難解答