线性规划与对偶

感谢 lcw 学长的 blog,讲的很清晰,受益匪浅。

本文使用大量非正式语言,如有需要可以去看原论文。

定义

称形如 f(x1,,xn)=i=1naixi 的函数为线性函数。

f(x1,,xn)b,f(x1,,xn)=b,f(x1,,xn)b 为线性约束。

称满足所有限制的解 (x1,,xn) 为可行解,使目标函数达到最优的可行解称为最优解,所有可行解构成的区域为解空间。

标准型线性规划

形如

maxj=1ncjxjs.t.j=1nai,jxjbii[1,m]xj0j[1,n]

的问题为标准型线性规划。

可用矩阵表示为

maxcTxs.t.Axbx0

松弛型线性规划

形如

maxj=1ncjxjs.t.xi+n=bij=1nai,jxji[1,m]xj0j[1,n+m]

的问题为松弛型线性规划。

容易将标准型线性规划转化为松弛型线性规划

单纯形

单纯形算法是一种解决松弛型线性规划的算法。

maxj=1ncjxjs.t.xi+n=bij=1nai,jxji[1,m]xj0j[1,n+m]

x1,,xn 为基变量,称 xn+1,,xn+m 为非基变量。

定义转轴操作 pivot(i,j),以实现一个交换基变量和非基变量的效果。具体地,将 xi+n=bij=1nai,jxj 改写为 xj=biai,jkjai,kai,jxk1ai,jxi+n,将其他式子中的 xj 如是替换即可。

算法流程如下。先假设 bi 均非负。

初始显然有一可行解 i[1,n+m],xi=0。此时答案为 0

不断执行如下操作,找到一个 j 满足 cj>0,然后:

  • i[1,m],ai,j0,此时可令 xj=,可使答案为正无穷且符合所有约束,故答案无界。
  • i[1,m],ai,j>0,找出所有 ai,j>0biai,j 最小的 i,执行 pivot(i,j),考虑 b 的非负性是否仍然满足。考虑 ki,若 bk<0bkak,jbiai,j<0,显然 ak,j>0,于是 bkak,j<biai,j,这与 biai,j 最小矛盾。这次转轴操作会使答案增加 cjbjai,j

j[1,n],cj0,则解 i[1,n+m],xi=0 为最优解,原线性规划问题的答案即为所有转轴操作累加的答案。

算法理论复杂度上界是指数级的,期望时间复杂度 O(nm2)

关于算法的正确性,引用 lcw 博客的一段:

考察一个线性规划的解空间,这个解空间是多个线性不等式解空间的交。可以证明每个线性不等式的解空间都是一个凸形区域(凸形区域的一个直观定义是,区域内任意两点连线上的点都属于这个区域),那么它们的交也是一个凸形区域。

因为解空间是凸形的,所以考虑在解空间内从一个初始解开始,进行爬山算法,这样所找到的局部最优解一定是全局最优解,因为 “山顶” 只有一个。

我们还没解决存在 bi 为负数的情况,考虑辅助线性规划

maxx0s.t.xi+n=bij=1nai,jxj+x0i[1,m]xj0j[0,n+m]

我这里也完全没看懂,直接把 lcw 的解释贺上来。

显然,若 (x1,,xn+m) 是原线性规划的一组可行解,那么辅助线性规划的最优解 (x0,,xn+m)
应当使 x0=0
。另一方面,若辅助线性规划的最优解 (x0,,xn+m)
满足 x0=0
,那么 (x1,,xn+m) 就是一组原线性规划的可行解。

从而我们只需求出辅助线性规划的最优解即可。

而对于辅助线性规划,找到 i[1,m],bi 最小的那个。然后执行转轴操作 pivot(i,0)
。此时对于任意 ki

bk=bkbi0,从而转换成 bk 均非负的线性规划问题。

namespace Simplex {
	double a[N][N], b[N], c[N];
	double ans;
	int n, m;
	void pivot(int l, int e) {
		b[l] /= a[l][e];
		for(int j = 1; j <= n; j++)
			if(j != e) a[l][j] /= a[l][e];
		a[l][e] = 1 / a[l][e];
		for(int i = 1; i <= m; i++)
			if(i != l && fabs(a[i][e]) > 0) {
				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[i][e] * a[l][e];
			}
		ans += c[e] * b[l];
		for(int j = 1; j <= n; j++)
			if(j != e) c[j] -= c[e] * a[l][j];
		c[e] = -c[e] * a[l][e];
	}
	double simplex() {
		while(1) {
			int e = n, l = 0;
			for(; e; e--)
				if(c[e] >(double)0) break;
			if(!e) return ans;
			double mn = 1e18;
			for(int i = 1; i <= m; i++)
				if(a[i][e] > (double)0 && mn > b[i] / a[i][e])
					mn = b[i] / a[i][e], l = i;
			if(mn == 1e18) return 1e18;
			pivot(l, e);
		}
	}
} using namespace Simplex;

对偶

标准型线性规划形如

maxcTxs.t.Axbx0

规定其对偶形式为

minbTys.t.ATycy0

规定以上两种线性规划互为对偶。

弱对偶定理

在上面的定义下,有 maxcTxminbTy

证明较显然。

强对偶定理

在上面的定义下,有 maxcTx=minbTy

证明极为复杂。

posted @   Terac  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示