Skip to content

Commit eb32a20

Browse files
Joao-Dionisioscip-ciDominikKamp
authored
Add feastol numerics checks (#997)
* Add feastol numerics checks * typos * test * fixed? * add locktype * add addVarLocksType * Dom's comments * typo * Apply suggestions from code review Co-authored-by: DominikKamp <[email protected]> * relax, docstring, and locktype * Add getNLocksDown, getNLocksUp, getNLocksUpType, getNLocksDownType and tests * Apply suggestions from code review Co-authored-by: DominikKamp <[email protected]> * lock tests * Apply suggestions from code review Co-authored-by: DominikKamp <[email protected]> * dom's comments * Apply suggestions from code review Co-authored-by: DominikKamp <[email protected]> * store variable in model data --------- Co-authored-by: SCIP CI Bot <[email protected]> Co-authored-by: DominikKamp <[email protected]>
1 parent be5e698 commit eb32a20

File tree

7 files changed

+273
-64
lines changed

7 files changed

+273
-64
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## Unreleased
44
### Added
55
- Added support for knapsack constraints
6+
- Added isPositive(), isNegative(), isFeasLE(), isFeasLT(), isFeasGE(), isFeasGT(), isHugeValue(), and tests
7+
- Added SCIP_LOCKTYPE, addVarLocksType(), getNLocksDown(), getNLocksUp(), getNLocksDownType(), getNLocksUpType(), and tests
68
### Fixed
79
### Changed
810
### Removed

src/pyscipopt/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
from pyscipopt.scip import PY_SCIP_PRESOLTIMING as SCIP_PRESOLTIMING
4949
from pyscipopt.scip import PY_SCIP_HEURTIMING as SCIP_HEURTIMING
5050
from pyscipopt.scip import PY_SCIP_EVENTTYPE as SCIP_EVENTTYPE
51+
from pyscipopt.scip import PY_SCIP_LOCKTYPE as SCIP_LOCKTYPE
5152
from pyscipopt.scip import PY_SCIP_LPSOLSTAT as SCIP_LPSOLSTAT
5253
from pyscipopt.scip import PY_SCIP_BRANCHDIR as SCIP_BRANCHDIR
5354
from pyscipopt.scip import PY_SCIP_BENDERSENFOTYPE as SCIP_BENDERSENFOTYPE

src/pyscipopt/scip.pxd

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ cdef extern from "scip/scip.h":
295295
SCIP_EVENTTYPE SCIP_EVENTTYPE_ROWCHANGED
296296
SCIP_EVENTTYPE SCIP_EVENTTYPE_ROWEVENT
297297

298-
299298
ctypedef int SCIP_LPSOLQUALITY
300299
cdef extern from "lpi/type_lpi.h":
301300
SCIP_LPSOLQUALITY SCIP_LPSOLQUALITY_ESTIMCONDITION
@@ -541,9 +540,9 @@ cdef extern from "scip/scip.h":
541540
ctypedef union SCIP_DOMCHG:
542541
pass
543542

544-
ctypedef void (*messagecallback) (SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg) noexcept
545-
ctypedef void (*errormessagecallback) (void *data, FILE *file, const char *msg)
546-
ctypedef SCIP_RETCODE (*messagehdlrfree) (SCIP_MESSAGEHDLR *messagehdlr)
543+
ctypedef void (*messagecallback) (SCIP_MESSAGEHDLR* messagehdlr, FILE* file, const char* msg) noexcept
544+
ctypedef void (*errormessagecallback) (void* data, FILE* file, const char* msg)
545+
ctypedef SCIP_RETCODE (*messagehdlrfree) (SCIP_MESSAGEHDLR* messagehdlr)
547546

548547
# General SCIP Methods
549548
SCIP_RETCODE SCIPcreate(SCIP** scip)
@@ -569,15 +568,15 @@ cdef extern from "scip/scip.h":
569568
SCIP_Bool* valid)
570569
SCIP_RETCODE SCIPcopyOrigVars(SCIP* sourcescip, SCIP* targetscip, SCIP_HASHMAP* varmap, SCIP_HASHMAP* consmap, SCIP_VAR** fixedvars, SCIP_Real* fixedvals, int nfixedvars )
571570
SCIP_RETCODE SCIPcopyOrigConss(SCIP* sourcescip, SCIP* targetscip, SCIP_HASHMAP* varmap, SCIP_HASHMAP* consmap, SCIP_Bool enablepricing, SCIP_Bool* valid)
572-
SCIP_RETCODE SCIPmessagehdlrCreate(SCIP_MESSAGEHDLR **messagehdlr,
571+
SCIP_RETCODE SCIPmessagehdlrCreate(SCIP_MESSAGEHDLR** messagehdlr,
573572
SCIP_Bool bufferedoutput,
574-
const char *filename,
573+
const char* filename,
575574
SCIP_Bool quiet,
576575
messagecallback,
577576
messagecallback,
578577
messagecallback,
579578
messagehdlrfree,
580-
SCIP_MESSAGEHDLRDATA *messagehdlrdata)
579+
SCIP_MESSAGEHDLRDATA* messagehdlrdata)
581580

582581
SCIP_RETCODE SCIPsetMessagehdlr(SCIP* scip, SCIP_MESSAGEHDLR* messagehdlr)
583582
void SCIPsetMessagehdlrQuiet(SCIP* scip, SCIP_Bool quiet)
@@ -787,6 +786,11 @@ cdef extern from "scip/scip.h":
787786
SCIP_RETCODE SCIPtransformVar(SCIP* scip, SCIP_VAR* var, SCIP_VAR** transvar)
788787
SCIP_RETCODE SCIPgetTransformedVar(SCIP* scip, SCIP_VAR* var, SCIP_VAR** transvar)
789788
SCIP_RETCODE SCIPaddVarLocks(SCIP* scip, SCIP_VAR* var, int nlocksdown, int nlocksup)
789+
SCIP_RETCODE SCIPaddVarLocksType(SCIP* scip, SCIP_VAR* var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
790+
int SCIPvarGetNLocksDown(SCIP_VAR* var)
791+
int SCIPvarGetNLocksUp(SCIP_VAR* var)
792+
int SCIPvarGetNLocksDownType(SCIP_VAR* var, SCIP_LOCKTYPE locktype)
793+
int SCIPvarGetNLocksUpType(SCIP_VAR* var, SCIP_LOCKTYPE locktype)
790794
SCIP_VAR** SCIPgetVars(SCIP* scip)
791795
SCIP_VAR** SCIPgetOrigVars(SCIP* scip)
792796
const char* SCIPvarGetName(SCIP_VAR* var)
@@ -813,11 +817,11 @@ cdef extern from "scip/scip.h":
813817
void SCIPvarSetData(SCIP_VAR* var, SCIP_VARDATA* vardata)
814818
SCIP_VARDATA* SCIPvarGetData(SCIP_VAR* var)
815819
SCIP_Real SCIPvarGetAvgSol(SCIP_VAR* var)
816-
SCIP_Real SCIPgetVarPseudocost(SCIP* scip, SCIP_VAR *var, SCIP_BRANCHDIR dir)
820+
SCIP_Real SCIPgetVarPseudocost(SCIP* scip, SCIP_VAR* var, SCIP_BRANCHDIR dir)
817821
SCIP_Real SCIPvarGetCutoffSum(SCIP_VAR* var, SCIP_BRANCHDIR dir)
818822
SCIP_Longint SCIPvarGetNBranchings(SCIP_VAR* var, SCIP_BRANCHDIR dir)
819823
SCIP_Bool SCIPvarMayRoundUp(SCIP_VAR* var)
820-
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR * var)
824+
SCIP_Bool SCIPvarMayRoundDown(SCIP_VAR* var)
821825

822826
# LP Methods
823827
SCIP_RETCODE SCIPgetLPColsData(SCIP* scip, SCIP_COL*** cols, int* ncols)
@@ -831,8 +835,8 @@ cdef extern from "scip/scip.h":
831835
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP* scip)
832836
int SCIPgetNLPRows(SCIP* scip)
833837
int SCIPgetNLPCols(SCIP* scip)
834-
SCIP_COL** SCIPgetLPCols(SCIP *scip)
835-
SCIP_ROW** SCIPgetLPRows(SCIP *scip)
838+
SCIP_COL** SCIPgetLPCols(SCIP* scip)
839+
SCIP_ROW** SCIPgetLPRows(SCIP* scip)
836840
SCIP_Bool SCIPallColsInLP(SCIP* scip)
837841

838842
# Cutting Plane Methods
@@ -872,11 +876,11 @@ cdef extern from "scip/scip.h":
872876
const char* SCIPconshdlrGetName(SCIP_CONSHDLR* conshdlr)
873877
SCIP_RETCODE SCIPdelConsLocal(SCIP* scip, SCIP_CONS* cons)
874878
SCIP_RETCODE SCIPdelCons(SCIP* scip, SCIP_CONS* cons)
875-
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
876-
SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
877-
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
878-
SCIP_RETCODE SCIPsetConsModifiable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool modifiable)
879-
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
879+
SCIP_RETCODE SCIPsetConsChecked(SCIP* scip, SCIP_CONS* cons, SCIP_Bool check)
880+
SCIP_RETCODE SCIPsetConsRemovable(SCIP* scip, SCIP_CONS* cons, SCIP_Bool removable)
881+
SCIP_RETCODE SCIPsetConsInitial(SCIP* scip, SCIP_CONS* cons, SCIP_Bool initial)
882+
SCIP_RETCODE SCIPsetConsModifiable(SCIP* scip, SCIP_CONS* cons, SCIP_Bool modifiable)
883+
SCIP_RETCODE SCIPsetConsEnforced(SCIP* scip, SCIP_CONS* cons, SCIP_Bool enforce)
880884

881885
# Primal Solution Methods
882886
SCIP_SOL** SCIPgetSols(SCIP* scip)
@@ -906,8 +910,8 @@ cdef extern from "scip/scip.h":
906910
SCIP_Real SCIPgetGap(SCIP* scip)
907911
int SCIPgetDepth(SCIP* scip)
908912
SCIP_RETCODE SCIPcutoffNode(SCIP* scip, SCIP_NODE* node)
909-
SCIP_Bool SCIPhasPrimalRay(SCIP * scip)
910-
SCIP_Real SCIPgetPrimalRayVal(SCIP * scip, SCIP_VAR * var)
913+
SCIP_Bool SCIPhasPrimalRay(SCIP* scip)
914+
SCIP_Real SCIPgetPrimalRayVal(SCIP* scip, SCIP_VAR* var)
911915
SCIP_RETCODE SCIPaddSolFree(SCIP* scip, SCIP_SOL** sol, SCIP_Bool* stored)
912916
SCIP_RETCODE SCIPaddSol(SCIP* scip, SCIP_SOL* sol, SCIP_Bool* stored)
913917
SCIP_RETCODE SCIPreadSol(SCIP* scip, const char* filename)
@@ -1051,7 +1055,7 @@ cdef extern from "scip/scip.h":
10511055
SCIP_RETCODE (*consgetnvars) (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, int* nvars, SCIP_Bool* success),
10521056
SCIP_RETCODE (*consgetdivebdchgs) (SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_DIVESET* diveset, SCIP_SOL* sol, SCIP_Bool* success, SCIP_Bool* infeasible),
10531057
SCIP_RETCODE (*consgetpermsymgraph)(SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, SYM_GRAPH* graph, SCIP_Bool* success),
1054-
SCIP_RETCODE (*consgetsignedpermsymgraph)(SCIP * scip, SCIP_CONSHDLR * conshdlr, SCIP_CONS * cons, SYM_GRAPH * graph, SCIP_Bool * success),
1058+
SCIP_RETCODE (*consgetsignedpermsymgraph)(SCIP* scip, SCIP_CONSHDLR* conshdlr, SCIP_CONS* cons, SYM_GRAPH* graph, SCIP_Bool* success),
10551059
SCIP_CONSHDLRDATA* conshdlrdata)
10561060
SCIP_CONSHDLRDATA* SCIPconshdlrGetData(SCIP_CONSHDLR* conshdlr)
10571061
SCIP_CONSHDLR* SCIPfindConshdlr(SCIP* scip, const char* name)
@@ -1339,13 +1343,17 @@ cdef extern from "scip/scip.h":
13391343
SCIP_Bool SCIPisLT(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
13401344
SCIP_Bool SCIPisGE(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
13411345
SCIP_Bool SCIPisGT(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1342-
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
1343-
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
1344-
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
1345-
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
1346-
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
1347-
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
1348-
SCIP_Real SCIPgetTreesizeEstimation(SCIP *scip)
1346+
SCIP_Bool SCIPisEQ(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1347+
SCIP_Bool SCIPisFeasEQ(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1348+
SCIP_Bool SCIPisFeasLT(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1349+
SCIP_Bool SCIPisFeasGT(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1350+
SCIP_Bool SCIPisFeasLE(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1351+
SCIP_Bool SCIPisFeasGE(SCIP* scip, SCIP_Real val1, SCIP_Real val2)
1352+
SCIP_Bool SCIPisHugeValue(SCIP* scip, SCIP_Real val)
1353+
SCIP_Bool SCIPisPositive(SCIP* scip, SCIP_Real val)
1354+
SCIP_Bool SCIPisNegative(SCIP* scip, SCIP_Real val)
1355+
SCIP_Bool SCIPisIntegral(SCIP* scip, SCIP_Real val)
1356+
SCIP_Real SCIPgetTreesizeEstimation(SCIP* scip)
13491357

13501358
# Statistic Methods
13511359
SCIP_RETCODE SCIPprintStatistics(SCIP* scip, FILE* outfile)
@@ -1611,22 +1619,22 @@ cdef extern from "scip/cons_sos2.h":
16111619
SCIP_VAR* var)
16121620

16131621
cdef extern from "scip/cons_disjunction.h":
1614-
SCIP_RETCODE SCIPcreateConsDisjunction(SCIP *scip,
1615-
SCIP_CONS **cons,
1616-
const char *name,
1622+
SCIP_RETCODE SCIPcreateConsDisjunction(SCIP* scip,
1623+
SCIP_CONS** cons,
1624+
const char* name,
16171625
int nconss,
1618-
SCIP_CONS **conss,
1619-
SCIP_CONS *relaxcons,
1626+
SCIP_CONS** conss,
1627+
SCIP_CONS* relaxcons,
16201628
SCIP_Bool initial,
16211629
SCIP_Bool enforce,
16221630
SCIP_Bool check,
16231631
SCIP_Bool local,
16241632
SCIP_Bool modifiable,
16251633
SCIP_Bool dynamic)
16261634

1627-
SCIP_RETCODE SCIPaddConsElemDisjunction(SCIP *scip,
1628-
SCIP_CONS *cons,
1629-
SCIP_CONS *addcons)
1635+
SCIP_RETCODE SCIPaddConsElemDisjunction(SCIP* scip,
1636+
SCIP_CONS* cons,
1637+
SCIP_CONS* addcons)
16301638

16311639
cdef extern from "scip/cons_and.h":
16321640
SCIP_RETCODE SCIPcreateConsAnd(SCIP* scip,
@@ -1963,7 +1971,7 @@ cdef extern from "scip/pub_lp.h":
19631971
SCIP_Real* SCIPcolGetVals(SCIP_COL* col)
19641972
int SCIPcolGetAge(SCIP_COL* col)
19651973
int SCIPcolGetIndex(SCIP_COL* col)
1966-
SCIP_Real SCIPcolGetObj(SCIP_COL *col)
1974+
SCIP_Real SCIPcolGetObj(SCIP_COL* col)
19671975

19681976
cdef extern from "scip/scip_tree.h":
19691977
SCIP_RETCODE SCIPgetOpenNodesData(SCIP* scip, SCIP_NODE*** leaves, SCIP_NODE*** children, SCIP_NODE*** siblings, int* nleaves, int* nchildren, int* nsiblings)

src/pyscipopt/scip.pxi

Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,9 @@ cdef class PY_SCIP_EVENTTYPE:
255255
ROWCHANGED = SCIP_EVENTTYPE_ROWCHANGED
256256
ROWEVENT = SCIP_EVENTTYPE_ROWEVENT
257257

258+
cdef class PY_SCIP_LOCKTYPE:
259+
MODEL = SCIP_LOCKTYPE_MODEL
260+
CONFLICT = SCIP_LOCKTYPE_CONFLICT
258261

259262
cdef class PY_SCIP_LPSOLSTAT:
260263
NOTSOLVED = SCIP_LPSOLSTAT_NOTSOLVED
@@ -1671,6 +1674,60 @@ cdef class Variable(Expr):
16711674
"""
16721675
return SCIPvarGetAvgSol(self.scip_var)
16731676

1677+
def getNLocksDown(self):
1678+
"""
1679+
Returns the number of locks for rounding down.
1680+
1681+
Returns
1682+
-------
1683+
int
1684+
1685+
"""
1686+
return SCIPvarGetNLocksDown(self.scip_var)
1687+
1688+
def getNLocksUp(self):
1689+
"""
1690+
Returns the number of locks for rounding up.
1691+
1692+
Returns
1693+
-------
1694+
int
1695+
1696+
"""
1697+
return SCIPvarGetNLocksUp(self.scip_var)
1698+
1699+
def getNLocksDownType(self, locktype):
1700+
"""
1701+
Returns the number of locks for rounding down of a certain type.
1702+
1703+
Parameters
1704+
----------
1705+
locktype : SCIP_LOCKTYPE
1706+
type of variable locks
1707+
1708+
Returns
1709+
-------
1710+
int
1711+
1712+
"""
1713+
return SCIPvarGetNLocksDownType(self.scip_var, locktype)
1714+
1715+
def getNLocksUpType(self, locktype):
1716+
"""
1717+
Returns the number of locks for rounding up of a certain type.
1718+
1719+
Parameters
1720+
----------
1721+
locktype : SCIP_LOCKTYPE
1722+
type of variable locks
1723+
1724+
Returns
1725+
-------
1726+
int
1727+
1728+
"""
1729+
return SCIPvarGetNLocksUpType(self.scip_var, locktype)
1730+
16741731
def varMayRound(self, direction="down"):
16751732
"""
16761733
Checks whether it is possible to round variable up / down and stay feasible for the relaxation.
@@ -3070,7 +3127,7 @@ cdef class Model:
30703127

30713128
def isFeasEQ(self, val1, val2):
30723129
"""
3073-
Checks, if relative difference of values is in range of feasibility tolerance.
3130+
Returns if relative difference between val1 and val2 is in range of feasibility tolerance.
30743131
30753132
Parameters
30763133
----------
@@ -3083,6 +3140,70 @@ cdef class Model:
30833140
30843141
"""
30853142
return SCIPisFeasEQ(self._scip, val1, val2)
3143+
3144+
def isFeasLT(self, val1, val2):
3145+
"""
3146+
Returns whether relative difference between val1 and val2 is lower than minus feasibility tolerance.
3147+
3148+
Parameters
3149+
----------
3150+
val1 : float
3151+
val2 : float
3152+
3153+
Returns
3154+
-------
3155+
bool
3156+
3157+
"""
3158+
return SCIPisFeasLT(self._scip, val1, val2)
3159+
3160+
def isFeasLE(self, val1, val2):
3161+
"""
3162+
Returns whether relative difference between val1 and val2 is not greater than feasibility tolerance.
3163+
3164+
Parameters
3165+
----------
3166+
val1 : float
3167+
val2 : float
3168+
3169+
Returns
3170+
-------
3171+
bool
3172+
3173+
"""
3174+
return SCIPisFeasLE(self._scip, val1, val2)
3175+
3176+
def isFeasGT(self, val1, val2):
3177+
"""
3178+
Returns whether relative difference between val1 and val2 is greater than feasibility tolerance.
3179+
3180+
Parameters
3181+
----------
3182+
val1 : float
3183+
val2 : float
3184+
3185+
Returns
3186+
-------
3187+
bool
3188+
3189+
"""
3190+
return SCIPisFeasGT(self._scip, val1, val2)
3191+
3192+
def isFeasGE(self, val1, val2):
3193+
"""
3194+
Returns whether relative difference of val1 and val2 is not lower than minus feasibility tolerance.
3195+
3196+
Parameters
3197+
----------
3198+
val1 : float
3199+
val2 : float
3200+
3201+
Returns
3202+
-------
3203+
bool
3204+
3205+
"""
3206+
return SCIPisFeasGE(self._scip, val1, val2)
30863207

30873208
def isLE(self, val1, val2):
30883209
"""
@@ -3792,7 +3913,7 @@ cdef class Model:
37923913

37933914
return Variable.create(_tvar)
37943915

3795-
def addVarLocks(self, Variable var, nlocksdown, nlocksup):
3916+
def addVarLocks(self, Variable var, int nlocksdown, int nlocksup):
37963917
"""
37973918
Adds given values to lock numbers of variable for rounding.
37983919
@@ -3808,6 +3929,24 @@ cdef class Model:
38083929
"""
38093930
PY_SCIP_CALL(SCIPaddVarLocks(self._scip, var.scip_var, nlocksdown, nlocksup))
38103931

3932+
def addVarLocksType(self, Variable var, int locktype, int nlocksdown, int nlocksup):
3933+
"""
3934+
adds given values to lock numbers of type locktype of variable for rounding
3935+
3936+
Parameters
3937+
----------
3938+
var : Variable
3939+
variable to adjust the locks for
3940+
locktype : SCIP_LOCKTYPE
3941+
type of variable locks
3942+
nlocksdown : int
3943+
modification in number of down locks
3944+
nlocksup : int
3945+
modification in number of up locks
3946+
3947+
"""
3948+
PY_SCIP_CALL(SCIPaddVarLocksType(self._scip, var.scip_var, locktype, nlocksdown, nlocksup))
3949+
38113950
def fixVar(self, Variable var, val):
38123951
"""
38133952
Fixes the variable var to the value val if possible.

0 commit comments

Comments
 (0)