[单纯形法与线性规划]【学习笔记】
很早以前学过理论,3个月前又学了一遍写了一点笔记,现在觉得以(已)前(经)写(完)的(全)太(忘)丑(记)于是重写一遍
参考资料:
1.算法导论
2.2016国家集训队论文
标准型
个变量,个约束
构造的矩阵,维向量,维向量
转化为标准型:
松弛型
松弛变量
等式左侧为基本变量,右侧为非基本变量
单纯型算法
每个约束定义了维空间中的一个半空间(超平面),交集形成的可行域是一个凸区域称为单纯型
目标函数是一个超平面,最优解在凸区域定点处取得
基本解:非基本变量值为,基本变量为右侧的常数
基本可行解:所有
通过不断的转轴操作,在维凸区域的顶点上不断移动(转轴),使得基本解的目标值不断变大,最终达到最优解
转轴:
选取一个非基本变量为替入变量,基本变量为替出变量,将其互换
为了防止循环,根据规则,选择下标最小的变量
初始化:
算法导论上有一个辅助线性规划的做法
但我发现好多人都用了随机初始化的黑科技
在所有的约束中随机选一个作为,再随机选一个的作为,然后后就变正了...
代码实现:
直接用一个来保存目标函数和约束
里的各种操作推导一下很清楚,用了两个避免了一些判断
用来保存基本变量和非基本变量集合
针对全幺模矩阵可以进行提取非零系数的优化

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef long long ll; const int N=25; const double eps=1e-8,INF=1e15; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} return x*f; } int n,m,type; double a[N][N],ans[N]; int id[N<<1]; int q[N]; void Pivot(int l,int e){ swap(id[n+l],id[e]); double t=a[l][e]; a[l][e]=1; for(int j=0;j<=n;j++) a[l][j]/=t; for(int i=0;i<=m;i++) if(i!=l && abs(a[i][e])>eps){ t=a[i][e]; a[i][e]=0; for(int j=0;j<=n;j++) a[i][j]-=a[l][j]*t; } } bool init(){ while(true){ int e=0,l=0; for(int i=1;i<=m;i++) if(a[i][0]<-eps && (!l||(rand()&1))) l=i; if(!l) break; for(int j=1;j<=n;j++) if(a[l][j]<-eps && (!e||(rand()&1))) e=j; if(!e) {puts("Infeasible");return false;} Pivot(l,e); } return true; } bool simplex(){ while(true){ int l=0,e=0; double mn=INF; for(int j=1;j<=n;j++) if(a[0][j]>eps) {e=j;break;} if(!e) break; for(int i=1;i<=m;i++) if(a[i][e]>eps && a[i][0]/a[i][e]<mn) mn=a[i][0]/a[i][e],l=i; if(!l) {puts("Unbounded");return false;} Pivot(l,e); } return true; } int main(){ freopen("in","r",stdin); srand(317); n=read();m=read();type=read(); for(int i=1;i<=n;i++) a[0][i]=read(); for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++) a[i][j]=read(); a[i][0]=read(); } for(int i=1;i<=n;i++) id[i]=i; if(init() && simplex()){ printf("%.8lf\n",-a[0][0]); if(type){ for(int i=1;i<=m;i++) ans[id[n+i]]=a[i][0]; for(int i=1;i<=n;i++) printf("%.8lf ",ans[i]); } } }
问题转化为单纯型:
最短路
最大流
最小费用最大流
多商品流(目前没写过)
对偶性:
最大化与最小化互换,常数与目标函数互换,改变不等号,变量与约束对应
最大流与最小割
二分图最大权匹配与最小顶标和
最小顶标和:一个带权二分图,两个顶点的顶标之和不小于连接它们的边的边权,求最小顶标和
所有边权为,就是最大匹配和最小点覆盖
表示是否匹配
令为两类约束对偶之后的变量
全幺模矩阵(totally unimodular matrix)
充分条件:
1.仅有构成
2.每列至多两个非零数
3.行可分为两个集合:
一列包含两个同号非零数,两行不在同一个集合
一列包含两个异号非零数,两行在同一个集合
线性规划中为全幺模矩阵,则单纯形法过程中所有系数
可以去除系数为的项进行优化!
任何最大流、最小费用最大流的线性规划都是全幺模矩阵
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具