最小成本线性规划构建与求解疑问:建筑公司用工成本优化
问题分析与修正方案
首先,咱们先拆解你原来模型里的几个关键错误,这些错误是导致Matlab求解失败的核心原因:
一、你的模型存在的问题
指示变量的约束逻辑错误
你定义z_i = 0 ⇨ x_i > 0,但给出的约束z_i ≥ 1 - x_i根本无法实现这个逻辑:比如当x_i=5时,1-x_i=-4,z_i≥-4是恒成立的,完全约束不了z_i=0。而且这个约束在x_i是连续变量时,根本没法把z_i和x_i的状态绑定起来。工人数量的约束方向搞反了
你写的y_i ≥ y_{i-1} + x_i是完全错误的:y_i是第i个项目保留的往期工人,它不可能比之前的总工人(y_{i-1}+x_i)还多——毕竟解雇无成本,你最多保留所有现有工人,不可能凭空多出来。这个约束会导致变量值无限增大,直接让求解器崩溃。变量定义模糊且遗漏初始条件
你没明确y_1=0(项目1启动时无工人),这会让求解器不知道初始状态;同时y_i的定义是“保留的往期工人”,但和“第i个项目实际使用的工人数量”的关系没有理清楚,容易导致薪资成本计算混淆。
二、正确的混合整数线性规划(MILP)模型设定
因为涉及到“是否雇佣新工人”的二元决策(触发培训基础费),所以这是一个混合整数线性规划问题(需要0-1指示变量),具体设定如下:
1. 变量定义
w_i:第i个项目开始时公司拥有的工人数量(非负整数/连续变量,根据求解需求选择)x_i:第i个项目雇佣的新工人数量(非负整数/连续变量)z_i:0-1指示变量,z_i=1表示第i个项目雇佣了新工人(x_i>0),z_i=0表示未雇佣新工人w_{7}:第6个项目结束后的工人数量(可以设为0,因为没有后续项目,理性选择解雇所有工人)
2. 目标函数(最小化总成本)
总成本=培训费用+薪资费用:
min ∑_{i=1}^6 [ (300z_i + 50x_i) + 100(w_i + x_i) ]
解释:
- 培训费用:只要雇佣新工人(
z_i=1),就支付300美元基础费,加上每个新工人50美元的额外培训费;未雇佣则培训费用为0 - 薪资费用:每个项目中,公司拥有的工人(
w_i)+新雇佣的工人(x_i)都需要支付100美元/人的薪资(符合题目描述的“工人每个项目的薪资为100美元”)
3. 约束条件
- 项目需求约束:每个项目的总工人数量必须满足需求
w_i + x_i ≥ d_i ,∀i=1,2,...,6 - 工人数量流转约束:第i+1个项目开始时的工人数量,不能超过第i个项目结束时的总工人数量(可以解雇任意数量工人)
w_{i+1} ≤ w_i + x_i ,∀i=1,2,...,6 - 初始条件:项目1启动时无工人
w_1 = 0 - 指示变量与新雇工人的绑定约束:用大M法绑定
z_i和x_i,M取足够大的数(比如所有d_i的总和,确保覆盖最大可能的雇佣量)
解释:当x_i ≤ M * z_i ,∀i=1,2,...,6z_i=0时,x_i≤0,结合x_i≥0,可得x_i=0(未雇佣新工人);当z_i=1时,x_i≤M(允许雇佣任意数量的新工人) - 变量非负性与整数约束:
(如果允许工人数量为连续变量,也可以去掉整数约束,求解后再取整,结果差异很小)w_i ≥ 0, x_i ≥ 0 ,∀i=1,2,...,6 z_i ∈ {0,1} ,∀i=1,2,...,6
三、Matlab求解建议
因为这是混合整数线性规划,你需要用Matlab的intlinprog函数(而不是普通的linprog),步骤大概是:
- 把所有变量转换成一维向量,区分整数变量(
z_i)和连续变量(w_i, x_i) - 构造目标函数系数向量、约束矩阵
A和右端向量b、变量上下界 - 调用
intlinprog求解,指定整数变量的索引
比如,假设变量顺序是w1,w2,...,w7,x1,x2,...,x6,z1,z2,...,z6,那么整数变量是最后6个(z1-z6)。
内容的提问来源于stack exchange,提问作者Roi Hezkiyahu
相关产品推荐
相关产品推荐

