线性规划是求一个线性多项式的最值。
线性规划有两种形式:
1.标准型 不等式型
2.松弛型 除了非负约束,其他都是等式
变量名称:
在res=x+y+z中。
1.基本变量,基本变量是res。
2.非基本变量,如x,y,z。
单纯形法:
适用于松弛型。
单纯形法是不断通过迭代来增大最大值。达到无法更新时,就是最大值。
这就是实现的简单的过程。
然而细节又很多(算法导论上有详细的描述),这里只是简单的概述。
1.没有非负约束。
对于任意一个x没有非负约束。
则我们将x拆成y-z,y>=0,z>=0。
2.标准型转为松弛型。
我们假设x>=z,
那么我们可以假设一个res=x-z,res>=0。来进行替换。
这是两个最常见的问题。
现在,我们来谈一谈迭代背后的主要思想。
每一轮迭代,我们从目标函数中找到非负的那一个变量。
然后将任意一个方程式进行替换。将一个基本变量与一个非基本变量进行交换。
然后将它带入每一个方程式(包括目标式)中进行替换原来的基本变量。
这样会增大目标值(算法导论上有证明)。
这就是主要的思想。
uoj–线性规划
#include<cstdio>
#include<iostream>
#define For(aa,bb,cc) for(int aa=(bb);aa<=(int)(cc);++aa)
using namespace std;
const double eps=1e-8,inf=1e18;
const int maxn=21;
int n,m,t,flag;
double ans[maxn],a[maxn][maxn];
int id[maxn+maxn];
template<class T>
void read(T &x){
x=0;char c=getchar();int fuhao=1;
while(!isdigit(c)) fuhao=c=='-'?-1:fuhao,c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+(c^48),c=getchar();
x*=fuhao;
}
inline void pivot(int line,int col){
swap(id[col],id[n+line]);
double res=a[line][col];
a[line][col]=1;
For(i,0,n) a[line][i]/=res;
For(i,0,m){
if(i!=line){
res=a[i][col],a[i][col]=0;
For(j,0,n) a[i][j]-=res*a[line][j];
}
}
}
inline void init_simplex(){
int line,col;double res;
while(1){
line=col=0;res=-eps;
For(i,1,m)
if(a[i][0]<res)
line=i,res=a[i][0];
if(!line) break;
For(i,1,n)
if(a[line][i]<-eps) col=i;
if(!col){
puts("Infeasible");
flag=0;
return ;
}
pivot(line,col);
}
}
inline void simplex(){
int line,col;double res;
while(1){
line=col=0;
For(i,1,n)
if(a[0][i]>eps){
col=i;
break;
}
if(!col) break;
res=inf;
For(i,1,m)
if(a[i][col]>eps && a[i][0]/a[i][col]<res)
res=a[i][0]/a[i][col],line=i;
if(!line){
puts("Unbounded");
flag=0;
return ;
}
pivot(line,col);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
read(n),read(m),read(t);flag=1;
For(i,1,n) scanf("%lf",&a[0][i]),id[i]=i;//c[i]
For(i,1,m){
For(j,1,n) scanf("%lf",&a[i][j]);
scanf("%lf",&a[i][0]);//b[i]
}
init_simplex();
if(!flag) return 0;
simplex();
if(!flag) return 0;
printf("%.10f\n",-a[0][0]);
if(!t) return 0;
For(i,1,m) ans[id[i+n]]=a[i][0];
For(i,1,n) printf("%.10f ",ans[i]);
puts("");
return 0;
}