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

如何用约束变量统计整数列表中大于5的元素数量?代码问题解惑

整数规划约束问题:布尔求和与除法约束的异常原因

问题场景

给定整数列表(比如[1,2,5,3,8,10]),要通过变量统计列表里大于5的元素数量,再用这个变量做除法约束。但代码运行后,用变量s1(预期值为3)写的除法约束,和直接写3的结果不一样;把s1的定义域改成1-3后就正常了,搞不懂为啥。

用户代码

bs = []
for i in range(6):
   b = model.NewBoolVar(f'b_{i}')
   p = model.NewIntVar(s, 50, f'p_{i}')
   model.Add(p >= 5).OnlyEnforceIf(b)
   model.Add(p < 5).OnlyEnforceIf(b.Not())
   bs.append(b)

x = model.NewIntVar(0, 10000, 'x')
y = model.NewIntVar(0, 10000, 'y')
s1 = model.NewIntVar(0, 3, 's1')
#...
model.Add(s1 == sum(bs))
model.AddDivisionEquality(x, y, s1)

原因分析

1. 除数为0的潜在冲突

OR-Tools里的AddDivisionEquality(x, y, s1)本质是要求y = x * s1(也就是y必须能被s1整除,x是商)。当你把s1的下界设为0时,求解器必须考虑s1=0的情况:

  • 数学上除数不能为0,这会导致约束逻辑出现矛盾,求解器可能会优先寻找满足s1=0的解(此时要求y=0),直接忽略了你预期的s1=3的场景,最终结果自然和直接写3不一样。

2. 布尔约束的小细节(额外提醒)

你代码里的布尔变量约束是p>=5时b=True,这会把列表里的5也统计进去,所以s1预期为3(对应5、8、10三个元素)。如果你的需求是严格大于5,得把约束改成:

model.Add(p > 5).OnlyEnforceIf(b)
model.Add(p <= 5).OnlyEnforceIf(b.Not())

这样5就不会被计入统计了。

3. 为什么改定义域就正常了

把s1的定义域改成1-3,直接排除了s1=0的非法情况,求解器只能在1、2、3里找符合s1 == sum(bs)的值,最终匹配到s1=3,除法约束的逻辑就和直接写3完全一致了。

总结

核心问题就是初始代码允许s1=0,触发了除法约束的非法场景,干扰了求解器的计算。把s1下界设为1,排除除数为0的可能,就能得到预期结果。

内容的提问来源于stack exchange,提问作者John M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:55:41