博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[单纯形法与线性规划]【学习笔记】
阅读量:6383 次
发布时间:2019-06-23

本文共 3110 字,大约阅读时间需要 10 分钟。

很早以前学过理论,3个月前又学了一遍写了一点笔记,现在觉得以(已)前(经)写(完)的(全)太(忘)丑(记)于是重写一遍

参考资料:

1.算法导论

2.2016国家集训队论文


 

标准型

$Maximize\quad \sum\limits_{j=1}^{n} c_jx_j$

$Satisfy\quad constraint:$

$\sum\limits_{j=1}^{n} a_{ij}x_j \le b_i,\ i=1,2,...,m$

$x_j \ge 0,\ j=1,2,...,n$

 

$n$个变量,$m+n$个约束

构造$m*n$的矩阵$A$,$m$维向量$b$,$n$维向量$c$

 

$Maximize\quad c^Tx$

$Satisfy\quad constraint:$

$Ax \le b$

$x \ge 0$

 

转化为标准型:

 

 

松弛型

松弛变量$x_{n+i}$

$ \sum\limits_{j=1}^{n} a_{ij}x_j \le b_i\  \rightarrow\  $$x_{n+i}=b_i - \sum\limits_{j=1}^{n} a_{ij}x_j,\ x_{n+i} \ge 0$

等式左侧为基本变量,右侧为非基本变量

 


 

 

单纯型算法

每个约束定义了$n$维空间中的一个半空间(超平面),交集形成的可行域是一个凸区域称为单纯型

目标函数是一个超平面,最优解在凸区域定点处取得

 

基本解:非基本变量值为$0$,基本变量为右侧的常数

基本可行解:所有$b_i \ge 0$

通过不断的转轴操作,在$n$维凸区域的顶点上不断移动(转轴),使得基本解的目标值不断变大,最终达到最优解

 

转轴:

选取一个非基本变量$x_e$为替入变量,基本变量$x_l$为替出变量,将其互换

为了防止循环,根据$Bland$规则,选择下标最小的变量

 

初始化:

算法导论上有一个辅助线性规划的做法

但我发现好多人都用了随机初始化的黑科技

在所有$b_i < 0$的约束中随机选一个作为$x_l$,再随机选一个$a_{le} < 0$的作为$x_e$,然后$Pivot(l,e)$后$b_i$就变正了...

 


代码实现:

直接用一个$a[][]$来保存目标函数和约束

$Pivot$里的各种操作推导一下很清楚,用了两个$trick$避免了一些判断

$id$用来保存基本变量和非基本变量集合

 

针对全幺模矩阵可以进行提取非零系数的优化

#include
#include
#include
#include
#include
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]
View Code

 


 

 

 

问题转化为单纯型:

最短路

最大流

最小费用最大流

多商品流(目前没写过)

 

对偶性:

${Max\ c^Tx\ :\ Ax \le b,\ x \ge 0}\ \quad {Min b^Ty\ :\ A^Ty \ge c,\ t \ge 0}$

最大化与最小化互换,常数与目标函数互换,改变不等号,变量与约束对应

最大流与最小割

二分图最大权匹配与最小顶标和

最小顶标和:一个带权二分图,两个顶点的顶标之和不小于连接它们的边的边权,求最小顶标和

所有边权为$1$,就是最大匹配和最小点覆盖

 

$d_{uv}$表示$u,v$是否匹配

$Max\quad \sum\limits_{(u,v)\in E}c_{uv}d_{uv}$

$Sat$

$\sum\limits_{v \in Y}d_{uv} \le 1 \quad \quad u \in X$

$\sum\limits_{u \in X}d_{uv} \le 1 \quad \quad v \in Y$

$d_{u,v}\in \{0,1\}$

 

令$p_u,p_v$为两类约束对偶之后的变量

$Min\quad \sum\limits_{u \in X}p_u + \sum\limits_{v \in Y}p_v$

$Sat$

$p_u+p_v \ge c_{uv} \quad \quad u \in X,v \in Y$

$p_u,p_v \ge 0$

 

 

全幺模矩阵(totally unimodular matrix)

充分条件:

1.仅有$-1,0,1$构成

2.每列至多两个非零数

3.行可分为两个集合:

一列包含两个同号非零数,两行不在同一个集合

一列包含两个异号非零数,两行在同一个集合

 

线性规划中$A$为全幺模矩阵,则单纯形法过程中所有系数$\in{-1,0,1}$

可以去除系数为$0$的项进行优化!

任何最大流、最小费用最大流的线性规划都是全幺模矩阵

 

转载地址:http://lgwha.baihongyu.com/

你可能感兴趣的文章
IOS-导航路线
查看>>
word2010图片仅仅显示边框
查看>>
启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法...
查看>>
数据质量及数据清洗方法
查看>>
排序算法(一)桶排法
查看>>
【POJ 1062】昂贵的聘礼(最短路)
查看>>
vim:去掉响铃
查看>>
Spring 小示例
查看>>
MySql清空表的方法介绍 : truncate table 表名
查看>>
codeforces水题100道 第四题 Codeforces Round #105 (Div. 2) A. Insomnia cure (math)
查看>>
利用 SPL 快速实现 Observer 设计模式: SplSubject 、SplObserver与SplObjectStorage【转】
查看>>
C\C++ 1A2B小游戏源码
查看>>
【SDK fix】iOS 8下将UIButton放置于tabbar位置无法响应event
查看>>
Android项目实战(三十八):2017最新 将AndroidLibrary提交到JCenter仓库(图文教程)...
查看>>
地平线“小目标”:2025年,三千万汽车搭载地平线自动驾驶BPU
查看>>
“2016大数据技术与应用人才培养研讨会” 在泸州成功召开
查看>>
大数据和数字化转型
查看>>
如何知道自己的CPU支持SLAT
查看>>
客户端在使用citrix应用如何开启本地输入法
查看>>
C# 一个字符串是否在另外一个字符串数组里 Array.Exists 的用法 Array.IndexOf 用法...
查看>>