Python中Docplex整数/二进制变量输出近似浮点值问题排查
问题分析与解决方案
为什么会出现浮点值?
你的变量定义本身没有问题(从模型统计的binary=54143, integer=6798可确认所有变量都是整数/二进制类型),出现近似浮点值的原因主要有两个:
- 求解器浮点精度误差:MILP求解器内部使用浮点数运算,当问题规模较大(你这里有6万+变量)时,数值计算的累积误差会导致结果显示为接近整数的浮点数(比如
8314.999999999944实际就是整数8315)。 - 你看到的是聚合值:QB、QBR是五维整数变量数组,LR是二维二进制变量数组,你输出的应该是这些变量的求和结果,而非单个变量的值。聚合后的浮点偏差是多个变量浮点误差的累积结果。
另外,你的代码存在一个明显错误:Qproduct变量未定义,会导致运行时抛出NameError,需要先根据实际需求定义该变量。
修正方法
1. 修正代码中的未定义变量
在变量定义前添加Qproduct的定义:
from docplex.mp.model import Model from datetime import datetime model = Model(name='Logistics') T = 3 P = 5 A = 13 B = 2 R = 2 Qproduct = 10 # 替换为你实际的产品数量 QB = [[[[[model.integer_var(name=f"QB_{t}_{p}_{q}_{a}_{b}") for b in range(B)] for a in range(A)] for q in range(Qproduct)] for p in range(P)] for t in range(T)] QBR = [[[[[model.integer_var(name=f"QBR_{t}_{p}_{q}_{b}_{r}") for r in range(R)] for b in range(B)] for q in range(Qproduct)] for p in range(P)] for t in range(T)] LR = [[model.binary_var(name=f"LR_{t}_{r}") for r in range(R)] for t in range(T)]
2. 处理浮点结果的显示与取值
对于单个变量或聚合值,可通过四舍五入或格式化输出得到整数结果:
# 获取单个QB变量的整数解 qb_single_value = round(QB[0][0][0][0][0].solution_value) # 计算所有QB变量的总和并转为整数 total_qb = sum(QB[t][p][q][a][b].solution_value for t in range(T) for p in range(P) for q in range(Qproduct) for a in range(A) for b in range(B)) total_qb_int = round(total_qb) # 格式化输出结果 print(f"QB总和 = {total_qb_int}") print(f"LR总和 = {round(sum(LR[t][r].solution_value for t in range(T) for r in range(R)))}")
3. 调整求解器精度参数
如果希望求解器更严格地收敛到整数解,可以调整求解器的容差参数:
# 设置整数容差(更小的值意味着更严格的整数约束) model.parameters.mip.tolerances.integrality = 1e-6 # 设置MIP间隙(更小的间隙意味着求解器会更接近最优整数解) model.parameters.mip.tolerances.mipgap = 1e-8 # 求解模型 solution = model.solve()
内容的提问来源于stack exchange,提问作者Nasser Tarin
相关产品推荐
相关产品推荐

