You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Gurobi/Python API中用决策变量实现多条件约束?

线性规划约束实现方案(基于二进制辅助变量)

核心思路

引入二进制辅助变量z[1]到z[18],每个z[k]取值为0或1,用来标记是否激活第k个W的条件(即W[k]>0且所有W[j>k]=0)。通过二进制变量的互斥性和线性约束,将原逻辑转化为LP可识别的约束。

具体约束实现

1. 二进制变量互斥约束

确保最多只有一个z[k]被激活(如果业务要求必须有一个W>0,将≤改为=):

sum(z[1] + z[2] + ... + z[18]) ≤ 1

2. W变量与二进制变量的关联约束

设M为W变量的最大可能取值(根据实际业务场景设定),ε为极小正数(如1e-6,用来模拟W[k]>0的条件):

  • 对每个k∈[1,18]:
    W[k] ≤ M * z[k]          # z[k]=0时,W[k]必须为0
    W[k] ≥ ε * z[k]          # z[k]=1时,W[k]至少为ε(近似W[k]>0)
    
  • 对每个k∈[1,17],约束所有j>k的W[j]在z[k]激活时为0:
    for j in range(k+1, 19):
        W[j] ≤ M * (1 - z[k])
    

3. U变量的约束

  • 对每个t∈[1,17],当存在任何j>t的z[j]激活时,U[t]必须为0:
    U[t] ≤ M * (1 - sum(z[t+1], z[t+2], ..., z[18]))
    U[t] ≥ -M * (1 - sum(z[t+1], z[t+2], ..., z[18]))
    
    两个约束结合后,当sum(z[t+1]..z[18])=1时,U[t]只能等于0;否则无强制约束。
  • 对每个k∈[1,18],当z[k]激活时,U[k]≥0:
    U[k] ≥ 0 - M * (1 - z[k])
    
    当z[k]=1时,约束简化为U[k]≥0;当z[k]=0时,该约束自动满足(因为-M*(1-0)=-M,而U[k]的取值范围通常不会低于-M)。

代码示例(适配你的manpower模型)

# 定义二进制变量z[1]到z[18]
z = {}
for k in range(1, 19):
    z[k] = manpower.addVar(vtype=GRB.BINARY, name=f"z_{k}")

# 1. 互斥约束
manpower.addConstr(quicksum(z[k] for k in range(1, 19)) <= 1, name="z_mutually_exclusive")

# 设定M和ε(根据实际问题调整)
M = 1000  # W的最大可能值
epsilon = 1e-6

# 2. W与z的关联约束
for k in range(1, 19):
    # W[k] <= M*z[k]
    manpower.addConstr(W[k] <= M * z[k], name=f"W_upper_{k}")
    # W[k] >= epsilon*z[k]
    manpower.addConstr(W[k] >= epsilon * z[k], name=f"W_lower_{k}")
    # 约束j>k的W[j]为0当z[k]=1
    for j in range(k+1, 19):
        manpower.addConstr(W[j] <= M * (1 - z[k]), name=f"W_j_zero_{j}_when_z{k}")

# 3. U变量约束
for t in range(1, 18):
    # sum(z[t+1]到z[18])
    sum_z = quicksum(z[j] for j in range(t+1, 19))
    # U[t] <= M*(1 - sum_z)
    manpower.addConstr(U[t] <= M * (1 - sum_z), name=f"U_upper_{t}")
    # U[t] >= -M*(1 - sum_z)
    manpower.addConstr(U[t] >= -M * (1 - sum_z), name=f"U_lower_{t}")

for k in range(1, 19):
    # U[k] >= 0 - M*(1 - z[k])
    manpower.addConstr(U[k] >= -M * (1 - z[k]), name=f"U_k_nonneg_{k}")

补充说明

  • 如果W变量本身默认非负,可省略部分冗余约束;
  • M的取值要足够大,确保覆盖W和U的所有可能取值,避免约束失效;
  • ε的取值要足够小,既满足“W[k]>0”的逻辑,又不会影响模型求解精度。

内容的提问来源于stack exchange,提问作者Adri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:32:49