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

Docplex中add_sos1方法运行过慢的原因排查求助

问题分析与解决方案

为什么add_sos1运行缓慢?

这不是bug,是大规模SOS1约束的正常性能表现。如果Yijpt的规模较大(比如数千甚至上万条),你逐个调用add_sos1会生成大量独立的SOS1集合,每个集合包含2个变量。求解器处理SOS1约束的开销远高于普通线性约束,尤其是当集合数量爆炸时,会导致预处理和约束加载速度骤降。

更关键的问题:你的线性化思路错误

你试图用TV + TVP表示|0.5 - Y|,但当前的约束和目标设置完全偏离了初衷:

  • 约束TV - TVP = 0.5 - Y加上目标最大化TV + TVP,并不能保证TV + TVP等于|0.5 - Y|。求解器会尽可能让TV和TVP同时取最大值,使得TV + TVP远大于实际的绝对值,完全达不到“推动解向整数值靠拢”的目的。
  • 你根本不需要用SOS1,直接用普通线性约束就能准确实现目标。

正确的实现方式

要最大化|0.5 - Y|,最直接高效的线性化方法是引入辅助变量表示绝对值,添加两个线性约束:

# 为每个Yijpt创建辅助变量Z,用于表示|0.5 - Yijpt|
Zijpt = MODEL.continuous_var_dict(Yijpt.keys(), name='Z', lb=0)

# 目标函数:最大化所有Z的和
MODEL.set_objective(sum(Zijpt[k] for k in Yijpt.keys()), sense='max')

# 添加绝对值的线性约束
for k in Yijpt.keys():
    Y = Yijpt[k]
    Z = Zijpt[k]
    MODEL.add_constraint(Z >= 0.5 - Y)
    MODEL.add_constraint(Z >= Y - 0.5)

补充说明

如果你坚持要用TV/TVP变量(不推荐),必须修正目标和约束:

  • 目标应该是让TV + TVP等于|0.5 - Y|,而非最大化TV + TVP,同时用SOS1约束TV和TVP不同时非零。但这种方式既复杂又低效,远不如上面的线性约束方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 21:45:25