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

如何在Google OR-Tools中使用max函数?线性求解器报错处理

在Google OR-Tools中实现Σmax(0, C_i - d_i)的正确方式

你的错误根源在于:Google OR-Tools的线性求解器仅支持线性表达式和约束,不能直接使用Python内置的max()函数,也不能基于求解器变量(比如C_i[i])写条件判断(if C_i[i] > d_j[i]这类逻辑)——这些操作会引入非线性逻辑,超出线性求解器的处理范围。

正确实现思路

要模拟max(0, x)的线性表达,需要引入辅助变量并添加线性约束:

  1. 对每个任务i,创建辅助变量s_i,用于表示max(0, C_i - d_i)。
  2. 添加两个约束:
    • s_i >= C_i - d_i:确保s_i至少等于C_i - d_i的差值
    • s_i >= 0:确保s_i不会为负数
  3. 将目标函数设为所有s_i的和,进行最小化。

因为我们的目标是最小化总和,最优解中s_i会自动取max(0, C_i - d_i):

  • 当C_i - d_i <= 0时,s_i取0(满足两个约束且总和最小)
  • 当C_i - d_i > 0时,s_i会等于C_i - d_i(否则总和可以更小)

代码示例

假设你已经初始化了LinearSolver,且C_i是已定义的完工时间变量数组,d_i是交货期数组:

from ortools.linear_solver import pywraplp

# 初始化求解器(示例用SCIP,可替换为其他线性求解器)
solver = pywraplp.Solver.CreateSolver('SCIP')
if not solver:
    exit()

job_num = 5  # 示例任务数
d_i = [10, 15, 8, 20, 12]  # 示例交货期

# 假设C_i是已定义的完工时间变量(比如调度问题中通过约束计算的变量)
C_i = []
for i in range(job_num):
    C_i.append(solver.NumVar(0, solver.infinity(), f'C_{i}'))

# 创建辅助变量s_i
s = []
for i in range(job_num):
    s_i = solver.NumVar(0, solver.infinity(), f's_{i}')
    s.append(s_i)
    # 添加约束:s_i >= C_i[i] - d_i[i]
    solver.Add(s_i >= C_i[i] - d_i[i])
    # s_i >=0 已在变量定义时设下界为0,可省略显式约束

# 设置目标函数:最小化sum(s_i)
objective = solver.Objective()
for s_i in s:
    objective.SetCoefficient(s_i, 1)
objective.SetMinimization()

# 求解
status = solver.Solve()

if status == pywraplp.Solver.OPTIMAL:
    print('最优目标值:', solver.Objective().Value())
    for i in range(job_num):
        print(f'任务{i}:C_i={C_i[i].solution_value()}, s_i={s[i].solution_value()}')
else:
    print('未找到最优解')

为什么你的之前尝试不可行

你写的T1和T2中用了if C_i[i] <= d_j[i]这类条件判断,这会直接尝试对求解器变量做比较运算,而OR-Tools线性求解器不支持这种操作——所有逻辑必须通过线性约束来表达,不能用Python的条件分支直接过滤变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 18:44:59