数学建模线性规划
写在最前面:
我是一个刚学数模的小白,觉得把自己的思路和代码啊公式写出来能提升学习效率,在参考了司守奎老师的《数学建模算法与应用》(第二版)一书后想把自己的想法分享给大家!如果下面的有错误,欢迎指正~~~参考一些博主的解答和文档会把链接放出来~~~代码使用MATLAB操作,公式使用AxMath编辑。
1.1、常规求解线性规划
需要注意三个问题:
1)分清哪些是列向量,哪些是行向量;
2)如“-2x1+x3”中的x2系数为0,但是不能忽略;
3)MATLAB 默认求最小值,那么需要分清哪些需要加负号;
4)求最大值等于加负号后求最小值。
代码:
clear;clc
c=[-3,1,1];
a=[1,-2,1;4,-1,-2];
b=[11,-3]';
aeq=[-2,0,1];
beq=1;
lb=zeros(3,1);
[x,fval]=linprog(c,a,b,aeq,beq,zeros(3,1))
z=-fval
答案:x1=4,x2=1,x3=9,z=2
1.2、带有绝对值的线性规划求解
这种看似非线性的问题 可以转化成线性的问题进行求解:
代码:
clear;clc
c=[1,2,3,4];
aeq=[1,-1,-1,1;1,-1,1,-3;1,-1,-2,3];
beq=[0,1,-0.5]';
prob=optimproblem;
u=optimvar('u',4,'LowerBound',0);
v=optimvar('v',4,'LowerBound',0);
prob.Objective=sum(c*(u+v));
prob.Constraints.con=aeq*(u-v)== beq;
[sol,fval]=solve(prob)
x=sol.u-sol.v
答案:x1=0.25 x2=x3=0 x4=-0.25 z=1.25
这里补充一些MATLAB的基础知识:
1、prob=optimproblem 创建优化问题
u=optimvar('u',4,'LowerBound',0);
v=optimvar('v',4,'LowerBound',0);
创建优化变量 其中参数意义如下:
‘u’:创建一个名为 u 的标量优化变量
‘4’:创建一个名为 u 的 4×1 优化变量向量,而且是列向量
'LowerBound':是指下界,因为u和v都是大于等于0的,详解看上面的图(UpperBound是上界)
后面接一个标量代表下界(上界为多少)
3、最后用solve函数进行求解,原书里面给的是输出四个参数,但是我这里为了简化,只输出两个参数:sol代表一个类(可能这样解释有误,但我是这么理解的),因为x=u-v,|x|=u+v,所以最后计算出答案,fval就是最优解。
帮助文档传送门:MATLAB优化问题 MATLAB优化变量
1.3、单下标求解生产利润问题
1、目标函数正号的那一部分,是产品的利润和数量的乘积,利润是单价减去原料费。数量应该怎么表示很简单,举个例子:对于产品I必须要经过A1、A2、B1、B2、B3的过程,那么x1+x2就是数量,当然我这里都统一最后的工序的数量。并且有:x1+x2=x3+x4+x5和x6+x7=x8;
2、负号那一部分是计算单位时间的设备费用,这个费用等于满负荷时设备的费用与设备有效台时的比值,原本的分式我都化成小数了。
这里对目标函数进行化简得:
代码:
clear;clc
c=[0.25,0.2247,-0.625,-0.5524,-0.65,0.5,0.2889,-1.15,-0.6839];
a=zeros(5,9);
a(1,1)=5;
a(1,6)=10;
a(2,2)=7;
a(2,7)=9;
a(2,9)=12;
a(3,3)=6;
a(3,8)=8;
a(4,4)=4;
a(4,9)=11;
a(5,5)=7;
b=[6000,10000,4000,7000,4000]';
aeq=[1,1,-1,-1,-1,0,0,0,0;0,0,0,0,0,1,1,-1,0];
beq=[0;0];
lb=zeros(9,1);
[x,fval]=linprog(c,a,b,aeq,beq,lb)
fval=-fval
答案:x1=1200 x2=230 x3=0 x4=859 x5=571 x6=0 x7=500 x8=500 x9=324 z=1146.4142
1.4 、双下标求解利润问题
1)每种货物可以分布在一个或多个货舱内 以及 不同的货物可以放在一个货舱内 这里就说明了要使用双变量进行求解,即用i=1,2,3,4 分别表示货物 1 货物 2 货物 3 和货物 4 ;j=1,2,3 分别表示前船中舱和后舱。那么有设 xij(i=1,2,3,4;j=1,2,3)表示第i种货物装在第j个货舱内的质量;
2)接着我们需要表示题目给出的量:
wj和vj分别表示第j个货舱的重量限制和体积限制;j=1,2,3
ai,bi,ci分别表示货物规格中的重量、单位质量的空间和利润;i=1,2,3,4
3)这里有一个很细节的点:“三个货舱所能装载的货物的重量必须与其最大的容许量成比例”
这句话的意思就是说我们放在某一个货舱内货物重量与其货舱的最大容积的比值是一个常数,这个常数满足三个货舱。
这里我们可以这样理解:以货物为研究对象,而不是货舱,因为货物可以放在不同的货舱内。举个例子:c1就是货物一的单价,乘上货物一在三个舱里的质量总和。
接着我们需要考虑如下约束对象:
1)所放货物总质量不能超过货舱质量限制;(货舱为研究对象)
2)所放货物的空间不能超过货舱的体积限制;(货舱为研究对象)
3)所放货物的总质量不能超过现有货物的总质量;(货物为研究对象)
4)三个货舱所能装载的货物的重量必须与其最大的容许量成比例;(货舱为研究对象)
5)货物质量一定为非负数。
写到这里就有一点感悟啦!对于找约束条件,约束的主体一定是我们构造的决策变量xij,这也就是为什么有3)的约束,而没有对自身体积的约束(因为xij表示质量)
代码:
clear;clc
a=[18,15,23,12]';% 货物质量
b=[4800,650,580,390];% 单位质量的空间
c=[3100,3800,3500,2850];% 利润
w=[10,16,8];% 质量限制
v=[6800,8700,5300]';% 体积限制
prob=optimproblem('ObjectiveSense','max');% 创建优化问题
x=optimvar('x',4,3,'LowerBound',0);% 创建4X3的优化问题
prob.Objective=c*sum(x,2);% 目标函数 xi1到xi3 是对行求和
% 这样计算的是1X4的行向量c乘上对x行求和后的4X1的列向量得出一个数:利润
con1=sum(x,1)<=w;
con2=(b*x)'<=v;% 1X4 * 4X3 =1X3 对矩阵乘法的基础有要求哇
con3=sum(x,2)<=a;
con4=[sum(x(:,1))/10==sum(x(:,2))/16;sum(x(:,2))/16==sum(x(:,3))/8];
prob.Constraints.con1=con1;
prob.Constraints.con2=con2;
prob.Constraints.con3=con3;
prob.Constraints.con4=con4;
[sol,fval]= solve (prob)% fval 121515元
sum(sol.x,2)% 第i行代表货物i,第j列代表货舱j,计算货物i的总质量需要把分散在各个货舱的质量都求和
答案:四种货物的质量(吨)分别为:0 15 15.9474 3.0526 总利润(元):1.2152+e5