学了单纯形决定写个小结,方便以后复习。
这里只打算写结论和实现过程,证明什么的统统没有。
定义
标准型
最大化
满足
松弛型
每个约束都引入一个松弛变量
xn+i
,
最大化
满足
对偶性
给定上面的标准型线性规划,定义其对偶线性规划为
最小化
满足
此对偶线性规划的最优值等于原始线性规划的最优值。
转化到标准型
对于最小化目标函数,取反转化成最大化。
对于等式约束,拆成两个大于等于和小于等于的不等式约束。
符号与标准型相反的约束,取反。
对于取值范围无限制的变量
xi
,用两个新变量
xi1
和
xi2
来表示,其中
xi=xi1−xi2,xi1,xi2≥0
。
更简洁的表示形式
称松弛型中左边的变量为基本变量,右边的变量为非基本变量。
用集合
N
表示非基本变量下标集合,
用
z
来表示目标函数值,并添加一个常数项
最大化
满足
其他
满足所有约束的一组
x
称为可行解。
将非基本变量(等式右边)取
若基本解满足所有约束则称为基本可行解。
单纯形算法
方便起见先假设初始状态得到的基本解可行,即所有的 bi 非负。
主要思想
每次选择一个非基本变量
xi
(称为替入变量),满足对应的目标函数上的系数
ci
为正,增大它的值直到某个基本变量(称为替出变量)变为
0
。然后重写松弛型,交换替入变量和替出变量,并更新目标函数和其他约束上的系数。
每一轮迭代后,目标函数的值将不变或增大。
转动
假设我们已经找到了替入变量
首先要先交换
xe
和
xl
的位置,变
xe
为基本变量。
其次是把新式子带入其他约束和目标函数中,得到新的松弛型。
代码
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]-=a[i][e]*b[l];
for (int j=1;j<=n;j++)
if (j!=e) a[i][j]-=a[i][e]*a[l][j];
a[i][e]*=-a[l][e];
}
v+=c[e]*b[l];
for (int i=1;i<=n;i++)
if (i!=e) c[i]-=a[l][i]*c[e];
c[e]*=-a[l][e];
}
选择替入变量和替出变量
选择一个系数在目标函数中为正值的非基本变量
xe
,若不存在(即目标函数所有系数均
≤0
)说明目标函数已达到最优值。
检查每个约束,找出一个约束,使得该约束限制
xe
可取的最大值尽量小,设这个约束的基本变量为
xl
。若没有约束可以限制
xe
的取值,说明该目标函数无界。
由于所有的非基本变量都为0,因此第
i
个约束可以写成
因此找到满足
aie>0
且
bi/aie
最小的
i
即可。
代码
double SIMPLEX(){
for (;1;){
int e=-1,l=-1;
for (int i=1;i<=n;i++)
if (c[i]>eps){
e=i;break;
}
if (e==-1) break;
double tmp=inf;
for (int i=1;i<=m;i++)
if (a[i][e]>eps && b[i]/a[i][e]<tmp)
l=i,tmp=b[i]/a[i][e];
if (l==-1) return inf;
PIVOT(l,e);
}
return v;
}
还存在的问题
在OI中遇到的许多问题(比如网络流)都可以直接使用单纯形。虽然单纯形算法不是多项式时间算法,但是实际运行效果往往较好。对于题目中的原始线性规划,当初始基本解不是可行解时,一般可以通过转化成对偶线性规划来得到基本可行解。
需要注意的是单纯形算法求出的解是在实数范围内,许多题目可能会要求整数解,但是一般可以转化成线性规划的问题(比如网络流)通常有些奇怪的性质(咦?)使得实数解和整数解的最优目标值一样。即使单纯形算法并不能得到正确的答案也能骗到十分可观的分数。
因此如果只是想大概地了解一下单纯形算法并使用,看到这里就可以辣。
初始基本可行解
前面说到初始基本解可能并不可行,因此我们需要找到一个基本可行解,或者判断该线性规划不存在可行解。
辅助线性规划
设
最大化
满足
若 Laux 的最优目标值为0,那么 L 是可行的,否则不可行。
判定可行性
当
此时在
Laux
中找到一个
l
使得
若 Laux 最优解目标值为0,说明 L 是可行的。
求出基本可行解
由于
退化
单纯形算法每次迭代都会使目标函数不变或增大,这其中可能会出现一种退化情况,即循环现象,使得算法不会终止。
Bland规则:在选择替入变量和替出变量时,总是选择满足条件的下标中最小的,这样可以避免循环。算法最多在