Pulp调用Gurobi求解LP时状态最优但约束未满足问题排查
问题分析与解决方案
核心问题:约束逻辑错误+数值精度问题
你当前的约束存在两个关键问题,导致Gurobi返回"最优解"但实际违反约束:
过大的
inf值引发数值不稳定
你用了inf=1e6,远大于var_shengmu的上下界(0-100),这种极端大的M值会让约束的数值条件极差,Gurobi在处理整数规划时,可能因为浮点精度误差,无法准确判断约束是否被严格满足,从而接受了违反约束的解。约束逻辑错误+多余的
epsvar_shengmu是整数变量,整数之间的差至少为1,用eps=1e-5这种小数完全多余,反而会导致约束逻辑失效:
- 当
var_qiuyi_shengmu[i][j]=1时,约束(b)要求var_shengmu[j]-var_shengmu[i]>=1e-5,但两个整数都是0时,0>=1e-5显然不成立,这是矛盾的; - 当
var_qiuyi_shengmu[i][j]=0时,约束(b)的右边变成1e-5 -1e6≈-1e6,var_shengmu[j]-var_shengmu[i]>=-1e6是必然成立的,完全起不到强制变量不同的作用。
正确的约束写法
利用整数变量的性质,我们只需要强制两个变量的差至少为1,结合二进制变量选择差的方向即可。将inf替换为变量上下界的合理差值(这里取100,因为var_shengmu最大为100,最小为0),去掉eps,重新定义约束:
MyProblem = pulp.LpProblem("MyProblem", pulp.LpMinimize) # 定义变量 var_shengmu = {i: pulp.LpVariable(name=f"var_shengmu{i}", lowBound=0, upBound=100, cat=pulp.LpInteger) for i in range(N)} var_qiuyi_shengmu = {i:{j:pulp.LpVariable(name=f"var_qiuyi_shengmu{i}{j}", cat=pulp.LpBinary) for j in range(i+1,N)} for i in range(N)} # 定义合理的M值(变量上下界差) M = 100 # 添加约束 for i in range(N): for j in range(i+1,N): if some_condition: # 需要var_shengmu[i]和var_shengmu[j]取值不同 y = var_qiuyi_shengmu[i][j] # 情况1:y=1时,var_shengmu[i] <= var_shengmu[j] - 1 MyProblem += var_shengmu[i] - var_shengmu[j] <= -1 + M * (1 - y) # 情况2:y=0时,var_shengmu[j] <= var_shengmu[i] - 1 MyProblem += var_shengmu[j] - var_shengmu[i] <= -1 + M * y
约束逻辑说明
- 当二进制变量
y=1时,第一个约束生效:var_shengmu[i] <= var_shengmu[j] -1,强制var_shengmu[i]比var_shengmu[j]至少小1; - 当二进制变量
y=0时,第二个约束生效:var_shengmu[j] <= var_shengmu[i] -1,强制var_shengmu[j]比var_shengmu[i]至少小1; - 两个约束覆盖了所有变量不同的情况,且没有数值精度问题,求解器能准确执行约束逻辑。
内容的提问来源于stack exchange,提问作者FeiYiZhaiMenRen
相关产品推荐
相关产品推荐

