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

OR-Tools Python MIP包装器如何实现半连续变量与乘积约束?

解决OR-Tools中半连续变量的建模问题

核心问题分析

OR-Tools的MIP求解器仅支持线性约束,不允许变量直接相乘(比如x*y),这是触发TypeError的根本原因。半连续变量的逻辑必须转化为等价的线性约束,而非直接使用非线性乘积表达式。

线性化半连续变量的正确建模方式

对于每个产品的产量Xᵢ(半连续变量)和二进制开关变量Yᵢ(0=不生产,1=生产),需添加以下两个线性约束:

  • Xᵢ ≤ Uᵢ * Yᵢ:Uᵢ是Xᵢ的最大可能产量上限。当Yᵢ=0时,Xᵢ必须为0;当Yᵢ=1时,Xᵢ可取值0到Uᵢ(结合下一个约束,实际下限为MOQᵢ)。
  • Xᵢ ≥ MOQᵢ * Yᵢ:当Yᵢ=1时,Xᵢ必须不小于最小订货量MOQᵢ;当Yᵢ=0时,Xᵢ≥0(结合上一个约束,最终Xᵢ=0)。

针对你提到的目标函数/约束(比如X₁Y₁ + ... + XᵢYᵢ ≤ 1000),由于上述约束保证了Yᵢ=0时Xᵢ=0,因此XᵢYᵢ等价于Xᵢ,直接替换为X₁ + ... + Xᵢ ≤ 1000即可,无需使用乘积。

OR-Tools代码示例

from ortools.linear_solver import pywraplp

solver = pywraplp.Solver.CreateSolver('SCIP')  # 可选用CBC等其他MIP求解器
infinity = solver.infinity()

# 定义参数
MOQ = 50       # 最小订货量
MAX_OUTPUT = 500  # 单产品最大产量
TOTAL_CAPACITY = 1000  # 总产能上限

# 定义变量
x = solver.NumVar(0.0, infinity, 'x')
y = solver.IntVar(0, 1, 'y')

# 添加半连续约束
solver.Add(x <= MAX_OUTPUT * y)
solver.Add(x >= MOQ * y)

# 添加总产能约束(等价于x*y ≤ TOTAL_CAPACITY)
solver.Add(x <= TOTAL_CAPACITY)

# 定义目标函数(示例:最大化产量)
solver.Maximize(x)

# 求解并输出结果
status = solver.Solve()
if status == pywraplp.Solver.OPTIMAL:
    print(f'最优解:x={round(x.solution_value(), 2)}, y={y.solution_value()}')
else:
    print('未找到最优解或问题无解')

替代工具推荐

如果希望更便捷地处理半连续变量,可选择原生支持该变量类型的求解器/建模框架:

  • Gurobi:直接提供半连续变量类型(GRB.SEMICONT),无需手动引入二进制变量,建模更简洁。
  • CPLEX:同样支持半连续变量,可通过API直接定义。
  • PuLP:轻量级建模框架,可通过线性约束模拟半连续逻辑,也能对接Gurobi/CPLEX等支持半连续的求解器。
  • Pyomo:灵活的建模语言,支持半连续变量的直接定义,兼容多种求解器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 22:31:15