声明:文章参考数学建模清风的网课编写。
什么是数学规划?
数学规划研究:在给定的条件下(约束条件),如何按照某一横梁指标(目标函数)来寻求计划、管理工作的最优方案。
即:求目标函数在一定约束条件下的极值问题。
数学规划的一般形式
一般形式:min or max f(x) s.t 不等式约束
目标函数:
m i n z = 6 x 1 + 3 x 2 + 4 x 3 min \ z = 6x_{1} + 3x_{2} + 4x_{3} min z=6x1+3x2+4x3
约束条件:
{ x 1 + 2 x 2 − 3 x 3 ⩽ 80 x 1 + x 2 + x 3 = 120 x 1 ⩾ 30 0 ⩽ x 2 ⩽ 50 x 3 ⩾ 20 \left\{\begin{matrix} x_{1} + 2x_{2} - 3x_{3} \leqslant 80 \\ x_{1} + x_{2} + x_{3} = 120 \\ x_{1} \geqslant 30 \\ 0 \leqslant x_{2} \leqslant 50 \\ x_{3} \geqslant 20 \end{matrix}\right. ⎩ ⎨ ⎧x1+2x2−3x3⩽80x1+x2+x3=120x1⩾300⩽x2⩽50x3⩾20
数学规划的分类
数学规划问题主要有线性规划,非线性规划和整数规划等。
当目标函数和约束条件都为线性表达式时,那么此时的数学规划问题就是线性规划问题。1947年,美国数学家丹齐格提出解决数学规划问题的算法–单纯形。
目标函数:
m i n z = 6 x 1 + 3 x 2 + 4 x 3 min \ z = 6x_{1} + 3x_{2} + 4x_{3} min z=6x1+3x2+4x3
约束条件:
{ x 1 + 2 x 2 − 3 x 3 ⩽ 80 x 1 + x 2 + x 3 = 120 x 1 ⩾ 30 0 ⩽ x 2 ⩽ 50 x 3 ⩾ 20 \left\{\begin{matrix} x_{1} + 2x_{2} - 3x_{3} \leqslant 80 \\ x_{1} + x_{2} + x_{3} = 120 \\ x_{1} \geqslant 30 \\ 0 \leqslant x_{2} \leqslant 50 \\ x_{3} \geqslant 20 \end{matrix}\right. ⎩ ⎨ ⎧x1+2x2−3x3⩽80x1+x2+x3=120x1⩾300⩽x2⩽50x3⩾20
使用matlab求解线性规划问题
matlab求解线性规划问题时,对求解问题的输入加以格式上的规定。比如:
使用matlab命令求解线性规划问题
[x, fval] = linprog(c, A, b, Aeq, beq, lb, ub, X0)
[]
占位;+inf
和-inf
分别表示无上界和无下界。例如:
m a x z = 2 x 1 + 3 x 2 − 5 x 3 S . t { x 1 + x 2 + x 3 = 7 2 x 1 − 5 x 2 + x 3 ≥ 10 x 1 + 3 x 2 + x 3 ≤ 12 x 1 , x 2 , x 3 ≥ 0 max \ z = 2x_{1} +3x_{2}-5x_{3} \\ S.t\left\{\begin{matrix} x_{1} + x_{2}+x_{3} = 7\\ 2x_{1} - 5x_{2} + x_{3}\ge10 \\ x_{1} + 3x_{2} + x_{3} \le 12 \\ x_{1},x_{2},x_{3}\ge 0 \end{matrix}\right. max z=2x1+3x2−5x3S.t⎩ ⎨ ⎧x1+x2+x3=72x1−5x2+x3≥10x1+3x2+x3≤12x1,x2,x3≥0
matlab命令为:
% 目标函数系数
c = [-2; -3; 5];
% 不等式约束数
A = [-2 5 -1;
1 3 1];
b = [-10; 12];
% 等式约束
Aeq = [1 1 1];
beq = 7;
% 上下界约束
lb = [0; 0; 0];
[x, fval] = linprog(c, A, b, Aeq, beq, lb);
fval = -fval;
求解结果为:
Optimal solution found.
x =
6.4286
0.5714
0
fval =
14.5714
当目标函数或约束条件为非线性表达式时,那么此时的数学规划问题就是非线性规划问题。非线性规划问题的求解通常困难得多,目前没有通用的算法。大多数算法采用选定决策变量的初始值后,通过搜索的方式寻求最优解。
目标函数:
m i n z = x 1 + 3 x 2 + 4 x 3 min \ z = x_{1} + 3x_{2} + 4x_{3} min z=x1+3x2+4x3
约束条件:
{ x 1 + x 2 − x 3 ⩽ 80 x 1 + 7 x 2 + x 3 = 120 0 ⩽ x 2 2 ⩽ 50 x 1 , x 3 ⩾ 20 \left\{\begin{matrix} x_{1} + x_{2} - x_{3} \leqslant 80 \\ x_{1} + 7x_{2} + x_{3} = 120 \\ 0 \leqslant x_{2}^{2} \leqslant 50 \\ x_{1}, x_{3} \geqslant 20 \end{matrix}\right. ⎩ ⎨ ⎧x1+x2−x3⩽80x1+7x2+x3=1200⩽x22⩽50x1,x3⩾20
使用matlab求解非线性规划问题
[x, val] = fmincon(@fun, X0, A, b, Aeq, beq, lb, ub, @nonfun, option)
@fun
表示目标函数, 需要单独编写一个m文件储存目标函数。
function f = func(x)
f = x(1) ^ 2 + x(2) + ... - x(n) ^ 4
end
其中,f为返回值,x为变量是一个向量。
X0
为初始值。不同于线性规划,非线性规划中的初始值选取非常重要,因为线性规划求解出的结果只是一个局部最优解。要想使结果尽可能优可以采用以下几个方法:(1)给定不同的初始值,在里面找最优解;(2)先使用蒙特卡洛得到一个解,并使用这个解作为初始值求解。
A, b, Aeq, beq, lb, ub同上。
@nonlfun
表示非线性约束条件函数。
function [c, ceq] = nonlfunc(x)
c = [非线性不等式约束1,非线性不等式约束2...非线性不等式约束n]
c = [非线性等式约束1,非线性等式约束2...非线性等式约束n]
end
当有的约束条件不存在时使用[]
占位即可。
option
求解算法的选择。matlab一共提供了4中不同的选项,各有各的实应条件以及优缺点,不妨使用不同的算法依次求解选取最优值。四种算法依次为:interior-point
内点法(不主动修改选项的话为默认值)、sqp
序列二次规划法、active-set
有效集法和trust-region-reflective
信赖域反射算法。
更换求解算法的方法:
option = optimoption('fmincon', 'Algorithm', '选择算法')
% 可供选择的算法有 interior-point、sqp、active-set、trust-region-reflective
对于例2,matlab求解代码为:
func.m(目标函数)
% 目标函数
function f = func(x)
f = x(1)^2 + x(2)^2 + x(3)^2 + 7;
end
nonlfunc.m(非线性约束条件)
% 非线性约束条件
function [c,ceq] = nonlfunc(x)
c = [-x(1)^2 + x(2) - x(3)^2;
x(1) + x(2)^2 + x(3)^2 - 20];
ceq = [-x(1) - x(2)^2 + 2;
x(2) + 2*x(3)^2 - 3];
end
求解代码:
% 线性不等式约束
A = [1 1 1];
b = 5;
% 上下界约束
lb = [0 0 0]';
% 初始值选取 注意选取的初始值越合理(符合约束),得到的值越优求解速度越快
x0 = [1 1 1];
[x, fval] = fmincon(@func, x0, A, b, [], [], lb, [], @nonlfunc);
求解结果:
x =
0.5522 1.2033 0.9478
fval =
9.6511
可以看出针对此题的初始值的选取还是不错的,但是初始值选取运气并不总是非常好。需要采取一定的策略。例如,采用蒙特卡洛模拟:
% 随机组数
n = 10000000;
% 根据后两个约束条件进一步压缩随机数范围
x1 = unifrnd(0, 5, n, 1); % 生成n组[0, 5]之间的随机数
x2 = unifrnd(0, 5, n, 1);
x3 = unifrnd(0, 5, n, 1);
fmin = +inf;
for i = 1 : n
xx = [x1(i) x2(i) x3(i)];
if (xx(1)^2 - xx(2) + xx(3)^2 >=0 && xx(1) + xx(2)^2 + xx(3)^2 <=20)
result = xx(1)^2 + xx(2)^2 + xx(3)^2 + 7;
if result < fmin
fmin = result;
x0 = xx;
end
end
end
disp(x0); % 模拟得到的一组初值为0.0601 0.0043 0.0380
[x, fval] = fmincon(@func, x0, A, b, [], [], lb, [], @nonlfunc);
整数规划是一类变量为整数的数学规划问题。分为整数线性规划和整数非线性规划。目前,所流行的整数规划算法往往只能求解整数线性规划。
使用matlab求解整数规划问题–线性
[x, fval] = intlinprog(c, intcon, A, b, Aeq, beq, lb, ub)
例如:
m a x z = 2 x 1 + 3 x 2 − 5 x 3 S . t { x 1 + x 2 + x 3 = 7 2 x 1 − 5 x 2 + x 3 ≥ 10 x 1 + 3 x 2 + x 3 ≤ 12 x 1 , x 2 , x 3 ∈ Z x 1 , x 2 , x 3 ≥ 0 max \ z = 2x_{1} +3x_{2}-5x_{3} \\ S.t\left\{\begin{matrix} x_{1} + x_{2}+x_{3} = 7\\ 2x_{1} - 5x_{2} + x_{3}\ge10 \\ x_{1} + 3x_{2} + x_{3} \le 12 \\ x_{1}, x_{2}, x_{3 \ \in Z} \\ x_{1},x_{2},x_{3}\ge 0 \end{matrix}\right. max z=2x1+3x2−5x3S.t⎩ ⎨ ⎧x1+x2+x3=72x1−5x2+x3≥10x1+3x2+x3≤12x1,x2,x3 ∈Zx1,x2,x3≥0
matlab程序:
% 目标函数系数
c = [-2; -3; 5];
% 不等式约束数
A = [-2 5 -1;
1 3 1];
b = [-10; 12];
% 等式约束
Aeq = [1 1 1];
beq = 7;
% 上下界约束
lb = [0; 0; 0];
[x, fval] = intlinprog(c, [1, 2, 3], A, b, Aeq, beq, lb);
fval = -fval;
求解结果:
x =
7.0000
0
0
fval =
14.0000
0-1规划是整数规划的特例,0-1规划的变量取值只能为0或1.
使用matlab求解01规划问题–线性
[x, fval] = intlinprog(c, intcon, A, b, Aeq, beq, lb, ub)
与求解线性整数规划相同,只需要修改上下界约束为:
l b = [ 0 0 0 0 ] , u b = [ 1 1 1 1 ] lb=\begin{bmatrix} 0\\ 0\\ 0\\ 0 \end{bmatrix}, ub=\begin{bmatrix} 1\\ 1\\ 1\\ 1 \end{bmatrix} lb=⎣ ⎡0000⎦ ⎤,ub=⎣ ⎡1111⎦ ⎤
使用整数线性01规划求解01背包问题(背包容量为30):
物品 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
重量 | 6 | 3 | 4 | 5 | 1 | 2 | 3 | 5 | 4 | 2 |
价值 | 540 | 200 | 180 | 350 | 60 | 150 | 280 | 450 | 320 | 120 |
matlab求解程序:
% 目标函数系数
c = [-540; -200; -180; -350; -60; -150; -280; -450; -320; -120];
% 不等式约束数
A = [6 3 4 5 1 2 3 5 4 2];
b = 30;
intcon = 1:10;
% 上下界约束
lb = zeros(10, 1);
ub = ones(10, 1);
[x, fval] = intlinprog(c, intcon, A, b, [], [], lb, ub);
fval = -fval;
求解结果:
x =
1
1
0
1
0
1
1
1
1
1
fval =
2410