
本文介绍在pulp等线性规划建模工具中,如何仅使用线性约束为取值 {0,1,2} 的整数变量 s 构造二元指示变量 y,使其满足 y=1 当且仅当 s=0 或 s=2,y=0 当且仅当 s=1。
本文介绍在pulp等线性规划建模工具中,如何仅使用线性约束为取值 {0,1,2} 的整数变量 s 构造二元指示变量 y,使其满足 y=1 当且仅当 s=0 或 s=2,y=0 当且仅当 s=1。
在混合整数线性规划(MILP)建模中,常需将离散逻辑关系转化为线性约束。本例中,整数变量 ( s \in {0,1,2} ) 与二元变量 ( y \in {0,1} ) 的映射是非平凡的:要求 ( y = \mathbb{I}[s \neq 1] ),即 y 在 s 取极值(0 或 2)时激活,而在中间值(1)时关闭。该逻辑看似简单,但直接用乘积(如 ( y = z_1(1 - z_2) ))会引入非线性,破坏LP/MILP求解器的兼容性。
幸运的是,利用变量取值范围有限(仅3个可能值)这一结构特性,可通过引入一个辅助二元变量 ( s_1 \in {0,1} ) 实现完全线性化。核心思路是构造一个仿射表达式,精确覆盖所有三组可行解:
# PuLP 示例代码
from pulp import LpProblem, LpVariable, LpMaximize
prob = LpProblem("IndicatorExample", LpMaximize)
s = LpVariable("s", lowBound=0, upBound=2, cat="Integer")
y = LpVariable("y", cat="Binary")
s1 = LpVariable("s1", cat="Binary")
# 线性约束:y == 1 - s + 2*s1
prob += y == 1 - s + 2 * s1
# 隐含于 cat="Binary",但显式声明更清晰:
prob += y >= 0
prob += y = 0
prob += s1 <p>该约束在三个取值点上严格满足目标逻辑:</p>
- 当 ( s = 0 ):代入得 ( y = 1 - 0 + 2s_1 = 1 + 2s_1 )。因 ( y \leq 1 ),必有 ( s_1 = 0 ),故 ( y = 1 ) ✅
- 当 ( s = 1 ):( y = 1 - 1 + 2s_1 = 2s_1 )。因 ( y \in {0,1} ),唯一可行解为 ( s_1 = 0 \Rightarrow y = 0 ) ✅
- 当 ( s = 2 ):( y = 1 - 2 + 2s_1 = -1 + 2s_1 )。为使 ( y \geq 0 ),需 ( s_1 = 1 \Rightarrow y = 1 ) ✅
关键优势:所有约束均为线性等式/不等式,完全兼容 PuLP、Gurobi、CPLEX 等主流求解器,无需分段建模或大M技巧。
⚠️ 注意事项:
- 此方法依赖于 ( s ) 的已知、有限、有序整数域(此处为 {0,1,2})。若 ( s ) 范围扩大(如 0–10),需改用标准的大M法或分段线性化;
- 辅助变量 ( s_1 ) 无业务含义,仅为数学实现服务,建模时可命名如
s_is_two以增强可读性; - 在实际模型中,建议添加注释说明该约束的逻辑意图,例如
# y=1 iff s==0 or s==2,提升代码可维护性。
综上,通过巧妙引入单个辅助二元变量并构建精准仿射关系,即可在纯线性框架下实现所需逻辑指示功能——这体现了MILP建模中“结构洞察优于暴力枚举”的设计哲学。










