Skip to content

Commit 3599159

Browse files
committed
Support for AND-constraints
1 parent 14ba422 commit 3599159

4 files changed

Lines changed: 144 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44
### Added
5+
- More support for AND-Constraints
56
- Added getLinearConsIndicator
67
- Added SCIP_LPPARAM, setIntParam, setRealParam, getIntParam, getRealParam, isOptimal, getObjVal, getRedcost for lpi
78
- Added isFeasPositive

src/pyscipopt/scip.pxd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,6 +1612,11 @@ cdef extern from "scip/cons_and.h":
16121612
SCIP_Bool dynamic,
16131613
SCIP_Bool removable,
16141614
SCIP_Bool stickingatnode)
1615+
int SCIPgetNVarsAnd(SCIP* scip, SCIP_CONS* cons)
1616+
SCIP_VAR** SCIPgetVarsAnd(SCIP* scip, SCIP_CONS* cons)
1617+
SCIP_VAR* SCIPgetResultantAnd(SCIP* scip, SCIP_CONS* cons)
1618+
SCIP_Bool SCIPisAndConsSorted(SCIP* scip, SCIP_CONS* cons)
1619+
SCIP_RETCODE SCIPsortAndCons(SCIP* scip, SCIP_CONS* cons)
16151620

16161621
cdef extern from "scip/cons_or.h":
16171622
SCIP_RETCODE SCIPcreateConsOr(SCIP* scip,

src/pyscipopt/scip.pxi

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5689,6 +5689,124 @@ cdef class Model:
56895689

56905690
return vars
56915691

5692+
def getNVarsAnd(self, Constraint constraint):
5693+
"""
5694+
Gets number of variables in and constraint.
5695+
5696+
Parameters
5697+
----------
5698+
constraint : Constraint
5699+
Constraint to get the number of variables from.
5700+
5701+
Returns
5702+
-------
5703+
int
5704+
5705+
"""
5706+
cdef int nvars
5707+
cdef SCIP_Bool success
5708+
5709+
return SCIPgetConsNVarsAnd(self._scip, constraint.scip_cons)
5710+
5711+
def getConsVarsAnd(self, Constraint constraint):
5712+
"""
5713+
Gets variables in and constraint.
5714+
5715+
Parameters
5716+
----------
5717+
constraint : Constraint
5718+
Constraint to get the variables from.
5719+
5720+
Returns
5721+
-------
5722+
list of Variable
5723+
5724+
"""
5725+
cdef SCIP_VAR** _vars
5726+
cdef int nvars
5727+
cdef SCIP_Bool success
5728+
cdef int i
5729+
5730+
SCIPgetConsNVarsAnd(self._scip, constraint.scip_cons, &nvars, &success)
5731+
_vars = <SCIP_VAR**> malloc(nvars * sizeof(SCIP_VAR*))
5732+
_vars = SCIPgetConsVarsAnd(self._scip, constraint.scip_cons)
5733+
5734+
vars = []
5735+
for i in range(nvars):
5736+
ptr = <size_t>(_vars[i])
5737+
# check whether the corresponding variable exists already
5738+
if ptr in self._modelvars:
5739+
vars.append(self._modelvars[ptr])
5740+
else:
5741+
# create a new variable
5742+
var = Variable.create(_vars[i])
5743+
assert var.ptr() == ptr
5744+
self._modelvars[ptr] = var
5745+
vars.append(var)
5746+
5747+
return vars
5748+
5749+
def getResultantAnd(self, Constraint constraint):
5750+
"""
5751+
Gets the resultant variable in And constraint.
5752+
5753+
Parameters
5754+
----------
5755+
constraint : Constraint
5756+
Constraint to get the resultant variable from.
5757+
5758+
Returns
5759+
-------
5760+
Variable
5761+
5762+
"""
5763+
cdef SCIP_VAR* _resultant
5764+
cdef SCIP_Bool success
5765+
5766+
_resultant = SCIPgetResultantAnd(self._scip, constraint.scip_cons)
5767+
5768+
ptr = <size_t>(_resultant)
5769+
# check whether the corresponding variable exists already
5770+
if ptr not in self._modelvars:
5771+
# create a new variable
5772+
var = Variable.create(_resultant)
5773+
assert var.ptr() == ptr
5774+
self._modelvars[ptr] = var
5775+
5776+
return resultant
5777+
5778+
def isAndConsSorted(self, Constraint constraint):
5779+
"""
5780+
Returns if the variables of the AND-constraint are sorted with respect to their indices.
5781+
5782+
Parameters
5783+
----------
5784+
constraint : Constraint
5785+
Constraint to check.
5786+
5787+
Returns
5788+
-------
5789+
bool
5790+
5791+
"""
5792+
cdef SCIP_Bool success
5793+
5794+
return SCIPisAndConsSorted(self._scip, constraint.scip_cons)
5795+
5796+
def sortAndCons(self, Constraint constraint):
5797+
"""
5798+
Sorts the variables of the AND-constraint with respect to their indices.
5799+
5800+
Parameters
5801+
----------
5802+
constraint : Constraint
5803+
Constraint to sort.
5804+
5805+
"""
5806+
cdef SCIP_Bool success
5807+
5808+
PY_SCIP_CALL(SCIPsortAndCons(self._scip, constraint.scip_cons))
5809+
56925810
def printCons(self, Constraint constraint):
56935811
"""
56945812
Print the constraint

tests/test_cons.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,26 @@ def test_cons_logical():
7272
assert m.isEQ(m.getVal(result1), 1)
7373
assert m.isEQ(m.getVal(result2), 0)
7474

75+
def test_cons_and():
76+
m = Model()
77+
x1 = m.addVar(vtype="B")
78+
x2 = m.addVar(vtype="B")
79+
result = m.addVar(vtype="B")
80+
81+
and_cons = m.addConsAnd([x1, x2], result)
82+
83+
assert m.getNConsAnd(and_cons) == 1
84+
vars = m.getVarsAnd(and_cons)
85+
assert len(vars) == 2
86+
assert vars[0] == x1
87+
assert vars[1] == x2
88+
resultant_var = m.getResultAnd(and_cons)
89+
assert resultant_var == result
90+
m.optimize()
91+
92+
m.sortAndCons(and_cons)
93+
assert m.isAndConsSorted(and_cons)
94+
7595
def test_SOScons():
7696
m = Model()
7797
x = {}

0 commit comments

Comments
 (0)