單純形法與對偶定理


給自己挖坑

單純形法

一般oi中遇到的線性規划問題都長這樣

比如某一些網絡流問題,以及二分圖最大權匹配啥的,結合對偶定理,可以有很多很強的結論

以及一個最小費用流的線性規划式子

現在考慮怎么做這類問題

不妨先引入一個基變量(松弛變量)

比如說現在的系數矩陣是
比如說現在的系數矩陣是

\[\left\{ \begin{matrix} x_{11} & x_{12} & x_{13} & x_{14} & ... &x_{1n + 1}\\ x_{21} & x_{22} & x_{23} & x_{24} & ... &x_{2n + 1}\\ x_{31} & x_{32} & x_{33} & x_{34} & ... &x_{3n + 1}\\ x_{41} & x_{42} & x_{43} & x_{44} & ... &x_{4n + 1}\\ . ..\\ x_{m1} & x_{m2} & x_{m3} & x_{m4} & ... &x_{mn + 1}\\ \end{matrix} \right\}\\ 對於第i行\\ x_{i,n+1} = b_i - \sum_{j = 1}^nx_{i , j} * a_{i , j}\\ 不妨將第x_{i , k}表示出來\\ x_{i , k} = \frac{x_{i , n + 1} + \sum_{j\ !=\ k}x_{i , j} * a_{i , j} - b_i}{-a_{i , k}}\\ 給你要最大化的式子帶來的價值是\\ \frac{x_{i , n + 1} + \sum_{j\ !=\ k}x_{i , j} * a_{i , j} - b_i}{-a_{i , k}} * val_k\\ \]

這樣可以吧\(x_{i , n + 1}\)的值給去\(x_{i , k}\),這樣的操作叫做轉軸

之后就可以用這個過程來時目標函數有最大值

有一個例題吧

很容易列出線性規划式子

\[\left\{ \begin{matrix} max:c_1 * x_1 + c_2 * x_2 + ... + c_n *x_n\\ a_{11} * x_1 + a_{12} * x_2 + ... + a_{1n} * x_n <= b_1\\ .\\ .\\ a_{m1} * x_1 + a_{m2} * x_2 + ... + a_{mn} * x_n <= b_m\\ \end{matrix} \right. \]

就是一個板子題

#include<bits/stdc++.h>
#define MAXN 500
#define eps 1e-7
typedef double ll;
const ll inf  = 1e18;
using namespace std;

int n,m;
ll a[MAXN][MAXN];
int id[MAXN];

void out(){
	for(int i = 1 ; i <= n ; i++)printf("%.2f " , a[0][i]);
	puts("");
	for(int i = 1 ; i <= m ; i++){
		for(int j = 1 ; j <= n ; j++){
			printf("%.2f " , a[i][j]);
		}
		printf("%.2f " , a[i][0]);
		puts("");
	}
}

void plot(int x , int y){
	swap(id[x + n] , id[y]);
	double t = a[x][y];	a[x][y] = 1;
	for(int j = 0 ; j <= n ; j++)a[x][j] /= t;
	for(int i = 0 ; i <= m ; i++){
		if(i == x || a[i][y] < eps)continue;
		t = a[i][y] , a[i][y] = 0;
		for(int j = 0 ; j <= n ; j++)a[i][j] -= a[x][j] * t;
	}
}

bool simplex(){
	for(int i = 1 ; i <= n ; i++)id[i] = i;
	int x = 0, y = 0;
	int cnt = 0;
	ll minl;
	while(1){
		x = y = 0 , minl = inf;
		cnt++;
		for(int i = 1 ; i <= n ; i++)if(a[0][i] > eps){x = i;break;}
		if(!x)break;
		for(int i = 1 ; i <= m ; i++)if(a[i][x] > eps && minl > a[i][0] / a[i][x])minl = a[i][0] / a[i][x] , y = i;
		if(!y) {puts("Unbounded"); return false;}
		plot(y , x);
	}
	return true;
}

int main(){
	while(scanf("%d%d",&n,&m) == 2){
		memset(a , 0 ,sizeof(a));
		for(int i = 1 ; i <= n ; i++)cin>>a[0][i];
		for(int i = 1 ; i <= m ; i++){
			for(int j = 1 ; j <= n ; j++)cin>>a[i][j];
			cin>>a[i][0];
		}
		simplex();
		printf("Nasa can spend %d taka.\n",(int)ceil(-a[0][0]*m));	
	}
}

對偶定理

考慮一個基本的線性規划模型

\[\left\{ \begin{matrix} max:c_1 * x_1 + c_2 * x_2 + ... + c_n *x_n\\ a_{11} * x_1 + a_{12} * x_2 + ... + a_{1n} * x_n <= b_1\\ .\\ .\\ a_{m1} * x_1 + a_{m2} * x_2 + ... + a_{mn} * x_n <= b_m\\ x_i >= 0 \end{matrix} \right. \]

其系數矩陣為

\[\left[ \begin{matrix} a_{11} & a_{12} & ... & a_{1n}\\ a_{21} & a_{22} & ... & a_{2n}\\ a_{31} & a_{32} & ... & a_{3n}\\ .\\ .\\ a_{m1} & a_{m2} & ... & a_{mn}\\ \end{matrix} \right] \]

那么上面這個線性規划模型的對偶問題的系數矩陣為上述系數矩陣的轉置矩陣

\[\left[ \begin{matrix} a_{11} & a_{12} & ... & a_{1n}\\ a_{21} & a_{22} & ... & a_{2n}\\ a_{31} & a_{32} & ... & a_{3n}\\ .\\ .\\ a_{m1} & a_{m2} & ... & a_{mn}\\ \end{matrix} \right] ^ T\\即: \\ \left[ \begin{matrix} a_{11} & a_{21} & ... & a_{m1}\\ a_{12} & a_{22} & ... & a_{m2}\\ a_{13} & a_{32} & ... & a_{m3}\\ .\\ .\\ a_{1n} & a_{2n} & ... & a_{nm}\\ \end{matrix} \right]\\ \]

那么線性規划模型對偶過來就是

\[\left\{ \begin{matrix} max:b_1 * y_1 + b_2 * y_2 + ... + b_m *y_m\\ a_{11} * x_1 + a_{21} * x_2 + ... + a_{m1} * x_n <= c_1\\ .\\ .\\ a_{1n} * y_1 + a_{2n} * y_2 + ... + a_{nm} * y_m <= c_m\\ y_i >= 0 \end{matrix} \right. \]

基本上大多數的線性規划模型都可以通過對\(x_i\)的轉換化成標准形式

不過還是應該列個表:

並且注意:

原問題有無界解等價於對偶問題無可行解

但是對偶問題無可行解時,原問題可能為無界解或者無可行解

線性規划在網絡流中的應用

全幺模矩陣(任何一個行數列數相同的子矩陣的值都是+1/-1)

有一個很好的性質,對於一個線性規划模型的系數矩陣是一個全幺模矩陣,那么有每一個單純形法的調整系數都應當為(-1,0,1)

線性規划對偶性--->>可以通過很顯然的式子推導推導出---->>(最大流 = 最小割)

部分題目沒有很顯然的建圖,一般是轉線性規划,然后看一看是不是一個全幺模矩陣,如果是,就可以使用網絡流解決

有一個可以判斷是否是全幺模矩陣的方法


直接考慮差分,對於每一個約束 + 表示入,-表示出,直接建圖,跑一個最小最小費用流就好了

也可以直接對偶掉,做一個單純形法



線性規划與特殊的整數規划

前40分可以直接dp掉

還有一道題Codeforces 375E,有\(O(n^3)\)的dp做法,但是線性規划可以很快的做掉。。。


感覺對於這種約束很多的題,是一個不二的騙分通解


線性規划與博弈問題

納什均衡:沒有人可以通過該表自己的決策得到更多的利益

之后的都挺不可做的吧


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM