本文偏向于数学建模实战,针对对于规划问题有一定的基础和理解的读者,所以其中数学理论与代码不过多讲解,重在解题过程的展示。
求解线性规划模型已经有比较成熟的算法。对于一般的线性规划问题,常用的求解方法有图解法,单纯形法等。
<不太清楚的朋友可以参考系列文章《线性规划对偶问题》>
链接:https://blog.csdn.net/weixin_51128278/article/details/116246003
虽然针对线性规划的理论算法已经比较完善,但是当需要求解的模型的决策变量和约束条件数量比较多时,手工求解模型是十分繁杂甚至是不可能的,通常需要借助计算机软件来实现。
目前,求解数学规划模型的常用软件有MATLAB、Python、Lingo等多种,本文主要以MATLAB软件求解。MATLAB求解数学规划问题(包括线性规划、整数规划和非线性规划)采用两种模式:基于求解器的求解方法和基于问题的求解方法。
以下是本篇文章正文内容,下面案例可供参考
在建立模型之前,有几个方面需要提前认知清楚,下面继续:
规定线性规划问题的标准格式是:
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)
先需要用变量和表达式构造优化问题,然后用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 %显示决策变量的值
灵敏度分析是指对系统因周围条件变化显示出来的敏感程度的分析。
可参考系列文章《数学建模评价类方法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
《运筹学教程》胡运权
《数学算法与应用》司守奎 孙玺菁