Skip to content

Commit c90edde

Browse files
committed
some work on iis
1 parent 33af1b3 commit c90edde

File tree

4 files changed

+78
-10
lines changed

4 files changed

+78
-10
lines changed

src/pyscipopt/iisfinder.pxi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
cdef class IISfinder:
44
cdef public Model model
55
cdef public str name
6-
cdef SCIP_IIS* _iisfinder
6+
cdef SCIP_IISFINDER* _iisfinder
7+
cdef SCIP_IIS* _iis
78

89
def iisfinderfree(self):
910
'''calls destructor and frees memory of iis finder'''

src/pyscipopt/scip.pxd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,10 @@ cdef extern from "scip/scip.h":
12231223
SCIP_RETCODE SCIPiisGreedyMakeIrreducible(SCIP_IIS* iis)
12241224
SCIP_Bool SCIPiisIsSubscipInfeasible(SCIP_IIS* iis)
12251225
SCIP_Bool SCIPiisIsSubscipIrreducible(SCIP_IIS* iis)
1226+
SCIP_IIS* SCIPgetIIS(SCIP* scip)
1227+
SCIP_Real SCIPiisGetTime(SCIP_IIS* scip)
1228+
SCIP_Bool SCIPiisIsSubscipIrreducible(SCIP_IIS* scip)
1229+
SCIP_Longint SCIPiisGetNNodes(SCIP_IIS* scip)
12261230
SCIP* SCIPiisGetSubscip(SCIP_IIS* iis)
12271231

12281232
#Relaxation plugin
@@ -2212,6 +2216,8 @@ cdef class Model:
22122216
cdef int _generated_event_handlers_count
22132217
# store references to Benders subproblem Models for proper cleanup
22142218
cdef _benders_subproblems
2219+
# store iis, if found
2220+
cdef SCIP_IIS* _iis
22152221

22162222
@staticmethod
22172223
cdef create(SCIP* scip)

src/pyscipopt/scip.pxi

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,6 +2663,23 @@ cdef class _VarArray:
26632663
if self.ptr != NULL:
26642664
free(self.ptr)
26652665

2666+
cdef class IIS:
2667+
cdef SCIP_IIS* _iis
2668+
cdef SCIP* subscip
2669+
cdef public object time
2670+
cdef public object irreducible
2671+
cdef public object nodes
2672+
cdef public object model
2673+
2674+
def __init__(self, Model model):
2675+
self._iis = SCIPgetIIS(model._scip)
2676+
self.time = SCIPiisGetTime(self._iis)
2677+
self.irreducible = SCIPiisIsSubscipIrreducible(self._iis)
2678+
self.nodes = SCIPiisGetNNodes(self._iis)
2679+
subscip = SCIPiisGetSubscip(self._iis)
2680+
self.model = Model.create(subscip)
2681+
model._iis = self._iis
2682+
26662683
# - remove create(), includeDefaultPlugins(), createProbBasic() methods
26672684
# - replace free() by "destructor"
26682685
# - interface SCIPfreeProb()
@@ -2706,6 +2723,7 @@ cdef class Model:
27062723
self._modelvars = {}
27072724
self._generated_event_handlers_count = 0
27082725
self._benders_subproblems = [] # Keep references to Benders subproblem Models
2726+
self._iis = NULL
27092727

27102728
if not createscip:
27112729
# if no SCIP instance should be created, then an empty Model object is created.
@@ -9283,16 +9301,40 @@ cdef class Model:
92839301
"""
92849302
Generates an Irreducible Infeasible Subsystem (IIS) from the current
92859303
problem.
9304+
9305+
Returns
9306+
-------
9307+
IIS
9308+
9309+
"""
9310+
PY_SCIP_CALL( SCIPgenerateIIS(self._scip) )
9311+
iis = IIS(self)
9312+
return iis
9313+
9314+
def getIIS(self):
9315+
"""
9316+
Get the IIS object.
9317+
Note: Needs to be called after generateIIS, or after a single execution of the iisfinderExec.
9318+
9319+
Returns
9320+
-------
9321+
IIS
92869322
"""
9323+
assert self._iis != NULL, "No IIS exists. You need to first call generateIIS() or run the iisfinderexec method of your custom IISfinder class."
92879324

9288-
PY_SCIP_CALL(SCIPgenerateIIS(self._scip))
9325+
return IIS(self)
92899326

9290-
def iisGreedyMakeIrreducible(self, IISfinder iisfinder):
9327+
def iisGreedyMakeIrreducible(self, IIS iis):
92919328
"""
92929329
Perform the greedy deletion algorithm with singleton batches to obtain an irreducible infeasible subsystem (IIS)
9330+
9331+
Parameters
9332+
----------
9333+
iis : IIS
9334+
The IIS to apply the greedy deletion algorithm to.
92939335
"""
92949336

9295-
PY_SCIP_CALL(SCIPiisGreedyMakeIrreducible(iisfinder._iisfinder))
9337+
PY_SCIP_CALL(SCIPiisGreedyMakeIrreducible(iis._iis))
92969338

92979339
def includeRelax(self, Relax relax, name, desc, priority=10000, freq=1):
92989340
"""

tests/test_iis.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,37 @@ def infeasible_model():
1212
m.addCons(x1 + x2 == 1, name="c1")
1313
m.addCons(x2 + x3 == 1, name="c2")
1414
m.addCons(x1 + x3 == 1, name="c3")
15+
m.addCons(x1 + x2 + x3 <= 0, name="c4")
1516

1617
return m
1718

1819
def test_generate_iis():
1920
m = infeasible_model()
2021

2122
# make sure IIS generation doesn't raise any exceptions
22-
m.generateIIS()
23-
23+
iis = m.generateIIS()
24+
assert iis.irreducible
25+
assert iis.model.getNConss() == 2
26+
assert iis.nodes == 0
27+
iis.time
2428

2529
class myIIS(IISfinder):
26-
def __init__(self, model):
30+
def __init__(self, model, skip=False):
2731
super().__init__()
2832
self.model = model
2933
self.size = 0
3034
self.iis = None
35+
self.skip = skip
3136

3237
def iisfinderexec(self):
33-
n_infeasibilities, aux_vars = get_infeasible_constraints(self.model.__repr__.__self__)
38+
if self.skip:
39+
return {"result": SCIP_RESULT.SUCCESS} # success to attempt to skip further processing
40+
41+
n_infeasibilities, _ = get_infeasible_constraints(self.model.__repr__.__self__)
3442
if n_infeasibilities == 0:
3543
return {"result": SCIP_RESULT.DIDNOTFIND}
3644

3745
self.size = n_infeasibilities
38-
self.iis = aux_vars
3946
return {"result": SCIP_RESULT.SUCCESS}
4047

4148
def test_custom_iis_finder():
@@ -46,4 +53,16 @@ def test_custom_iis_finder():
4653
m.includeIISfinder(my_iis, "", "")
4754

4855
m.generateIIS()
49-
assert my_iis.size == 1
56+
iis = m.getIIS()
57+
assert iis.model.getNConss() == my_iis.size
58+
59+
def test_iisGreddyMakeIrreducible():
60+
m = infeasible_model()
61+
my_iis = myIIS(m, skip=True)
62+
m.includeIISfinder(my_iis, "", "")
63+
iis = m.generateIIS()
64+
with pytest.raises(AssertionError):
65+
assert not iis.irreducible # currently breaking. do SCIP IIS methods enter after custom iisfinder?
66+
67+
m.iisGreedyMakeIrreducible(iis)
68+
assert iis.irreducible

0 commit comments

Comments
 (0)