线性规划的实例赏析
本文偏向于数学建模实战,针对对于规划问题有一定的基础和理解的读者,所以其中数学理论与代码不过多讲解,重在解题过程的展示。
文章目录
前言
求解线性规划模型已经有比较成熟的算法。对于一般的线性规划问题,常用的求解方法有图解法,单纯形法等。
<不太清楚的朋友可以参考系列文章《线性规划对偶问题》>
链接:https://blog.csdn.net/weixin_51128278/article/details/116246003
虽然针对线性规划的理论算法已经比较完善,但是当需要求解的模型的决策变量和约束条件数量比较多时,手工求解模型是十分繁杂甚至是不可能的,通常需要借助计算机软件来实现。
目前,求解数学规划模型的常用软件有MATLAB、Python、Lingo等多种,本文主要以MATLAB软件求解。MATLAB求解数学规划问题(包括线性规划、整数规划和非线性规划)采用两种模式:基于求解器的求解方法和基于问题的求解方法。
以下是本篇文章正文内容,下面案例可供参考
一、解题思考模式
在建立模型之前,有几个方面需要提前认知清楚,下面继续:
1.MATLAB求解方法
(1)基于求解器的求解方法:
规定线性规划问题的标准格式是:
max
f
T
x
,
\max f^Tx,
maxfTx,
s
.
t
.
{
A
⋅
x
≤
b
A
e
q
⋅
x
≤
b
e
q
l
b
≤
x
≤
u
b
s.t.\begin{cases} \ A·x≤b \\ Aeq·x≤beq \\ lb≤x≤ub \\ \end{cases}
s.t.⎩⎪⎨⎪⎧ A⋅x≤bAeq⋅x≤beqlb≤x≤ub
调用格式为:
[x,fval]=linprog(f,A,b)
[x,fval]-linprog(f,A,b,Aeq,beq)
[x,fval]-linprog(f,A,b,Aeq,beq,lb,ub)
(2)基于问题的求解方法:
先需要用变量和表达式构造优化问题,然后用solve函数求解。
例如:
clc, clear
prob = optimproblem('ObjectiveSense', 'max')
c = [4;3]; b = [10;8;7];
a = [2,1;1,1;0,1]; lb = zeros(2,1);
x = optimvar('x',2,'LowerBound',0);
prob.Objective = c'*x;
prob.Constraints.con = a*x<=b;
[sol, fval, flage, out] = solve(prob)
sol.x %显示决策变量的值
2.规划问题的构成元素
3.线性规划问题的求解步骤
4.线性规划模型的形式
4.线性规划问题的解的概念
5.灵敏度分析
灵敏度分析是指对系统因周围条件变化显示出来的敏感程度的分析。
可参考系列文章《数学建模评价类方法01——灵敏度分析》
链接:https://blog.csdn.net/weixin_51128278/article/details/117898155
二、线性规划模型的求解及应用
【例一】一般问题。
捷运公司在下一年度的1~4月的4个月内拟租用仓库堆放物资。仓库租借费用随合同期而定,期限越长,折扣越大。已知各月份所需仓库面积列于、折扣见表1.1。租借仓库的合同每月初都可办理,每份合同具体规定租用面积和期限。因此该公司可根据需要,在任何一个月初办理租借合同。每次办理时可签一份合同,也可签若干份租用面积和租借期限不同的合同,试确定该公司签订租借合同的最优决策,目的是使所付租借费用最小。
clc, clear
prob = optimproblem
x = optimvar('x',4,4,'LowerBound',0);
prob.Objective = 2800*sum(x(:,1))+4500*sum(x(1:3,2))+...
6000*sum(x(1:2,3))+7300*x(1,4);
prob.Constraints.con = [sum(x(1,:))>=15
sum(x(1,2:4))+sum(x(2,1:3))>=10
x(1,3)+x(1,4)+x(2,2)+x(2,3)+x(3,1)+x(3,2)>=20
x(1,4)+x(2,3)+x(3,2)+x(4,1)>=12];
[sol,fval,flag,out]= solve(prob), sol.x
【例二】运输问题。
可参考系列文章《特殊规划问题——运输问题》
clc, clear, a = load('data1_5_1.txt');
c = a(1:end-1,1:end-1);
e = a(1:end-1,end); d = a(end,1:end-1);
prob = optimproblem;
x = optimvar('x',6,8,'LowerBound',0);
prob.Objective = sum(sum(c.*x));
prob.Constraints.con1 = sum(x,1) == d;
prob.Constraints.con2 = sum(x,2)<= e;
[sol,fval,flag,out]=solve(prob), xx=sol.x
writematrix(xx, 'data1_5_2.xlsx') %数据写到Excel文件,便于做表使用
【例三】可以转化为线性规划的问题
例如:
clc, clear
c = [1:4]'; b = [-2,-1,-1/2]';
a = [1,-1,-1,1;1,-1,1,-3;1,-1,-2,3];
prob = optimproblem;
u = optimvar('u',4,'LowerBound',0);
v = optimvar('v',4,'LowerBound',0);
prob.Objective = sum(c'*(u+v));
prob.Constraints.con = a*(u-v)<=b;
[sol,fval,flag,out]=solve(prob)
x = sol.u - sol.v
三、投资的收益与风险
(本题选自1998年全国大学生数学建模竞赛A题)
市场上有
n
n
n种资产(如股票、债券等)
S
i
(
i
=
1
,
2
,
.
.
.
,
n
)
S_{i}(i=1,2,...,n)
Si(i=1,2,...,n) 供投资者选择,某公司有数额为
M
M
M的一笔相当大的资金可用作一个时期的投资。公司财务分析人员对这
n
n
n种资产进行了评估,估算出在这一时期内购买资产
S
i
S_{i}
Si 的平均收益率为
r
i
r_{i}
ri,并预测出购买
S
i
S_{i}
Si的风险损失率为
q
i
q_{i}
qi 。考虑到投资越分散,总的风险越小,公司确定,当用这笔资金购买若干种资产时,总体风险可用所投资的
S
i
S_{i}
Si中最大的一个风险来度量。
购买
S
i
S_{i}
Si 要付交易费,费率为
p
i
p_{i}
pi ,并且当购买额不超过给定值
u
i
u_{i}
ui 时,交易费按购买
u
i
u_{i}
ui 计算(不买当然无须付费)。另外,假定同期银行存款利率是
r
0
r_{0}
r0
(
r
0
=
5
(r_{0}=5%)
(r0=5 ,且既无交易费又无风险。
试给该公司设计一种投资组合方案,即用给定的资金
M
M
M ,有选择地购买若干种资产或存银行生息,使净收益尽可能大,而总体风险尽可能小。
(Ⅰ)问题分析
(Ⅱ)符号说明
(Ⅲ)模型假设
(Ⅳ)模型建立
【模型一求解】
clc, clear, close all
prob = optimproblem('ObjectiveSense','max');
x = optimvar('x',5,1,'LowerBound',0);
c=[0.05,0.27,0.19,0.185,0.185]; %净收益率
Aeq=[1,1.01,1.02,1.045,1.065]; %等号约束矩阵
prob.Objective = c*x; M = 10000;
prob.Constraints.con1 = Aeq*x==M; %等号约束条件
q=[0.025,0.015,0.055,0.026]'; %风险损失率
a = 0; aa = []; QQ = []; XX = []; hold on
while a<0.05
prob.Constraints.con2 = q.*x(2:end)<=a*M;
[sol,Q,flag,out]= solve(prob);
aa = [aa; a]; QQ = [QQ,Q];
XX = [XX; sol.x']; a=a+0.001;
end
plot(aa, QQ, '*k')
xlabel('$a$','Interpreter','Latex'),
ylabel('$Q$','Interpreter','Latex','Rotation',0)
【模型三求解】
clc, clear, close all
prob = optimproblem('ObjectiveSense','max');
x = optimvar('x',5,1,'LowerBound',0);
c=[0.05,0.27,0.19,0.185,0.185]; %净收益率
Aeq=[1,1.01,1.02,1.045,1.065]; %等号约束矩阵
prob.Objective = c*x; M = 10000;
prob.Constraints.con1 = Aeq*x==M; %等号约束条件
q=[0.025,0.015,0.055,0.026]'; %风险损失率
a = 0; aa = []; QQ = []; XX = []; hold on
while a<0.05
prob.Constraints.con2 = q.*x(2:end)<=a*M;
[sol,Q,flag,out]= solve(prob);
aa = [aa; a]; QQ = [QQ,Q];
XX = [XX; sol.x']; a=a+0.001;
end
plot(aa, QQ, '*k')
xlabel('$a$','Interpreter','Latex'),
ylabel('$Q$','Interpreter','Latex','Rotation',0)
clc, clear, close all, format long g
M =10000; prob = optimproblem;
x = optimvar('x',6,1,'LowerBound',0);
r=[0.05,0.28,0.21,0.23,0.25]; %收益率
p=[0, 0.01, 0.02, 0.045, 0.065]; %交易费率
q=[0, 0.025, 0.015, 0.055, 0.026]'; %风险损失率
%w = 0:0.1:1
w = [0.766, 0.767, 0.810, 0.811, 0.824, 0.825, 0.962, 0.963, 1.0]
V = []; %风险初始化
Q = []; %收益初值化
X = []; %最优解的初始化
prob.Constraints.con1 = (1+p)*x(1:end-1)==M;
prob.Constraints.con2 = q(2:end).*x(2:end-1)<=x(end);
for i = 1:length(w)
prob.Objective = w(i)*x(end)-(1-w(i))*(r-p)*x(1:end-1);
[sol,fval,flag,out]=solve(prob);
xx = sol.x; V=[V,max(q.*xx(1:end-1))];
Q=[Q,(r-p)*xx(1:end-1)]; X=[X; xx'];
plot(V, Q, '*-'); grid on
xlabel('风险(元)'); ylabel('收益(元)')
end
V, Q, format
四、总结
因为线性规划的PPT上内容完整,所以大部分内容还是参考PPT来的,也不用手打很多字,算是节约了不少时间。 不出意外这应该是线性规划问题的最后一篇了,我现在明白了为什么运筹学讲线性规划就用掉11周的课......太要命了。接下来会进入图论的学习,不过那就是,期末考试之后的事儿辣~ 肝完这周的活儿,差不多全身心投入复习了!!!五、引用
《运筹学教程》胡运权
《数学算法与应用》司守奎 孙玺菁