【发布时间】:2021-02-26 15:36:05
【问题描述】:
我正在使用 PySCIPOpt(SCIP 版本 6.0.2,PySCIPOpt 版本 2.2.3)来解决混合整数问题。约束处理程序应该检查和执行一些没有直接建模到问题中的需求(惰性约束)。
问题:预求解极大地简化了原始问题(删除变量),以至于约束处理程序(在预求解之后)插入的约束导致不可行。
在下面的示例中,仅存在两个二进制变量和一个集合分区约束。预求解能够删除所有变量和约束。约束处理程序将x_0 变量限制为0,问题变得不可行。如果关闭预求解,则会找到“正确”的解 x_1 = 1。
from pyscipopt import Model, quicksum, Conshdlr, SCIP_RESULT, SCIP_PRESOLTIMING, SCIP_PROPTIMING, SCIP_PARAMSETTING
class ConshdlrNotZero(Conshdlr):
def __init__(self):
pass
def conscheck(self, constraints, solution, checkintegrality, checklprows, printreason, completely):
x = self.data
if self.model.getSolVal(solution, x[0]) > 0.5:
return {"result": SCIP_RESULT.INFEASIBLE}
return {"result": SCIP_RESULT.FEASIBLE}
def consenfolp(self, constraints, nusefulconss, solinfeasible):
x = self.data
if self.model.getSolVal(None, x[0]) > 0.5:
self.model.addCons(x[0] <= 0, name='fix_x0')
return {"result": SCIP_RESULT.CONSADDED}
return {"result": SCIP_RESULT.FEASIBLE}
def conslock(self, constraint, locktype, nlockspos, nlocksneg):
pass
m = Model('test_presolve')
x = dict()
x[0] = m.addVar(vtype='BINARY', obj=0, name="x_%d" % 0)
x[1] = m.addVar(vtype='BINARY', obj=1, name="x_%d" % 1)
m.addCons(quicksum(x_var for x_var in x.values()) == 1, name="set_partitioning")
conshdlr = ConshdlrNotZero()
conshdlr.data = x
m.includeConshdlr(conshdlr, "n0", "please not the x_0 variable",
sepapriority=-1, enfopriority=-1, chckpriority=-1, sepafreq=-1, propfreq=-1,
eagerfreq=-1, maxprerounds=0, delaysepa=False, delayprop=False, needscons=False,
presoltiming=SCIP_PRESOLTIMING.FAST, proptiming=SCIP_PROPTIMING.BEFORELP)
# m.setPresolve(SCIP_PARAMSETTING.OFF)
m.setMinimize()
m.optimize()
m.printSol()
有没有办法确保在预求解中考虑约束处理程序(禁用预求解除外)?
编辑:在预求解作品中禁用双重缩减(将 misc/allowdualreds 设置为 0)。我仍然想知道为什么这可以解决问题以及是否有更好的解决方案。
【问题讨论】:
标签: scip