数学建模class 1 —— 数学规划问题

零. 问题引入(雾)

        还有两周就是5.20了,阿疯今年不想再度过只能‘享受’狗粮的‘幸福’,于是他打算同时和两位女生刷好感(好孩子不要学习o),一位叫桂言叶,另一位叫西园寺世界,由于可怜的阿疯身上只有1500的生活费,和叶酱学习需要1.5小时,加0.5好感,当好感度每到达5点便可解锁一张cg,和世界酱逛公园需要2小时,加1好感,当好感度每到达7点便可解锁一张cg,使用150元可邀请其中任意一位女孩逛动物园,耗时3小时,加2好感。

        假设这三人生在一个made in heaven的世界,能无限进行剧情,请问阿疯如何把握着两周的时间收集尽可能多的cg以顺利到达脑洞大开的柴刀结局呢?(祭奠诚哥ing)

(图片素材来源于网络)

一. 最优化问题的数学模型

       

二. 线性规划

我们首先来谈一谈线性规划问题:

1.概念

        线性规划(Linear Programming 简记 LP)是了运筹学中数学规划的一个重要分支。自从 1947 年 G. B. Dantzig 提出 求解线性规划的单纯形法以来,线性规划在理论上趋向成熟,在实用中由于计算机能处理成千上万个约束条件和决策变量的线性规划问题之后,线性规划现代管理中经常采用的基本方法之一。 在解决实际问题时,需要把问题归结成一个线性规划数学模型,关键及难点在于选适当的决策变量建立恰当的模型,这直接影响到问题的求解。

         线性规划问题的目标函数及约束条件均为线性函数;约束条件记为 s.t.(即 subject to)。目标函数可以是求最大值,也可以是求最小值,约束条件的不等号可以 是小于号也可以是大于号。

        一般线性规划问题的(数学)标准型为 :

2.典型例题

(一)生产问题

(1)题目

(2)思路与解法

        一眼看上去像一道小学算数题,但它是一道典型的线性规划问题,我们可以假设他生产了x1公斤A1,x2公斤A2,列出目标方程(即利润)和约束方程组如下:

        然后开始绘图,即可找出解:

        由于最优解一定在多边形顶点上,我们可以把多边形的顶点一个一个带进去试(因为用maxz切不是那么好画)。因此我们可以使用MATLAB来绘制该图像。

(3)相关程序及解释

        先请不怎么会使用matlab的同学登入以下网站学习相关基础知识:MATLAB 教程 - MatLab教程 - 菜鸟教程MATLAB是MathWorks开发的一种编程语言。它最初是一种矩阵编程语言,线性代数编程很简单。它既可以在交互式会话下运行,也可以作为批处理作业运行。本教程为您积极地介绍了MATLAB编程语言。它旨在让学生流利使用MATLAB编程语言。基于问题的MATLAB示例已经以简单的方式给出,以使您的学习快速而有效。https://www.cainiaojc.com/matlab/matlab-tutorial.html        为解决线性规划问题,我们将会使用以下模型:

在这其中:

c 是目标函数形成的矩阵,比如max z=72x1+64y1,表述就是c=[72;64];
A,b 是约束条件不等式的系数,比如题目中,A=[1,1; 12,8; 3,0],b=[50;  480; 100];
Aeq,beq 对应的是线性等式约束;
lb,ub 分别对应的是决策向量的下界和上界;

注:没有等式约束用[]表示

具体代码如下:

clear
clc
%第一问
f = [-72; -64];          % 目标函数系数(注意负号,因为linprog默认求最小)
A = [1, 1; 12, 8; 1, 0]; % 不等式约束矩阵
b = [50; 480; 100/3];    % 约束右侧值
lb = zeros(2, 1);         % 变量下界

% 调用linprog并获取lambda
[x, fval, ~, ~, lambda] = linprog(f, A, b, [], [], lb);

% 计算利润和结果
profit = -fval;
x1 = x(1);
x2 = x(2);
disp(['生产计划: x1 = ', num2str(x1), ' 桶, x2 = ', num2str(x2), ' 桶']);
disp(['最大利润: ', num2str(profit), ' 元']);
%第四问
f_new = [-90; -64]; % A1利润增至 90元/桶
[x_new, fval_new] = linprog(f_new, A, b, [], [], lb);
profit_new = -fval_new;

if ~isequal(round(x_new,2), round(x,2))
    disp('需调整生产计划');
else
    disp('无需调整生产计划');
end
disp(['新利润为: ', num2str(profit_new), ' 元']);

        接下来在解决二三问前,我们要先了解一个概念——影子价格,详细可参考以下专栏:

https://zhuanlan.zhihu.com/p/47989254

        简单来说就是假如改变其中一个原本固定的因素(例如题目中的时间和金钱),目标的值也会随之改变,为了获取影子数据,我参考了以下帮助文档的输出一栏。

https://ww2.mathworks.cn/help/optim/ug/linprog.html#buusznx-3

        其中,linprog函数的格式为:[x,fval,exitflag,output,lambda] = linprog(___)

        其中·x — 解,fval — 解处的目标函数值,exitflag — linprog 停止的原因,output — 有关优化过程的信息,而我们要使用的便是第五项lambda,根据文档:

        我们得到的lambda结构体中的ineqlin即为解出的符合条件约束的解,即为在最优条件下实际上相当的时间和金钱,例如使用以下代码:

lambda.ineqlin

        可以得到以下的反馈:

ans =

   48.0000
    2.0000
         0

        其中返回的48指原料增加1单位, 利润增长48,而2指时间增加1单位, 利润增长2,也就是说只要我买就是赚,而为保证赚的更多,我需要在保证不突破限制的情况下,即生产加工能力的前提下尽可能多买,而易知生产x1最多时用33.33桶,生产x2最多时60桶(在另一种不生产时)所以最多购买60-50=10桶。

        而付出工资最多即收支平衡时的值,也就是2.(资本实在太坏了)

(4)变式

        你现在已经会了基础解法了,现在试试解决以下问题吧:

        说说思路,同样设用x1桶牛奶生产a1,x2牛奶生产a2,y1公斤a1生产b1,y2公斤a2生产b2,列目标方程和约束方程,跑出极限值。第二问同上题解,第三问即把b1和b2的上下限代入,看看有没有变化。

        答案如下:

(二)运输问题

(1)题目

(2)思路与解法

        收入与其余支出固定,需要利润最大,即要求支出最小,根据题目要求列出以下目标方程与约束方程(有点混乱):

(3)程序

        有了数学模型后程序比较好给出(就是有点长),如下:

f = [160, 130, 220, 170, 140, 130, 190, 150, 190, 200, 230];

% 等式约束
Aeq = [
    1,1,1,1,0,0,0,0,0,0,0;    % 水库1总供水量
    0,0,0,0,1,1,1,1,0,0,0;    % 水库2总供水量
    0,0,0,0,0,0,0,0,1,1,1;    % 水库3总供水量
];
beq = [50; 60; 50];

% 不等式约束
A = [
    -1,0,0,0,-1,0,0,0,-1,0,0;  % 小区1下限
    1,0,0,0,1,0,0,0,1,0,0;     % 小区1上限
    0,-1,0,0,0,-1,0,0,0,-1,0;  % 小区2下限
    0,1,0,0,0,1,0,0,0,1,0;     % 小区2上限
    0,0,-1,0,0,0,-1,0,0,0,-1;  % 小区3下限
    0,0,1,0,0,0,1,0,0,0,1;     % 小区3上限
    0,0,0,-1,0,0,0,-1,0,0,0;   % 小区4下限
    0,0,0,1,0,0,0,1,0,0,0;     % 小区4上限
];
b = [-30; 80; -70; 140; -10; 30; -10; 50];

% 非负约束
lb = zeros(11, 1);

% 求解线性规划
[x, fval] = linprog(f, A, b, Aeq, beq, lb);

% 显示结果
if ~isempty(x)
    disp('最优供水量分配:');
    disp(['x11=', num2str(x(1)), ', x12=', num2str(x(2)), ', x13=', num2str(x(3)), ', x14=', num2str(x(4))]);
    disp(['x21=', num2str(x(5)), ', x22=', num2str(x(6)), ', x23=', num2str(x(7)), ', x24=', num2str(x(8))]);
    disp(['x31=', num2str(x(9)), ', x32=', num2str(x(10)), ', x33=', num2str(x(11))]);
    disp(['最小运输成本: ', num2str(fval), ' 元']);
else
    disp('无可行解');
end

(4)变式1

        由于方法一样,我就把答案列下面了

注意多余约束!

解如下:

(三)指派问题(待施工)

———————————————————————————————————————————

三. 参考文献如下

线性规划入门-CSDN博客

线性规划(二):运输问题 (产销平衡)  & 指派问题_表上作业法求解指派问题-CSDN博客

https://zhuanlan.zhihu.com/p/47989254

matlab精讲如何使用linprog(例子引述)_linprog在matlab中的用法-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿疯77

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值