如果你在使用 Matlab 来处理一些数学问题,希望这篇博客可以帮到你。你可以根据所需要的内容查看对应的标题的内容,可以知道在 Matlab 中使用什么函数来解决问题。
1.1.1. 线性规划的标准形式
线性规划的目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以是小于号也可以是大于号。
Matlab 中规定线性规划的标准形式为
min x c T x s . t . { A x ≤ b A e q ⋅ x = b e q l b ≤ x ≤ u b \min_x c^Tx \\ s.t. \begin{cases} Ax \leq b \\ Aeq \cdot x = beq \\ lb \leq x \leq ub \\ \end{cases} xmincTxs.t.⎩⎪⎨⎪⎧Ax≤bAeq⋅x=beqlb≤x≤ub
第一个式子为目标函数, s . t . s.t. s.t. 式是约束条件。其中 c c c 和 x x x 为 n n n 维列向量, A A A、 A e q Aeq Aeq 为适当维数的矩阵, b b b、 b e q beq beq 为适当维数的列向量。
1.1.2. linprog() 的使用
在 matlab 中,线性规划的函数为 linprog()
,它有两种常用形式:X = linprog(f,A,b,Aeq,beq,LB,UB,X0)
和 [X, FVAL] = linprog(f,A,b,Aeq,beq,LB,UB,X0)
返回的值 X 是向量 x x x 的值,FVAL 是目标函数的值,LB 和 UB 分别是变量 x x x 的下界和上界, x 0 x_0 x0 是 x x x 的初始值。
1.1.3. 应用例子
例子 1.
求下列线性规划问题:
max 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. \begin{cases} x_1+x_2+x_3=7 \\ 2x_1-5x_2+x_3 \ge 10 \\ x_1+3x_2+x_3 \leq 12 \\ x_1,x_2,x_3 \ge 0 \\ \end{cases} maxz=2x1+3x2−5x3s.t.⎩⎪⎪⎪⎨⎪⎪⎪⎧x1+x2+x3=72x1−5x2+x3≥10x1+3x2+x3≤12x1,x2,x3≥0
依据 Matlab 的标准,默认求解是求最小值,而本例是求的最大值,把 z z z 的系数变为相反数,即 − 1 -1 −1 就好了,同理 下面的大于等于号 ≥ \ge ≥ 也做同样处理,就是把 10 → − 10 10 \to -10 10→−10,然后没有上界 UB,下界 LB 为三个变量都为 0 0 0 ,也就是一个全零的矩阵 zeros(3, 1)
编写一个 .m
文件:
c = [2; 3; -5];
a = [-2, 5, -1; 1, 3, 1];
b = [-10; 12];
aeq = [1, 1, 1];
beq = 7;
x = linprog(-c, a, b, aeq, beq, zeros(3, 1))
value = c'*x
执行后输出最优解和目标函数在最优解的取值:
x =
6.4286
0.5714
0.0000
value =
14.5714
1.2.1. 非线性规划的标准形式
如果目标函数或约束条件中包含非线性函数,就称这种规划问题为非线性规划问题。
线性规划与非线性规划的区别:
线性规划的最优解只能在其可行域的边界上达到;而非线性规划的最优解则可能在可行域的任意一点达到。
1.2.2. fmincon() 的使用
Matlab 中非线性规划的数学模型的形式为:
min f ( x ) s . t . { A x ≤ B A e q ⋅ x = B e q C ( x ) ≤ 0 C e q ( x ) = 0 \min f(x) \\ s.t. \begin{cases} Ax \leq B \\ Aeq \cdot x = Beq \\ C(x) \leq 0 \\ Ceq(x) = 0 \end{cases} minf(x)s.t.⎩⎪⎪⎪⎨⎪⎪⎪⎧Ax≤BAeq⋅x=BeqC(x)≤0Ceq(x)=0
f ( x ) f(x) f(x) 是标量函数, A A A, B B B, A e q Aeq Aeq, B e q Beq Beq 是相应位数的矩阵和向量, C ( x ) C(x) C(x), C e q ( x ) Ceq(x) Ceq(x) 是非线性向量函数。
Matlab 中的函数是:X = fmincon(FUN,X0,A,B,Aeq,Beq,LB,UB,NONLCON,OPTIONS)
它的返回值是向量 x x x,其中 FUN 是用 M 文件定义的函数 f ( x ) f(x) f(x) ;X0 是 x x x 的初始值; A, B, Aeq, Beq 定义了线性约束 A ∗ X ≤ B A * X \leq B A∗X≤B, A e q ∗ X = B e q Aeq * X = Beq Aeq∗X=Beq,如果没有线性约束,则 A=[], B=[], Aeq=[], Beq=[];LB 和 UB 是变量 x x x 的下界和上界,如果上界和下界没有约 束,则 LB=[],UB=[],如果 x x x 无下界,则 LB 的各分量都为 -inf,如果 x x x无上界,则 UB 的各分量都为 inf;NONLCON 是用 M 文件定义的非线性向量函数 C ( x ) C(x) C(x), C e q ( x ) Ceq(x) Ceq(x);OPTIONS 定义了优化参数,可以使用 Matlab 缺省的参数设置。
1.2.3. 应用例子
例子 1.
求下列非线性规划:
min f ( x ) = x 1 2 + x 2 2 + x 3 2 + 8 s . t . x 1 2 − x 2 + x 3 2 ≥ 0 x 1 + x 2 2 + x 3 3 ≤ 20 − x 1 − x 2 2 + 2 = 0 x 2 + 2 x 3 2 = 3 x 1 , x 2 , x 3 ≥ 0 \min f(x)=x^2_1+x_2^2+x_3^2+8 \\ \begin{matrix} s.t. & x_1^2-x_2+x_3^2 \ge 0 \\ & x_1+x_2^2+x_3^3 \leq 20 \\ & -x_1-x_2^2+2=0 \\ & x_2+2x_3^2=3 \\ & x_1, x_2, x_3 \ge 0 \\ \end{matrix} minf(x)=x12+x22+x32+8s.t.x12−x2+x32≥0x1+x22+x33≤20−x1−x22+2=0x2+2x32=3x1,x2,x3≥0
编写 M 文件 fun1.m
, fun2.m
, example2.m
,内容分别为下:
%% content of fun1.m
function f=fun1(x);
f=sum(x.^2)+8;
%% content of fun2.m
function [g,h]=fun2(x);
g=[-x(1)^2+x(2)-x(3)^2 x(1)+x(2)^2+x(3)^3-20]; %非线性不等式约束
h=[-x(1)-x(2)^2+2 x(2)+2*x(3)^2-3]; %非线性等式约束
%% content of exemple.m
options=optimset('largescale','off');
[x,y]=fmincon('fun1',rand(3,1),[],[],[],[],zeros(3,1),[],'fun2', options)
运行的结果:
x =
0.5522
1.2033
0.9478
y =
10.6511
1.3.1. 整数规划的标准形式
规划中的变量(部分或全部)限制为整数时,称为整数规划。若在线性规划模型中, 变量限制为整数,则称为整数线性规划。如不加特殊说明,一般指整数线性规划。
整数规划在 Matlab 上的标准形式是:
min x   c T x s . t . { A x ≤ b A e q ⋅ x = b e q l b ≤ x ≤ u b \min_x \, c^Tx \\ s.t. \begin{cases} Ax \leq b \\ Aeq \cdot x = beq \\ lb \leq x \leq ub \\ \end{cases} xmincTxs.t.⎩⎪⎨⎪⎧Ax≤bAeq⋅x=beqlb≤x≤ub
与之前的线性规划一样,不同的是这里我们的 x x x 是取整数的。
1.3.2. intlinprog() 的使用
由于《数学建模算法与程序》这本书写得算是比较早,那个时候 Matlab 对于整数规划还没有函数,而唯一一个出现的 bintprog()
函数在如今的 Matlab 上也移除了,用了一个新的函数 intlinprog()
代替,也就是说,我们现在可以在 Matlab 上处理整数规划问题了。
先看看 intlinprog()
的用法解释:
X = intlinprog(f,intcon,A,b,Aeq,beq,LB,UB)
与上面一样,但是第二个参数 intcon
是指定要限定哪一个 x x x 为整数,如果想要限定 x 2 x_2 x2 和 x 10 x_{10} x10 为整数,那就是 [2,10]
。
1.3.3. 应用例子
这里我们使用 intlinprog()
解决书上的第一个整数规划(书上使用的是分支定界法,还是挺复杂的):
例子 1.
求解下述整数规划:
M a x   z = 10 x 1 + 90 x 2 { 9 x 1 + 7 x 2 ≤ 56 7 x 1 + 20 x 2 ≤ 70 x 1 , x 2 ≥ 0   ( x 1 , x 2 ∈ Z ) \mathrm{Max} \, z=10x_1+90x_2 \\ \begin{cases} 9x_1+7x_2 \leq 56 \\ 7x_1+20x_2 \leq 70 \\ x_1, x_2 \ge 0 \, (x_1,x_2 \in \boldsymbol{Z}) \end{cases} Maxz=10x1+90x2⎩⎪⎨⎪⎧9x1+7x2≤567x1+20x2≤70x1,x2≥0(x1,x2∈Z)
编写程序:
c=[40;90];
A=[9 7;7 20];
b=[56 70];
Aeq=[];
beq=[];
LB=[0;0];
UB=[inf;inf]
X=intlinprog(-c,[1,2],A,b,Aeq,beq,LB,UB)
value=f'*X
运行,解得:
X =
4.0000
2.0000
value =
340