线性规划与对偶
感谢 lcw 学长的 blog,讲的很清晰,受益匪浅。
本文使用大量非正式语言,如有需要可以去看原论文。
定义
称形如
称
称满足所有限制的解
标准型线性规划
形如
的问题为标准型线性规划。
可用矩阵表示为
松弛型线性规划
形如
的问题为松弛型线性规划。
容易将标准型线性规划转化为松弛型线性规划
单纯形
单纯形算法是一种解决松弛型线性规划的算法。
称
定义转轴操作
算法流程如下。先假设
初始显然有一可行解
不断执行如下操作,找到一个
- 若
,此时可令 ,可使答案为正无穷且符合所有约束,故答案无界。 - 若
,找出所有 中 最小的 ,执行 ,考虑 的非负性是否仍然满足。考虑 ,若 即 ,显然 ,于是 ,这与 最小矛盾。这次转轴操作会使答案增加 。
若
算法理论复杂度上界是指数级的,期望时间复杂度
关于算法的正确性,引用 lcw 博客的一段:
考察一个线性规划的解空间,这个解空间是多个线性不等式解空间的交。可以证明每个线性不等式的解空间都是一个凸形区域(凸形区域的一个直观定义是,区域内任意两点连线上的点都属于这个区域),那么它们的交也是一个凸形区域。
因为解空间是凸形的,所以考虑在解空间内从一个初始解开始,进行爬山算法,这样所找到的局部最优解一定是全局最优解,因为 “山顶” 只有一个。
我们还没解决存在
我这里也完全没看懂,直接把 lcw 的解释贺上来。
显然,若
是原线性规划的一组可行解,那么辅助线性规划的最优解
应当使
。另一方面,若辅助线性规划的最优解
满足
,那么就是一组原线性规划的可行解。
从而我们只需求出辅助线性规划的最优解即可。
而对于辅助线性规划,找到
最小的那个。然后执行转轴操作
。此时对于任意
有
,从而转换成 均非负的线性规划问题。
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;
对偶
标准型线性规划形如
规定其对偶形式为
规定以上两种线性规划互为对偶。
弱对偶定理
在上面的定义下,有
证明较显然。
强对偶定理
在上面的定义下,有
证明极为复杂。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!