本文为北海的数模课程学习笔记,课程出自微信公众号:数学建模BOOM。
数学建模,就是把题目翻译成数学语言
目录
线性规划
模型简介
适用:解决优化类问题——有限的资源,最大的收益。
通俗例子:华强利用有限的瓜使挑衅值最大。
模型分析
适用赛题
注意“最合理”这种模糊词
要自己给它下定义,是利润最大,还是时间最短等等 。
判断线性和非线性的标准:约束条件和目标函数中的变量是否全为一次方。
典型例题与原理讲解
多目标线性规划
既要净收益尽可能大,又要总风险尽可能小
合理假设可以简化模型
例1:交易费原本是一个分段函数,但是可以通过一个合理的假设简化掉一段。
例2:
有些简化的坑还可以再填上,论文里写作“模型改进
对a的不同取值再次求解,此时就是把a当成变量了。
代码求解
linprog基本用法
linprog
是 MATLAB 中的一个函数,用于求解线性规划问题。
[x, fval] = linprog(f, A, b, Aeq, beq, lb, ub, options)
这里的参数:
-
f
- 是目标函数的系数矩阵。如果你想最小化c(1)*x(1) + c(2)*x(2) + ...
,那么f
就是c
的向量。 -
A
,b
- 这是不等式约束。他们代表Ax ≤ b
。例如,如果想有约束x1 + 2x2 ≤ 8
和2x1 + x2 ≤ 6
,那么A
会是一个 2x2 矩阵,b
会是一个 2x1 向量。 -
Aeq
,beq
- 这是等式约束。它们表示Aeqx = beq
。与A
和b
类似,但它们是等式约束而不是不等式约束。 -
lb
,ub
- 这是x
的下界和上界。例如,如果x1
必须在 0 到 5 之间,那么lb(1) = 0
,ub(1) = 5
。 -
options
- 是一个结构体,包含优化选项。使用optimoptions
可以创建此结构体。
返回值 x
是一个向量,包含了使目标函数 f
最小化的变量值,fval为目标函数的最优值。
示例:
最小化: f=2x1+3x2
不等式约束:
x1 + x2 ≤ 4
x1 - x2 ≤ 2
那么可以这样使用 linprog
:
f = [2; 3];
A = [1, 1; 1, -1];
b = [4; 2];
[x, fval] = linprog(f, A, b);
最后, x
会包含最优解,fval为目标函数的最小值。
linprog注意事项
- linprog函数的标准形式是[x, fval ]= linprog(f,A,b,Aeq,beq,lb,ub)
- 若不存在不等式约束,用“ [ ]” 代替𝐴和𝑏: [𝑥, fval ]= linprog (𝑓,[ ],[ ],𝐴𝑒𝑞, beq ,𝑙𝑏,𝑢𝑏)
- 若不存在等式约束,用“ [ ]” 代替𝐴𝑒𝑞和𝑏𝑒𝑞: [𝑥, fval ]= linprog (𝑓,𝐴,𝑏,[ ], [ ] ,𝑙𝑏,𝑢𝑏)
- 没有等式约束和最小、最大取值的约束时,可以不写𝐴𝑒𝑞,𝑏𝑒𝑞 和𝑙𝑏,𝑢𝑏: [𝑥, fval ]= linprog (𝑓,𝐴,𝑏)
- 若题目求最大值:目标函数等号两端加负号转为求最小值,求解后目标值再取负
写出已知参数的矩阵
- min...对应f
- st1对应A,b
- st2对应Aeq,beq
- st3对应lb
完整代码
% clc是清除命令行窗口,clear是清除存储空间的变量
clc,clear;
% a矩阵的元素是不同风险率,从0到0.05等差取值,相邻两个数相差0.001
a = (0:0.001:0.05);
f = [-0.05,-0.27,-0.19,-0.185,-0.185]; % 目标函数的系数向量
% A是不等式约束条件的变量系数构成的矩阵
% 用zeros(4,1)先构造4行一列的全是0的矩阵,也就是对x_0无约束;
% 再构造对角矩阵diag([0.025,0.015,0.055,0.026]),对角线上元素为约束条件中变量的系数
A = [zeros(4,1),diag([0.025,0.015,0.055,0.026])];
Aeq = [1,1.01,1.02,1.045,1.065]; % 等式约束的系数矩阵,也就是所有资产投资
beq = 1;
LB = zeros(5,1);
Q = zeros(1,length(a)); % 初始化保存最优解的矩阵Q,因为现在还没求出最优解,元素全设为0
XX = []; % 定义个空矩阵,用来存不同风险率下的最优解
% 利用矩阵Q存储风险率a(i)下最大的收益;for循环中i在变化,风险率a(i)不同,求出对应的最优解存在矩阵Q内
for i = 1:length(a) % length求出矩阵a的元素个数,有多少个元素,就循环多少次
b = a(i)*ones(4,1); % b是约束条件的常数项矩阵,4行1列,每个元素值都是常数a(i)
[x,y] = linprog(f,A,b,Aeq,beq,LB); % 调用linprog函数,x为最优解,由于标准化,此时的y为最小值
Q(i) = -y; % 负负得正,就是所需求的最大值了
XX = [XX;x']; % x'是x的转置的意思,XX用来保存每一次的投资方案
end
plot(a,Q,'*r'); % 以风险率为横轴,收益为纵轴,绘制不同风险率下的最优收益,*是点,r是红色
xlabel('风险率'); % x和y轴分别附上标签
ylabel('最大收益');
结果分析
简单分析(此处还不完善)
其他思路
无论对错,管用即可,合理的假设是必要的