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

CPLEX(docplex)中对决策变量用floor函数报LinearExpr错如何解决

报错根因

math.floor是Python标准库提供的数值计算函数,仅支持传入整数、浮点数这类原生数值类型,无法识别docplex定义的决策变量、线性表达式对象(即报错信息中提到的LinearExpr类型)。直接把决策变量传入该函数时,函数无法对优化模型中的符号表达式执行数值计算,就会触发该类型错误。

所有Python原生数学函数(包括math模块下的floor、sqrt、log等)都不能直接作用于docplex的决策变量,这类函数不具备优化模型表达式的解析能力。

步长离散化的正确实现

你要实现的步长为1/6小时的向下取整离散化,不需要强行调用floor函数,用整数变量+线性约束的方式等价建模即可,这也是数学规划求解器处理这类离散逻辑的标准方案,模型保持线性,求解效率极高:

  • 离散步长固定为1/6小时,说明离散后的时间值一定是1/6的非负整数倍
  • 为每个标签新增一个非负整数决策变量k[a],代表对应时间点覆盖的离散步长数量
  • 离散后的时间直接用k[a] * 1/6表示,天然符合步长要求
  • 补充两组线性约束,和原连续变量x1[a]绑定:k[a]*(1/6) ≤ x1[a] < (k[a]+1)*(1/6),这组约束的效果和math.floor(x1[a]/(1/6))*(1/6)完全等价。

修正后的可运行代码如下:

from docplex.mp.model import Model

m = Model(name='time_schedule')
labels = ['home', 'study', 'work']
disc_step = 1/6  # 10分钟为一个离散步长

# 原连续开始时间变量
x1 = m.continuous_var_dict(labels, lb=0, name='start_time')
# 新增整数变量:记录对应时间对应的离散步长计数
step_cnt = m.integer_var_dict(labels, lb=0, name='step_count')
discret_start = {}

for loc in labels:
    # 离散后的时间值,天然为1/6的整数倍
    discret_start[loc] = step_cnt[loc] * disc_step
    # 加约束保证离散值是原时间向下取步长倍数的结果
    m.add_constraint(discret_start[loc] <= x1[loc])
    m.add_constraint(x1[loc] < discret_start[loc] + disc_step)

# 后续正常添加业务约束、目标函数,调用m.solve()求解即可

注意:如果你的时间本身就只需要按1/6小时的粒度调度,甚至可以直接把x1定义为整数变量,单位设为1/6小时,后续计算实际时间的时候再乘1/6即可,模型会更简洁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 00:15:53