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

Docplex中Model.if_then()触发DOcplexException的问题排查与修复

Docplex if_then约束异常:原因及修复

原代码

from docplex.mp.model import Model

car=[1, 2, 3]
myorder=[391, 392, 393, 448, 449, 450]

mdl = Model(name='planning')
Assignment = mdl.binary_var_matrix(myorder, car, name='Assignment')

CarLoaded = mdl.integer_var_dict(car, name='CarLoaded')
for f in car:
    CarLoaded[f] = mdl.sum(Assignment[o, f] * 20 for o in myorder)

CarUtilized = mdl.binary_var_dict(car, name='CarUtilized')
for f in car:
    mdl.add_constraint(
        mdl.if_then(CarLoaded[f] / 123 >= 0.8, CarUtilized[f] == 1))

LoadSum = mdl.sum(CarUtilized[f] * CarLoaded[f] / 30 for f in car)
mdl.maximize(LoadSum)

运行异常

Traceback (most recent call last):
  File "D:\Dev\my_test.py", line 17, in <module>
    mdl.if_then(CarLoaded[f] / 123 >= 0.8, CarUtilized[f] == 1))
  File "C:\ProgramData\Anaconda3\lib\site-packages\docplex\mp\model.py", line 3971, in if_then
    StaticTypeChecker.typecheck_discrete_constraint(logger=self, ct=if_ct, msg='Model.if_then()')
  File "C:\ProgramData\Anaconda3\lib\site-packages\docplex\mp\sttck.py", line 66, in typecheck_discrete_constraint
    logger.fatal('{0}, {1!s} is not discrete', msg, ct)
  File "C:\ProgramData\Anaconda3\lib\site-packages\docplex\mp\model.py", line 1078, in fatal
    self._error_handler.fatal(msg, args)
  File "C:\ProgramData\Anaconda3\lib\site-packages\docplex\mp\error_handler.py", line 210, in fatal
    raise DOcplexException(resolved_message)
docplex.mp.utils.DOcplexException: Model.if_then(), 0.163Assignment_391_1+0.163Assignment_392_1+0.163Assignment_393_1+0.163Assignment_448_1+0.163Assignment_449_1+0.163Assignment_450_1 >= 0.8 is not discrete

异常原因

Docplex的if_then约束要求条件部分必须是离散约束——即约束中的所有系数、常数项都需为整数,避免浮点运算引发的精度问题和类型不兼容。原代码中CarLoaded[f] / 123 >= 0.8是浮点运算,导致条件约束变为非离散类型,触发了类型检查错误。

修复方案

将浮点条件转换为等价的整数约束:
计算0.8 * 123 = 98.4,由于CarLoaded[f]是整数变量,要满足CarLoaded[f]/123 >=0.8,等价于CarLoaded[f] >= 99(因为整数98<98.4,不满足条件;99≥98.4,满足条件)。

修复后的代码:

from docplex.mp.model import Model

car=[1, 2, 3]
myorder=[391, 392, 393, 448, 449, 450]

mdl = Model(name='planning')
Assignment = mdl.binary_var_matrix(myorder, car, name='Assignment')

CarLoaded = mdl.integer_var_dict(car, name='CarLoaded')
for f in car:
    CarLoaded[f] = mdl.sum(Assignment[o, f] * 20 for o in myorder)

CarUtilized = mdl.binary_var_dict(car, name='CarUtilized')
for f in car:
    # 替换浮点约束为等价整数约束
    mdl.add_constraint(
        mdl.if_then(CarLoaded[f] >= 99, CarUtilized[f] == 1))

LoadSum = mdl.sum(CarUtilized[f] * CarLoaded[f] / 30 for f in car)
mdl.maximize(LoadSum)

也可以通过两边同乘10的方式保留原逻辑形式:CarLoaded[f] * 10 >= 123 * 8,计算后同样得到CarLoaded[f] >= 99,效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 15:39:36