By 进栈需检票
当题目要求的最优解是整数,例如物件的数量,参与人员的数量等时,就不能继续使用之前的线性规划了(当出现小数的情况),这个时候需考虑整数规划这样的一种建模形式
但是目前所流行的求整数规划的方法,只适用于整数线性规划,不能解决一切的整数规划问题
1.变量全限制为整数时,称为纯(完全)整数规划
2.变量部分限制为整数时,称为混合整数规划
1.原线性规划有最优解,当自变量限制为整数的时候:
(1)原线性规划的最优解全为整数,则整数规划的最优解与原线性规划的最优解一致
(2)整数规划可能无解(考虑原先自变量的取值范围)
0 ≤ x 1 ≤ 1 0.1 ≤ x 2 ≤ 0.9 0 \leq x_1\leq 1 \ \ \ \ \ 0.1 \leq x_2 \leq 0.9 0≤x1≤1 0.1≤x2≤0.9
这样的情况下,考虑到自身自变量无法取整,最后的最优解不是整数就是肯定的
(3)有可行解(存在最优解),但是最优解值有变差(效果worse)
2.整数规划的最优解==不能按照实数最优解简单的取整去得到==
如此,如果简单的把 x 1 x_1 x1约等为5,那么第一个约束条件则无法完成
目标函数
m i n Z = ∑ j = 1 n x j min\ Z = \sum_{j = 1}^nx_j min Z=j=1∑nxj
约束条件
∑ j = 1 n a i j x j ≥ b i ( i = 1 , 2 , L , n ) \sum_{j = 1}^na_{ij}x_j\geq b_i\ \ (i = 1 , 2, L , n) j=1∑naijxj≥bi (i=1,2,L,n)
x j ≥ 0 ( j = 1 , 2 , L , n ) x_j \geq 0\ \ (j = 1 , 2 , L , n) xj≥0 (j=1,2,L,n)
目标函数:
前半部分是运输的总共费用,后半部分是建厂的费用(没有建厂的 x i j = 0 x_{ij} = 0 xij=0)
约束条件:
(1)运输的量应该要小于总的生产能力
(2)同时运输的量要满足于运输地的需求量
(3)定义取值限制
当题目中出现以下等式的时候(小于等于一个整数)
x 1 + x 2 ≤ 10 x_1 + x_2 \leq 10 x1+x2≤10
此时不好去分析 x 1 , x 2 x_1\ ,\ x_2 x1 , x2的整数情况
那么此时引入临时变量 x 3 x_3 x3
x 1 + x 2 + x 3 = 10 x_1 + x_2 + x_3 = 10 x1+x2+x3=10
若
x 3 ≥ 0 x_3 \geq 0 x3≥0
则必有
x 1 + x 2 ≤ 10 x_1 + x_2 \leq 10 x1+x2≤10
那么此时 x 1 , x 2 x_1\ ,\ x_2 x1 , x2两个变量的整数问题就转化到了x3身上,x3就是所谓的松弛变量
与1.1类似,此时情况为==大于等于一个整数==
x 1 + x 2 ≥ 10 x_1 + x_2 \geq 10 x1+x2≥10
x 1 + x 2 − x 3 = 10 x_1+x_2-x_3 = 10 x1+x2−x3=10
x 3 ≥ 0 x_3 \geq 0 x3≥0
只要满足 x 3 x_3 x3大于等于0,那么 x 1 + x 2 ≥ 10 x_1 + x_2 \geq 10 x1+x2≥10就一定存在,在这里, x 3 x_3 x3就是所谓的剩余变量
在这中情况下,所有的变量包括我们可能引入的松弛变量和剩余变量都需要为整数的时候
如名字所示
所有的决策变量只能去 0 , 1 0 , 1 0,1两个整数(一般适用于工作安排,非黑即白)
1.整数规划可行解是松弛问题可行域中的整数网格点
2.松弛问题无可行解,整数规划也不会有可行解
3.ILP最优质小于或等于松弛问题的最优解
4.松弛问题的最优解满足整数条件,则该最优解可以作为整数规划的最优解
首先不考虑整数约束,得到一般的线性规划问题
目标函数
m a x Z = x 1 + x 2 max\ Z = x_1+x_2 max Z=x1+x2
约束条件
14 x 1 + 9 x 2 ≤ 51 14x_1 + 9x_2 \leq51 14x1+9x2≤51
− 6 x 1 + 3 x 2 ≤ 1 -6x_1+3x_2\leq 1 −6x1+3x2≤1
x 1 , x 2 ≥ 0 x_1\ ,x_2 \geq 0 x1 ,x2≥0
(一般称之为松弛问题或者伴随问题)
法一:高中的图解法
假设 x i 0 = 2.3 x_i^0 = 2.3 xi0=2.3,则 [ x i o ] = 2 [x_i^o] = 2 [xio]=2,也就是所谓的取整计算,通过分别的去构造新的两个约束条件:
x i ≤ [ x i o ] = 2 x_i \leq [x_i^o] = 2 xi≤[xio]=2
x i ≥ [ x i o ] + 1 = 3 x_i \geq [x_i^o] + 1 = 3 xi≥[xio]+1=3
注意:一定记得是分别使用两种约束条件!!
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎨⎪⎧2x1+3x2≤142x1+x2≤9x1 ,x2≥0 且为整数
松弛问题首先看待:
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [0 , 0];
ub = [inf , inf];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
x =
3.2500
2.5000
fval =
14.7500
此时均不是整数,采用分支定界算法
① x i 0 ≤ [ x i 0 ] x_i^0 \leq [x_i^0] xi0≤[xi0]
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 ≤ 3 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1 \leq3 \\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x1≤3x1 ,x2≥0 且为整数
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [0 , 0];
ub = [3 , inf];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
x =
3.0000
2.6667
fval =
14.3333
此时任然不满足整数的条件,继续尝试
② x i 0 ≥ [ x i 0 ] + 1 x_i^0 \geq [x_i^0] + 1 xi0≥[xi0]+1
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 ≥ 4 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1 \geq 4 \\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x1≥4x1 ,x2≥0 且为整数
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [4 , 0];
ub = [inf , inf];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
x =
4.0000
1.0000
fval =
14.0000
像啊,太像了,而且只要决策变量为整数就行
但是,这个时候我们还不能确定,因为我们只尝试了 x 1 x_1 x1
③ x 2 ≤ [ x 2 ] = 2 x_2 \leq [x_2] = 2 x2≤[x2]=2
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 2 ≤ 2 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_2 \leq 2 \\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x2≤2x1 ,x2≥0 且为整数
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [0 , 0];
ub = [inf , 2];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
x =
3.5000
2.0000
fval =
14.5000
no
④ x 2 ≥ [ x 2 ] + 1 = 3 x_2 \geq [x_2]+1 = 3 x2≥[x2]+1=3
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 2 ≥ 3 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_2 \geq 3 \\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x2≥3x1 ,x2≥0 且为整数
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [0 , 3];
ub = [inf , inf];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
x =
2.5000
3.0000
fval =
13.5000
此时好像也没有哦
但是,我们还有两个决策变量一起的情况没有与考虑
鉴于只有第②种情况才是整数的,所以我们基于 x 1 ≥ 4 x_1 \geq 4 x1≥4来去思考 x 2 x_2 x2的范围是否影响最后的值
⑤
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 ≥ 4 , x 2 ≤ 2 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1 \geq 4 \ ,\ x_2 \leq 2\\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x1≥4 , x2≤2x1 ,x2≥0 且为整数
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [4 , 0];
ub = [inf , 2];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
x =
4.0000
1.0000
fval =
14.0000
same
⑥
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 ≥ 4 , x 2 ≥ 3 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1 \geq 4 \ ,\ x_2 \geq 3\\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x1≥4 , x2≥3x1 ,x2≥0 且为整数
f = [-3 , -2];
A = [2 3;
2 1];
b = [14 , 9];
lb = [4 , 3];
ub = [inf , inf];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval;
fval
----------
Output
Linprog stopped because no point satisfies the constraints.
当然,为了保险起见
⑦
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 ≤ 3 , x 2 ≥ 3 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1 \leq 3 \ ,\ x_2 \geq 3\\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x1≤3 , x2≥3x1 ,x2≥0 且为整数
x =
2.5000
3.0000
fval =
13.5000
no
⑧
m a x Z = 3 x 1 + 2 x 2 { 2 x 1 + 3 x 2 ≤ 14 2 x 1 + x 2 ≤ 9 x 1 ≤ 3 , x 2 ≤ 2 x 1 , x 2 ≥ 0 且 为 整 数 max Z = 3x_1 + 2x_2 \\ \begin{cases} 2x_1+3x_2 \leq 14\\ 2x_1+x_2 \leq 9\\ x_1 \leq 3 \ ,\ x_2 \leq 2\\ x_1\ , x_2 \geq 0 \ \ 且为整数 \end{cases} maxZ=3x1+2x2⎩⎪⎪⎪⎨⎪⎪⎪⎧2x1+3x2≤142x1+x2≤9x1≤3 , x2≤2x1 ,x2≥0 且为整数
x =
3
2
fval =
13
!,但是看来看去还是没有第②种来得大
综上所述,最大的情况为②
当然,增加了约束条件求出来的值肯定比没增加之前来的差,所以,其实我们只要分别考虑 x 1 , x 2 x_1\ ,\ x_2 x1 , x2两个决策变量的新的约束条件去分别限制求值就好了
intlinprog( )
混合整数线性规划 (MILP)在linprog( )
的基础上,基于整数的求解要求,发展出了intlinprog( )
函数
x = intlinprog(f,intcon,A,b,Aeq,beq,lb,ub,x0,options)
[x,fval,exitflag,output] = intlinprog(...)
其格式标注如下
m i n f T x { x ( i n t c o n ) a r e i n t e g e r s A ⋅ x ≤ b Aeq ⋅ x = b e q l b ≤ x ≤ u b min\ f^Tx\\ \begin{cases} x(intcon)\ are\ integers\\ \textbf{A} \cdot x \leq b\\ \textbf{Aeq} \cdot x = beq\\ lb\leq x \leq ub \end{cases} min fTx⎩⎪⎪⎪⎨⎪⎪⎪⎧x(intcon) are integersA⋅x≤bAeq⋅x=beqlb≤x≤ub
与linprog
相比,多了参数intcon
,代表了整数决策变量所在的位置
整数约束组成的向量,指定为正整数向量。intcon
中的值指示决策变量 x
中应取整数值的分量。intcon
的值在 1
到 numel(f)
范围内
intcon = [1,2,7]
表示 x(1)
、x(2)
和 x(7)
仅取整数值
m i n Z = 8 x 1 + x 2 { x 2 ( i n t c o n ) a r e i n t e g e r s x 1 + 2 x 2 ≥ − 14 − 4 x 1 − x 2 ≤ − 33 2 x 1 + x 2 ≤ 20 min \ Z = 8x_1+x_2 \\ \begin{cases} x_2(intcon)\ are\ integers\\ x_1+2x_2 \geq-14\\ -4x_1-x_2 \leq -33\\ 2x_1+x_2 \leq20 \end{cases} min Z=8x1+x2⎩⎪⎪⎪⎨⎪⎪⎪⎧x2(intcon) are integersx1+2x2≥−14−4x1−x2≤−332x1+x2≤20
f = [8 , 1];
intcon = 2;
A = [-1 , -2
-4 , -1
2 , 1];
b = [14 , -33 , 20];
[x , fval] = intlinprog(f,intcon,A,b);
x
fval
----------
Output
x =
6.5000
7.0000
fval =
59.0000
m a x Z = 5 x 1 + 8 x 2 { x 1 , x 2 ( i n t c o n ) a r e i n t e g e r s x 1 + x 2 ≤ 6 5 x 1 + 9 x 2 ≤ 45 x 1 , x 2 ≥ 0 max\ Z = 5x_1+8x_2\\ \begin{cases} x_1\ , \ x_2(intcon)\ are\ integers\\ x_1+x_2\leq 6\\ 5x_1+9x_2\leq 45\\ x_1\ ,\ x_2 \geq 0 \end{cases} max Z=5x1+8x2⎩⎪⎪⎪⎨⎪⎪⎪⎧x1 , x2(intcon) are integersx1+x2≤65x1+9x2≤45x1 , x2≥0
f = [-5 , -8];
A = [1 1
5 9];
b = [6 , 45];
lb = zeros(2 , 1);
intcon=[1 , 2];
[x , fval] = intlinprog(f , intcon , A , b , [ ] , [ ] , lb , [ ]);
x
fval = -fval
----------
Output
x =
0
5.0000
fval =
40
m a x Z = 6 x 1 + 2 x 2 + 3 x 3 + 5 x 4 { 3 x 1 − 5 x 2 + x 3 + 6 x 4 ≥ 4 2 x 1 + x 2 + x 3 − x 4 ≤ 3 x 1 + 2 x 2 + 4 x 3 + 5 x 4 ≤ 10 x j = 0 o r 1 , j = 1 , 2 , 3 , 4 max\ Z = 6x_1 + 2x_2 + 3x_3 + 5x_4\\ \begin{cases} 3x_1 - 5x_2 + x_3 + 6x_4 \geq 4\\ 2x_1 + x_2 + x_3 - x_4 \leq 3\\ x_1 + 2x_2 +4x_3 + 5x_4 \leq 10\\ x_j=0\ or \ 1, \ \ j = 1\ ,2\ ,3\ ,4 \end{cases} max Z=6x1+2x2+3x3+5x4⎩⎪⎪⎪⎨⎪⎪⎪⎧3x1−5x2+x3+6x4≥42x1+x2+x3−x4≤3x1+2x2+4x3+5x4≤10xj=0 or 1, j=1 ,2 ,3 ,4
f = [-6 , -2 , -3 , -5];
A=[-3 5 -1 -6
2 1 1 -1
1 2 4 5];
b=[-4 , 3 , 10];
intcon=[1 ,2 , 3 , 4];
lb = zeros(4 , 1);
ub = ones(4 , 1);
[x , fval] = intlinprog(f , intcon , A , b , [ ] , [ ] , lb , ub);
x
fval = -fval
----------
Ouptut
x =
1
0
1
1
fval =
14
当然,我们也可以使用Lingo这个软件去实现以上功能
不在此次讨论范围内
“本内容部分借鉴于:https://zhuanlan.zhihu.com/p/28387290”
①如果松弛问题无解,则此题目也无解(通用)
②如果松弛问题的最优解就是整数,则也是割平面算法的最优解(通用)
③如果松弛问题(P0)无整数解,则对原始题目增加割平面条件:
a.对P0增加一个线性约束条件,将P0的可行区域割掉一小块
b.使得整数解恰好落在割掉的那一部分,但又没有割掉原问题的可行解
Example
m a x Z = x 1 + x 2 { − x 1 + x 2 ≤ 1 3 x 1 + x 2 ≤ 4 x 1 , x 2 ≥ 0 x 1 , x 2 a r e i n t e g e r s max\ Z = x_1 + x_2\\ \begin{cases} -x_1 + x_2 \leq 1\\ 3x_1 + x_2 \leq 4\\ x_1\ ,\ x_2 \geq 0\\ x_1\ ,\ x_2 \ are\ integers \end{cases} max Z=x1+x2⎩⎪⎪⎪⎨⎪⎪⎪⎧−x1+x2≤13x1+x2≤4x1 , x2≥0x1 , x2 are integers
% LP
f = [-1 , -1];
A = [-1 , 1
3 , 1];
b = [1 , 4];
lb = [0 , 0];
[x , fval] = linprog(f , A , b , [ ] , [ ] , lb);
x
fval = -fval
----------
Output
x =
0.7500
1.7500
fval =
2.5000
% ILP
f = [-1 , -1];
intcon = [1 , 2];
A = [-1 , 1
3 , 1];
b = [1 , 4];
lb = [0 , 0];
[x , fval] = intlinprog(f , intcon , A , b , [ ] , [ ] , lb);
x
fval = -fval
----------
Output
x =
1
1
fval =
2.0000
这就是以上两种方法求出来的解
现在我们数形结合一下:
交点为(3/4 , 7/4),从这里我们可以看到, x 2 − 1 ≥ 0 x_2 - 1\geq 0 x2−1≥0以及 x 1 − 1 ≥ 0 x_1-1\geq 0 x1−1≥0这两个区域,割掉并不会影响到最后的取值
所以最后只保留那个正方形区域,易得解
“如上图,有这么一个整数规划问题,黑色线段是线性不等式,蓝色的点是离散的可行域,蓝色线段包围的空间是IP Hull(整数解形成的凸包,NP-hard to find,因为一旦找到,那么求解整数规划只需要求解凸包这个LP问题),在其外面黑色线段的包围是LP Hull(线性松弛解形成的凸包)
正是因为IP Hull和LP Hull中间的间隙,使得该LP的最优解是fractional(对于原问题infeasible)的,而这段间隙,对于LP(线性规划)来讲,是多余的搜索空间。如果我们在这个时候可以加上一个或多个线性不等式(cut),把无用空间完全“砍”掉,那么LP Hull = IP Hull,这时我们就得到整数解了
当然一般情况没有这么好运,可以把无用空间完全砍掉。如上图,加上红色虚线这个cut,我们砍掉了红色阴影区域这部分无用空间。虽然没有把LP Hull直接缩小成IP Hull这么立竿见影,但对于求解原问题,由于减少了搜索空间,也是一种效率上的提升
另外值得注意的是,红色虚线的cut,对于原问题(IP Hull)也是满足的(valid),它砍掉的,只是实数部分无用的搜索空间”
“如上图,我们有IP hull和LP hull,我们加上一个Lazy Constraints,这时候把顶上三个原问题的可行整数解也砍掉了
割平面法最经典的应用,莫过于Travelling Salesman Problem,个问题是每个学运筹学特别是组合优化必学的经典问题”
“如上图,TSP需要找从一点出发,遍历所有城市(1-6点)再回到出发点的cycle(回路)。为了简化问题,在master problem(初始问题)的表达式中,我们忽略subtour(小的cycle,例如上图4-5-6)约束(因为有指数级个数该约束),然后求解该IP问题
忽略掉subtour求得的IP问题虽然是整数可行解,但是其中可能存在subtour(如上图俩个subtour),因此其实并不是我们想要的解。这时候,我们设计一个启发式算法,来探测这些subtour,然后加上相应的cut砍掉这些subtour对应的整数解,然后再次求解IP。由此循环,直到求得的IP整数解中,不再存在subtour,这时候我们找到了最终问题的全局最优解”
PS:了解就行,其实这个系列的问题,intlinprog
走天下,实在不行转战linpog
,浅尝辄止即可
割平面在计算机视觉有所应用,attention
咱们还是接着上面来
截取平面之后,怎样求出 x 1 = 1 , x 2 = 1 , z = 2 x_1 =1 \ , \ x_2 = 1\ , \ z = 2 x1=1 , x2=1 , z=2?
这个时候就需要:
引入之后的效果与原先是一致的
如: − x 1 + x 2 < = 1 -x_1+x_2<=1 −x1+x2<=1引入 x 3 ≥ 0 x_3\geq 0 x3≥0 之 后 得 到 之后得到 之后得到 − x 1 + x 2 + x 3 = 1 -x_1+x_2+x_3=1 −x1+x2+x3=1 则 此 时 则此时 则此时 − x 1 + x 2 ≤ 1 -x_1+x_2\leq 1 −x1+x2≤1$任然成立,所以不影响结果
m a x Z = x 1 + x 2 { − x 1 + x 2 + x 3 ≤ 1 3 x 1 + x 2 + x 4 ≤ 4 x 1 , x 2 , x 3 , x 4 ≥ 0 x 1 , x 2 , x 3 , x 4 a r e i n t e g e r s max\ Z = x_1 + x_2\\ \begin{cases}{} -x_1 + x_2 + x_3\leq 1\\ 3x_1 + x_2 + x_4\leq 4\\ x_1\ ,\ x_2 \ ,\ x_3\ ,\ x_4\geq 0\\ x_1\ ,\ x_2 \ ,\ x_3\ , \ x_4\ are\ integers \end{cases} max Z=x1+x2⎩⎪⎪⎪⎨⎪⎪⎪⎧−x1+x2+x3≤13x1+x2+x4≤4x1 , x2 , x3 , x4≥0x1 , x2 , x3 , x4 are integers
上面两个式子通过一定的转化可以转化为:
x 1 − 1 4 x 3 + 1 4 x 4 = 3 4 ( 1 ) x 2 + 3 4 x 3 + 1 4 x 4 = 7 4 ( 2 ) x_1-\frac{1}{4}x_3+\frac{1}{4}x_4 = \frac{3}{4}\ \ (1)\\ {}\\ x_2 + \frac{3}{4}x_3 + \frac{1}{4}x_4 = \frac{7}{4}\ \ (2) x1−41x3+41x4=43 (1)x2+43x3+41x4=47 (2)
然后再把整数部分(系数为整数与单个整数)放在左边,小数部分放在右边(系数为小数+单个小数)
( 1 − 0 ) x 1 + ( − 1 + 3 4 ) x 3 + ( 0 + 1 4 ) x 4 = 0 + 3 4 (1-0)x_1 + (-1 + \frac{3}{4})x_3 + (0 + \frac{1}{4})x_4 = 0+\frac{3}{4} (1−0)x1+(−1+43)x3+(0+41)x4=0+43
整理为整数部分=小数部分!!!
x 1 − x 3 = 3 4 − ( 3 4 x 3 + 1 4 x 4 ) x_1 - x_3 = \frac{3}{4}-(\frac{3}{4}x_3 + \frac{1}{4}x_4) x1−x3=43−(43x3+41x4)
也就是:
3 4 − 正 数 = 一 个 整 数 而 且 0 ≤ 3 4 ≤ 1 x 3 , x 4 > = 0 所 以 , 3 4 − 正 数 ≤ 0 所 以 3 x 3 + x 4 ≥ 3 ( 1 ) a n d 4 x 2 + 3 x 3 + x 4 ≥ 7 ( 2 ) \frac{3}{4}-正数=一个整数\\ {}\\ 而且0\leq \frac{3}{4}\leq 1 \ \ \ x_3\ ,\ x_4>=0\\ {}\\ 所以 ,\ \ \frac{3}{4}-正数\leq0\\ {}\\ 所以 \ \ 3x_3+x_4\geq3\ (1)\ and\ 4x_2+3x_3+x_4 \geq 7\ (2) 43−正数=一个整数而且0≤43≤1 x3 , x4>=0所以, 43−正数≤0所以 3x3+x4≥3 (1) and 4x2+3x3+x4≥7 (2)
引入松弛变量,变不等式为等式 a i k x k a_{ik}x_k aikxk松弛变量
a i k = [ a i k ] + f i k a_{ik}=[a_{ik}]+f_{ik} aik=[aik]+fik松弛变量的系数化为正数部分和小数部分
[ a i k ] , x k [a_{ik}]\ ,\ x_k [aik] , xk正数部分汇合
f i k , x k f_{ik}\ ,\ x_k fik , xk小数部分汇合
[ a i k ] x k − [ b i ] [a_{ik}]x_k -[b_i] [aik]xk−[bi]整数部分放在左侧
[ b i ] + f i [b_i]+f_i [bi]+fi小数部分放在右侧
Cannot read properties of undefined (reading 'type')
引入松弛变量:
Cannot read properties of undefined (reading 'type')
DividePlane.m
function [intx,intf] = DividePlane(A,c,b,baseVector)
%功能:用割平面法求解整数规划
%调用格式:[intx,intf]=DividePlane(A,c,b,baseVector)
%其中, A:约束矩阵;
% c:目标函数系数向量;
% b:约束右端向量;
% baseVector:初始基向量;
% intx:目标函数取最值时的自变量值;
% intf:目标函数的最值;
sz = size(A);
nVia = sz(2);%获取有多少决策变量
n = sz(1);%获取有多少约束条件
xx = 1:nVia;
if length(baseVector) ~= n
disp('基变量的个数要与约束矩阵的行数相等!');
mx = NaN;
mf = NaN;
return;
end
M = 0;
sigma = -[transpose(c) zeros(1,(nVia-length(c)))];
xb = b;
%首先用单纯形法求出最优解
while 1
[maxs,ind] = max(sigma);
%--------------------用单纯形法求最优解--------------------------------------
if maxs <= 0 %当检验数均小于0时,求得最优解。
vr = find(c~=0 ,1,'last');
for l=1:vr
ele = find(baseVector == l,1);
if(isempty(ele))
mx(l) = 0;
else
mx(l)=xb(ele);
end
end
if max(abs(round(mx) - mx))<1.0e-7 %判断最优解是否为整数解,如果是整数解。
intx = mx;
intf = mx*c;
return;
else %如果最优解不是整数解时,构建切割方程
sz = size(A);
sr = sz(1);
sc = sz(2);
[max_x, index_x] = max(abs(round(mx) - mx));
[isB, num] = find(index_x == baseVector);
fi = xb(num) - floor(xb(num));
for i=1:(index_x-1)
Atmp(1,i) = A(num,i) - floor(A(num,i));
end
for i=(index_x+1):sc
Atmp(1,i) = A(num,i) - floor(A(num,i));
end
Atmp(1,index_x) = 0; %构建对偶单纯形法的初始表格
A = [A zeros(sr,1);-Atmp(1,:) 1];
xb = [xb;-fi];
baseVector = [baseVector sc+1];
sigma = [sigma 0];
%-------------------对偶单纯形法的迭代过程----------------------
while 1
%----------------------------------------------------------
if xb >= 0 %判断如果右端向量均大于0,求得最优解
if max(abs(round(xb) - xb))<1.0e-7 %如果用对偶单纯形法求得了整数解,则返回最优整数解
vr = find(c~=0 ,1,'last');
for l=1:vr
ele = find(baseVector == l,1);
if(isempty(ele))
mx_1(l) = 0;
else
mx_1(l)=xb(ele);
end
end
intx = mx_1;
intf = mx_1*c;
return;
else %如果对偶单纯形法求得的最优解不是整数解,继续添加切割方程
sz = size(A);
sr = sz(1);
sc = sz(2);
[max_x, index_x] = max(abs(round(mx_1) - mx_1));
[isB, num] = find(index_x == baseVector);
fi = xb(num) - floor(xb(num));
for i=1:(index_x-1)
Atmp(1,i) = A(num,i) - floor(A(num,i));
end
for i=(index_x+1):sc
Atmp(1,i) = A(num,i) - floor(A(num,i));
end
Atmp(1,index_x) = 0; %下一次对偶单纯形迭代的初始表格
A = [A zeros(sr,1);-Atmp(1,:) 1];
xb = [xb;-fi];
baseVector = [baseVector sc+1];
sigma = [sigma 0];
continue;
end
else %如果右端向量不全大于0,则进行对偶单纯形法的换基变量过程
minb_1 = inf;
chagB_1 = inf;
sA = size(A);
[br,idb] = min(xb);
for j=1:sA(2)
if A(idb,j)<0
bm = sigma(j)/A(idb,j);
if bm0
bz = xb(j)/A(j,ind);
if bz
Example.m
f = [-20 , -14 , -16 , -36 , -32 , -30]; % 不要加松弛变量
A = [0.01 0.01 0.01 0.03 0.03 0.03 1 0 0 0;
0.02 0 0 0.05 0 0 0 1 0 0;
0 0.02 0 0 0.05 0 0 0 1 0;
0 0 0.03 0 0 0.08 0 0 0 1]; % 加上松弛变量
b = [850 700 100 900];
[intx , intf] = DividePlane(A,c,b,[7 8 9 10]); % 松弛变量 7 8 9 10
intx
intf = -intf
----------
Output
intx =
35000 5000 30000 0 0 0
intf =
1250000