在PuLP建模中如何用线性约束定义满足特定条件的Binary indicator variable
在PuLP建模中如何用线性约束定义满足特定条件的Binary indicator variable
嗨,我来帮你搞定这个问题!你需要让二进制变量y在s取0或2时为1,s取1时为0,还得避开非线性的变量乘积,这完全可以通过纯线性约束实现,不用那些麻烦的非线性项。
我给你两种方法,你可以选顺手的用:
方法一:用辅助0-1变量(稳妥清晰)
先定义两个辅助的二进制变量:
- z1:当s≥1时z1=1,s=0时z1=0
- z2:当s≥2时z2=1,s≤1时z2=0
先给这两个辅助变量加线性约束:
约束z1的规则:
z1 ≤ s:s=0时z1必须为0,s≥1时z1最多为1(符合二进制要求)s ≤ 2*z1:z1=0时s只能是0,z1=1时s可以是1或2(不限制)
约束z2的规则:
z2 ≤ s - 1:s≤1时z2必须为0,s=2时z2最多为1s ≥ 2*z2:z2=1时s只能是2,z2=0时s可以是0或1(不限制)
接下来,我们要的y满足:y=1当s=0或2(也就是s≠1),y=0当s=1。而s=1等价于z1=1且z2=0,我们先定义一个中间变量y_temp(代表s=1的情况,y_temp=1当s=1),把y_temp的非线性乘积约束转成线性的:
y_temp的线性约束:
y_temp ≤ z1y_temp ≤ 1 - z2y_temp ≥ z1 - z2y_temp ≥ 0
最后,我们要的y就是:y = 1 - y_temp
现在验证下所有情况:
- s=0时:z1=0,z2=0 → y_temp必须为0 → y=1,完全符合要求
- s=1时:z1=1,z2=0 → y_temp必须为1 → y=0,正确
- s=2时:z1=1,z2=1 → y_temp必须为0 → y=1,完美
所有约束都是线性的,彻底避开了非线性乘积问题。
方法二:直接给y加线性约束(更简洁,适合小取值范围)
因为s的取值只有0、1、2三个整数,我们可以直接给y加以下线性约束:
y ≥ 1 - s:s=0时y必须≥1(也就是y=1),s≥1时这个约束不限制yy ≥ s - 1:s=2时y必须≥1(也就是y=1),s≤1时这个约束不限制ys ≥ 1 - y:y=0时s必须≥1s ≤ 1 + y:y=0时s必须≤1,结合上一个约束,s只能是1
这里要注意,默认情况下s=1时y理论上可以取0或1,如果你需要严格限制y必须为0,可以再加一个约束:y ≤ (2 - s) * s?不对,这是非线性的,其实更简单的方式是在模型中明确:当s=1时y只能为0,你可以加y ≤ 1 - (s - 1)和y ≤ 1 - (1 - s),不过这两个约束在s=1时会限制y≤0,刚好符合要求;s=0或2时也不会限制y的正确取值。如果你的模型目标函数会自然引导y取正确值,前面四个约束就足够用了;如果要绝对严格,还是方法一更稳妥。
备注:内容来源于stack exchange,提问作者cmukid
相关产品推荐
相关产品推荐

