数学建模实战:从投资组合到生产计划,5个案例详解MATLAB intlinprog 求解
数学建模实战:从投资组合到生产计划,5个案例详解MATLAB intlinprog 求解
在数学建模竞赛和工程优化领域,混合整数线性规划(MILP)因其强大的离散决策能力而备受青睐。MATLAB的 intlinprog 函数作为求解MILP问题的利器,能够高效处理包含整数变量的复杂优化问题。本文将通过五个典型场景,展示如何将实际问题转化为数学模型,并利用 intlinprog 实现求解。
1. 投资组合优化:风险约束下的收益最大化
问题背景 :某投资者有100万元资金,考虑投资于4种金融产品。每种产品的预期收益率、风险系数和最低投资额如下表所示:
| 产品 | 预期收益率(%) | 风险系数 | 最低投资额(万元) |
|---|---|---|---|
| A | 8 | 1.2 | 10 |
| B | 6 | 0.8 | 15 |
| C | 12 | 1.8 | 20 |
| D | 4 | 0.5 | 5 |
要求整体投资风险系数不超过1.0,且每种产品要么不投,要么至少达到最低投资额。
建模步骤 :
- 定义决策变量:设投资产品A-D的金额为$x_1$-$x_4$(单位:万元),引入0-1变量$y_i$表示是否投资产品i
- 目标函数:最大化总收益 $\max 0.08x_1 + 0.06x_2 + 0.12x_3 + 0.04x_4$
- 约束条件:
- 总投资额:$x_1 + x_2 + x_3 + x_4 \leq 100$
- 风险控制:$1.2x_1 + 0.8x_2 + 1.8x_3 + 0.5x_4 \leq 100$(总风险不超过100万×1.0)
- 最低投资额约束:
- $x_1 \geq 10y_1$, $x_1 \leq 100y_1$
- $x_2 \geq 15y_2$, $x_2 \leq 100y_2$
- $x_3 \geq 20y_3$, $x_3 \leq 100y_3$
- $x_4 \geq 5y_4$, $x_4 \leq 100y_4$
MATLAB实现 :
f = -[0.08; 0.06; 0.12; 0.04]; % 目标函数系数(求最大值转为最小值)
A = [1.2, 0.8, 1.8, 0.5; 1, 1, 1, 1];
b = [100; 100];
Aeq = [];
beq = [];
lb = zeros(8,1);
ub = [100;100;100;100;1;1;1;1];
intcon = 5:8; % y1-y4为整数变量
% 构造不等式约束矩阵
A = [A, zeros(2,4);
-eye(4), [10;15;20;5].*eye(4);
eye(4), -100*eye(4)];
b = [b; zeros(4,1); zeros(4,1)];
[x, fval] = intlinprog(f, intcon, A, b, Aeq, beq, lb, ub);
disp(['最优投资方案:', num2str(x(1:4)'), '万元']);
disp(['预期最大收益:', num2str(-fval), '万元']);
2. 生产计划优化:多产品多约束排产
问题场景 :某工厂生产三种产品,需要经过两道工序。每种产品在各工序的加工时间、利润及市场需求如下:
| 产品 | 工序1(小时) | 工序2(小时) | 利润(元) | 最大需求 |
|---|---|---|---|---|
| P1 | 2 | 3 | 120 | 50 |
| P2 | 4 | 1 | 150 | 30 |
| P3 | 3 | 2 | 180 | 20 |
工厂每月可用工时为:工序1-200小时,工序2-150小时。要求至少生产每种产品10件。
数学模型 :
- 变量:$x_i$为产品i的生产量(整数)
- 目标:$\max 120x_1 + 150x_2 + 180x_3$
- 约束:
- $2x_1 + 4x_2 + 3x_3 \leq 200$
- $3x_1 + x_2 + 2x_3 \leq 150$
- $10 \leq x_1 \leq 50$
- $10 \leq x_2 \leq 30$
- $10 \leq x_3 \leq 20$
MATLAB求解 :
f = -[120; 150; 180]; % 目标系数
A = [2,4,3; 3,1,2];
b = [200;150];
lb = [10;10;10];
ub = [50;30;20];
intcon = 1:3; % 全部变量为整数
[x, fval] = intlinprog(f, intcon, A, b, [], [], lb, ub);
disp(['最优生产计划:P1=',num2str(x(1)),' P2=',num2str(x(2)),' P3=',num2str(x(3))]);
disp(['最大利润:', num2str(-fval), '元']);
3. 运输优化:多仓库多需求点配送
问题描述 :某公司有3个仓库和4个销售点,运输成本、供应量和需求量如下:
运输成本矩阵(元/吨):
[8 6 10 9;
9 12 13 7;
14 9 16 5]
仓库供应量:[50; 60; 40]吨
销售点需求量:[30; 45; 25; 50]吨
要求每个销售点只能由1个仓库供货(全有或全无)。
建模要点 :
- 引入0-1变量$y_{ij}$表示仓库i是否向销售点j供货
- 连续变量$x_{ij}$表示实际运输量
- 约束:
- 供应限制:$\sum_j x_{ij} \leq \text{供应量}_i$
- 需求限制:$\sum_i x_{ij} = \text{需求量} j \times y {ij}$
- 单一来源:$\sum_i y_{ij} = 1$
MATLAB实现 :
cost = [8 6 10 9; 9 12 13 7; 14 9 16 5];
supply = [50;60;40];
demand = [30;45;25;50];
f = [cost(:); zeros(12,1)]; % xij在前,yij在后
intcon = 13:24; % yij为整数变量
% 构造约束矩阵
A = zeros(19,24);
b = zeros(19,1);
% 供应约束
for i = 1:3
A(i, (i-1)*4+(1:4)) = 1;
b(i) = supply(i);
end
% 需求约束
for j = 1:4
A(3+j, (1:3)*4-4+j) = 1;
A(3+j, 12+j) = -demand(j);
beq(j) = 0;
end
% 单一来源约束
for j = 1:4
A(7+j, 12+j:4:24) = 1;
beq(4+j) = 1;
end
lb = zeros(24,1);
ub = [repmat(supply,4,1); ones(12,1)];
[x, fval] = intlinprog(f, intcon, A, b, Aeq, beq, lb, ub);
4. 排班优化:医院护士调度系统
场景 :某医院需要为护士排班,满足每日需求:
- 早班(8:00-16:00):最少8人
- 中班(16:00-24:00):最少5人
- 夜班(0:00-8:00):最少3人
护士工作规则:
- 连续工作不超过2班
- 工作后至少休息1班
- 每人每周工作不超过40小时
整数规划模型 :
- 变量:$x_{d,s,t}$(第d天第s班次类型t的护士数,t=1新上班,t=2连续第二班)
- 目标:最小化总护士数
- 约束:
- 满足各班次需求
- 连续性约束
- 休息约束
- 工作时间约束
MATLAB关键代码 :
% 定义7天3班次的变量
num_days = 7;
shifts_per_day = 3;
total_shifts = num_days * shifts_per_day;
% 构建目标函数:最小化总护士数
f = ones(1, total_shifts * 2); % 每种班次类型都有变量
% 构建需求约束
A = [];
b = [];
for d = 1:num_days
for s = 1:shifts_per_day
% 每班次总人数 >= 需求
shift_idx = (d-1)*shifts_per_day + s;
constr = zeros(1, total_shifts*2);
constr([shift_idx, shift_idx+total_shifts]) = -1; % x1+x2 >= demand
A = [A; constr];
end
end
b = -[repmat([8;5;3], num_days, 1)]; % 需求向量
% 添加连续性、休息和工作时间约束...
5. 设施选址:物流中心最优布局
问题 :某物流公司需要在10个候选地点中选择3个建立配送中心,满足15个客户点的需求。已知:
- 每个候选中心的建设成本
- 每个客户点的需求量
- 从各候选中心到客户点的运输成本
目标是最小化总成本(建设成本+运输成本)。
建模技巧 :
- 使用0-1变量表示是否选择某候选点
- 连续变量表示从各中心到客户的运输量
- 添加逻辑约束确保只有被选中的中心才能供货
MATLAB实现框架 :
% 参数初始化
fixed_cost = [120, 150, 180, 90, 200, 130, 110, 160, 140, 170]; % 建设成本
transport_cost = rand(10,15); % 运输成本矩阵
demand = randi([10,50],1,15); % 客户需求
% 变量设置
num_warehouses = 10;
num_customers = 15;
total_vars = num_warehouses + num_warehouses*num_customers;
f = [fixed_cost, transport_cost(:)']; % 目标函数系数
intcon = 1:num_warehouses; % 选址变量为整数
% 约束条件构建
A = [];
b = [];
Aeq = zeros(num_customers, total_vars);
beq = demand';
% 每个客户需求必须满足
for c = 1:num_customers
Aeq(c, num_warehouses+c:num_warehouses:end) = 1;
end
% 只有被选中的仓库才能供货
counter = 1;
A = zeros(num_warehouses*num_customers, total_vars);
for w = 1:num_warehouses
for c = 1:num_customers
A(counter, num_warehouses + (w-1)*num_customers + c) = 1;
A(counter, w) = -demand(c);
counter = counter + 1;
end
end
b = zeros(size(A,1),1);
% 选择恰好3个仓库
Aeq = [Aeq; ones(1,num_warehouses), zeros(1,num_warehouses*num_customers)];
beq = [beq; 3];
[x, fval] = intlinprog(f, intcon, A, b, Aeq, beq, zeros(total_vars,1), []);
高级技巧与注意事项
-
模型简化 :对于大规模问题,可考虑:
- 预处理消除冗余变量
- 分解为多个子问题
- 使用启发式算法获取初始解
-
求解加速 :
options = optimoptions('intlinprog',... 'Heuristics','advanced',... 'CutGeneration','intermediate',... 'IntegerPreprocess','advanced'); -
结果验证 :检查
exitflag确认求解状态:- 1:最优解找到
- 2:达到整数可行点
- 0:达到最大迭代次数
-
敏感性分析 :通过
lambda结构体获取影子价格,分析约束松紧程度
混合整数规划在数学建模中应用广泛,从最初的简单生产计划到复杂的物流网络设计, intlinprog 提供了强大的求解能力。实际应用中,良好的模型构建往往比算法选择更重要——合理的变量定义、有效的约束简化能显著提升求解效率。
更多推荐


所有评论(0)