SCIP自定义MIP切割器:约束绑定检测失败问题求助
问题原因与解决方案
为什么直接比较LHS和RHS会失败?
SCIP里,不等式约束(比如a^T x ≤ b或a^T x ≥ b)会把未使用的一侧边界设为极端值(1e20或-1e20),只有等式约束(a^T x = b)的LHS和RHS才会相等。你要找的是当前LP解下被激活的紧约束,不是约束本身是等式,所以直接对比LHS和RHS完全找错了方向。
正确的紧约束判断方法
得计算当前LP解下约束的实际活动值,再检查这个值是否在SCIP的可行性容差范围内,等于约束的LHS或RHS。具体步骤:
- 用
row.getActivity()获取当前LP解下该行约束的实际计算值 - 用
m.getFeastol()获取模型的可行性容差(别硬编码数值,适配模型配置) - 判断活动值是否接近有效边界(过滤掉±1e20这种无界标记)
修改后的代码示例
class Cutter(scip.Sepa): def sepaexeclp(self): m: scip.Model = self.model if not m.getLPSolstat() or not m.isLPSolBasic(): return {"result": scip.PY_SCIP_RESULT.DIDNOTRUN} rows = m.getLPRowsData() feastol = m.getFeastol() tight_constraints = [] for row in rows: lhs = row.getLhs() rhs = row.getRhs() activity = row.getActivity() # 判断是否接近有效边界 is_tight = False # 只有当LHS不是极端下界时,才检查是否紧在LHS上 if lhs > -1e19 and abs(activity - lhs) <= feastol: is_tight = True # 只有当RHS不是极端上界时,才检查是否紧在RHS上 if rhs < 1e19 and abs(activity - rhs) <= feastol: is_tight = True if is_tight: tight_constraints.append(row) # 后续处理tight_constraints... ...
关键细节
row.getActivity():返回当前LP解下,该行约束左边线性组合的实际计算值m.getFeastol():模型内置的可行性容差,用来避免直接用==比较浮点数的精度问题- 过滤极端边界:SCIP用±1e20表示约束无对应方向的界,比如LHS=-1e20时,约束实际是
a^T x ≤ rhs,不用检查是否紧在LHS上
内容的提问来源于stack exchange,提问作者Brannon
相关产品推荐
相关产品推荐

