os.path
importabspath
5 fromos.path
importsplitext
12 fromcpython cimport Py_INCREF, Py_DECREF
13 fromcpython.pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer
14 fromlibc.stdlib cimport malloc, free
15 fromlibc.stdio cimport fdopen, fclose
16 fromposix.stdio cimport fileno
18 fromcollections.abc
importIterable
19 fromitertools
importrepeat
20 fromdataclasses
importdataclass
25include
"benderscut.pxi" 26include
"branchrule.pxi" 27include
"conshdlr.pxi" 30include
"heuristic.pxi" 33include
"propagator.pxi" 47 ifsys.version_info >= (3, 0):
48str_conversion =
lambdax:bytes(x,
'utf-8')
50str_conversion =
lambdax:x
52_SCIP_BOUNDTYPE_TO_STRING = {SCIP_BOUNDTYPE_UPPER:
'<=',
53SCIP_BOUNDTYPE_LOWER:
'>='}
59cdef
classPY_SCIP_RESULT:
60DIDNOTRUN = SCIP_DIDNOTRUN
61DELAYED = SCIP_DELAYED
62DIDNOTFIND = SCIP_DIDNOTFIND
63FEASIBLE = SCIP_FEASIBLE
64INFEASIBLE = SCIP_INFEASIBLE
65UNBOUNDED = SCIP_UNBOUNDED
67SEPARATED = SCIP_SEPARATED
68NEWROUND = SCIP_NEWROUND
69REDUCEDDOM = SCIP_REDUCEDDOM
70CONSADDED = SCIP_CONSADDED
71CONSCHANGED = SCIP_CONSCHANGED
72BRANCHED = SCIP_BRANCHED
73SOLVELP = SCIP_SOLVELP
74FOUNDSOL = SCIP_FOUNDSOL
75SUSPENDED = SCIP_SUSPENDED
76SUCCESS = SCIP_SUCCESS
78cdef
classPY_SCIP_PARAMSETTING:
79DEFAULT = SCIP_PARAMSETTING_DEFAULT
80AGGRESSIVE = SCIP_PARAMSETTING_AGGRESSIVE
81FAST = SCIP_PARAMSETTING_FAST
82OFF = SCIP_PARAMSETTING_OFF
84cdef
classPY_SCIP_PARAMEMPHASIS:
85DEFAULT = SCIP_PARAMEMPHASIS_DEFAULT
86CPSOLVER = SCIP_PARAMEMPHASIS_CPSOLVER
87EASYCIP = SCIP_PARAMEMPHASIS_EASYCIP
88FEASIBILITY = SCIP_PARAMEMPHASIS_FEASIBILITY
89HARDLP = SCIP_PARAMEMPHASIS_HARDLP
90OPTIMALITY = SCIP_PARAMEMPHASIS_OPTIMALITY
91COUNTER = SCIP_PARAMEMPHASIS_COUNTER
92PHASEFEAS = SCIP_PARAMEMPHASIS_PHASEFEAS
93PHASEIMPROVE = SCIP_PARAMEMPHASIS_PHASEIMPROVE
94PHASEPROOF = SCIP_PARAMEMPHASIS_PHASEPROOF
95NUMERICS = SCIP_PARAMEMPHASIS_NUMERICS
96BENCHMARK = SCIP_PARAMEMPHASIS_BENCHMARK
98cdef
classPY_SCIP_STATUS:
99UNKNOWN = SCIP_STATUS_UNKNOWN
100USERINTERRUPT = SCIP_STATUS_USERINTERRUPT
101NODELIMIT = SCIP_STATUS_NODELIMIT
102TOTALNODELIMIT = SCIP_STATUS_TOTALNODELIMIT
103STALLNODELIMIT = SCIP_STATUS_STALLNODELIMIT
104TIMELIMIT = SCIP_STATUS_TIMELIMIT
105MEMLIMIT = SCIP_STATUS_MEMLIMIT
106GAPLIMIT = SCIP_STATUS_GAPLIMIT
107SOLLIMIT = SCIP_STATUS_SOLLIMIT
108BESTSOLLIMIT = SCIP_STATUS_BESTSOLLIMIT
109RESTARTLIMIT = SCIP_STATUS_RESTARTLIMIT
110PRIMALLIMIT = SCIP_STATUS_PRIMALLIMIT
111DUALLIMIT = SCIP_STATUS_DUALLIMIT
112OPTIMAL = SCIP_STATUS_OPTIMAL
113INFEASIBLE = SCIP_STATUS_INFEASIBLE
114UNBOUNDED = SCIP_STATUS_UNBOUNDED
115INFORUNBD = SCIP_STATUS_INFORUNBD
119cdef
classPY_SCIP_STAGE:
120INIT = SCIP_STAGE_INIT
121PROBLEM = SCIP_STAGE_PROBLEM
122TRANSFORMING = SCIP_STAGE_TRANSFORMING
123TRANSFORMED = SCIP_STAGE_TRANSFORMED
124INITPRESOLVE = SCIP_STAGE_INITPRESOLVE
125PRESOLVING = SCIP_STAGE_PRESOLVING
126EXITPRESOLVE = SCIP_STAGE_EXITPRESOLVE
127PRESOLVED = SCIP_STAGE_PRESOLVED
128INITSOLVE = SCIP_STAGE_INITSOLVE
129SOLVING = SCIP_STAGE_SOLVING
130SOLVED = SCIP_STAGE_SOLVED
131EXITSOLVE = SCIP_STAGE_EXITSOLVE
132FREETRANS = SCIP_STAGE_FREETRANS
133FREE = SCIP_STAGE_FREE
135cdef
classPY_SCIP_NODETYPE:
136FOCUSNODE = SCIP_NODETYPE_FOCUSNODE
137PROBINGNODE = SCIP_NODETYPE_PROBINGNODE
138SIBLING = SCIP_NODETYPE_SIBLING
139CHILD = SCIP_NODETYPE_CHILD
140LEAF = SCIP_NODETYPE_LEAF
141DEADEND = SCIP_NODETYPE_DEADEND
142JUNCTION = SCIP_NODETYPE_JUNCTION
143PSEUDOFORK = SCIP_NODETYPE_PSEUDOFORK
144FORK = SCIP_NODETYPE_FORK
145SUBROOT = SCIP_NODETYPE_SUBROOT
146REFOCUSNODE = SCIP_NODETYPE_REFOCUSNODE
149cdef
classPY_SCIP_PROPTIMING:
150BEFORELP = SCIP_PROPTIMING_BEFORELP
151DURINGLPLOOP = SCIP_PROPTIMING_DURINGLPLOOP
152AFTERLPLOOP = SCIP_PROPTIMING_AFTERLPLOOP
153AFTERLPNODE = SCIP_PROPTIMING_AFTERLPNODE
155cdef
classPY_SCIP_PRESOLTIMING:
156NONE = SCIP_PRESOLTIMING_NONE
157FAST = SCIP_PRESOLTIMING_FAST
158MEDIUM = SCIP_PRESOLTIMING_MEDIUM
159EXHAUSTIVE = SCIP_PRESOLTIMING_EXHAUSTIVE
161cdef
classPY_SCIP_HEURTIMING:
162BEFORENODE = SCIP_HEURTIMING_BEFORENODE
163DURINGLPLOOP = SCIP_HEURTIMING_DURINGLPLOOP
164AFTERLPLOOP = SCIP_HEURTIMING_AFTERLPLOOP
165AFTERLPNODE = SCIP_HEURTIMING_AFTERLPNODE
166AFTERPSEUDONODE = SCIP_HEURTIMING_AFTERPSEUDONODE
167AFTERLPPLUNGE = SCIP_HEURTIMING_AFTERLPPLUNGE
168AFTERPSEUDOPLUNGE = SCIP_HEURTIMING_AFTERPSEUDOPLUNGE
169DURINGPRICINGLOOP = SCIP_HEURTIMING_DURINGPRICINGLOOP
170BEFOREPRESOL = SCIP_HEURTIMING_BEFOREPRESOL
171DURINGPRESOLLOOP = SCIP_HEURTIMING_DURINGPRESOLLOOP
172AFTERPROPLOOP = SCIP_HEURTIMING_AFTERPROPLOOP
176cdef
classPY_SCIP_EVENTTYPE:
177DISABLED = SCIP_EVENTTYPE_DISABLED
178VARADDED = SCIP_EVENTTYPE_VARADDED
179VARDELETED = SCIP_EVENTTYPE_VARDELETED
180VARFIXED = SCIP_EVENTTYPE_VARFIXED
181VARUNLOCKED = SCIP_EVENTTYPE_VARUNLOCKED
182OBJCHANGED = SCIP_EVENTTYPE_OBJCHANGED
183GLBCHANGED = SCIP_EVENTTYPE_GLBCHANGED
184GUBCHANGED = SCIP_EVENTTYPE_GUBCHANGED
185LBTIGHTENED = SCIP_EVENTTYPE_LBTIGHTENED
186LBRELAXED = SCIP_EVENTTYPE_LBRELAXED
187UBTIGHTENED = SCIP_EVENTTYPE_UBTIGHTENED
188UBRELAXED = SCIP_EVENTTYPE_UBRELAXED
189GHOLEADDED = SCIP_EVENTTYPE_GHOLEADDED
190GHOLEREMOVED = SCIP_EVENTTYPE_GHOLEREMOVED
191LHOLEADDED = SCIP_EVENTTYPE_LHOLEADDED
192LHOLEREMOVED = SCIP_EVENTTYPE_LHOLEREMOVED
193IMPLADDED = SCIP_EVENTTYPE_IMPLADDED
194PRESOLVEROUND = SCIP_EVENTTYPE_PRESOLVEROUND
195NODEFOCUSED = SCIP_EVENTTYPE_NODEFOCUSED
196NODEFEASIBLE = SCIP_EVENTTYPE_NODEFEASIBLE
197NODEINFEASIBLE = SCIP_EVENTTYPE_NODEINFEASIBLE
198NODEBRANCHED = SCIP_EVENTTYPE_NODEBRANCHED
199NODEDELETE = SCIP_EVENTTYPE_NODEDELETE
200FIRSTLPSOLVED = SCIP_EVENTTYPE_FIRSTLPSOLVED
201LPSOLVED = SCIP_EVENTTYPE_LPSOLVED
202LPEVENT = SCIP_EVENTTYPE_LPEVENT
203POORSOLFOUND = SCIP_EVENTTYPE_POORSOLFOUND
204BESTSOLFOUND = SCIP_EVENTTYPE_BESTSOLFOUND
205ROWADDEDSEPA = SCIP_EVENTTYPE_ROWADDEDSEPA
206ROWDELETEDSEPA = SCIP_EVENTTYPE_ROWDELETEDSEPA
207ROWADDEDLP = SCIP_EVENTTYPE_ROWADDEDLP
208ROWDELETEDLP = SCIP_EVENTTYPE_ROWDELETEDLP
209ROWCOEFCHANGED = SCIP_EVENTTYPE_ROWCOEFCHANGED
210ROWCONSTCHANGED = SCIP_EVENTTYPE_ROWCONSTCHANGED
211ROWSIDECHANGED = SCIP_EVENTTYPE_ROWSIDECHANGED
212SYNC = SCIP_EVENTTYPE_SYNC
213GBDCHANGED = SCIP_EVENTTYPE_GBDCHANGED
214LBCHANGED = SCIP_EVENTTYPE_LBCHANGED
215UBCHANGED = SCIP_EVENTTYPE_UBCHANGED
216BOUNDTIGHTENED = SCIP_EVENTTYPE_BOUNDTIGHTENED
217BOUNDRELAXED = SCIP_EVENTTYPE_BOUNDRELAXED
218BOUNDCHANGED = SCIP_EVENTTYPE_BOUNDCHANGED
219GHOLECHANGED = SCIP_EVENTTYPE_GHOLECHANGED
220LHOLECHANGED = SCIP_EVENTTYPE_LHOLECHANGED
221HOLECHANGED = SCIP_EVENTTYPE_HOLECHANGED
222DOMCHANGED = SCIP_EVENTTYPE_DOMCHANGED
223VARCHANGED = SCIP_EVENTTYPE_VARCHANGED
224VAREVENT = SCIP_EVENTTYPE_VAREVENT
225NODESOLVED = SCIP_EVENTTYPE_NODESOLVED
226NODEEVENT = SCIP_EVENTTYPE_NODEEVENT
227SOLFOUND = SCIP_EVENTTYPE_SOLFOUND
228SOLEVENT = SCIP_EVENTTYPE_SOLEVENT
229ROWCHANGED = SCIP_EVENTTYPE_ROWCHANGED
230ROWEVENT = SCIP_EVENTTYPE_ROWEVENT
233cdef
classPY_SCIP_LPSOLSTAT:
234NOTSOLVED = SCIP_LPSOLSTAT_NOTSOLVED
235OPTIMAL = SCIP_LPSOLSTAT_OPTIMAL
236INFEASIBLE = SCIP_LPSOLSTAT_INFEASIBLE
237UNBOUNDEDRAY = SCIP_LPSOLSTAT_UNBOUNDEDRAY
238OBJLIMIT = SCIP_LPSOLSTAT_OBJLIMIT
239ITERLIMIT = SCIP_LPSOLSTAT_ITERLIMIT
240TIMELIMIT = SCIP_LPSOLSTAT_TIMELIMIT
241ERROR = SCIP_LPSOLSTAT_ERROR
243cdef
classPY_SCIP_BRANCHDIR:
244DOWNWARDS = SCIP_BRANCHDIR_DOWNWARDS
245UPWARDS = SCIP_BRANCHDIR_UPWARDS
246FIXED = SCIP_BRANCHDIR_FIXED
247AUTO = SCIP_BRANCHDIR_AUTO
249cdef
classPY_SCIP_BENDERSENFOTYPE:
250LP = SCIP_BENDERSENFOTYPE_LP
251RELAX = SCIP_BENDERSENFOTYPE_RELAX
252PSEUDO = SCIP_BENDERSENFOTYPE_PSEUDO
253CHECK = SCIP_BENDERSENFOTYPE_CHECK
255cdef
classPY_SCIP_ROWORIGINTYPE:
256UNSPEC = SCIP_ROWORIGINTYPE_UNSPEC
257CONS = SCIP_ROWORIGINTYPE_CONS
258SEPA = SCIP_ROWORIGINTYPE_SEPA
259REOPT = SCIP_ROWORIGINTYPE_REOPT
261 defPY_SCIP_CALL(SCIP_RETCODE rc):
264 elifrc == SCIP_ERROR:
265 raiseException(
'SCIP: unspecified error!')
266 elifrc == SCIP_NOMEMORY:
267 raiseMemoryError(
'SCIP: insufficient memory error!')
268 elifrc == SCIP_READERROR:
269 raiseIOError(
'SCIP: read error!')
270 elifrc == SCIP_WRITEERROR:
271 raiseIOError(
'SCIP: write error!')
272 elifrc == SCIP_NOFILE:
273 raiseIOError(
'SCIP: file not found error!')
274 elifrc == SCIP_FILECREATEERROR:
275 raiseIOError(
'SCIP: cannot create file!')
276 elifrc == SCIP_LPERROR:
277 raiseException(
'SCIP: error in LP solver!')
278 elifrc == SCIP_NOPROBLEM:
279 raiseException(
'SCIP: no problem exists!')
280 elifrc == SCIP_INVALIDCALL:
281 raiseException(
'SCIP: method cannot be called at this time' 282+
' in solution process!')
283 elifrc == SCIP_INVALIDDATA:
284 raiseException(
'SCIP: error in input data!')
285 elifrc == SCIP_INVALIDRESULT:
286 raiseException(
'SCIP: method returned an invalid result code!')
287 elifrc == SCIP_PLUGINNOTFOUND:
288 raiseException(
'SCIP: a required plugin was not found !')
289 elifrc == SCIP_PARAMETERUNKNOWN:
290 raiseKeyError(
'SCIP: the parameter with the given name was not found!')
291 elifrc == SCIP_PARAMETERWRONGTYPE:
292 raiseLookupError(
'SCIP: the parameter is not of the expected type!')
293 elifrc == SCIP_PARAMETERWRONGVAL:
294 raiseValueError(
'SCIP: the value is invalid for the given parameter!')
295 elifrc == SCIP_KEYALREADYEXISTING:
296 raiseKeyError(
'SCIP: the given key is already existing in table!')
297 elifrc == SCIP_MAXDEPTHLEVEL:
298 raiseException(
'SCIP: maximal branching depth level exceeded!')
300 raiseException(
'SCIP: unknown return code!')
303 """Base class holding a pointer to corresponding SCIP_EVENT""" 306cdef create(SCIP_EVENT* scip_event):
307 ifscip_event == NULL:
308 raiseWarning(
"cannot create Event with SCIP_EVENT* == NULL")
310event.event = scip_event
314 """gets type of event""" 318 """gets name of event""" 321 returnEventNames[self.
getType()]
323 def_getEventNames(self):
324 """gets event names""" 325 forname
indir(PY_SCIP_EVENTTYPE):
326attr = getattr(PY_SCIP_EVENTTYPE, name)
327 ifisinstance(attr, int):
328EventNames[attr] = name
337 """gets new bound for a bound change event""" 341 """gets old bound for a bound change event""" 345 """gets variable for a variable event (var added, var deleted, var fixed, objective value or domain change, domain hole added or removed)""" 347 returnVariable.create(var)
350 """gets node for a node or LP event""" 352 returnNode.create(node)
355 """gets row for a row event""" 357 returnRow.create(row)
360 returnhash(<size_t>self.
event)
363 return(self.
__class__== other.__class__
364 andself.
event== (<Event>other).event)
367 """Base class holding a pointer to corresponding SCIP_COL""" 370cdef create(SCIP_COL* scipcol):
372 raiseWarning(
"cannot create Column with SCIP_COL* == NULL")
374col.scip_col = scipcol
378 """gets position of column in current LP, or -1 if it is not in LP""" 382 """gets the basis status of a column in the LP solution, Note: returns basis status `zero` for columns not in the current SCIP LP""" 384 ifstat == SCIP_BASESTAT_LOWER:
386 elifstat == SCIP_BASESTAT_BASIC:
388 elifstat == SCIP_BASESTAT_UPPER:
390 elifstat == SCIP_BASESTAT_ZERO:
393 raiseException(
'SCIP returned unknown base status!')
396 """returns whether the associated variable is of integral type (binary, integer, implicit integer)""" 400 """gets variable this column represents""" 402 returnVariable.create(var)
405 """gets the primal LP solution of a column""" 409 """gets lower bound of column""" 413 """gets upper bound of column""" 417 """gets objective value coefficient of a column""" 421 """Gets the age of the column, i.e., the total number of successive times a column was in the LP 422 and was 0.0 in the solution""" 426 returnhash(<size_t>self.
scip_col)
429 return(self.
__class__== other.__class__
430 andself.
scip_col== (<Column>other).scip_col)
433 """Base class holding a pointer to corresponding SCIP_ROW""" 436cdef create(SCIP_ROW* sciprow):
438 raiseWarning(
"cannot create Row with SCIP_ROW* == NULL")
440row.scip_row = sciprow
446 returncname.decode(
'utf-8')
449 """returns the left hand side of row""" 453 """returns the right hand side of row""" 457 """gets constant shift of row""" 461 """gets position of row in current LP, or -1 if it is not in LP""" 465 """gets the basis status of a row in the LP solution, Note: returns basis status `basic` for rows not in the current SCIP LP""" 467 ifstat == SCIP_BASESTAT_LOWER:
469 elifstat == SCIP_BASESTAT_BASIC:
471 elifstat == SCIP_BASESTAT_UPPER:
473 elifstat == SCIP_BASESTAT_ZERO:
475 raiseException(
'SCIP returned base status zero for a row!')
477 raiseException(
'SCIP returned unknown base status!')
480 """returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution """ 484 """returns TRUE iff the row is only valid locally """ 488 """returns TRUE iff row is modifiable during node processing (subject to column generation) """ 492 """returns TRUE iff row is removable from the LP (due to aging or cleanup)""" 496 """return TRUE iff row is a member of the global cut pool""" 500 """returns type of origin that created the row""" 504 """returns type of constraint handler that created the row""" 509 """get number of nonzero entries in row vector""" 513 """get number of nonzero entries in row vector that correspond to columns currently in the SCIP LP""" 517 """gets list with columns of nonzero entries""" 519 return[Column.create(cols[i])
fori
inrange(self.
getNNonz())]
522 """gets list with coefficients of nonzero entries""" 524 return[vals[i]
fori
inrange(self.
getNNonz())]
527 """Gets the age of the row. (The consecutive times the row has been non-active in the LP)""" 531 """gets Euclidean norm of row vector """ 535 returnhash(<size_t>self.
scip_row)
538 return(self.
__class__== other.__class__
539 andself.
scip_row== (<Row>other).scip_row)
542 """Base class holding a pointer to corresponding SCIP_NLROW""" 545cdef create(SCIP_NLROW* scipnlrow):
546 ifscipnlrow == NULL:
547 raiseWarning(
"cannot create NLRow with SCIP_NLROW* == NULL")
549nlrow.scip_nlrow = scipnlrow
555 returncname.decode(
'utf-8')
558 """returns the constant of a nonlinear row""" 562 """returns a list of tuples (var, coef) representing the linear part of a nonlinear row""" 566 return[(Variable.create(linvars[i]), lincoefs[i])
fori
inrange(nlinvars)]
569 """returns the left hand side of a nonlinear row""" 573 """returns the right hand side of a nonlinear row""" 577 """gets the dual NLP solution of a nonlinear row""" 584 return(self.
__class__== other.__class__
585 andself.
scip_nlrow== (<NLRow>other).scip_nlrow)
588 """Base class holding a pointer to corresponding SCIP_SOL""" 593 raiseValueError(
"To create a solution you should use the createSol method of the Model class.")
596cdef create(SCIP* scip, SCIP_SOL* scip_sol):
598 raiseWarning(
"cannot create Solution with SCIP* == NULL")
606 ifisinstance(expr, Variable):
608var = <Variable> expr
610 returnsum(self.
_evaluate(term)*coeff
forterm, coeff
inexpr.terms.items()
ifcoeff != 0)
612 def_evaluate(self, term):
615 forvar
interm.vartuple:
623cdef SCIP_VAR* scip_var
632name = cname.decode(
'utf-8')
637 def_checkStage(self, method):
638 ifmethod
in[
"SCIPgetSolVal",
"getSolObjVal"]:
639stage_check =
SCIPgetStage(self.
scip)
not in[SCIP_STAGE_INIT, SCIP_STAGE_FREE]
641 if notstage_check
orself.
sol== NULL
and SCIPgetStage(self.
scip) != SCIP_STAGE_SOLVING:
642 raiseWarning(f
"{method} can only be called with a valid solution or in stage SOLVING (current stage: {SCIPgetStage(self.scip)})")
649cdef create(SCIP_BOUNDCHG* scip_boundchg):
650 ifscip_boundchg == NULL:
651 raiseWarning(
"cannot create BoundChange with SCIP_BOUNDCHG* == NULL")
653boundchg.scip_boundchg = scip_boundchg
657 """Returns the new value of the bound in the bound change.""" 661 """Returns the variable of the bound change.""" 665 """Returns the bound change type of the bound change.""" 669 """Returns the bound type of the bound change.""" 673 """Returns whether the bound change is redundant due to a more global bound that is at least as strong.""" 677 return "{} {} {}".format(self.
getVar(),
682 """Set of domain changes.""" 685cdef create(SCIP_DOMCHG* scip_domchg):
686 ifscip_domchg == NULL:
687 raiseWarning(
"cannot create DomainChanges with SCIP_DOMCHG* == NULL")
689domchg.scip_domchg = scip_domchg
693 """Returns the bound changes in the domain change.""" 696 fori
inrange(nboundchgs)]
699 """Base class holding a pointer to corresponding SCIP_NODE""" 702cdef create(SCIP_NODE* scipnode):
706node.scip_node = scipnode
710 """Retrieve parent node (or None if the node has no parent node).""" 714 """Retrieve number of node.""" 718 """Retrieve depth of node.""" 722 """Retrieve type of node.""" 726 """Retrieve lower bound of node.""" 730 """Retrieve the estimated value of the best feasible solution in subtree of the node""" 734 """Retrieve all constraints added at this node.""" 736 ifaddedconsssize == 0:
738cdef SCIP_CONS** addedconss = <SCIP_CONS**> malloc(addedconsssize * sizeof(SCIP_CONS*))
741 assertnconss == addedconsssize
742constraints = [Constraint.create(addedconss[i])
fori
inrange(nconss)]
747 """Retrieve number of added constraints at this node""" 751 """Is the node in the path to the current node?""" 755 """Is the node marked to be propagated again?""" 759 """Retrieve the number of variable branchings that were performed in the parent node to create this node.""" 760cdef SCIP_VAR* dummy_branchvars
761cdef SCIP_Real dummy_branchbounds
762cdef SCIP_BOUNDTYPE dummy_boundtypes
768&dummy_branchbounds, &dummy_boundtypes,
773 """Retrieve the set of variable branchings that were performed in the parent node to create this node.""" 778cdef SCIP_VAR** branchvars = <SCIP_VAR**> malloc(nbranchvars * sizeof(SCIP_VAR*))
779cdef SCIP_Real* branchbounds = <SCIP_Real*> malloc(nbranchvars * sizeof(SCIP_Real))
780cdef SCIP_BOUNDTYPE* boundtypes = <SCIP_BOUNDTYPE*> malloc(nbranchvars * sizeof(SCIP_BOUNDTYPE))
783boundtypes, &nbranchvars, nbranchvars)
785py_variables = [Variable.create(branchvars[i])
fori
inrange(nbranchvars)]
786py_branchbounds = [branchbounds[i]
fori
inrange(nbranchvars)]
787py_boundtypes = [boundtypes[i]
fori
inrange(nbranchvars)]
792 returnpy_variables, py_branchbounds, py_boundtypes
795 """Retrieve the number of bound changes due to branching, constraint propagation, and propagation.""" 800 returnnbranchings, nconsprop, nprop
803 """Retrieve domain changes for this node.""" 807 returnDomainChanges.create(domchg)
813 return(self.
__class__== other.__class__
814 andself.
scip_node== (<Node>other).scip_node)
817 """Is a linear expression and has SCIP_VAR*""" 820cdef create(SCIP_VAR* scipvar):
822 raiseWarning(
"cannot create Variable with SCIP_VAR* == NULL")
824var.scip_var = scipvar
825Expr.__init__(var, {Term(var) : 1.0})
831 returncname.decode(
'utf-8')
841 """Retrieve the variables type (BINARY, INTEGER, IMPLINT or CONTINUOUS)""" 843 ifvartype == SCIP_VARTYPE_BINARY:
845 elifvartype == SCIP_VARTYPE_INTEGER:
847 elifvartype == SCIP_VARTYPE_CONTINUOUS:
849 elifvartype == SCIP_VARTYPE_IMPLINT:
853 """Retrieve whether the variable belongs to the original problem""" 857 """Retrieve whether the variable is a COLUMN variable that is member of the current LP""" 862 """Retrieve the unique index of the variable.""" 866 """Retrieve column of COLUMN variable""" 867cdef SCIP_COL* scip_col
869 returnColumn.create(scip_col)
872 """Retrieve original lower bound of variable""" 876 """Retrieve original upper bound of variable""" 880 """Retrieve global lower bound of variable""" 884 """Retrieve global upper bound of variable""" 888 """Retrieve current lower bound of variable""" 892 """Retrieve current upper bound of variable""" 896 """Retrieve current objective value of variable""" 900 """Retrieve the current LP solution value of variable""" 904 """Get the weighted average solution of variable in all feasible primal solutions found""" 908 """Base class holding a pointer to corresponding SCIP_CONS""" 911cdef create(SCIP_CONS* scipcons):
913 raiseWarning(
"cannot create Constraint with SCIP_CONS* == NULL")
915cons.scip_cons = scipcons
921 returncname.decode(
'utf-8')
927 """Retrieve whether the constraint belongs to the original problem""" 931 """Retrieve True if the relaxation of the constraint should be in the initial LP""" 935 """Retrieve True if constraint should be separated during LP processing""" 939 """Retrieve True if constraint should be enforced during node processing""" 943 """Retrieve True if constraint should be checked for feasibility""" 947 """Retrieve True if constraint should be propagated during node processing""" 951 """Retrieve True if constraint is only locally valid or not added to any (sub)problem""" 955 """Retrieve True if constraint is modifiable (subject to column generation)""" 959 """Retrieve True if constraint is subject to aging""" 963 """Retrieve True if constraint's relaxation should be removed from the LP due to aging or cleanup""" 967 """Retrieve True if constraint is only locally valid or not added to any (sub)problem""" 971 """returns True iff constraint is active in the current node""" 975 """Retrieve True if constraint is linear""" 977 returnconstype ==
'linear' 980 """Retrieve True if constraint is nonlinear""" 982 returnconstype ==
'nonlinear' 985 """Return the constraint handler's name""" 993 return(self.
__class__== other.__class__
994 andself.
scip_cons== (<Constraint>other).scip_cons)
997cdef void relayMessage(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg) noexcept:
998sys.stdout.write(msg.decode(
'UTF-8'))
1000cdef void relayErrorMessage(void *messagehdlr, FILE *file, const char *msg) noexcept:
1001sys.stderr.write(msg.decode(
'UTF-8'))
1010 """Main class holding a pointer to SCIP for managing most interactions""" 1012 def __init__(self, problemName='model', defaultPlugins=True, Model sourceModel=None, origcopy=False, globalcopy=True, enablepricing=False, createscip=True, threadsafe=False):
1014 :param problemName: name of the problem (default 'model') 1015 :param defaultPlugins: use default plugins? (default True) 1016 :param sourceModel: create a copy of the given Model instance (default None) 1017 :param origcopy: whether to call copy or copyOrig (default False) 1018 :param globalcopy: whether to create a global or a local copy (default True) 1019 :param enablepricing: whether to enable pricing in copy (default False) 1020 :param createscip: initialize the Model object and creates a SCIP instance 1021 :param threadsafe: False if data can be safely shared between the source and target problem 1024 raiseException(
"linked SCIP is not compatible to this version of PySCIPOpt - use at least version", MAJOR)
1025 ifself.
version() < MAJOR + MINOR/10.0 + PATCH/100.0:
1026warnings.warn(
"linked SCIP {} is not recommended for this version of PySCIPOpt - use version {}.{}.{}".format(self.
version(), MAJOR, MINOR, PATCH))
1036 elifsourceModel
is None:
1044self.
_bestSol= <Solution> sourceModel._bestSol
1047PY_SCIP_CALL(
SCIPcopyOrig(sourceModel._scip, self.
_scip, NULL, NULL, n, enablepricing, threadsafe,
True, self._valid))
1049PY_SCIP_CALL(
SCIPcopy(sourceModel._scip, self.
_scip, NULL, NULL, n, globalcopy, enablepricing, threadsafe,
True, self._valid))
1058 returnhash(<size_t>self.
_scip)
1061 return(self.
__class__== other.__class__
1062 andself.
_scip== (<Model>other)._scip)
1065cdef create(SCIP* scip):
1066 """Creates a model and appropriately assigns the scip and bestsol parameters 1069 raiseWarning(
"cannot create Model with SCIP* == NULL")
1076 def_freescip(self):
1077 """Return whether the underlying Scip pointer gets deallocted when the current 1083 def_freescip(self, val):
1084 """Set whether the underlying Scip pointer gets deallocted when the current 1089@cython.always_allow_keywords(
True)
1092 """Create a Model from a given pointer. 1094 :param cpasule: The PyCapsule containing the SCIP pointer under the name "scip". 1095 :param take_ownership: Whether the newly created Model assumes ownership of the 1096 underlying Scip pointer (see `_freescip`). 1098 if notPyCapsule_IsValid(capsule,
"scip"):
1099 raiseValueError(
"The given capsule does not contain a valid scip pointer")
1100model = Model.create(<SCIP*>PyCapsule_GetPointer(capsule,
"scip"))
1101model._freescip = take_ownership
1104@cython.always_allow_keywords(
True)
1106 """Return the underlying Scip pointer to the current Model. 1108 :param give_ownership: Whether the current Model gives away ownership of the 1109 underlying Scip pointer (see `_freescip`). 1110 :return capsule: The underlying pointer to the current Model, wrapped in a 1111 PyCapsule under the name "scip". 1113capsule = PyCapsule_New(<void*>self.
_scip,
"scip", NULL)
1119 """Includes all default plug-ins into SCIP""" 1120PY_SCIP_CALL(SCIPincludeDefaultPlugins(self.
_scip))
1123 """Create new problem instance with given name 1125 :param problemName: name of model or problem (Default value = 'model') 1132 """Frees problem and solution process data""" 1136 """Frees all solution process data including presolving and transformed problem, only original problem is kept""" 1140 ifvalue.isOriginal()
1145 """Retrieve SCIP version""" 1149 """Print version, copyright information and compile mode""" 1150user_locale = locale.getlocale(category=locale.LC_NUMERIC)
1151locale.setlocale(locale.LC_NUMERIC,
"C")
1155locale.setlocale(locale.LC_NUMERIC,user_locale)
1158 """Print external code versions, e.g. symmetry, non-linear solver, lp solver""" 1159user_locale = locale.getlocale(category=locale.LC_NUMERIC)
1160locale.setlocale(locale.LC_NUMERIC,
"C")
1164locale.setlocale(locale.LC_NUMERIC,user_locale)
1167 """Retrieve problem name""" 1171 """Retrieve the current total SCIP time in seconds, i.e. the total time since the SCIP instance has been created""" 1175 """Retrieve the current solving time in seconds""" 1179 """Retrieve the current reading time in seconds""" 1183 """Retrieve the curernt presolving time in seconds""" 1187 """Retrieve the total number of LP iterations so far.""" 1191 """gets number of processed nodes in current run, including the focus node.""" 1195 """gets number of processed nodes in all runs, including the focus node.""" 1199 """Retrieve number of leaf nodes processed with feasible relaxation solution.""" 1203 """gets number of infeasible leaf nodes processed.""" 1207 """gets number of leaves in the tree.""" 1211 """gets number of children of focus node.""" 1215 """gets number of siblings of focus node.""" 1219 """Retrieve current node.""" 1223 """Retrieve the gap, i.e. |(primalbound - dualbound)/min(|primalbound|,|dualbound|)|.""" 1227 """Retrieve the depth of the current node""" 1231 """Retrieve SCIP's infinity value""" 1235 """Retrieve epsilon for e.g. equality checks""" 1239 """Retrieve feasibility tolerance""" 1243 """returns fractional part of value, i.e. x - floor(x) in feasible tolerance: x - floor(x+feastol)""" 1247 """returns fractional part of value, i.e. x - floor(x) in epsilon tolerance: x - floor(x+eps)""" 1251 """returns whether abs(value) < eps""" 1255 """returns whether abs(value) < feastol""" 1259 """returns whether value is SCIP's infinity""" 1263 """returns whether value < -feastol""" 1267 """returns whether value is integral within the LP feasibility bounds""" 1271 """checks, if values are in range of epsilon""" 1275 """checks, if relative difference of values is in range of feasibility tolerance""" 1279 """returns whether val1 <= val2 + eps""" 1283 """returns whether val1 < val2 - eps""" 1287 """returns whether val1 >= val2 - eps""" 1291 """returns whether val1 > val2 + eps""" 1295 """Get the current LP's condition number 1297 :param exact: whether to get an estimate or the exact value (Default value = False) 1302cdef SCIP_Real quality = 0
1311 """include specific heuristics and branching rules for reoptimization""" 1315 """Get the iteration count of the last solved LP""" 1325 """Set the objective sense to minimization.""" 1329 """Set the objective sense to maximization.""" 1333 """Set a limit on the objective function. 1334 Only solutions with objective value better than this limit are accepted. 1336 :param objlimit: limit on the objective function 1342 """returns current limit on objective function.""" 1346 """Establish the objective function as a linear expression. 1348 :param expr: the objective function SCIP Expr, or constant value 1349 :param sense: the objective sense (Default value = 'minimize') 1350 :param clear: set all other variables objective coefficient to zero (Default value = 'true') 1354cdef SCIP_VAR** _vars
1358 if notisinstance(expr, Expr):
1359assert(_is_number(expr)),
"given coefficients are neither Expr or number but %s"% expr.__class__.__name__
1360expr = Expr() + expr
1362 ifexpr.degree() > 1:
1363 raiseValueError(
"SCIP does not support nonlinear objective functions. Consider using set_nonlinear_objective in the pyscipopt.recipe.nonlinear")
1370 fori
inrange(_nvars):
1373 ifexpr[CONST] != 0.0:
1376 forterm, coef
inexpr.terms.items():
1379 assertlen(term) == 1
1380var = <Variable>term[0]
1383 ifsense ==
"minimize":
1385 elifsense ==
"maximize":
1388 raiseWarning(
"unrecognized optimization sense: %s"% sense)
1391 """Retrieve objective function as Expr""" 1394 forvar
invariables:
1395coeff = var.getObj()
1397objective += coeff * var
1398objective.normalize()
1402 """Add constant offset to objective 1404 :param offset: offset to add 1405 :param solutions: add offset also to existing solutions (Default value = False) 1414 """Retrieve constant objective offset 1416 :param original: offset of original or transformed problem (Default value = True) 1425 """informs SCIP that the objective value is always integral in every feasible solution 1426 Note: This function should be used to inform SCIP that the objective function is integral, helping to improve the 1427 performance. This is useful when using column generation. If no column generation (pricing) is used, SCIP 1428 automatically detects whether the objective function is integral or can be scaled to be integral. However, in 1429 any case, the user has to make sure that no variable is added during the solving process that destroys this 1435 """gets estimate of best primal solution w.r.t. original or transformed problem contained in current subtree 1437 :param original: estimate of original or transformed problem (Default value = False) 1446 """Set presolving parameter settings. 1448 :param setting: the parameter settings (SCIP_PARAMSETTING) 1454 """Set problem name""" 1459 """Set separating parameter settings. 1461 :param setting: the parameter settings (SCIP_PARAMSETTING) 1467 """Set heuristics parameter settings. 1469 :param setting: the parameter setting (SCIP_PARAMSETTING) 1475 """Disables propagation in SCIP to avoid modifying the original problem during transformation. 1477 :param onlyroot: use propagation when root processing is finished (Default value = False) 1480self.
setIntParam(
"propagating/maxroundsroot", 0)
1484 def writeProblem(self, filename='model.cip', trans=False, genericnames=False, verbose=True):
1485 """Write current model/problem to a file. 1487 :param filename: the name of the file to be used (Default value = 'model.cip'). Should have an extension corresponding to one of the readable file formats, described in https://www.scipopt.org/doc/html/group__FILEREADERS.php. 1488 :param trans: indicates whether the transformed problem is written to file (Default value = False) 1489 :param genericnames: indicates whether the problem should be written with generic variable and constraint names (Default value = False) 1490 :param verbose: indicates whether a success message should be printed 1492user_locale = locale.getlocale(category=locale.LC_NUMERIC)
1493locale.setlocale(locale.LC_NUMERIC,
"C")
1495str_absfile = abspath(filename)
1497fn, ext = splitext(absfile)
1510print(
'wrote problem to file '+ str_absfile)
1512locale.setlocale(locale.LC_NUMERIC,user_locale)
1516 def addVar(self, name='', vtype='C', lb=0.0, ub=None, obj=0.0, pricedVar=False, pricedVarScore=1.0):
1517 """Create a new variable. Default variable is non-negative and continuous. 1519 :param name: name of the variable, generic if empty (Default value = '') 1520 :param vtype: type of the variable: 'C' continuous, 'I' integer, 'B' binary, and 'M' implicit integer 1521 (see https://www.scipopt.org/doc/html/FAQ.php#implicitinteger) (Default value = 'C') 1522 :param lb: lower bound of the variable, use None for -infinity (Default value = 0.0) 1523 :param ub: upper bound of the variable, use None for +infinity (Default value = None) 1524 :param obj: objective value of variable (Default value = 0.0) 1525 :param pricedVar: is the variable a pricing candidate? (Default value = False) 1526 :param pricedVarScore: score of variable in case it is priced, the higher the better (Default value = 1.0) 1529cdef SCIP_VAR* scip_var
1542vtype = vtype.upper()
1543 ifvtype
in[
'C',
'CONTINUOUS']:
1545 elifvtype
in[
'B',
'BINARY']:
1551 elifvtype
in[
'I',
'INTEGER']:
1553 elifvtype
in[
'M',
'IMPLINT']:
1556 raiseWarning(
"unrecognized variable type")
1563pyVar = Variable.create(scip_var)
1575 """Retrieve the transformed variable. 1577 :param Variable var: original variable to get the transformed of 1580cdef SCIP_VAR* _tvar
1583 returnVariable.create(_tvar)
1586 """adds given values to lock numbers of variable for rounding 1588 :param Variable var: variable to adjust the locks for 1589 :param nlocksdown: new number of down locks 1590 :param nlocksup: new number of up locks 1596 """Fixes the variable var to the value val if possible. 1598 :param Variable var: variable to fix 1599 :param val: float, the fix value 1600 :return: tuple (infeasible, fixed) of booleans 1603cdef SCIP_Bool infeasible
1604cdef SCIP_Bool fixed
1605PY_SCIP_CALL(
SCIPfixVar(self.
_scip, var.scip_var, val, &infeasible, &fixed))
1606 returninfeasible, fixed
1609 """Delete a variable. 1611 :param var: the variable which shall be deleted 1612 :return: bool, was deleting succesful 1615cdef SCIP_Bool deleted
1622 """Tighten the lower bound in preprocessing or current node, if the bound is tighter. 1624 :param var: SCIP variable 1625 :param lb: possible new lower bound 1626 :param force: force tightening even if below bound strengthening tolerance 1627 :return: tuple of bools, (infeasible, tightened) 1628 infeasible: whether new domain is empty 1629 tightened: whether the bound was tightened 1632cdef SCIP_Bool infeasible
1633cdef SCIP_Bool tightened
1635 returninfeasible, tightened
1638 """Tighten the upper bound in preprocessing or current node, if the bound is tighter. 1640 :param var: SCIP variable 1641 :param ub: possible new upper bound 1642 :param force: force tightening even if below bound strengthening tolerance 1643 :return: tuple of bools, (infeasible, tightened) 1644 infeasible: whether new domain is empty 1645 tightened: whether the bound was tightened 1648cdef SCIP_Bool infeasible
1649cdef SCIP_Bool tightened
1651 returninfeasible, tightened
1654 """Tighten the global upper bound, if the bound is tighter. 1656 :param var: SCIP variable 1657 :param ub: possible new upper bound 1658 :param force: force tightening even if below bound strengthening tolerance 1659 :return: tuple of bools, (infeasible, tightened) 1660 infeasible: whether new domain is empty 1661 tightened: whether the bound was tightened 1664cdef SCIP_Bool infeasible
1665cdef SCIP_Bool tightened
1667 returninfeasible, tightened
1670 """Tighten the global upper bound, if the bound is tighter. 1672 :param var: SCIP variable 1673 :param lb: possible new upper bound 1674 :param force: force tightening even if below bound strengthening tolerance 1675 :return: tuple of bools, (infeasible, tightened) 1676 infeasible: whether new domain is empty 1677 tightened: whether the bound was tightened 1680cdef SCIP_Bool infeasible
1681cdef SCIP_Bool tightened
1683 returninfeasible, tightened
1686 """Changes the lower bound of the specified variable. 1688 :param Variable var: variable to change bound of 1689 :param lb: new lower bound (set to None for -infinity) 1697 """Changes the upper bound of the specified variable. 1699 :param Variable var: variable to change bound of 1700 :param ub: new upper bound (set to None for +infinity) 1708 """Changes the global lower bound of the specified variable. 1710 :param Variable var: variable to change bound of 1711 :param lb: new lower bound (set to None for -infinity) 1719 """Changes the global upper bound of the specified variable. 1721 :param Variable var: variable to change bound of 1722 :param ub: new upper bound (set to None for +infinity) 1730 """Changes the lower bound of the specified variable at the given node. 1732 :param Variable var: variable to change bound of 1733 :param lb: new lower bound (set to None for -infinity) 1741 """Changes the upper bound of the specified variable at the given node. 1743 :param Variable var: variable to change bound of 1744 :param ub: new upper bound (set to None for +infinity) 1752 """Changes the type of a variable 1754 :param Variable var: variable to change type of 1755 :param vtype: new variable type 1758cdef SCIP_Bool infeasible
1759 ifvtype
in[
'C',
'CONTINUOUS']:
1760PY_SCIP_CALL(
SCIPchgVarType(self.
_scip, var.scip_var, SCIP_VARTYPE_CONTINUOUS, &infeasible))
1761 elifvtype
in[
'B',
'BINARY']:
1762PY_SCIP_CALL(
SCIPchgVarType(self.
_scip, var.scip_var, SCIP_VARTYPE_BINARY, &infeasible))
1763 elifvtype
in[
'I',
'INTEGER']:
1764PY_SCIP_CALL(
SCIPchgVarType(self.
_scip, var.scip_var, SCIP_VARTYPE_INTEGER, &infeasible))
1765 elifvtype
in[
'M',
'IMPLINT']:
1766PY_SCIP_CALL(
SCIPchgVarType(self.
_scip, var.scip_var, SCIP_VARTYPE_IMPLINT, &infeasible))
1768 raiseWarning(
"unrecognized variable type")
1770print(
'could not change variable type of variable %s'% var)
1773 """Retrieve all variables. 1775 :param transformed: get transformed variables instead of original (Default value = False) 1778cdef SCIP_VAR** _vars
1790 fori
inrange(_nvars):
1791ptr = <size_t>(_vars[i])
1798var = Variable.create(_vars[i])
1799 assertvar.ptr() == ptr
1806 """Retrieve number of variables in the problems. 1808 :param transformed: get transformed variables instead of original (Default value = True) 1816 """gets number of integer active problem variables""" 1820 """gets number of binary active problem variables""" 1824 """gets dictionary with variables names as keys and current variable values as items""" 1827var_dict[var.name] = self.
getVal(var)
1831 """if given value is larger than the node's lower bound (in transformed problem), 1832 sets the node's lower bound to the new value 1834 :param node: Node, the node to update 1835 :param newbound: float, new bound (if greater) for the node 1841 """Relaxes the integrality restrictions of the model""" 1842 ifself.
getStage() != SCIP_STAGE_PROBLEM:
1843 raiseWarning(
"method can only be called in stage PROBLEM")
1850 """gets the best child of the focus node w.r.t. the node selection strategy.""" 1854 """gets the best sibling of the focus node w.r.t. the node selection strategy.""" 1858 """gets the best leaf from the node queue w.r.t. the node selection strategy.""" 1862 """gets the best node from the tree (child, sibling, or leaf) w.r.t. the node selection strategy.""" 1866 """gets the node with smallest lower bound from the tree (child, sibling, or leaf).""" 1870 """access to all data of open nodes (leaves, children, and siblings) 1872 :return: three lists containing open leaves, children, siblings 1874cdef SCIP_NODE** _leaves
1875cdef SCIP_NODE** _children
1876cdef SCIP_NODE** _siblings
1881PY_SCIP_CALL(
SCIPgetOpenNodesData(self.
_scip, &_leaves, &_children, &_siblings, &_nleaves, &_nchildren, &_nsiblings))
1883leaves = [Node.create(_leaves[i])
fori
inrange(_nleaves)]
1884children = [Node.create(_children[i])
fori
inrange(_nchildren)]
1885siblings = [Node.create(_siblings[i])
fori
inrange(_nsiblings)]
1887 returnleaves, children, siblings
1890 """marks the given node to be propagated again the next time a node of its subtree is processed""" 1896 """Gets solution status of current LP""" 1901 """makes sure that the LP of the current node is loaded and 1902 may be accessed through the LP information methods 1904 :return: bool cutoff, i.e. can the node be cut off? 1907cdef SCIP_Bool cutoff
1912 """gets objective value of current LP (which is the sum of column and loose objective value)""" 1917 """Retrieve current LP columns""" 1918cdef SCIP_COL** cols
1922 return[Column.create(cols[i])
fori
inrange(ncols)]
1925 """Retrieve current LP rows""" 1926cdef SCIP_ROW** rows
1930 return[Row.create(rows[i])
fori
inrange(nrows)]
1933 """Retrieve the number of rows currently in the LP""" 1937 """Retrieve the number of cols currently in the LP""" 1941 """Gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1""" 1943cdef int* inds = <int *> malloc(nrows * sizeof(int))
1946result = [inds[i]
fori
inrange(nrows)]
1951 """gets a row from the inverse basis matrix B^-1""" 1954cdef SCIP_Real* coefs = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
1957result = [coefs[i]
fori
inrange(nrows)]
1962 """gets a row from B^-1 * A""" 1965cdef SCIP_Real* coefs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
1968result = [coefs[i]
fori
inrange(ncols)]
1973 """returns whether the current LP solution is basic, i.e. is defined by a valid simplex basis""" 1977 """checks if all columns, i.e. every variable with non-empty column is present in the LP. 1978 This is not True when performing pricing for instance.""" 1984 """gets the reduced cost of the column in the current LP 1986 :param Column col: the column of the LP for which the reduced cost will be retrieved 1992 def createEmptyRowSepa(self, Sepa sepa, name="row", lhs = 0.0, rhs = None, local = True, modifiable = False, removable = True):
1993 """creates and captures an LP row without any coefficients from a separator 1995 :param sepa: separator that creates the row 1996 :param name: name of row (Default value = "row") 1997 :param lhs: left hand side of row (Default value = 0) 1998 :param rhs: right hand side of row (Default value = None) 1999 :param local: is row only valid locally? (Default value = True) 2000 :param modifiable: is row modifiable during node processing (subject to column generation)? (Default value = False) 2001 :param removable: should the row be removed from the LP due to aging or cleanup? (Default value = True) 2008PyRow = Row.create(row)
2011 def createEmptyRowUnspec(self, name="row", lhs = 0.0, rhs = None, local = True, modifiable = False, removable = True):
2012 """creates and captures an LP row without any coefficients from an unspecified source 2014 :param name: name of row (Default value = "row") 2015 :param lhs: left hand side of row (Default value = 0) 2016 :param rhs: right hand side of row (Default value = None) 2017 :param local: is row only valid locally? (Default value = True) 2018 :param modifiable: is row modifiable during node processing (subject to column generation)? (Default value = False) 2019 :param removable: should the row be removed from the LP due to aging or cleanup? (Default value = True) 2025PyRow = Row.create(row)
2029 """returns the activity of a row in the last LP or pseudo solution""" 2033 """returns the activity of a row in the last LP solution""" 2038 """decreases usage counter of LP row, and frees memory if necessary""" 2042 """informs row, that all subsequent additions of variables to the row should be cached and not directly applied; 2043 after all additions were applied, flushRowExtensions() must be called; 2044 while the caching of row extensions is activated, information methods of the row give invalid results; 2045 caching should be used, if a row is build with addVarToRow() calls variable by variable to increase the performance""" 2049 """flushes all cached row extensions after a call of cacheRowExtensions() and merges coefficients with equal columns into a single coefficient""" 2052 def addVarToRow(self, Row row not None, Variable var not None, value):
2053 """resolves variable to columns and adds them with the coefficient to the row""" 2061 """Returns number of intergal columns in the row""" 2065 """Returns 1 if the row is parallel, and 0 if orthogonal""" 2069 """Returns the degree of parallelism between hyplerplanes. 1 if perfectly parallel, 0 if orthogonal. 2070 For two row vectors v, w the parallelism is calculated as: |v*w|/(|v|*|w|). 2071 101 in this case is an 'e' (euclidean) in ASCII. The other acceptable input is 100 (d for discrete).""" 2075 """Gets the dual LP solution of a row""" 2080 """if not already existing, adds row to global cut pool""" 2084 """returns efficacy of the cut with respect to the given primal solution or the current LP solution: e = -feasibility/norm""" 2088 """ returns whether the cut's efficacy with respect to the given primal solution or the current LP solution is greater than the minimal cut efficacy""" 2092 """ returns row's cutoff distance in the direction of the given primal solution""" 2095 def addCut(self, Row cut not None, forcecut = False):
2096 """adds cut to separation storage and returns whether cut has been detected to be infeasible for local bounds""" 2097cdef SCIP_Bool infeasible
2098PY_SCIP_CALL(
SCIPaddRow(self.
_scip, cut.scip_row, forcecut, &infeasible))
2102 """Retrieve total number of cuts in storage""" 2106 """Retrieve number of currently applied cuts""" 2110 """Retrieve the number of separation rounds that have been performed 2111 at the current node""" 2114 def separateSol(self, Solution sol = None, pretendroot = False, allowlocal = True, onlydelayed = False):
2115 """separates the given primal solution or the current LP solution by calling the separators and constraint handlers' 2117 the generated cuts are stored in the separation storage and can be accessed with the methods SCIPgetCuts() and 2119 after evaluating the cuts, you have to call SCIPclearCuts() in order to remove the cuts from the 2121 it is possible to call SCIPseparateSol() multiple times with different solutions and evaluate the found cuts 2123 :param Solution sol: solution to separate, None to use current lp solution (Default value = None) 2124 :param pretendroot: should the cut separators be called as if we are at the root node? (Default value = "False") 2125 :param allowlocal: should the separator be asked to separate local cuts (Default value = True) 2126 :param onlydelayed: should only separators be called that were delayed in the previous round? (Default value = False) 2128 delayed -- whether a separator was delayed 2129 cutoff -- whether the node can be cut off 2131cdef SCIP_Bool delayed
2132cdef SCIP_Bool cutoff
2134PY_SCIP_CALL(
SCIPseparateSol(self.
_scip, NULL
ifsol
is None elsesol.sol, pretendroot, allowlocal, onlydelayed, &delayed, &cutoff) )
2135 returndelayed, cutoff
2137 def_createConsLinear(self, ExprCons lincons, **kwargs):
2138 assertisinstance(lincons, ExprCons),
"given constraint is not ExprCons but %s"% lincons.__class__.__name__
2140 assertlincons.expr.degree() <= 1,
"given constraint is not linear, degree == %d"% lincons.expr.degree()
2141terms = lincons.expr.terms
2143cdef SCIP_CONS* scip_cons
2145cdef int nvars = len(terms.items())
2147vars_array = <SCIP_VAR**> malloc(nvars * sizeof(SCIP_VAR*))
2148coeffs_array = <SCIP_Real*> malloc(nvars * sizeof(SCIP_Real))
2150 fori, (key, coeff)
inenumerate(terms.items()):
2151vars_array[i] = <SCIP_VAR*>(<Variable>key[0]).scip_var
2152coeffs_array[i] = <SCIP_Real>coeff
2155self.
_scip, &scip_cons,
str_conversion(kwargs[
'name']), nvars, vars_array, coeffs_array,
2156kwargs[
'lhs'], kwargs[
'rhs'], kwargs[
'initial'],
2157kwargs[
'separate'], kwargs[
'enforce'], kwargs[
'check'],
2158kwargs[
'propagate'], kwargs[
'local'], kwargs[
'modifiable'],
2159kwargs[
'dynamic'], kwargs[
'removable'], kwargs[
'stickingatnode']))
2161PyCons = Constraint.create(scip_cons)
2167 def_createConsQuadratic(self, ExprCons quadcons, **kwargs):
2168terms = quadcons.expr.terms
2169 assertquadcons.expr.degree() <= 2,
"given constraint is not quadratic, degree == %d"% quadcons.expr.degree()
2171cdef SCIP_CONS* scip_cons
2172cdef SCIP_EXPR* prodexpr
21760, NULL, NULL, NULL,
2177kwargs[
'lhs'], kwargs[
'rhs'],
2178kwargs[
'initial'], kwargs[
'separate'], kwargs[
'enforce'],
2179kwargs[
'check'], kwargs[
'propagate'], kwargs[
'local'],
2180kwargs[
'modifiable'], kwargs[
'dynamic'], kwargs[
'removable']))
2182 forv, c
interms.items():
2184var = <Variable>v[0]
2187 assertlen(v) == 2,
'term length must be 1 or 2 but it is %s'% len(v)
2189varexprs = <SCIP_EXPR**> malloc(2 * sizeof(SCIP_EXPR*))
2190var1, var2 = <Variable>v[0], <Variable>v[1]
2202PyCons = Constraint.create(scip_cons)
2206 def_createConsNonlinear(self, cons, **kwargs):
2207cdef SCIP_EXPR* expr
2208cdef SCIP_EXPR** varexprs
2209cdef SCIP_EXPR** monomials
2211cdef SCIP_CONS* scip_cons
2213terms = cons.expr.terms
2216variables = {var.ptr():var
forterm
interms
forvar
interm}
2217variables = list(variables.values())
2218varindex = {var.ptr():idx
for(idx,var)
inenumerate(variables)}
2221monomials = <SCIP_EXPR**> malloc(len(terms) * sizeof(SCIP_EXPR*))
2222termcoefs = <SCIP_Real*> malloc(len(terms) * sizeof(SCIP_Real))
2223 fori, (term, coef)
inenumerate(terms.items()):
2224termvars = <SCIP_VAR**> malloc(len(term) * sizeof(SCIP_VAR*))
2225 forj, var
inenumerate(term):
2226termvars[j] = (<Variable>var).scip_var
2228termcoefs[i] = <SCIP_Real>coef
2232PY_SCIP_CALL(
SCIPcreateExprSum(self.
_scip, &expr, <int>len(terms), monomials, termcoefs, 0.0, NULL, NULL))
2242kwargs[
'initial'],
2243kwargs[
'separate'],
2244kwargs[
'enforce'],
2246kwargs[
'propagate'],
2248kwargs[
'modifiable'],
2249kwargs[
'dynamic'],
2250kwargs[
'removable']) )
2252PyCons = Constraint.create(scip_cons)
2255 fori
inrange(<int>len(terms)):
2261 def_createConsGenNonlinear(self, cons, **kwargs):
2262cdef SCIP_EXPR** childrenexpr
2263cdef SCIP_EXPR** scipexprs
2264cdef SCIP_CONS* scip_cons
2281 ifnode[0] == Operator.varidx:
2283vars = <SCIP_VAR**> malloc(nvars * sizeof(SCIP_VAR*))
2286scipexprs = <SCIP_EXPR**> malloc(len(nodes) * sizeof(SCIP_EXPR*))
2287 fori,node
inenumerate(nodes):
2289 ifopidx == Operator.varidx:
2290 assertlen(node[1]) == 1
2293vars[varpos] = (<Variable>pyvar).scip_var
2296 ifopidx == Operator.const:
2297 assertlen(node[1]) == 1
2301 ifopidx == Operator.add:
2302nchildren = len(node[1])
2303childrenexpr = <SCIP_EXPR**> malloc(nchildren * sizeof(SCIP_EXPR*))
2304coefs = <SCIP_Real*> malloc(nchildren * sizeof(SCIP_Real))
2305 forc, pos
inenumerate(node[1]):
2306childrenexpr[c] = scipexprs[pos]
2308PY_SCIP_CALL(
SCIPcreateExprSum(self.
_scip, &scipexprs[i], nchildren, childrenexpr, coefs, 0, NULL, NULL))
2312 ifopidx == Operator.prod:
2313nchildren = len(node[1])
2314childrenexpr = <SCIP_EXPR**> malloc(nchildren * sizeof(SCIP_EXPR*))
2315 forc, pos
inenumerate(node[1]):
2316childrenexpr[c] = scipexprs[pos]
2320 ifopidx == Operator.power:
2322valuenode = nodes[node[1][1]]
2323 assertvaluenode[0] == Operator.const
2324exponent = valuenode[1][0]
2325PY_SCIP_CALL(
SCIPcreateExprPow(self.
_scip, &scipexprs[i], scipexprs[node[1][0]], <SCIP_Real>exponent, NULL, NULL ))
2327 ifopidx == Operator.exp:
2328 assertlen(node[1]) == 1
2331 ifopidx == Operator.log:
2332 assertlen(node[1]) == 1
2335 ifopidx == Operator.sqrt:
2336 assertlen(node[1]) == 1
2337PY_SCIP_CALL(
SCIPcreateExprPow(self.
_scip, &scipexprs[i], scipexprs[node[1][0]], <SCIP_Real>0.5, NULL, NULL) )
2339 ifopidx == Operator.sin:
2340 assertlen(node[1]) == 1
2343 ifopidx == Operator.cos:
2344 assertlen(node[1]) == 1
2347 ifopidx == Operator.fabs:
2348 assertlen(node[1]) == 1
2352 raiseNotImplementedError
2353 assertvarpos == nvars
2360scipexprs[len(nodes) - 1],
2363kwargs[
'initial'],
2364kwargs[
'separate'],
2365kwargs[
'enforce'],
2367kwargs[
'propagate'],
2369kwargs[
'modifiable'],
2370kwargs[
'dynamic'],
2371kwargs[
'removable']) )
2372PyCons = Constraint.create(scip_cons)
2373 fori
inrange(len(nodes)):
2383enforce=True, check=True, propagate=True, local=False,
2384modifiable=False, dynamic=False, removable=False,
2385stickingatnode=False):
2386 """Create a linear or nonlinear constraint without adding it to the SCIP problem. This is useful for creating disjunction constraints 2387 without also enforcing the individual constituents. Currently, this can only be used as an argument to `.addConsElemDisjunction`. To add 2388 an individual linear/nonlinear constraint, prefer `.addCons()`. 2390 :param cons: constraint object 2391 :param name: the name of the constraint, generic name if empty (Default value = '') 2392 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2393 :param separate: should the constraint be separated during LP processing? (Default value = True) 2394 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2395 :param check: should the constraint be checked for feasibility? (Default value = True) 2396 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2397 :param local: is the constraint only valid locally? (Default value = False) 2398 :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False) 2399 :param dynamic: is the constraint subject to aging? (Default value = False) 2400 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2401 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2402 :return The created @ref scip#Constraint "Constraint" object. 2408kwargs = dict(name=name, initial=initial, separate=separate,
2409enforce=enforce, check=check,
2410propagate=propagate, local=local,
2411modifiable=modifiable, dynamic=dynamic,
2412removable=removable,
2413stickingatnode=stickingatnode)
2414kwargs[
'lhs'] = -
SCIPinfinity(self.
_scip)
ifcons._lhs
is None elsecons._lhs
2415kwargs[
'rhs'] =
SCIPinfinity(self.
_scip)
ifcons._rhs
is None elsecons._rhs
2417deg = cons.expr.degree()
2422 elifdeg == float(
'inf'):
2428 def addCons(self, cons, name='', initial=True, separate=True,
2429enforce=True, check=True, propagate=True, local=False,
2430modifiable=False, dynamic=False, removable=False,
2431stickingatnode=False):
2432 """Add a linear or nonlinear constraint. 2434 :param cons: constraint object 2435 :param name: the name of the constraint, generic name if empty (Default value = '') 2436 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2437 :param separate: should the constraint be separated during LP processing? (Default value = True) 2438 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2439 :param check: should the constraint be checked for feasibility? (Default value = True) 2440 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2441 :param local: is the constraint only valid locally? (Default value = False) 2442 :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False) 2443 :param dynamic: is the constraint subject to aging? (Default value = False) 2444 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2445 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2446 :return The added @ref scip#Constraint "Constraint" object. 2449 assertisinstance(cons, ExprCons),
"given constraint is not ExprCons but %s"% cons.__class__.__name__
2451cdef SCIP_CONS* scip_cons
2453kwargs = dict(name=name, initial=initial, separate=separate,
2454enforce=enforce, check=check,
2455propagate=propagate, local=local,
2456modifiable=modifiable, dynamic=dynamic,
2457removable=removable,
2458stickingatnode=stickingatnode)
2464scip_cons = (<Constraint>pycons_initial).scip_cons
2467pycons = Constraint.create(scip_cons)
2472 def addConss(self, conss, name='', initial=True, separate=True,
2473enforce=True, check=True, propagate=True, local=False,
2474modifiable=False, dynamic=False, removable=False,
2475stickingatnode=False):
2476 """Adds multiple linear or quadratic constraints. 2478 Each of the constraints is added to the model using Model.addCons(). 2480 For all parameters, except @p conss, this method behaves differently depending on the type of the passed argument: 2481 1. If the value is iterable, it must be of the same length as @p conss. For each constraint, Model.addCons() will be called with the value at the corresponding index. 2482 2. Else, the (default) value will be applied to all of the constraints. 2484 :param conss An iterable of constraint objects. Any iterable will be converted into a list before further processing. 2485 :param name: the names of the constraints, generic name if empty (Default value = ''). If a single string is passed, it will be suffixed by an underscore and the enumerated index of the constraint (starting with 0). 2486 :param initial: should the LP relaxation of constraints be in the initial LP? (Default value = True) 2487 :param separate: should the constraints be separated during LP processing? (Default value = True) 2488 :param enforce: should the constraints be enforced during node processing? (Default value = True) 2489 :param check: should the constraints be checked for feasibility? (Default value = True) 2490 :param propagate: should the constraints be propagated during node processing? (Default value = True) 2491 :param local: are the constraints only valid locally? (Default value = False) 2492 :param modifiable: are the constraints modifiable (subject to column generation)? (Default value = False) 2493 :param dynamic: are the constraints subject to aging? (Default value = False) 2494 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2495 :param stickingatnode: should the constraints always be kept at the node where it was added, even if it may be @oved to a more global node? (Default value = False) 2496 :return A list of added @ref scip#Constraint "Constraint" objects. 2500 defensure_iterable(elem, length):
2501 ifisinstance(elem, Iterable):
2504 returnlist(repeat(elem, length))
2506 assertisinstance(conss, Iterable),
"Given constraint list is not iterable." 2509n_conss = len(conss)
2511 ifisinstance(name, str):
2513name = [
"" foridx
inrange(n_conss)]
2515name = [
"%s_%s"% (name, idx)
foridx
inrange(n_conss)]
2516initial = ensure_iterable(initial, n_conss)
2517separate = ensure_iterable(separate, n_conss)
2518enforce = ensure_iterable(enforce, n_conss)
2519check = ensure_iterable(check, n_conss)
2520propagate = ensure_iterable(propagate, n_conss)
2521local = ensure_iterable(local, n_conss)
2522modifiable = ensure_iterable(modifiable, n_conss)
2523dynamic = ensure_iterable(dynamic, n_conss)
2524removable = ensure_iterable(removable, n_conss)
2525stickingatnode = ensure_iterable(stickingatnode, n_conss)
2528 fori, cons
inenumerate(conss):
2530self.
addCons(cons, name[i], initial[i], separate[i], enforce[i],
2531check[i], propagate[i], local[i], modifiable[i],
2532dynamic[i], removable[i], stickingatnode[i])
2538relaxcons = None, enforce=True, check =True,
2539local=False, modifiable = False, dynamic = False):
2540 """Add a disjunction constraint. 2542 :param Iterable[Constraint] conss: An iterable of constraint objects to be included initially in the disjunction. Currently, these must be expressions. 2543 :param name: the name of the disjunction constraint. 2544 :param initial: should the LP relaxation of disjunction constraint be in the initial LP? (Default value = True) 2545 :param relaxcons: a conjunction constraint containing the linear relaxation of the disjunction constraint, or None. (Default value = None) 2546 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2547 :param check: should the constraint be checked for feasibility? (Default value = True) 2548 :param local: is the constraint only valid locally? (Default value = False) 2549 :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False) 2550 :param dynamic: is the constraint subject to aging? (Default value = False) 2551 :return The added @ref scip#Constraint "Constraint" object. 2553 defensure_iterable(elem, length):
2554 ifisinstance(elem, Iterable):
2557 returnlist(repeat(elem, length))
2558 assertisinstance(conss, Iterable),
"Given constraint list is not iterable" 2561n_conss = len(conss)
2563cdef SCIP_CONS* disj_cons
2565cdef SCIP_CONS* scip_cons
2567cdef SCIP_EXPR* scip_expr
2571initial, enforce, check, local, modifiable, dynamic
2576 fori, cons
inenumerate(conss):
2578enforce=enforce, check=check,
2579local=local, modifiable=modifiable, dynamic=dynamic
2584PyCons = Constraint.create(disj_cons)
2589 """Appends a constraint to a disjunction. 2591 :param Constraint disj_cons: the disjunction constraint to append to. 2592 :param Constraint cons: the Constraint to append 2593 :return The disjunction constraint with added @ref scip#Constraint object. 2601 Gets number of variables in a constraint. 2603 :param constraint: Constraint to get the number of variables from. 2606cdef SCIP_Bool success
2613 raiseTypeError(
"The constraint handler %s does not have this functionality."% conshdrlname)
2619 Gets variables in a constraint. 2621 :param constraint: Constraint to get the variables from. 2623cdef SCIP_Bool success
2628cdef SCIP_VAR** _vars = <SCIP_VAR**> malloc(_nvars * sizeof(SCIP_VAR*))
2629 SCIPgetConsVars(self.
_scip, constraint.scip_cons, _vars, _nvars*sizeof(SCIP_VAR*), &success)
2632 fori
inrange(_nvars):
2633ptr = <size_t>(_vars[i])
2639var = Variable.create(_vars[i])
2640 assertvar.ptr() == ptr
2649 fromtyping
importUnion
2652 Add coef*expr to nonlinear constraint. 2654 assertself.
getStage() == 1,
"addExprNonlinear cannot be called in stage %i."% self.
getStage()
2655 assertcons.isNonlinear(),
"addExprNonlinear can only be called with nonlinear constraints." 2657cdef Constraint temp_cons
2658cdef SCIP_EXPR* scip_expr
2660temp_cons = self.
addCons(expr <= 0)
2667 """Add coefficient to the linear constraint (if non-zero). 2669 :param Constraint cons: constraint to be changed 2670 :param Variable var: variable to be added 2671 :param coeff: coefficient of new variable 2676 def addConsNode(self, Node node, Constraint cons, Node validnode=None):
2677 """Add a constraint to the given node 2679 :param Node node: node to add the constraint to 2680 :param Constraint cons: constraint to add 2681 :param Node validnode: more global node where cons is also valid 2684 ifisinstance(validnode, Node):
2685PY_SCIP_CALL(
SCIPaddConsNode(self.
_scip, node.scip_node, cons.scip_cons, validnode.scip_node))
2691 """Add a constraint to the current node 2693 :param Constraint cons: constraint to add 2694 :param Node validnode: more global node where cons is also valid 2697 ifisinstance(validnode, Node):
2704initial=True, separate=True, enforce=True, check=True,
2705propagate=True, local=False, dynamic=False,
2706removable=False, stickingatnode=False):
2707 """Add an SOS1 constraint. 2709 :param vars: list of variables to be included 2710 :param weights: list of weights (Default value = None) 2711 :param name: name of the constraint (Default value = "SOS1cons") 2712 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2713 :param separate: should the constraint be separated during LP processing? (Default value = True) 2714 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2715 :param check: should the constraint be checked for feasibility? (Default value = True) 2716 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2717 :param local: is the constraint only valid locally? (Default value = False) 2718 :param dynamic: is the constraint subject to aging? (Default value = False) 2719 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2720 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2723cdef SCIP_CONS* scip_cons
2727initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
2729 ifweights
is None:
2735 fori
inrange(nvars):
2736var = <Variable>vars[i]
2740 returnConstraint.create(scip_cons)
2743initial=True, separate=True, enforce=True, check=True,
2744propagate=True, local=False, dynamic=False,
2745removable=False, stickingatnode=False):
2746 """Add an SOS2 constraint. 2748 :param vars: list of variables to be included 2749 :param weights: list of weights (Default value = None) 2750 :param name: name of the constraint (Default value = "SOS2cons") 2751 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2752 :param separate: should the constraint be separated during LP processing? (Default value = True) 2753 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2754 :param check: should the constraint be checked for feasibility? (Default value = True) 2755 :param propagate: is the constraint only valid locally? (Default value = True) 2756 :param local: is the constraint only valid locally? (Default value = False) 2757 :param dynamic: is the constraint subject to aging? (Default value = False) 2758 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2759 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2762cdef SCIP_CONS* scip_cons
2766initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
2768 ifweights
is None:
2774 fori
inrange(nvars):
2775var = <Variable>vars[i]
2779 returnConstraint.create(scip_cons)
2782initial=True, separate=True, enforce=True, check=True,
2783propagate=True, local=False, modifiable=False, dynamic=False,
2784removable=False, stickingatnode=False):
2785 """Add an AND-constraint. 2786 :param vars: list of BINARY variables to be included (operators) 2787 :param resvar: BINARY variable (resultant) 2788 :param name: name of the constraint (Default value = "ANDcons") 2789 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2790 :param separate: should the constraint be separated during LP processing? (Default value = True) 2791 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2792 :param check: should the constraint be checked for feasibility? (Default value = True) 2793 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2794 :param local: is the constraint only valid locally? (Default value = False) 2795 :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False) 2796 :param dynamic: is the constraint subject to aging? (Default value = False) 2797 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2798 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2800cdef SCIP_CONS* scip_cons
2804_vars = <SCIP_VAR**> malloc(len(vars) * sizeof(SCIP_VAR*))
2805 foridx, var
inenumerate(vars):
2806_vars[idx] = (<Variable>var).scip_var
2807_resVar = (<Variable>resvar).scip_var
2810initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
2813pyCons = Constraint.create(scip_cons)
2821initial=True, separate=True, enforce=True, check=True,
2822propagate=True, local=False, modifiable=False, dynamic=False,
2823removable=False, stickingatnode=False):
2824 """Add an OR-constraint. 2825 :param vars: list of BINARY variables to be included (operators) 2826 :param resvar: BINARY variable (resultant) 2827 :param name: name of the constraint (Default value = "ORcons") 2828 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2829 :param separate: should the constraint be separated during LP processing? (Default value = True) 2830 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2831 :param check: should the constraint be checked for feasibility? (Default value = True) 2832 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2833 :param local: is the constraint only valid locally? (Default value = False) 2834 :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False) 2835 :param dynamic: is the constraint subject to aging? (Default value = False) 2836 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2837 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2839cdef SCIP_CONS* scip_cons
2843_vars = <SCIP_VAR**> malloc(len(vars) * sizeof(SCIP_VAR*))
2844 foridx, var
inenumerate(vars):
2845_vars[idx] = (<Variable>var).scip_var
2846_resVar = (<Variable>resvar).scip_var
2849initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
2852pyCons = Constraint.create(scip_cons)
2860initial=True, separate=True, enforce=True, check=True,
2861propagate=True, local=False, modifiable=False, dynamic=False,
2862removable=False, stickingatnode=False):
2863 """Add a XOR-constraint. 2864 :param vars: list of BINARY variables to be included (operators) 2865 :param rhsvar: BOOLEAN value, explicit True, False or bool(obj) is needed (right-hand side) 2866 :param name: name of the constraint (Default value = "XORcons") 2867 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2868 :param separate: should the constraint be separated during LP processing? (Default value = True) 2869 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2870 :param check: should the constraint be checked for feasibility? (Default value = True) 2871 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2872 :param local: is the constraint only valid locally? (Default value = False) 2873 :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False) 2874 :param dynamic: is the constraint subject to aging? (Default value = False) 2875 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2876 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2878cdef SCIP_CONS* scip_cons
2882 asserttype(rhsvar)
istype(bool()),
"Provide BOOLEAN value as rhsvar, you gave %s."% type(rhsvar)
2883_vars = <SCIP_VAR**> malloc(len(vars) * sizeof(SCIP_VAR*))
2884 foridx, var
inenumerate(vars):
2885_vars[idx] = (<Variable>var).scip_var
2888initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
2891pyCons = Constraint.create(scip_cons)
2899initial=True, separate=True, enforce=True, check=True,
2900propagate=True, local=False, dynamic=False,
2901removable=False, stickingatnode=False):
2902 """Add a cardinality constraint that allows at most 'cardval' many nonzero variables. 2904 :param consvars: list of variables to be included 2905 :param cardval: nonnegative integer 2906 :param indvars: indicator variables indicating which variables may be treated as nonzero in cardinality constraint, or None if new indicator variables should be introduced automatically (Default value = None) 2907 :param weights: weights determining the variable order, or None if variables should be ordered in the same way they were added to the constraint (Default value = None) 2908 :param name: name of the constraint (Default value = "CardinalityCons") 2909 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2910 :param separate: should the constraint be separated during LP processing? (Default value = True) 2911 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2912 :param check: should the constraint be checked for feasibility? (Default value = True) 2913 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2914 :param local: is the constraint only valid locally? (Default value = False) 2915 :param dynamic: is the constraint subject to aging? (Default value = False) 2916 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2917 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2920cdef SCIP_CONS* scip_cons
2921cdef SCIP_VAR* indvar
2924initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
2927 ifweights
is None:
2928weights = list(range(1, len(consvars) + 1))
2930 fori, v
inenumerate(consvars):
2933indvar = (<Variable>indvars[i]).scip_var
2936 ifweights
is None:
2942pyCons = Constraint.create(scip_cons)
2949initial=True, separate=True, enforce=True, check=True,
2950propagate=True, local=False, dynamic=False,
2951removable=False, stickingatnode=False):
2952 """Add an indicator constraint for the linear inequality 'cons'. 2954 The 'binvar' argument models the redundancy of the linear constraint. A solution for which 2955 'binvar' is 1 must satisfy the constraint. 2957 :param cons: a linear inequality of the form "<=" 2958 :param binvar: binary indicator variable, or None if it should be created (Default value = None) 2959 :param activeone: constraint should active if binvar is 1 (0 if activeone = False) 2960 :param name: name of the constraint (Default value = "IndicatorCons") 2961 :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True) 2962 :param separate: should the constraint be separated during LP processing? (Default value = True) 2963 :param enforce: should the constraint be enforced during node processing? (Default value = True) 2964 :param check: should the constraint be checked for feasibility? (Default value = True) 2965 :param propagate: should the constraint be propagated during node processing? (Default value = True) 2966 :param local: is the constraint only valid locally? (Default value = False) 2967 :param dynamic: is the constraint subject to aging? (Default value = False) 2968 :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False) 2969 :param stickingatnode: should the constraint always be kept at the node where it was added, even if it may be moved to a more global node? (Default value = False) 2972 assertisinstance(cons, ExprCons),
"given constraint is not ExprCons but %s"% cons.__class__.__name__
2973cdef SCIP_CONS* scip_cons
2974cdef SCIP_VAR* _binVar
2975 ifcons._lhs
is not None andcons._rhs
is not None:
2976 raiseValueError(
"expected inequality that has either only a left or right hand side")
2978 ifcons.expr.degree() > 1:
2979 raiseValueError(
"expected linear inequality, expression has degree %d"% cons.expr.degree())
2981 ifcons._rhs
is not None:
2988 ifbinvar
is not None:
2989_binVar = (<Variable>binvar).scip_var
2996initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
2997terms = cons.expr.terms
2999 forkey, coeff
interms.items():
3000var = <Variable>key[0]
3006pyCons = Constraint.create(scip_cons)
3013 """Get slack variable of an indicator constraint. 3015 :param Constraint cons: indicator constraint 3019 returnVariable.create(var)
3022 """Adds a customly created cons. 3024 :param Constraint cons: constraint to add 3031 """Add variable to SOS1 constraint. 3033 :param Constraint cons: SOS1 constraint 3034 :param Variable var: new variable 3035 :param weight: weight of new variable 3041 """Append variable to SOS1 constraint. 3043 :param Constraint cons: SOS1 constraint 3044 :param Variable var: variable to append 3050 """Add variable to SOS2 constraint. 3052 :param Constraint cons: SOS2 constraint 3053 :param Variable var: new variable 3054 :param weight: weight of new variable 3060 """Append variable to SOS2 constraint. 3062 :param Constraint cons: SOS2 constraint 3063 :param Variable var: variable to append 3069 """Set "initial" flag of a constraint. 3073 newInit -- new initial value 3078 """Set "removable" flag of a constraint. 3082 newRem -- new removable value 3087 """Set "enforced" flag of a constraint. 3091 newEnf -- new enforced value 3096 """Set "check" flag of a constraint. 3100 newCheck -- new check value 3105 """Change right hand side value of a constraint. 3107 :param Constraint cons: linear or quadratic constraint 3108 :param rhs: new right hand side (set to None for +infinity) 3116 ifconstype ==
'linear':
3118 elifconstype ==
'nonlinear':
3121 raiseWarning(
"method cannot be called for constraints of type "+ constype)
3124 """Change left hand side value of a constraint. 3126 :param Constraint cons: linear or quadratic constraint 3127 :param lhs: new left hand side (set to None for -infinity) 3135 ifconstype ==
'linear':
3137 elifconstype ==
'nonlinear':
3140 raiseWarning(
"method cannot be called for constraints of type "+ constype)
3143 """Retrieve right hand side value of a constraint. 3145 :param Constraint cons: linear or quadratic constraint 3149 ifconstype ==
'linear':
3151 elifconstype ==
'quadratic':
3154 raiseWarning(
"method cannot be called for constraints of type "+ constype)
3157 """Retrieve left hand side value of a constraint. 3159 :param Constraint cons: linear or quadratic constraint 3163 ifconstype ==
'linear':
3165 elifconstype ==
'quadratic':
3168 raiseWarning(
"method cannot be called for constraints of type "+ constype)
3171 """Changes coefficient of variable in linear constraint; 3172 deletes the variable if coefficient is zero; adds variable if not yet contained in the constraint 3173 This method may only be called during problem creation stage for an original constraint and variable. 3174 This method requires linear time to search for occurences of the variable in the constraint data. 3176 :param Constraint cons: linear constraint 3177 :param Variable var: variable of constraint entry 3178 :param value: new coefficient of constraint entry 3184 """Deletes variable from linear constraint 3185 This method may only be called during problem creation stage for an original constraint and variable. 3186 This method requires linear time to search for occurences of the variable in the constraint data. 3188 :param Constraint cons: linear constraint 3189 :param Variable var: variable of constraint entry 3196 """Adds coefficient to linear constraint (if it is not zero) 3198 :param Constraint cons: linear constraint 3199 :param Variable var: variable of constraint entry 3200 :param value: coefficient of constraint entry 3207 """Retrieve activity of given constraint. 3208 Can only be called after solving is completed. 3210 :param Constraint cons: linear or quadratic constraint 3211 :param Solution sol: solution to compute activity of, None to use current node's solution (Default value = None) 3214cdef SCIP_Real activity
3215cdef SCIP_SOL* scip_sol
3217 if notself.
getStage() >= SCIP_STAGE_SOLVING:
3218 raiseWarning(
"method cannot be called before problem is solved")
3220 ifisinstance(sol, Solution):
3226 ifconstype ==
'linear':
3229 raiseWarning(
"method cannot be called for constraints of type "+ constype)
3234 def getSlack(self, Constraint cons, Solution sol = None, side = None):
3235 """Retrieve slack of given constraint. 3236 Can only be called after solving is completed. 3239 :param Constraint cons: linear or quadratic constraint 3240 :param Solution sol: solution to compute slack of, None to use current node's solution (Default value = None) 3241 :param side: whether to use 'lhs' or 'rhs' for ranged constraints, None to return minimum (Default value = None) 3244cdef SCIP_Real activity
3245cdef SCIP_SOL* scip_sol
3248 if notself.
getStage() >= SCIP_STAGE_SOLVING:
3249 raiseWarning(
"method cannot be called before problem is solved")
3251 ifisinstance(sol, Solution):
3257 ifconstype ==
'linear':
3262 raiseWarning(
"method cannot be called for constraints of type "+ constype)
3264lhsslack = activity - lhs
3265rhsslack = rhs - activity
3269 elifside ==
'rhs':
3272 returnmin(lhsslack, rhsslack)
3275 """Retrieve transformed constraint. 3277 :param Constraint cons: constraint 3280cdef SCIP_CONS* transcons
3282 returnConstraint.create(transcons)
3285 """returns whether SCIP's internal NLP has been constructed""" 3289 """gets current number of nonlinear rows in SCIP's internal NLP""" 3293 """returns a list with the nonlinear rows in SCIP's internal NLP""" 3294cdef SCIP_NLROW** nlrows
3297 return[NLRow.create(nlrows[i])
fori
inrange(self.
getNNlRows())]
3300 """gives the activity of a nonlinear row for a given primal solution 3302 nlrow -- nonlinear row 3303 solution -- a primal solution, if None, then the current LP solution is used 3305cdef SCIP_Real activity
3306cdef SCIP_SOL* solptr
3308solptr = sol.sol
if notsol
is None elseNULL
3313 """gives the feasibility of a nonlinear row for a given primal solution 3315 nlrow -- nonlinear row 3316 solution -- a primal solution, if None, then the current LP solution is used 3318cdef SCIP_Real feasibility
3319cdef SCIP_SOL* solptr
3321solptr = sol.sol
if notsol
is None elseNULL
3326 """gives the minimal and maximal activity of a nonlinear row w.r.t. the variable's bounds""" 3327cdef SCIP_Real minactivity
3328cdef SCIP_Real maxactivity
3331 return(minactivity, maxactivity)
3334 """prints nonlinear row""" 3338 """returns if the given constraint is quadratic 3340 :param Constraint cons: constraint 3343cdef SCIP_Bool isquadratic
3348 """Retrieve bilinear, quadratic, and linear terms of a quadratic constraint. 3350 :param Constraint cons: constraint 3353cdef SCIP_EXPR* expr
3356cdef SCIP_EXPR** _linexprs
3357cdef SCIP_Real* _lincoefs
3361cdef int _nbilinterms
3362cdef SCIP_EXPR* bilinterm1
3363cdef SCIP_EXPR* bilinterm2
3364cdef SCIP_Real bilincoef
3367cdef int _nquadterms
3368cdef SCIP_Real sqrcoef
3369cdef SCIP_Real lincoef
3370cdef SCIP_EXPR* sqrexpr
3373cdef SCIP_VAR* scipvar1
3374cdef SCIP_VAR* scipvar2
3376 assertcons.isNonlinear(),
"constraint is not nonlinear" 3386 fortermidx
inrange(_nlinvars):
3388linterms.append((var,_lincoefs[termidx]))
3390 fortermidx
inrange(_nbilinterms):
3394var1 = Variable.create(scipvar1)
3395var2 = Variable.create(scipvar2)
3396 ifscipvar1 != scipvar2:
3397bilinterms.append((var1,var2,bilincoef))
3399quadterms.append((var1,bilincoef,0.0))
3401 fortermidx
inrange(_nquadterms):
3406quadterms.append((var,sqrcoef,lincoef))
3408 return(bilinterms, quadterms, linterms)
3411 """sets the value of the given variable in the global relaxation solution""" 3415 """Retrieve all constraints. 3417 :param transformed: get transformed variables instead of original (Default value = True) 3419cdef SCIP_CONS** _conss
3429 return[Constraint.create(_conss[i])
fori
inrange(_nconss)]
3432 """Retrieve number of all constraints""" 3439 """Delete constraint from the model 3441 :param Constraint cons: constraint to be deleted 3447 """Delete constraint from the current node and it's children 3449 :param Constraint cons: constraint to be deleted 3455 """Retrieve the coefficients of a linear constraint 3457 :param Constraint cons: linear constraint to get the coefficients of 3460cdef SCIP_Real* _vals
3461cdef SCIP_VAR** _vars
3464 if notconstype ==
'linear':
3465 raiseWarning(
"coefficients not available for constraints of type ", constype)
3472valsdict[bytes(
SCIPvarGetName(_vars[i])).decode(
'utf-8')] = _vals[i]
3476 """Retrieve the linear relaxation of the given linear constraint as a row. 3477 may return NULL if no LP row was yet created; the user must not modify the row! 3479 :param Constraint cons: linear constraint to get the coefficients of 3483 if notconstype ==
'linear':
3484 raiseWarning(
"coefficients not available for constraints of type ", constype)
3487 returnRow.create(row)
3490 """Retrieve the dual solution to a linear constraint. 3492 :param Constraint cons: linear constraint 3496 if notconstype ==
'linear':
3497 raiseWarning(
"dual solution values not available for constraints of type ", constype)
3498 ifcons.isOriginal():
3505 """DEPRECATED: Retrieve the dual solution to a linear constraint. 3507 :param Constraint cons: linear constraint 3510 raiseWarning(
"model.getDualMultiplier(cons) is deprecated: please use model.getDualsolLinear(cons)")
3514 """Retrieve the dual farkas value to a linear constraint. 3516 :param Constraint cons: linear constraint 3520 ifcons.isOriginal():
3527 """Retrieve the reduced cost of a variable. 3529 :param Variable var: variable to get the reduced cost of 3538 raiseWarning(
"no reduced cost available for variable "+ var.name)
3542 """Retrieve returns dual solution value of a constraint. 3544 :param Constraint cons: constraint to get the dual solution value of 3545 :param boundconstraint bool: Decides whether to store a bool if the constraint is a bound constraint 3548cdef SCIP_Real _dualsol
3549cdef SCIP_Bool _bounded
3559 """Optimize the problem.""" 3564 """Transforms, presolves, and solves problem using additional solvers which emphasize on 3565 finding solutions.""" 3566 ifSCIPtpiGetNumThreads() == 1:
3567warnings.warn(
"SCIP was compiled without task processing interface. Parallel solve not possible - using optimize() instead of solveConcurrent()")
3574 """Presolve the problem.""" 3580 """initialises the default Benders' decomposition with a dictionary of subproblems 3583 subproblems -- a single Model instance or dictionary of Model instances 3585cdef SCIP** subprobs
3586cdef SCIP_BENDERS* benders
3589 ifisinstance(subproblems, dict):
3591nsubproblems = len(subproblems)
3597subprobs = <SCIP**> malloc(nsubproblems * sizeof(SCIP*))
3601 foridx, subprob
inenumerate(subproblems.values()):
3602subprobs[idx] = (<Model>subprob)._scip
3604subprobs[0] = (<Model>subproblems)._scip
3611self.
setBoolParam(
"constraints/benderslp/active",
True)
3612self.
setBoolParam(
"constraints/benders/active",
True)
3616 """Solves the subproblems with the best solution to the master problem. 3617 Afterwards, the best solution from each subproblem can be queried to get 3618 the solution to the original problem. 3620 If the user wants to resolve the subproblems, they must free them by 3621 calling freeBendersSubproblems() 3623cdef SCIP_BENDERS** _benders
3624cdef SCIP_Bool _infeasible
3626cdef int nsubproblems
3634 fori
inrange(nbenders):
3636 forj
inrange(nsubproblems):
3638_benders[i], self.
_bestSol.sol, j, SCIP_BENDERSENFOTYPE_CHECK))
3640_benders[i], self.
_bestSol.sol, j, &_infeasible, solvecip, NULL))
3643 """Calls the free subproblem function for the Benders' decomposition. 3644 This will free all subproblems for all decompositions. 3646cdef SCIP_BENDERS** _benders
3648cdef int nsubproblems
3654 fori
inrange(nbenders):
3656 forj
inrange(nsubproblems):
3661 """"updates the subproblem lower bounds for benders using 3662 the lowerbounds dict. If benders is None, then the default 3663 Benders' decomposition is updated 3665cdef SCIP_BENDERS* _benders
3667 asserttype(lowerbounds)
isdict
3669 ifbenders
is None:
3672_benders = benders._benders
3674 ford
inlowerbounds.keys():
3678 """Activates the Benders' decomposition plugin with the input name 3681 benders -- the Benders' decomposition to which the subproblem belongs to 3682 nsubproblems -- the number of subproblems in the Benders' decomposition 3687 """adds a subproblem to the Benders' decomposition given by the input 3691 benders -- the Benders' decomposition to which the subproblem belongs to 3692 subproblem -- the subproblem to add to the decomposition 3693 isconvex -- can be used to specify whether the subproblem is convex 3698 """sets a flag indicating whether the subproblem is convex 3701 benders -- the Benders' decomposition which contains the subproblem 3702 probnumber -- the problem number of the subproblem that the convexity will be set for 3703 isconvex -- flag to indicate whether the subproblem is convex 3707 def setupBendersSubproblem(self, probnumber, Benders benders = None, Solution solution = None, checktype = PY_SCIP_BENDERSENFOTYPE.LP):
3708 """ sets up the Benders' subproblem given the master problem solution 3711 probnumber -- the index of the problem that is to be set up 3712 benders -- the Benders' decomposition to which the subproblem belongs to 3713 solution -- the master problem solution that is used for the set up, if None, then the LP solution is used 3714 checktype -- the type of solution check that prompted the solving of the Benders' subproblems, either 3715 PY_SCIP_BENDERSENFOTYPE: LP, RELAX, PSEUDO or CHECK. Default is LP 3717cdef SCIP_BENDERS* scip_benders
3718cdef SCIP_SOL* scip_sol
3720 ifisinstance(solution, Solution):
3721scip_sol = solution.sol
3725 ifbenders
is None:
3728scip_benders = benders._benders
3732PY_SCIP_CALL(retcode)
3735 """ solves the Benders' decomposition subproblem. The convex relaxation will be solved unless 3736 the parameter solvecip is set to True. 3739 probnumber -- the index of the problem that is to be set up 3740 solvecip -- should the CIP of the subproblem be solved, if False, then only the convex relaxation is solved 3741 benders -- the Benders' decomposition to which the subproblem belongs to 3742 solution -- the master problem solution that is used for the set up, if None, then the LP solution is used 3745cdef SCIP_BENDERS* scip_benders
3746cdef SCIP_SOL* scip_sol
3747cdef SCIP_Real objective
3748cdef SCIP_Bool infeasible
3750 ifisinstance(solution, Solution):
3751scip_sol = solution.sol
3755 ifbenders
is None:
3758scip_benders = benders._benders
3761probnumber, &infeasible, solvecip, &objective))
3763 returninfeasible, objective
3766 """Returns a Model object that wraps around the SCIP instance of the subproblem. 3767 NOTE: This Model object is just a place holder and SCIP instance will not be freed when the object is destroyed. 3770 probnumber -- the problem number for subproblem that is required 3771 benders -- the Benders' decomposition object for the that the subproblem belongs to (Default = None) 3773cdef SCIP_BENDERS* scip_benders
3774cdef SCIP* scip_subprob
3776 ifbenders
is None:
3779scip_benders = benders._benders
3783 returnModel.create(scip_subprob)
3785 def getBendersVar(self, Variable var, Benders benders = None, probnumber = -1):
3786 """Returns the variable for the subproblem or master problem 3787 depending on the input probnumber 3790 var -- the source variable for which the target variable is requested 3791 benders -- the Benders' decomposition to which the subproblem variables belong to 3792 probnumber -- the problem number for which the target variable belongs, -1 for master problem 3794cdef SCIP_BENDERS* _benders
3795cdef SCIP_VAR* _mappedvar
3797 ifbenders
is None:
3800_benders = benders._benders
3802 ifprobnumber == -1:
3807 if_mappedvar == NULL:
3810mappedvar = Variable.create(_mappedvar)
3815 """Returns the auxiliary variable that is associated with the input problem number 3818 probnumber -- the problem number for which the target variable belongs, -1 for master problem 3819 benders -- the Benders' decomposition to which the subproblem variables belong to 3821cdef SCIP_BENDERS* _benders
3822cdef SCIP_VAR* _auxvar
3824 ifbenders
is None:
3827_benders = benders._benders
3830auxvar = Variable.create(_auxvar)
3835 """Returns whether the subproblem is optimal w.r.t the master problem auxiliary variables. 3838 solution -- the master problem solution that is being checked for optimamlity 3839 probnumber -- the problem number for which optimality is being checked 3840 benders -- the Benders' decomposition to which the subproblem belongs to 3842cdef SCIP_BENDERS* _benders
3843cdef SCIP_SOL* scip_sol
3844cdef SCIP_Bool optimal
3846 ifbenders
is None:
3849_benders = benders._benders
3851 ifisinstance(solution, Solution):
3852scip_sol = solution.sol
3857scip_sol, probnumber, &optimal) )
3862 """includes the default Benders' decomposition cuts to the custom Benders' decomposition plugin 3865 benders -- the Benders' decomposition that the default cuts will be applied to 3867PY_SCIP_CALL( SCIPincludeBendersDefaultCuts(self.
_scip, benders._benders) )
3871 """Include an event handler. 3874 eventhdlr -- event handler 3875 name -- name of event handler 3876 desc -- description of event handler 3889<SCIP_EVENTHDLRDATA*>eventhdlr))
3890eventhdlr.model = <Model>weakref.proxy(self)
3891eventhdlr.name = name
3892Py_INCREF(eventhdlr)
3895 """Include a pricer. 3897 :param Pricer pricer: pricer 3898 :param name: name of pricer 3899 :param desc: description of pricer 3900 :param priority: priority of pricer (Default value = 1) 3901 :param delay: should the pricer be delayed until no other pricers or already existing problem variables with negative reduced costs are found? (Default value = True) 3908PyPricerCopy, PyPricerFree, PyPricerInit, PyPricerExit, PyPricerInitsol, PyPricerExitsol, PyPricerRedcost, PyPricerFarkas,
3909<SCIP_PRICERDATA*>pricer))
3910cdef SCIP_PRICER* scip_pricer
3913pricer.model = <Model>weakref.proxy(self)
3917enfopriority=0, chckpriority=0, sepafreq=-1, propfreq=-1,
3918eagerfreq=100, maxprerounds=-1, delaysepa=False,
3919delayprop=False, needscons=True,
3920proptiming=PY_SCIP_PROPTIMING.BEFORELP,
3921presoltiming=PY_SCIP_PRESOLTIMING.MEDIUM):
3922 """Include a constraint handler 3924 :param Conshdlr conshdlr: constraint handler 3925 :param name: name of constraint handler 3926 :param desc: description of constraint handler 3927 :param sepapriority: priority for separation (Default value = 0) 3928 :param enfopriority: priority for constraint enforcing (Default value = 0) 3929 :param chckpriority: priority for checking feasibility (Default value = 0) 3930 :param sepafreq: frequency for separating cuts; 0 = only at root node (Default value = -1) 3931 :param propfreq: frequency for propagating domains; 0 = only preprocessing propagation (Default value = -1) 3932 :param eagerfreq: frequency for using all instead of only the useful constraints in separation, propagation and enforcement; -1 = no eager evaluations, 0 = first only (Default value = 100) 3933 :param maxprerounds: maximal number of presolving rounds the constraint handler participates in (Default value = -1) 3934 :param delaysepa: should separation method be delayed, if other separators found cuts? (Default value = False) 3935 :param delayprop: should propagation method be delayed, if other propagators found reductions? (Default value = False) 3936 :param needscons: should the constraint handler be skipped, if no constraints are available? (Default value = True) 3937 :param proptiming: positions in the node solving loop where propagation method of constraint handlers should be executed (Default value = SCIP_PROPTIMING.BEFORELP) 3938 :param presoltiming: timing mask of the constraint handler's presolving method (Default value = SCIP_PRESOLTIMING.MEDIUM) 3943PY_SCIP_CALL(
SCIPincludeConshdlr(self.
_scip, n, d, sepapriority, enfopriority, chckpriority, sepafreq, propfreq, eagerfreq,
3944maxprerounds, delaysepa, delayprop, needscons, proptiming, presoltiming,
3945PyConshdlrCopy, PyConsFree, PyConsInit, PyConsExit, PyConsInitpre, PyConsExitpre,
3946PyConsInitsol, PyConsExitsol, PyConsDelete, PyConsTrans, PyConsInitlp, PyConsSepalp, PyConsSepasol,
3947PyConsEnfolp, PyConsEnforelax, PyConsEnfops, PyConsCheck, PyConsProp, PyConsPresol, PyConsResprop, PyConsLock,
3948PyConsActive, PyConsDeactive, PyConsEnable, PyConsDisable, PyConsDelvars, PyConsPrint, PyConsCopy,
3949PyConsParse, PyConsGetvars, PyConsGetnvars, PyConsGetdivebdchgs, PyConsGetPermSymGraph, PyConsGetSignedPermSymGraph,
3950<SCIP_CONSHDLRDATA*>conshdlr))
3951conshdlr.model = <Model>weakref.proxy(self)
3952conshdlr.name = name
3955 def createCons(self, Conshdlr conshdlr, name, initial=True, separate=True, enforce=True, check=True, propagate=True,
3956local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False):
3957 """Create a constraint of a custom constraint handler 3959 :param Conshdlr conshdlr: constraint handler 3960 :param name: name of constraint 3961 :param initial: (Default value = True) 3962 :param separate: (Default value = True) 3963 :param enforce: (Default value = True) 3964 :param check: (Default value = True) 3965 :param propagate: (Default value = True) 3966 :param local: (Default value = False) 3967 :param modifiable: (Default value = False) 3968 :param dynamic: (Default value = False) 3969 :param removable: (Default value = False) 3970 :param stickingatnode: (Default value = False) 3975cdef SCIP_CONSHDLR* scip_conshdlr
3978PY_SCIP_CALL(
SCIPcreateCons(self.
_scip, &(constraint.scip_cons), n, scip_conshdlr, <SCIP_CONSDATA*>constraint,
3979initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
3982 def includePresol(self, Presol presol, name, desc, priority, maxrounds, timing=SCIP_PRESOLTIMING_FAST):
3983 """Include a presolver 3985 :param Presol presol: presolver 3986 :param name: name of presolver 3987 :param desc: description of presolver 3988 :param priority: priority of the presolver (>= 0: before, < 0: after constraint handlers) 3989 :param maxrounds: maximal number of presolving rounds the presolver participates in (-1: no limit) 3990 :param timing: timing mask of presolver (Default value = SCIP_PRESOLTIMING_FAST) 3995PY_SCIP_CALL(
SCIPincludePresol(self.
_scip, n, d, priority, maxrounds, timing, PyPresolCopy, PyPresolFree, PyPresolInit,
3996PyPresolExit, PyPresolInitpre, PyPresolExitpre, PyPresolExec, <SCIP_PRESOLDATA*>presol))
3997presol.model = <Model>weakref.proxy(self)
4000 def includeSepa(self, Sepa sepa, name, desc, priority=0, freq=10, maxbounddist=1.0, usessubscip=False, delay=False):
4001 """Include a separator 4003 :param Sepa sepa: separator 4004 :param name: name of separator 4005 :param desc: description of separator 4006 :param priority: priority of separator (>= 0: before, < 0: after constraint handlers) 4007 :param freq: frequency for calling separator 4008 :param maxbounddist: maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying separation 4009 :param usessubscip: does the separator use a secondary SCIP instance? (Default value = False) 4010 :param delay: should separator be delayed, if other separators found cuts? (Default value = False) 4015PY_SCIP_CALL(
SCIPincludeSepa(self.
_scip, n, d, priority, freq, maxbounddist, usessubscip, delay, PySepaCopy, PySepaFree,
4016PySepaInit, PySepaExit, PySepaInitsol, PySepaExitsol, PySepaExeclp, PySepaExecsol, <SCIP_SEPADATA*>sepa))
4017sepa.model = <Model>weakref.proxy(self)
4024 :param Reader reader: reader 4025 :param name: name of reader 4026 :param desc: description of reader 4027 :param ext: file extension of reader 4034PyReaderRead, PyReaderWrite, <SCIP_READERDATA*>reader))
4035reader.model = <Model>weakref.proxy(self)
4039 def includeProp(self, Prop prop, name, desc, presolpriority, presolmaxrounds,
4040proptiming, presoltiming=SCIP_PRESOLTIMING_FAST, priority=1, freq=1, delay=True):
4041 """Include a propagator. 4043 :param Prop prop: propagator 4044 :param name: name of propagator 4045 :param desc: description of propagator 4046 :param presolpriority: presolving priority of the propgator (>= 0: before, < 0: after constraint handlers) 4047 :param presolmaxrounds: maximal number of presolving rounds the propagator participates in (-1: no limit) 4048 :param proptiming: positions in the node solving loop where propagation method of constraint handlers should be executed 4049 :param presoltiming: timing mask of the constraint handler's presolving method (Default value = SCIP_PRESOLTIMING_FAST) 4050 :param priority: priority of the propagator (Default value = 1) 4051 :param freq: frequency for calling propagator (Default value = 1) 4052 :param delay: should propagator be delayed if other propagators have found reductions? (Default value = True) 4058priority, freq, delay,
4059proptiming, presolpriority, presolmaxrounds,
4060presoltiming, PyPropCopy, PyPropFree, PyPropInit, PyPropExit,
4061PyPropInitpre, PyPropExitpre, PyPropInitsol, PyPropExitsol,
4062PyPropPresol, PyPropExec, PyPropResProp,
4063<SCIP_PROPDATA*> prop))
4064prop.model = <Model>weakref.proxy(self)
4067 def includeHeur(self, Heur heur, name, desc, dispchar, priority=10000, freq=1, freqofs=0,
4068maxdepth=-1, timingmask=SCIP_HEURTIMING_BEFORENODE, usessubscip=False):
4069 """Include a primal heuristic. 4071 :param Heur heur: heuristic 4072 :param name: name of heuristic 4073 :param desc: description of heuristic 4074 :param dispchar: display character of heuristic 4075 :param priority: priority of the heuristic (Default value = 10000) 4076 :param freq: frequency for calling heuristic (Default value = 1) 4077 :param freqofs: frequency offset for calling heuristic (Default value = 0) 4078 :param maxdepth: maximal depth level to call heuristic at (Default value = -1) 4079 :param timingmask: positions in the node solving loop where heuristic should be executed (Default value = SCIP_HEURTIMING_BEFORENODE) 4080 :param usessubscip: does the heuristic use a secondary SCIP instance? (Default value = False) 4087priority, freq, freqofs,
4088maxdepth, timingmask, usessubscip,
4089PyHeurCopy, PyHeurFree, PyHeurInit, PyHeurExit,
4090PyHeurInitsol, PyHeurExitsol, PyHeurExec,
4091<SCIP_HEURDATA*> heur))
4092heur.model = <Model>weakref.proxy(self)
4097 """Include a relaxation handler. 4099 :param Relax relax: relaxation handler 4100 :param name: name of relaxation handler 4101 :param desc: description of relaxation handler 4102 :param priority: priority of the relaxation handler (negative: after LP, non-negative: before LP, Default value = 10000) 4103 :param freq: frequency for calling relaxation handler 4108PY_SCIP_CALL(
SCIPincludeRelax(self.
_scip, nam, des, priority, freq, PyRelaxCopy, PyRelaxFree, PyRelaxInit, PyRelaxExit,
4109PyRelaxInitsol, PyRelaxExitsol, PyRelaxExec, <SCIP_RELAXDATA*> relax))
4110relax.model = <Model>weakref.proxy(self)
4116 """include a cut selector 4118 :param Cutsel cutsel: cut selector 4119 :param name: name of cut selector 4120 :param desc: description of cut selector 4121 :param priority: priority of the cut selector 4127priority, PyCutselCopy, PyCutselFree, PyCutselInit, PyCutselExit,
4128PyCutselInitsol, PyCutselExitsol, PyCutselSelect,
4129<SCIP_CUTSELDATA*> cutsel))
4130cutsel.model = <Model>weakref.proxy(self)
4134 """Include a branching rule. 4136 :param Branchrule branchrule: branching rule 4137 :param name: name of branching rule 4138 :param desc: description of branching rule 4139 :param priority: priority of branching rule 4140 :param maxdepth: maximal depth level up to which this branching rule should be used (or -1) 4141 :param maxbounddist: maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying branching rule (0.0: only on current best node, 1.0: on all nodes) 4147priority, maxdepth, maxbounddist,
4148PyBranchruleCopy, PyBranchruleFree, PyBranchruleInit, PyBranchruleExit,
4149PyBranchruleInitsol, PyBranchruleExitsol, PyBranchruleExeclp, PyBranchruleExecext,
4150PyBranchruleExecps, <SCIP_BRANCHRULEDATA*> branchrule))
4151branchrule.model = <Model>weakref.proxy(self)
4152Py_INCREF(branchrule)
4154 def includeNodesel(self, Nodesel nodesel, name, desc, stdpriority, memsavepriority):
4155 """Include a node selector. 4157 :param Nodesel nodesel: node selector 4158 :param name: name of node selector 4159 :param desc: description of node selector 4160 :param stdpriority: priority of the node selector in standard mode 4161 :param memsavepriority: priority of the node selector in memory saving mode 4167stdpriority, memsavepriority,
4168PyNodeselCopy, PyNodeselFree, PyNodeselInit, PyNodeselExit,
4169PyNodeselInitsol, PyNodeselExitsol, PyNodeselSelect, PyNodeselComp,
4170<SCIP_NODESELDATA*> nodesel))
4171nodesel.model = <Model>weakref.proxy(self)
4174 def includeBenders(self, Benders benders, name, desc, priority=1, cutlp=True, cutpseudo=True, cutrelax=True,
4176 """Include a Benders' decomposition. 4179 benders -- the Benders decomposition 4181 desc -- the description 4182 priority -- priority of the Benders' decomposition 4183 cutlp -- should Benders' cuts be generated from LP solutions 4184 cutpseudo -- should Benders' cuts be generated from pseudo solutions 4185 cutrelax -- should Benders' cuts be generated from relaxation solutions 4186 shareaux -- should the Benders' decomposition share the auxiliary variables of the highest priority Benders' decomposition 4191priority, cutlp, cutrelax, cutpseudo, shareaux,
4192PyBendersCopy, PyBendersFree, PyBendersInit, PyBendersExit, PyBendersInitpre,
4193PyBendersExitpre, PyBendersInitsol, PyBendersExitsol, PyBendersGetvar,
4194PyBendersCreatesub, PyBendersPresubsolve, PyBendersSolvesubconvex,
4195PyBendersSolvesub, PyBendersPostsolve, PyBendersFreesub,
4196<SCIP_BENDERSDATA*>benders))
4197cdef SCIP_BENDERS* scip_benders
4199benders.model = <Model>weakref.proxy(self)
4201benders._benders = scip_benders
4204 def includeBenderscut(self, Benders benders, Benderscut benderscut, name, desc, priority=1, islpcut=True):
4205 """ Include a Benders' decomposition cutting method 4208 benders -- the Benders' decomposition that this cutting method is attached to 4209 benderscut --- the Benders' decomposition cutting method 4211 desc -- the description 4212 priority -- priority of the Benders' decomposition 4213 islpcut -- is this cutting method suitable for generating cuts for convex relaxations? 4215cdef SCIP_BENDERS* _benders
4217_benders = benders._benders
4222PyBenderscutCopy, PyBenderscutFree, PyBenderscutInit, PyBenderscutExit,
4223PyBenderscutInitsol, PyBenderscutExitsol, PyBenderscutExec,
4224<SCIP_BENDERSCUTDATA*>benderscut))
4226cdef SCIP_BENDERSCUT* scip_benderscut
4228benderscut.model = <Model>weakref.proxy(self)
4229benderscut.benders = benders
4230benderscut.name = name
4232Py_INCREF(benderscut)
4236 """gets branching candidates for LP solution branching (fractional variables) along with solution values, 4237 fractionalities, and number of branching candidates; The number of branching candidates does NOT account 4238 for fractional implicit integer variables which should not be used for branching decisions. Fractional 4239 implicit integer variables are stored at the positions *nlpcands to *nlpcands + *nfracimplvars - 1 4240 branching rules should always select the branching candidate among the first npriolpcands of the candidate list 4242 :return tuple (lpcands, lpcandssol, lpcadsfrac, nlpcands, npriolpcands, nfracimplvars) where 4244 lpcands: list of variables of LP branching candidates 4245 lpcandssol: list of LP candidate solution values 4246 lpcandsfrac list of LP candidate fractionalities 4247 nlpcands: number of LP branching candidates 4248 npriolpcands: number of candidates with maximal priority 4249 nfracimplvars: number of fractional implicit integer variables 4254cdef int npriolpcands
4255cdef int nfracimplvars
4257cdef SCIP_VAR** lpcands
4258cdef SCIP_Real* lpcandssol
4259cdef SCIP_Real* lpcandsfrac
4262&nlpcands, &npriolpcands, &nfracimplvars))
4264 return([Variable.create(lpcands[i])
fori
inrange(nlpcands)], [lpcandssol[i]
fori
inrange(nlpcands)],
4265[lpcandsfrac[i]
fori
inrange(nlpcands)], nlpcands, npriolpcands, nfracimplvars)
4268 """gets branching candidates for pseudo solution branching (non-fixed variables) 4269 along with the number of candidates. 4271 :return tuple (pseudocands, npseudocands, npriopseudocands) where 4273 pseudocands: list of variables of pseudo branching candidates 4274 npseudocands: number of pseudo branching candidates 4275 npriopseudocands: number of candidates with maximal priority 4278cdef int npseudocands
4279cdef int npriopseudocands
4281cdef SCIP_VAR** pseudocands
4285 return([Variable.create(pseudocands[i])
fori
inrange(npseudocands)], npseudocands, npriopseudocands)
4288 """Branch on a non-continuous variable. 4290 :param variable: Variable to branch on 4291 :return: tuple(downchild, eqchild, upchild) of Nodes of the left, middle and right child. Middle child only exists 4292 if branch variable is integer (it is None otherwise) 4295cdef SCIP_NODE* downchild
4296cdef SCIP_NODE* eqchild
4297cdef SCIP_NODE* upchild
4299PY_SCIP_CALL(
SCIPbranchVar(self.
_scip, (<Variable>variable).scip_var, &downchild, &eqchild, &upchild))
4300 returnNode.create(downchild), Node.create(eqchild), Node.create(upchild)
4304 """Branches on variable using a value which separates the domain of the variable. 4306 :param variable: Variable to branch on 4307 :param value: float, value to branch on 4308 :return: tuple(downchild, eqchild, upchild) of Nodes of the left, middle and right child. Middle child only exists 4309 if branch variable is integer (it is None otherwise) 4312cdef SCIP_NODE* downchild
4313cdef SCIP_NODE* eqchild
4314cdef SCIP_NODE* upchild
4316PY_SCIP_CALL(
SCIPbranchVarVal(self.
_scip, (<Variable>variable).scip_var, value, &downchild, &eqchild, &upchild))
4318 returnNode.create(downchild), Node.create(eqchild), Node.create(upchild)
4321 """calculates the node selection priority for moving the given variable's LP value 4322 to the given target value; 4323 this node selection priority can be given to the SCIPcreateChild() call 4325 :param variable: variable on which the branching is applied 4326 :param branchdir: type of branching that was performed 4327 :param targetvalue: new value of the variable in the child node 4328 :return: node selection priority for moving the given variable's LP value to the given target value 4334 """Calculates an estimate for the objective of the best feasible solution 4335 contained in the subtree after applying the given branching; 4336 this estimate can be given to the SCIPcreateChild() call 4338 :param variable: Variable to compute the estimate for 4339 :param targetvalue: new value of the variable in the child node 4340 :return: objective estimate of the best solution in the subtree after applying the given branching 4346 """Create a child node of the focus node. 4348 :param nodeselprio: float, node selection priority of new node 4349 :param estimate: float, estimate for(transformed) objective value of best feasible solution in subtree 4350 :return: Node, the child which was created 4353cdef SCIP_NODE* child
4355 returnNode.create(child)
4359 """Initiates LP diving 4360 It allows the user to change the LP in several ways, solve, change again, etc, without affecting the actual LP that has. When endDive() is called, 4361 SCIP will undo all changes done and recover the LP it had before startDive 4366 """Quits probing and resets bounds and constraints to the focus node's environment""" 4370 """changes (column) variable's objective value in current dive""" 4374 """changes variable's current lb in current dive""" 4378 """changes variable's current ub in current dive""" 4382 """returns variable's current lb in current dive""" 4386 """returns variable's current ub in current dive""" 4390 """changes row lhs in current dive, change will be undone after diving 4391 ends, for permanent changes use SCIPchgRowLhs() 4396 """changes row rhs in current dive, change will be undone after diving 4397 ends, for permanent changes use SCIPchgRowLhs() 4402 """adds a row to the LP in current dive""" 4406 """solves the LP of the current dive no separation or pricing is applied 4407 no separation or pricing is applied 4408 :param itlim: maximal number of LP iterations to perform (Default value = -1, that is, no limit) 4409 returns two booleans: 4410 lperror -- if an unresolved lp error occured 4411 cutoff -- whether the LP was infeasible or the objective limit was reached 4413cdef SCIP_Bool lperror
4414cdef SCIP_Bool cutoff
4417 returnlperror, cutoff
4420 """returns if the current node is already solved and only propagated again.""" 4425 """Initiates probing, making methods SCIPnewProbingNode(), SCIPbacktrackProbing(), SCIPchgVarLbProbing(), 4426 SCIPchgVarUbProbing(), SCIPfixVarProbing(), SCIPpropagateProbing(), SCIPsolveProbingLP(), etc available 4431 """Quits probing and resets bounds and constraints to the focus node's environment""" 4435 """creates a new probing sub node, whose changes can be undone by backtracking to a higher node in the 4436 probing path with a call to backtrackProbing() 4441 """undoes all changes to the problem applied in probing up to the given probing depth 4442 :param probingdepth: probing depth of the node in the probing path that should be reactivated 4447 """returns the current probing depth""" 4451 """changes (column) variable's objective value during probing mode""" 4455 """changes the variable lower bound during probing mode 4457 :param Variable var: variable to change bound of 4458 :param lb: new lower bound (set to None for -infinity) 4465 """changes the variable upper bound during probing mode 4467 :param Variable var: variable to change bound of 4468 :param ub: new upper bound (set to None for +infinity) 4475 """Fixes a variable at the current probing node.""" 4479 """returns whether the objective function has changed during probing mode""" 4483 """returns whether we are in probing mode; probing mode is activated via startProbing() and stopped via endProbing()""" 4487 """solves the LP at the current probing node (cannot be applied at preprocessing stage) 4488 no separation or pricing is applied 4489 :param itlim: maximal number of LP iterations to perform (Default value = -1, that is, no limit) 4490 returns two booleans: 4491 lperror -- if an unresolved lp error occured 4492 cutoff -- whether the LP was infeasible or the objective limit was reached 4494cdef SCIP_Bool lperror
4495cdef SCIP_Bool cutoff
4498 returnlperror, cutoff
4501 """applies the cuts in the separation storage to the LP and clears the storage afterwards; 4502 this method can only be applied during probing; the user should resolve the probing LP afterwards 4503 in order to get a new solution 4505 cutoff -- whether an empty domain was created 4507cdef SCIP_Bool cutoff
4513 """applies domain propagation on the probing sub problem, that was changed after SCIPstartProbing() was called; 4514 the propagated domains of the variables can be accessed with the usual bound accessing calls SCIPvarGetLbLocal() 4515 and SCIPvarGetUbLocal(); the propagation is only valid locally, i.e. the local bounds as well as the changed 4516 bounds due to SCIPchgVarLbProbing(), SCIPchgVarUbProbing(), and SCIPfixVarProbing() are used for propagation 4517 :param maxproprounds: maximal number of propagation rounds (Default value = -1, that is, no limit) 4519 cutoff -- whether the probing node can be cutoff 4520 ndomredsfound -- number of domain reductions found 4522cdef SCIP_Bool cutoff
4523cdef SCIP_Longint ndomredsfound
4526 returncutoff, ndomredsfound
4529 """Interrupt the solving process as soon as possible.""" 4533 """Restarts the solving process as soon as possible.""" 4539 """writes current LP to a file 4540 :param filename: file name (Default value = "LP.lp") 4542user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4543locale.setlocale(locale.LC_NUMERIC,
"C")
4548locale.setlocale(locale.LC_NUMERIC,user_locale)
4551 """Create a new primal solution in the transformed space. 4553 :param Heur heur: heuristic that found the solution (Default value = None) 4556cdef SCIP_HEUR* _heur
4559 ifisinstance(heur, Heur):
4565solution = Solution.create(self.
_scip, _sol)
4569 """Create a partial primal solution, initialized to unknown values. 4570 :param Heur heur: heuristic that found the solution (Default value = None) 4573cdef SCIP_HEUR* _heur
4576 ifisinstance(heur, Heur):
4582partialsolution = Solution.create(self.
_scip, _sol)
4583 returnpartialsolution
4586 """Create a new primal solution in the original space. 4588 :param Heur heur: heuristic that found the solution (Default value = None) 4591cdef SCIP_HEUR* _heur
4594 ifisinstance(heur, Heur):
4601solution = Solution.create(self.
_scip, _sol)
4605 """Prints the best feasible primal solution.""" 4606user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4607locale.setlocale(locale.LC_NUMERIC,
"C")
4611locale.setlocale(locale.LC_NUMERIC,user_locale)
4613 def printSol(self, Solution solution=None, write_zeros=False):
4614 """Print the given primal solution. 4617 solution -- solution to print 4618 write_zeros -- include variables that are set to zero 4621user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4622locale.setlocale(locale.LC_NUMERIC,
"C")
4624 ifsolution
is None:
4629locale.setlocale(locale.LC_NUMERIC,user_locale)
4632 """Write the best feasible primal solution to a file. 4635 filename -- name of the output file 4636 write_zeros -- include variables that are set to zero 4639user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4640locale.setlocale(locale.LC_NUMERIC,
"C")
4644 withopen(filename,
"w")
asf:
4645cfile = fdopen(f.fileno(),
"w")
4648locale.setlocale(locale.LC_NUMERIC,user_locale)
4651 """Write the best feasible primal solution for the transformed problem to a file. 4654 filename -- name of the output file 4655 write_zeros -- include variables that are set to zero 4657user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4658locale.setlocale(locale.LC_NUMERIC,
"C")
4662 withopen(filename,
"w")
asf:
4663cfile = fdopen(f.fileno(),
"w")
4666locale.setlocale(locale.LC_NUMERIC,user_locale)
4668 def writeSol(self, Solution solution, filename="origprob.sol", write_zeros=False):
4669 """Write the given primal solution to a file. 4672 solution -- solution to write 4673 filename -- name of the output file 4674 write_zeros -- include variables that are set to zero 4676user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4677locale.setlocale(locale.LC_NUMERIC,
"C")
4681 withopen(filename,
"w")
asf:
4682cfile = fdopen(f.fileno(),
"w")
4685locale.setlocale(locale.LC_NUMERIC,user_locale)
4687 def writeTransSol(self, Solution solution, filename="transprob.sol", write_zeros=False):
4688 """Write the given transformed primal solution to a file. 4691 solution -- transformed solution to write 4692 filename -- name of the output file 4693 write_zeros -- include variables that are set to zero 4695user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4696locale.setlocale(locale.LC_NUMERIC,
"C")
4700 withopen(filename,
"w")
asf:
4701cfile = fdopen(f.fileno(),
"w")
4704locale.setlocale(locale.LC_NUMERIC,user_locale)
4709 """Reads a given solution file, problem has to be transformed in advance. 4712 filename -- name of the input file 4714user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4715locale.setlocale(locale.LC_NUMERIC,
"C")
4720locale.setlocale(locale.LC_NUMERIC, user_locale)
4723 """Reads a given solution file. 4725 Solution is created but not added to storage/the model. 4726 Use 'addSol' OR 'trySol' to add it. 4729 filename -- name of the input file 4731cdef SCIP_Bool partial
4732cdef SCIP_Bool error
4733cdef SCIP_Bool stored
4734cdef Solution solution
4736str_absfile = abspath(filename)
4740user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4741locale.setlocale(locale.LC_NUMERIC,
"C")
4745locale.setlocale(locale.LC_NUMERIC, user_locale)
4748 raiseException(
"SCIP: reading solution from file "+ str_absfile +
" failed!")
4753 """Set a variable in a solution. 4755 :param Solution solution: solution to be modified 4756 :param Variable var: variable in the solution 4757 :param val: value of the specified variable 4761_sol = <SCIP_SOL*>solution.sol
4763 assert_sol != NULL,
"Cannot set value to a freed solution." 4766 def trySol(self, Solution solution, printreason=True, completely=False, checkbounds=True, checkintegrality=True, checklprows=True, free=True):
4767 """Check given primal solution for feasibility and try to add it to the storage. 4769 :param Solution solution: solution to store 4770 :param printreason: should all reasons of violations be printed? (Default value = True) 4771 :param completely: should all violation be checked? (Default value = False) 4772 :param checkbounds: should the bounds of the variables be checked? (Default value = True) 4773 :param checkintegrality: has integrality to be checked? (Default value = True) 4774 :param checklprows: have current LP rows (both local and global) to be checked? (Default value = True) 4775 :param free: should solution be freed? (Default value = True) 4778cdef SCIP_Bool stored
4780PY_SCIP_CALL(
SCIPtrySolFree(self.
_scip, &solution.sol, printreason, completely, checkbounds, checkintegrality, checklprows, &stored))
4782PY_SCIP_CALL(
SCIPtrySol(self.
_scip, solution.sol, printreason, completely, checkbounds, checkintegrality, checklprows, &stored))
4785 def checkSol(self, Solution solution, printreason=True, completely=False, checkbounds=True, checkintegrality=True, checklprows=True, original=False):
4786 """Check given primal solution for feasibility without adding it to the storage. 4788 :param Solution solution: solution to store 4789 :param printreason: should all reasons of violations be printed? (Default value = True) 4790 :param completely: should all violation be checked? (Default value = False) 4791 :param checkbounds: should the bounds of the variables be checked? (Default value = True) 4792 :param checkintegrality: has integrality to be checked? (Default value = True) 4793 :param checklprows: have current LP rows (both local and global) to be checked? (Default value = True) 4794 :param original: must the solution be checked against the original problem (Default value = False) 4797cdef SCIP_Bool feasible
4801PY_SCIP_CALL(
SCIPcheckSol(self.
_scip, solution.sol, printreason, completely, checkbounds, checkintegrality, checklprows, &feasible))
4804 def addSol(self, Solution solution, free=True):
4805 """Try to add a solution to the storage. 4807 :param Solution solution: solution to store 4808 :param free: should solution be freed afterwards? (Default value = True) 4811cdef SCIP_Bool stored
4819 """Free given solution 4821 :param Solution solution: solution to be freed 4827 """gets number of feasible primal solutions stored in the solution storage in case the problem is transformed; 4828 in case the problem stage is SCIP_STAGE_PROBLEM, the number of solution in the original solution candidate 4834 """gets number of feasible primal solutions found so far""" 4838 """gets number of feasible primal solutions respecting the objective limit found so far""" 4842 """gets number of feasible primal solutions found so far, that improved the primal bound at the time they were found""" 4846 """Retrieve list of all feasible primal solutions stored in the solution storage.""" 4847cdef SCIP_SOL** _sols
4853 fori
inrange(nsols):
4854sols.append(Solution.create(self.
_scip, _sols[i]))
4859 """Retrieve currently best known feasible primal solution.""" 4864 """Retrieve the objective value of the solution. 4866 :param Solution sol: solution 4867 :param original: objective value in original space (Default value = True) 4871sol = Solution.create(self.
_scip, NULL)
4873sol._checkStage(
"getSolObjVal")
4883 """Get clock time, when this solution was found. 4885 :param Solution sol: solution 4891 """Retrieve the objective value of value of best solution. 4893 :param original: objective value in original space (Default value = True) 4897 ifself.
getStage() != SCIP_STAGE_SOLVING:
4898 raiseWarning(
"Without a solution, method can only be called in stage SOLVING.")
4903min_stage_requirement = SCIP_STAGE_PROBLEM
4905min_stage_requirement = SCIP_STAGE_TRANSFORMING
4907 if notself.
getStage() >= min_stage_requirement:
4908 raiseWarning(
"method cannot be called in stage %i."% self.
getStage)
4913 """Retrieve value of given variable or expression in the given solution or in 4914 the LP/pseudo solution if sol == None 4916 :param Solution sol: solution 4917 :param Expr expr: polynomial expression to query the value of 4919 Note: a variable is also an expression 4922 ifsol ==
None andisinstance(expr, Variable):
4923var = <Variable> expr
4926sol = Solution.create(self.
_scip, NULL)
4930 """Retrieve the value of the given variable or expression in the best known solution. 4931 Can only be called after solving is completed. 4933 :param Expr expr: polynomial expression to query the value of 4935 Note: a variable is also an expression 4937stage_check =
SCIPgetStage(self.
_scip)
not in[SCIP_STAGE_INIT, SCIP_STAGE_FREE]
4940 raiseWarning(
"Method cannot be called in stage ", self.
getStage())
4946 Returns whether a primal ray is stored that proves unboundedness of the LP relaxation 4952 Gets value of given variable in primal ray causing unboundedness of the LP relaxation 4960 Gets primal ray causing unboundedness of the LP relaxation 4968 fori
inrange(_nvars):
4974 """Retrieve the best primal bound.""" 4978 """Retrieve the best dual bound.""" 4982 """Retrieve the best root dual bound.""" 4986 """Write the name of the variable to the std out. 4988 :param Variable var: variable 4991user_locale = locale.getlocale(category=locale.LC_NUMERIC)
4992locale.setlocale(locale.LC_NUMERIC,
"C")
4996locale.setlocale(locale.LC_NUMERIC,user_locale)
4999 """Retrieve current SCIP stage""" 5003 """Returns name of current stage as string""" 5006 returnStageNames[self.
getStage()]
5008 def_getStageNames(self):
5009 """Gets names of stages""" 5010 forname
indir(PY_SCIP_STAGE):
5011attr = getattr(PY_SCIP_STAGE, name)
5012 ifisinstance(attr, int):
5013StageNames[attr] = name
5016 """Retrieve solution status.""" 5018 ifstat == SCIP_STATUS_OPTIMAL:
5020 elifstat == SCIP_STATUS_TIMELIMIT:
5022 elifstat == SCIP_STATUS_INFEASIBLE:
5024 elifstat == SCIP_STATUS_UNBOUNDED:
5026 elifstat == SCIP_STATUS_USERINTERRUPT:
5027 return "userinterrupt" 5028 elifstat == SCIP_STATUS_INFORUNBD:
5030 elifstat == SCIP_STATUS_NODELIMIT:
5032 elifstat == SCIP_STATUS_TOTALNODELIMIT:
5033 return "totalnodelimit" 5034 elifstat == SCIP_STATUS_STALLNODELIMIT:
5035 return "stallnodelimit" 5036 elifstat == SCIP_STATUS_GAPLIMIT:
5038 elifstat == SCIP_STATUS_MEMLIMIT:
5040 elifstat == SCIP_STATUS_SOLLIMIT:
5042 elifstat == SCIP_STATUS_BESTSOLLIMIT:
5043 return "bestsollimit" 5044 elifstat == SCIP_STATUS_RESTARTLIMIT:
5045 return "restartlimit" 5046 elifstat == SCIP_STATUS_PRIMALLIMIT:
5047 return "primallimit" 5048 elifstat == SCIP_STATUS_DUALLIMIT:
5054 """Retrieve objective sense.""" 5056 ifsense == SCIP_OBJSENSE_MAXIMIZE:
5058 elifsense == SCIP_OBJSENSE_MINIMIZE:
5064 """catches a global (not variable or row dependent) event""" 5065cdef SCIP_EVENTHDLR* _eventhdlr
5066 ifisinstance(eventhdlr, Eventhdlr):
5070 raiseWarning(
"event handler not found")
5076 """drops a global event (stops to track event)""" 5077cdef SCIP_EVENTHDLR* _eventhdlr
5078 ifisinstance(eventhdlr, Eventhdlr):
5082 raiseWarning(
"event handler not found")
5088 """catches an objective value or domain change event on the given transformed variable""" 5089cdef SCIP_EVENTHDLR* _eventhdlr
5090 ifisinstance(eventhdlr, Eventhdlr):
5094 raiseWarning(
"event handler not found")
5098 """drops an objective value or domain change event (stops to track event) on the given transformed variable""" 5099cdef SCIP_EVENTHDLR* _eventhdlr
5100 ifisinstance(eventhdlr, Eventhdlr):
5104 raiseWarning(
"event handler not found")
5108 """catches a row coefficient, constant, or side change event on the given row""" 5109cdef SCIP_EVENTHDLR* _eventhdlr
5110 ifisinstance(eventhdlr, Eventhdlr):
5114 raiseWarning(
"event handler not found")
5118 """drops a row coefficient, constant, or side change event (stops to track event) on the given row""" 5119cdef SCIP_EVENTHDLR* _eventhdlr
5120 ifisinstance(eventhdlr, Eventhdlr):
5124 raiseWarning(
"event handler not found")
5130 """Print statistics.""" 5131user_locale = locale.getlocale(category=locale.LC_NUMERIC)
5132locale.setlocale(locale.LC_NUMERIC,
"C")
5136locale.setlocale(locale.LC_NUMERIC,user_locale)
5139 """Write statistics to a file. 5142 filename -- name of the output file 5144user_locale = locale.getlocale(category=locale.LC_NUMERIC)
5145locale.setlocale(locale.LC_NUMERIC,
"C")
5149 withopen(filename,
"w")
asf:
5150cfile = fdopen(f.fileno(),
"w")
5153locale.setlocale(locale.LC_NUMERIC,user_locale)
5157 Given a .stats file of a solved model, reads it and returns an instance of the Statistics class 5158 holding some statistics. 5161 filename -- name of the input file 5164file = open(filename)
5165data = file.readlines()
5167 assert "problem is solved" indata[0],
"readStatistics can only be called if the problem was solved" 5168available_stats = [
"Total Time",
"solving",
"presolving",
"reading",
"copying",
5169 "Problem name",
"Variables",
"Constraints",
"number of runs",
5170 "nodes",
"Solutions found",
"First Solution",
"Primal Bound",
5171 "Dual Bound",
"Gap",
"primal-dual"]
5174 fori, line
inenumerate(data):
5175split_line = line.split(
":")
5176split_line[1] = split_line[1][:-1]
5177stat_name = split_line[0].strip()
5179 ifseen_cons == 2
andstat_name ==
"Constraints":
5182 ifstat_name
inavailable_stats:
5183cur_stat = split_line[0].strip()
5184relevant_value = split_line[1].strip()
5186 ifstat_name ==
"Variables":
5187relevant_value = relevant_value[:-1]
5189split_var = relevant_value.split(
"(")
5190var_stats[
"total"] = int(split_var[0])
5191split_var = split_var[1].split(
",")
5193 forvar_type
insplit_var:
5194split_result = var_type.strip().split(
" ")
5195var_stats[split_result[1]] = int(split_result[0])
5197 if "Original" indata[i-2]:
5198result[
"Variables"] = var_stats
5200result[
"Presolved Variables"] = var_stats
5204 ifstat_name ==
"Constraints":
5207split_con = relevant_value.split(
",")
5208 forcon_type
insplit_con:
5209split_result = con_type.strip().split(
" ")
5210con_stats[split_result[1]] = int(split_result[0])
5212 if "Original" indata[i-3]:
5213result[
"Constraints"] = con_stats
5215result[
"Presolved Constraints"] = con_stats
5218relevant_value = relevant_value.split(
" ")[0]
5219 ifstat_name ==
"Problem name":
5220 if "Original" indata[i-1]:
5221result[
"Problem name"] = relevant_value
5223result[
"Presolved Problem name"] = relevant_value
5226 ifstat_name ==
"Gap":
5227result[
"Gap (%)"] = float(relevant_value[:-1])
5230 if_is_number(relevant_value):
5231result[cur_stat] = float(relevant_value)
5233result[cur_stat] = relevant_value
5236treated_keys = {
"Total Time":
"total_time",
"solving":
"solving_time",
"presolving":
"presolving_time",
"reading":
"reading_time",
"copying":
"copying_time",
5237 "Problem name":
"problem_name",
"Presolved Problem name":
"presolved_problem_name",
"Variables":
"_variables",
5238 "Presolved Variables":
"_presolved_variables",
"Constraints":
"_constraints",
"Presolved Constraints":
"_presolved_constraints",
5239 "number of runs":
"n_runs",
"nodes":
"n_nodes",
"Solutions found":
"n_solutions_found",
"First Solution":
"first_solution",
5240 "Primal Bound":
"primal_bound",
"Dual Bound":
"dual_bound",
"Gap (%)":
"gap",
"primal-dual":
"primal_dual_integral"}
5241treated_result = dict((treated_keys[key], value)
for(key, value)
inresult.items())
5247 """gets total number of LPs solved so far""" 5255 :param quiet: hide output? (Default value = True) 5263 """Send output to python instead of terminal.""" 5265cdef SCIP_MESSAGEHDLR *myMessageHandler
5267PY_SCIP_CALL(SCIPmessagehdlrCreate(&myMessageHandler,
False, NULL,
False, relayMessage, relayMessage, relayMessage, NULL, NULL))
5269SCIPmessageSetErrorPrinting(relayErrorMessage, NULL)
5272 """sets the log file name for the currently installed message handler 5273 :param path: name of log file, or None (no log) 5284 """Set a boolean-valued parameter. 5286 :param name: name of parameter 5287 :param value: value of parameter 5294 """Set an int-valued parameter. 5296 :param name: name of parameter 5297 :param value: value of parameter 5304 """Set a long-valued parameter. 5306 :param name: name of parameter 5307 :param value: value of parameter 5314 """Set a real-valued parameter. 5316 :param name: name of parameter 5317 :param value: value of parameter 5324 """Set a char-valued parameter. 5326 :param name: name of parameter 5327 :param value: value of parameter 5334 """Set a string-valued parameter. 5336 :param name: name of parameter 5337 :param value: value of parameter 5345 """Set a parameter with value in int, bool, real, long, char or str. 5347 :param name: name of parameter 5348 :param value: value of parameter 5350cdef SCIP_PARAM* param
5356 raiseKeyError(
"Not a valid parameter name")
5358paramtype = SCIPparamGetType(param)
5360 ifparamtype == SCIP_PARAMTYPE_BOOL:
5362 elifparamtype == SCIP_PARAMTYPE_INT:
5364 elifparamtype == SCIP_PARAMTYPE_LONGINT:
5366 elifparamtype == SCIP_PARAMTYPE_REAL:
5368 elifparamtype == SCIP_PARAMTYPE_CHAR:
5370 elifparamtype == SCIP_PARAMTYPE_STRING:
5376 """Get the value of a parameter of type 5377 int, bool, real, long, char or str. 5379 :param name: name of parameter 5381cdef SCIP_PARAM* param
5387 raiseKeyError(
"Not a valid parameter name")
5389paramtype = SCIPparamGetType(param)
5391 ifparamtype == SCIP_PARAMTYPE_BOOL:
5392 returnSCIPparamGetBool(param)
5393 elifparamtype == SCIP_PARAMTYPE_INT:
5394 returnSCIPparamGetInt(param)
5395 elifparamtype == SCIP_PARAMTYPE_LONGINT:
5396 returnSCIPparamGetLongint(param)
5397 elifparamtype == SCIP_PARAMTYPE_REAL:
5398 returnSCIPparamGetReal(param)
5399 elifparamtype == SCIP_PARAMTYPE_CHAR:
5400 returnchr(SCIPparamGetChar(param))
5401 elifparamtype == SCIP_PARAMTYPE_STRING:
5402 returnSCIPparamGetString(param).decode(
'utf-8')
5405 """Gets the values of all parameters as a dict mapping parameter names 5407cdef SCIP_PARAM** params
5412name = SCIPparamGetName(params[i]).decode(
'utf-8')
5413result[name] = self.
getParam(name)
5417 """Sets multiple parameters at once. 5419 :param params: dict mapping parameter names to their values. 5421 forname, value
inparams.items():
5425 """Read an external parameter file. 5427 :param file: file to be read 5432user_locale = locale.getlocale(category=locale.LC_NUMERIC)
5433locale.setlocale(locale.LC_NUMERIC,
"C")
5437locale.setlocale(locale.LC_NUMERIC, user_locale)
5439 def writeParams(self, filename='param.set', comments=True, onlychanged=True, verbose=True):
5440 """Write parameter settings to an external file. 5442 :param filename: file to be written (Default value = 'param.set') 5443 :param comments: write parameter descriptions as comments? (Default value = True) 5444 :param onlychanged: write only modified parameters (Default value = True) 5445 :param verbose: indicates whether a success message should be printed 5447user_locale = locale.getlocale(category=locale.LC_NUMERIC)
5448locale.setlocale(locale.LC_NUMERIC,
"C")
5450str_absfile = abspath(filename)
5455print(
'wrote parameter settings to file '+ str_absfile)
5457locale.setlocale(locale.LC_NUMERIC,user_locale)
5460 """Reset parameter setting to its default value 5462 :param name: parameter to reset 5469 """Reset parameter settings to their default values""" 5473 """Set emphasis settings 5475 :param paraemphasis: emphasis to set 5476 :param quiet: hide output? (Default value = True) 5482 """Read a problem instance from an external file. 5484 :param filename: problem file name 5485 :param extension: specify file extension/type (Default value = None) 5488user_locale = locale.getlocale(category=locale.LC_NUMERIC)
5489locale.setlocale(locale.LC_NUMERIC,
"C")
5492 ifextension
is None:
5498locale.setlocale(locale.LC_NUMERIC, user_locale)
5503 """Counts the number of feasible points of problem.""" 5507 """Get number of currently available readers.""" 5511 """Get number of feasible solution.""" 5512cdef SCIP_Bool valid
5513cdef SCIP_Longint nsols
5517print(
'total number of solutions found is not valid!')
5521 """Sets SCIP parameters such that a valid counting process is possible.""" 5525 """Frees all solution process data and prepares for reoptimization""" 5529 """Establish the objective function as a linear expression. 5531 :param coeffs: the coefficients 5532 :param sense: the objective sense (Default value = 'minimize') 5536cdef SCIP_OBJSENSE objsense
5538 ifsense ==
"minimize":
5539objsense = SCIP_OBJSENSE_MINIMIZE
5540 elifsense ==
"maximize":
5541objsense = SCIP_OBJSENSE_MAXIMIZE
5543 raiseWarning(
"unrecognized optimization sense: %s"% sense)
5545 assertisinstance(coeffs, Expr),
"given coefficients are not Expr but %s"% coeffs.__class__.__name__
5547 ifcoeffs.degree() > 1:
5548 raiseValueError(
"Nonlinear objective functions are not supported!")
5549 ifcoeffs[CONST] != 0.0:
5550 raiseValueError(
"Constant offsets in objective are not supported!")
5552cdef SCIP_VAR** _vars
5556_coeffs = <SCIP_Real*> malloc(_nvars * sizeof(SCIP_Real))
5558 fori
inrange(_nvars):
5561 forterm, coef
incoeffs.terms.items():
5564 assertlen(term) == 1
5565var = <Variable>term[0]
5566 fori
inrange(_nvars):
5567 if_vars[i] == var.scip_var:
5575 """Sets the branch priority of the variable. 5576 Variables with higher branch priority are always preferred to variables with lower priority in selection of branching variable. 5578 :param Variable var: variable to change priority of 5579 :param priority: the new priority of the variable (the default branching priority is 0) 5581 assertisinstance(var, Variable),
"The given variable is not a pyvar, but %s"% var.__class__.__name__
5585 """Start strong branching. Needs to be called before any strong branching. Must also later end strong branching. 5586 TODO: Propagation option has currently been disabled via Python. 5587 If propagation is enabled then strong branching is not done on the LP, but on additionally created nodes (has some overhead)""" 5592 """End strong branching. Needs to be called if startStrongBranching was called previously. 5593 Between these calls the user can access all strong branching functionality. """ 5598 """Get the results of the last strong branching call on this variable (potentially was called 5601 down - The dual bound of the LP after branching down on the variable 5602 up - The dual bound of the LP after branchign up on the variable 5603 downvalid - Whether down stores a valid dual bound or is NULL 5604 upvalid - Whether up stores a valid dual bound or is NULL 5605 solval - The solution value of the variable at the last strong branching call 5606 lpobjval - The LP objective value at the time of the last strong branching call 5608 :param Variable var: variable to get the previous strong branching information from 5613cdef SCIP_Real solval
5614cdef SCIP_Real lpobjval
5615cdef SCIP_Bool downvalid
5616cdef SCIP_Bool upvalid
5620 returndown, up, downvalid, upvalid, solval, lpobjval
5623 """Get the node number from the last time strong branching was called on the variable 5625 :param Variable var: variable to get the previous strong branching node from 5628cdef SCIP_Longint node_num
5634 """ Strong branches and gets information on column variable. 5636 :param Variable var: Variable to get strong branching information on 5637 :param itlim: LP iteration limit for total strong branching calls 5638 :param idempotent: Should SCIP's state remain the same after the call? 5639 :param integral: Boolean on whether the variable is currently integer. 5644cdef SCIP_Bool downvalid
5645cdef SCIP_Bool upvalid
5646cdef SCIP_Bool downinf
5647cdef SCIP_Bool upinf
5648cdef SCIP_Bool downconflict
5649cdef SCIP_Bool upconflict
5650cdef SCIP_Bool lperror
5654&upvalid, &downinf, &upinf, &downconflict, &upconflict, &lperror))
5657&upvalid, &downinf, &upinf, &downconflict, &upconflict, &lperror))
5659 returndown, up, downvalid, upvalid, downinf, upinf, downconflict, upconflict, lperror
5662 """Updates the pseudo costs of the given variable and the global pseudo costs after a change of valdelta 5663 in the variable's solution value and resulting change of objdelta in the LP's objective value. 5664 Update is ignored if objdelts is infinite. Weight is in range (0, 1], and affects how it updates 5665 the global weighted sum. 5667 :param Variable var: Variable whos pseudo cost will be updated 5668 :param valdelta: The change in variable value (e.g. the fractional amount removed or added by branching) 5669 :param objdelta: The change in objective value of the LP after valdelta change of the variable 5670 :param weight: the weight in range (0,1] of how the update affects the stored weighted sum. 5676 """Calculates the branching score out of the gain predictions for a branching with 5677 arbitrary many children. 5679 :param Variable var: variable to calculate the score for 5680 :param gains: list of gains for each child. 5683 assertisinstance(gains, list)
5684nchildren = len(gains)
5686cdef int _nchildren = nchildren
5687_gains = <SCIP_Real*> malloc(_nchildren * sizeof(SCIP_Real))
5688 fori
inrange(_nchildren):
5689_gains[i] = gains[i]
5698 """Get an estimation of the final tree size """ 5699 returnSCIPgetTreesizeEstimation(self.
_scip)
5703static_only=False, suppress_warnings=False):
5704 """This function generates the bipartite graph representation of an LP, which was first used in 5705 the following paper: 5706 @inproceedings{conf/nips/GasseCFCL19, 5707 title={Exact Combinatorial Optimization with Graph Convolutional Neural Networks}, 5708 author={Gasse, Maxime and Chételat, Didier and Ferroni, Nicola and Charlin, Laurent and Lodi, Andrea}, 5709 booktitle={Advances in Neural Information Processing Systems 32}, 5712 The exact features have been modified compared to the original implementation. 5713 This function is used mainly in the machine learning community for MIP. 5714 A user can only call it during the solving process, when there is an LP object. This means calling it 5715 from some user defined plugin on the Python side. 5716 An example plugin is a branching rule or an event handler, which is exclusively created to call this function. 5717 The user must then make certain to return the appropriate SCIP_RESULT (e.g. DIDNOTRUN) 5719 :param prev_col_features: The list of column features previously returned by this function 5720 :param prev_edge_features: The list of edge features previously returned by this function 5721 :param prev_row_features: The list of row features previously returned by this function 5722 :param static_only: Whether exclusively static features should be generated 5723 :param suppress_warnings: Whether warnings should be suppressed 5726cdef SCIP* scip = self.
_scip 5727cdef int i, j, k, col_i
5728cdef SCIP_VARTYPE vtype
5729cdef SCIP_Real sim, prod
5733 raiseWarning(
"This functionality can only been called in SCIP_STAGE SOLVING. The row and column" 5734 "information is then accessible")
5742col_feature_map = {
"continuous": 0,
"binary": 1,
"integer": 2,
"implicit_integer": 3,
"obj_coef": 4}
5745col_feature_map = {
"continuous": 0,
"binary": 1,
"integer": 2,
"implicit_integer": 3,
"obj_coef": 4,
5746 "has_lb": 5,
"has_ub": 6,
"sol_at_lb": 7,
"sol_at_ub": 8,
"sol_val": 9,
"sol_frac": 10,
5747 "red_cost": 11,
"basis_lower": 12,
"basis_basic": 13,
"basis_upper": 14,
5748 "basis_zero": 15,
"best_incumbent_val": 16,
"avg_incumbent_val": 17,
"age": 18}
5750 ifprev_col_features
is None:
5751col_features = [[0
for_
inrange(n_col_features)]
for_
inrange(ncols)]
5753 assertlen(prev_col_features) > 0,
"Previous column features is empty" 5754col_features = prev_col_features
5755 iflen(prev_col_features) != ncols:
5756 if notsuppress_warnings:
5757 raiseWarning(f
"The number of columns has changed. Previous column data being ignored")
5759col_features = [[0
for_
inrange(n_col_features)]
for_
inrange(ncols)]
5760prev_col_features =
None 5761 iflen(prev_col_features[0]) != n_col_features:
5762 raiseWarning(f
"Dimension mismatch in provided previous features and new features:" 5763f
"{len(prev_col_features[0])} != {n_col_features}")
5767cdef SCIP_Real lb, ub, solval
5768cdef SCIP_BASESTAT basis_status
5769 fori
inrange(ncols):
5778 ifprev_col_features
is None:
5781 ifvtype == SCIP_VARTYPE_BINARY:
5782col_features[col_i][col_feature_map[
"binary"]] = 1
5783 elifvtype == SCIP_VARTYPE_INTEGER:
5784col_features[col_i][col_feature_map[
"integer"]] = 1
5785 elifvtype == SCIP_VARTYPE_CONTINUOUS:
5786col_features[col_i][col_feature_map[
"continuous"]] = 1
5787 elifvtype == SCIP_VARTYPE_IMPLINT:
5788col_features[col_i][col_feature_map[
"implicit_integer"]] = 1
5790col_features[col_i][col_feature_map[
"obj_coef"]] =
SCIPcolGetObj(cols[i])
5796col_features[col_i][col_feature_map[
"has_lb"]] = 1
5800col_features[col_i][col_feature_map[
"has_ub"]] = 1
5804 ifbasis_status == SCIP_BASESTAT_LOWER:
5805col_features[col_i][col_feature_map[
"basis_lower"]] = 1
5806 elifbasis_status == SCIP_BASESTAT_BASIC:
5807col_features[col_i][col_feature_map[
"basis_basic"]] = 1
5808 elifbasis_status == SCIP_BASESTAT_UPPER:
5809col_features[col_i][col_feature_map[
"basis_upper"]] = 1
5810 elifbasis_status == SCIP_BASESTAT_ZERO:
5811col_features[col_i][col_feature_map[
"basis_zero"]] = 1
5814col_features[col_i][col_feature_map[
"red_cost"]] =
SCIPgetColRedcost(scip, cols[i])
5817col_features[col_i][col_feature_map[
"age"]] =
SCIPcolGetAge(cols[i])
5820col_features[col_i][col_feature_map[
"sol_val"]] = solval
5821col_features[col_i][col_feature_map[
"sol_frac"]] =
SCIPfeasFrac(scip, solval)
5822col_features[col_i][col_feature_map[
"sol_at_lb"]] = int(
SCIPisEQ(scip, solval, lb))
5823col_features[col_i][col_feature_map[
"sol_at_ub"]] = int(
SCIPisEQ(scip, solval, ub))
5827col_features[col_i][col_feature_map[
"best_incumbent_val"]] =
None 5828col_features[col_i][col_feature_map[
"avg_incumbent_val"]] =
None 5830col_features[col_i][col_feature_map[
"best_incumbent_val"]] =
SCIPgetSolVal(scip, sol, var)
5831col_features[col_i][col_feature_map[
"avg_incumbent_val"]] =
SCIPvarGetAvgSol(var)
5839row_feature_map = {
"has_lhs": 0,
"has_rhs": 1,
"n_non_zeros": 2,
"obj_cosine": 3,
"bias": 4,
"norm": 5}
5842row_feature_map = {
"has_lhs": 0,
"has_rhs": 1,
"n_non_zeros": 2,
"obj_cosine": 3,
"bias": 4,
"norm": 5,
5843 "sol_at_lhs": 6,
"sol_at_rhs": 7,
"dual_sol": 8,
"age": 9,
5844 "basis_lower": 10,
"basis_basic": 11,
"basis_upper": 12,
"basis_zero": 13}
5846 ifprev_row_features
is None:
5847row_features = [[0
for_
inrange(n_row_features)]
for_
inrange(nrows)]
5849 assertlen(prev_row_features) > 0,
"Previous row features is empty" 5850row_features = prev_row_features
5851 iflen(prev_row_features) != nrows:
5852 if notsuppress_warnings:
5853 raiseWarning(f
"The number of rows has changed. Previous row data being ignored")
5855row_features = [[0
for_
inrange(n_row_features)]
for_
inrange(nrows)]
5856prev_row_features =
None 5857 iflen(prev_row_features[0]) != n_row_features:
5858 raiseWarning(f
"Dimension mismatch in provided previous features and new features:" 5859f
"{len(prev_row_features[0])} != {n_row_features}")
5862cdef SCIP_Real lhs, rhs, cst
5863 fori
inrange(nrows):
5871 ifprev_row_features
is None:
5874nnzrs += row_features[i][row_feature_map[
"n_non_zeros"]]
5878row_features[i][row_feature_map[
"has_lhs"]] = 1
5882row_features[i][row_feature_map[
"has_rhs"]] = 1
5885row_features[i][row_feature_map[
"bias"]] = cst
5891row_features[i][row_feature_map[
"norm"]] =
SCIProwGetNorm(rows[i])
5900 ifbasis_status == SCIP_BASESTAT_LOWER:
5901row_features[i][row_feature_map[
"basis_lower"]] = 1
5902 elifbasis_status == SCIP_BASESTAT_BASIC:
5903row_features[i][row_feature_map[
"basis_basic"]] = 1
5904 elifbasis_status == SCIP_BASESTAT_UPPER:
5905row_features[i][row_feature_map[
"basis_upper"]] = 1
5906 elifbasis_status == SCIP_BASESTAT_ZERO:
5907row_features[i][row_feature_map[
"basis_zero"]] = 1
5910row_features[i][row_feature_map[
"age"]] =
SCIProwGetAge(rows[i])
5913row_features[i][row_feature_map[
"sol_at_lhs"]] = int(
SCIPisEQ(scip, activity, lhs))
5914row_features[i][row_feature_map[
"sol_at_rhs"]] = int(
SCIPisEQ(scip, activity, rhs))
5917cdef SCIP_COL** row_cols
5918cdef SCIP_Real * row_vals
5920edge_feature_map = {
"col_idx": 0,
"row_idx": 1,
"coef": 2}
5921 ifprev_edge_features
is None:
5922edge_features = [[0
for_
inrange(n_edge_features)]
for_
inrange(nnzrs)]
5924 fori
inrange(nrows):
5928 fork
inrange(row_features[i][row_feature_map[
"n_non_zeros"]]):
5929edge_features[j][edge_feature_map[
"col_idx"]] =
SCIPcolGetLPPos(row_cols[k])
5930edge_features[j][edge_feature_map[
"row_idx"]] = i
5931edge_features[j][edge_feature_map[
"coef"]] = row_vals[k]
5934 assertlen(prev_edge_features) > 0,
"Previous edge features is empty" 5935edge_features = prev_edge_features
5936 iflen(prev_edge_features) != nnzrs:
5937 if notsuppress_warnings:
5938 raiseWarning(f
"The number of coefficients in the LP has changed. Previous edge data being ignored")
5940edge_features = [[0
for_
inrange(3)]
for_
inrange(nnzrs)]
5941prev_edge_features =
None 5942 iflen(prev_edge_features[0]) != 3:
5943 raiseWarning(f
"Dimension mismatch in provided previous features and new features:" 5944f
"{len(prev_edge_features[0])} != 3")
5947 return(col_features, edge_features, row_features,
5948{
"col": col_feature_map,
"edge": edge_feature_map,
"row": row_feature_map})
5956 Total time since model was created 5958 Time spent solving the problem 5959 presolving_time: float 5960 Time spent on presolving 5962 Time spent on reading 5964 Time spent on copying 5967 presolved_problem_name: str 5968 Name of presolved problem 5970 The number of nodes explored in the branch-and-bound tree 5971 n_solutions_found: int 5972 number of found solutions 5973 first_solution: float 5974 objective value of first found solution 5976 The best primal bound found 5978 The best dual bound found 5980 The gap between the primal and dual bounds 5981 primal_dual_integral: float 5982 The primal-dual integral 5984 number of variables in the model 5986 number of binary variables in the model 5988 number of integer variables in the model 5989 n_implicit_integer_vars: int 5990 number of implicit integer variables in the model 5991 n_continuous_vars: int 5992 number of continuous variables in the model 5993 n_presolved_vars: int 5994 number of variables in the presolved model 5995 n_presolved_continuous_vars: int 5996 number of continuous variables in the presolved model 5997 n_presolved_binary_vars: int 5998 number of binary variables in the presolved model 5999 n_presolved_integer_vars: int 6000 number of integer variables in the presolved model 6001 n_presolved_implicit_integer_vars: int 6002 number of implicit integer variables in the presolved model 6004 number of maximal constraints in the model 6006 number of initial constraints in the presolved model 6007 n_presolved_maximal_cons: int 6008 number of maximal constraints in the presolved model 6009 n_presolved_conss: int 6010 number of initial constraints in the model 6015presolving_time: float
6019presolved_problem_name: str
6021_presolved_variables: dict
6023_presolved_constraints: dict
6026n_solutions_found: int
6027first_solution: float
6031primal_dual_integral: float
6037 returnself._variables[
"total"]
6041 returnself._variables[
"binary"]
6045 returnself._variables[
"integer"]
6049 returnself._variables[
"implicit"]
6053 returnself._variables[
"continuous"]
6057 returnself._presolved_variables[
"total"]
6061 returnself._presolved_variables[
"binary"]
6065 returnself._presolved_variables[
"integer"]
6069 returnself._presolved_variables[
"implicit"]
6073 returnself._presolved_variables[
"continuous"]
6077 returnself._constraints[
"initial"]
6081 returnself._constraints[
"maximal"]
6085 returnself._presolved_constraints[
"initial"]
6089 returnself._presolved_constraints[
"maximal"]
6093 returnBMSgetMemoryUsed() == 0
6096BMScheckEmptyMemory()
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4