PySCIPOpt
Python Interface to the SCIP Optimization Suite
scip.pyx
Go to the documentation of this file.
1 ##@file scip.pyx
2 #@brief holding functions in python that reference the SCIP public functions included in scip.pxd
3 import weakref
4 from os.path import abspath
5 from os.path import splitext
6 import sys
7 import warnings
8 
9 from cpython cimport Py_INCREF, Py_DECREF
10 from libc.stdlib cimport malloc, free
11 from libc.stdio cimport fdopen
12 
13 include "expr.pxi"
14 include "lp.pxi"
15 include "benders.pxi"
16 include "branchrule.pxi"
17 include "conshdlr.pxi"
18 include "event.pxi"
19 include "heuristic.pxi"
20 include "presol.pxi"
21 include "pricer.pxi"
22 include "propagator.pxi"
23 include "sepa.pxi"
24 include "relax.pxi"
25 
26 # recommended SCIP version; major version is required
27 MAJOR = 6
28 MINOR = 0
29 PATCH = 0
30 
31 # for external user functions use def; for functions used only inside the interface (starting with _) use cdef
32 # todo: check whether this is currently done like this
33 
34 if sys.version_info >= (3, 0):
35  str_conversion = lambda x:bytes(x,'utf-8')
36 else:
37  str_conversion = lambda x:x
38 
39 # Mapping the SCIP_RESULT enum to a python class
40 # This is required to return SCIP_RESULT in the python code
41 # In __init__.py this is imported as SCIP_RESULT to keep the
42 # original naming scheme using capital letters
43 cdef class PY_SCIP_RESULT:
44  DIDNOTRUN = SCIP_DIDNOTRUN
45  DELAYED = SCIP_DELAYED
46  DIDNOTFIND = SCIP_DIDNOTFIND
47  FEASIBLE = SCIP_FEASIBLE
48  INFEASIBLE = SCIP_INFEASIBLE
49  UNBOUNDED = SCIP_UNBOUNDED
50  CUTOFF = SCIP_CUTOFF
51  SEPARATED = SCIP_SEPARATED
52  NEWROUND = SCIP_NEWROUND
53  REDUCEDDOM = SCIP_REDUCEDDOM
54  CONSADDED = SCIP_CONSADDED
55  CONSCHANGED = SCIP_CONSCHANGED
56  BRANCHED = SCIP_BRANCHED
57  SOLVELP = SCIP_SOLVELP
58  FOUNDSOL = SCIP_FOUNDSOL
59  SUSPENDED = SCIP_SUSPENDED
60  SUCCESS = SCIP_SUCCESS
61 
62 cdef class PY_SCIP_PARAMSETTING:
63  DEFAULT = SCIP_PARAMSETTING_DEFAULT
64  AGGRESSIVE = SCIP_PARAMSETTING_AGGRESSIVE
65  FAST = SCIP_PARAMSETTING_FAST
66  OFF = SCIP_PARAMSETTING_OFF
67 
68 cdef class PY_SCIP_PARAMEMPHASIS:
69  DEFAULT = SCIP_PARAMEMPHASIS_DEFAULT
70  CPSOLVER = SCIP_PARAMEMPHASIS_CPSOLVER
71  EASYCIP = SCIP_PARAMEMPHASIS_EASYCIP
72  FEASIBILITY = SCIP_PARAMEMPHASIS_FEASIBILITY
73  HARDLP = SCIP_PARAMEMPHASIS_HARDLP
74  OPTIMALITY = SCIP_PARAMEMPHASIS_OPTIMALITY
75  COUNTER = SCIP_PARAMEMPHASIS_COUNTER
76  PHASEFEAS = SCIP_PARAMEMPHASIS_PHASEFEAS
77  PHASEIMPROVE = SCIP_PARAMEMPHASIS_PHASEIMPROVE
78  PHASEPROOF = SCIP_PARAMEMPHASIS_PHASEPROOF
79 
80 cdef class PY_SCIP_STATUS:
81  UNKNOWN = SCIP_STATUS_UNKNOWN
82  USERINTERRUPT = SCIP_STATUS_USERINTERRUPT
83  NODELIMIT = SCIP_STATUS_NODELIMIT
84  TOTALNODELIMIT = SCIP_STATUS_TOTALNODELIMIT
85  STALLNODELIMIT = SCIP_STATUS_STALLNODELIMIT
86  TIMELIMIT = SCIP_STATUS_TIMELIMIT
87  MEMLIMIT = SCIP_STATUS_MEMLIMIT
88  GAPLIMIT = SCIP_STATUS_GAPLIMIT
89  SOLLIMIT = SCIP_STATUS_SOLLIMIT
90  BESTSOLLIMIT = SCIP_STATUS_BESTSOLLIMIT
91  RESTARTLIMIT = SCIP_STATUS_RESTARTLIMIT
92  OPTIMAL = SCIP_STATUS_OPTIMAL
93  INFEASIBLE = SCIP_STATUS_INFEASIBLE
94  UNBOUNDED = SCIP_STATUS_UNBOUNDED
95  INFORUNBD = SCIP_STATUS_INFORUNBD
96 
97 cdef class PY_SCIP_STAGE:
98  INIT = SCIP_STAGE_INIT
99  PROBLEM = SCIP_STAGE_PROBLEM
100  TRANSFORMING = SCIP_STAGE_TRANSFORMING
101  TRANSFORMED = SCIP_STAGE_TRANSFORMED
102  INITPRESOLVE = SCIP_STAGE_INITPRESOLVE
103  PRESOLVING = SCIP_STAGE_PRESOLVING
104  EXITPRESOLVE = SCIP_STAGE_EXITPRESOLVE
105  PRESOLVED = SCIP_STAGE_PRESOLVED
106  INITSOLVE = SCIP_STAGE_INITSOLVE
107  SOLVING = SCIP_STAGE_SOLVING
108  SOLVED = SCIP_STAGE_SOLVED
109  EXITSOLVE = SCIP_STAGE_EXITSOLVE
110  FREETRANS = SCIP_STAGE_FREETRANS
111  FREE = SCIP_STAGE_FREE
112 
113 cdef class PY_SCIP_NODETYPE:
114  FOCUSNODE = SCIP_NODETYPE_FOCUSNODE
115  PROBINGNODE = SCIP_NODETYPE_PROBINGNODE
116  SIBLING = SCIP_NODETYPE_SIBLING
117  CHILD = SCIP_NODETYPE_CHILD
118  LEAF = SCIP_NODETYPE_LEAF
119  DEADEND = SCIP_NODETYPE_DEADEND
120  JUNCTION = SCIP_NODETYPE_JUNCTION
121  PSEUDOFORK = SCIP_NODETYPE_PSEUDOFORK
122  FORK = SCIP_NODETYPE_FORK
123  SUBROOT = SCIP_NODETYPE_SUBROOT
124  REFOCUSNODE = SCIP_NODETYPE_REFOCUSNODE
125 
126 
127 cdef class PY_SCIP_PROPTIMING:
128  BEFORELP = SCIP_PROPTIMING_BEFORELP
129  DURINGLPLOOP = SCIP_PROPTIMING_DURINGLPLOOP
130  AFTERLPLOOP = SCIP_PROPTIMING_AFTERLPLOOP
131  AFTERLPNODE = SCIP_PROPTIMING_AFTERLPNODE
132 
133 cdef class PY_SCIP_PRESOLTIMING:
134  NONE = SCIP_PRESOLTIMING_NONE
135  FAST = SCIP_PRESOLTIMING_FAST
136  MEDIUM = SCIP_PRESOLTIMING_MEDIUM
137  EXHAUSTIVE = SCIP_PRESOLTIMING_EXHAUSTIVE
138 
139 cdef class PY_SCIP_HEURTIMING:
140  BEFORENODE = SCIP_HEURTIMING_BEFORENODE
141  DURINGLPLOOP = SCIP_HEURTIMING_DURINGLPLOOP
142  AFTERLPLOOP = SCIP_HEURTIMING_AFTERLPLOOP
143  AFTERLPNODE = SCIP_HEURTIMING_AFTERLPNODE
144  AFTERPSEUDONODE = SCIP_HEURTIMING_AFTERPSEUDONODE
145  AFTERLPPLUNGE = SCIP_HEURTIMING_AFTERLPPLUNGE
146  AFTERPSEUDOPLUNGE = SCIP_HEURTIMING_AFTERPSEUDOPLUNGE
147  DURINGPRICINGLOOP = SCIP_HEURTIMING_DURINGPRICINGLOOP
148  BEFOREPRESOL = SCIP_HEURTIMING_BEFOREPRESOL
149  DURINGPRESOLLOOP = SCIP_HEURTIMING_DURINGPRESOLLOOP
150  AFTERPROPLOOP = SCIP_HEURTIMING_AFTERPROPLOOP
151 
152 cdef class PY_SCIP_EVENTTYPE:
153  DISABLED = SCIP_EVENTTYPE_DISABLED
154  VARADDED = SCIP_EVENTTYPE_VARADDED
155  VARDELETED = SCIP_EVENTTYPE_VARDELETED
156  VARFIXED = SCIP_EVENTTYPE_VARFIXED
157  VARUNLOCKED = SCIP_EVENTTYPE_VARUNLOCKED
158  OBJCHANGED = SCIP_EVENTTYPE_OBJCHANGED
159  GLBCHANGED = SCIP_EVENTTYPE_GLBCHANGED
160  GUBCHANGED = SCIP_EVENTTYPE_GUBCHANGED
161  LBTIGHTENED = SCIP_EVENTTYPE_LBTIGHTENED
162  LBRELAXED = SCIP_EVENTTYPE_LBRELAXED
163  UBTIGHTENED = SCIP_EVENTTYPE_UBTIGHTENED
164  UBRELAXED = SCIP_EVENTTYPE_UBRELAXED
165  GHOLEADDED = SCIP_EVENTTYPE_GHOLEADDED
166  GHOLEREMOVED = SCIP_EVENTTYPE_GHOLEREMOVED
167  LHOLEADDED = SCIP_EVENTTYPE_LHOLEADDED
168  LHOLEREMOVED = SCIP_EVENTTYPE_LHOLEREMOVED
169  IMPLADDED = SCIP_EVENTTYPE_IMPLADDED
170  PRESOLVEROUND = SCIP_EVENTTYPE_PRESOLVEROUND
171  NODEFOCUSED = SCIP_EVENTTYPE_NODEFOCUSED
172  NODEFEASIBLE = SCIP_EVENTTYPE_NODEFEASIBLE
173  NODEINFEASIBLE = SCIP_EVENTTYPE_NODEINFEASIBLE
174  NODEBRANCHED = SCIP_EVENTTYPE_NODEBRANCHED
175  FIRSTLPSOLVED = SCIP_EVENTTYPE_FIRSTLPSOLVED
176  LPSOLVED = SCIP_EVENTTYPE_LPSOLVED
177  LPEVENT = SCIP_EVENTTYPE_LPEVENT
178  POORSOLFOUND = SCIP_EVENTTYPE_POORSOLFOUND
179  BESTSOLFOUND = SCIP_EVENTTYPE_BESTSOLFOUND
180  ROWADDEDSEPA = SCIP_EVENTTYPE_ROWADDEDSEPA
181  ROWDELETEDSEPA = SCIP_EVENTTYPE_ROWDELETEDSEPA
182  ROWADDEDLP = SCIP_EVENTTYPE_ROWADDEDLP
183  ROWDELETEDLP = SCIP_EVENTTYPE_ROWDELETEDLP
184  ROWCOEFCHANGED = SCIP_EVENTTYPE_ROWCOEFCHANGED
185  ROWCONSTCHANGED = SCIP_EVENTTYPE_ROWCONSTCHANGED
186  ROWSIDECHANGED = SCIP_EVENTTYPE_ROWSIDECHANGED
187  SYNC = SCIP_EVENTTYPE_SYNC
188 
189 cdef class PY_SCIP_LPSOLSTAT:
190  NOTSOLVED = SCIP_LPSOLSTAT_NOTSOLVED
191  OPTIMAL = SCIP_LPSOLSTAT_OPTIMAL
192  INFEASIBLE = SCIP_LPSOLSTAT_INFEASIBLE
193  UNBOUNDEDRAY = SCIP_LPSOLSTAT_UNBOUNDEDRAY
194  OBJLIMIT = SCIP_LPSOLSTAT_OBJLIMIT
195  ITERLIMIT = SCIP_LPSOLSTAT_ITERLIMIT
196  TIMELIMIT = SCIP_LPSOLSTAT_TIMELIMIT
197  ERROR = SCIP_LPSOLSTAT_ERROR
198 
199 cdef class PY_SCIP_BRANCHDIR:
200  DOWNWARDS = SCIP_BRANCHDIR_DOWNWARDS
201  UPWARDS = SCIP_BRANCHDIR_UPWARDS
202  FIXED = SCIP_BRANCHDIR_FIXED
203  AUTO = SCIP_BRANCHDIR_AUTO
204 
205 def PY_SCIP_CALL(SCIP_RETCODE rc):
206  if rc == SCIP_OKAY:
207  pass
208  elif rc == SCIP_ERROR:
209  raise Exception('SCIP: unspecified error!')
210  elif rc == SCIP_NOMEMORY:
211  raise MemoryError('SCIP: insufficient memory error!')
212  elif rc == SCIP_READERROR:
213  raise IOError('SCIP: read error!')
214  elif rc == SCIP_WRITEERROR:
215  raise IOError('SCIP: write error!')
216  elif rc == SCIP_NOFILE:
217  raise IOError('SCIP: file not found error!')
218  elif rc == SCIP_FILECREATEERROR:
219  raise IOError('SCIP: cannot create file!')
220  elif rc == SCIP_LPERROR:
221  raise Exception('SCIP: error in LP solver!')
222  elif rc == SCIP_NOPROBLEM:
223  raise Exception('SCIP: no problem exists!')
224  elif rc == SCIP_INVALIDCALL:
225  raise Exception('SCIP: method cannot be called at this time'
226  + ' in solution process!')
227  elif rc == SCIP_INVALIDDATA:
228  raise Exception('SCIP: error in input data!')
229  elif rc == SCIP_INVALIDRESULT:
230  raise Exception('SCIP: method returned an invalid result code!')
231  elif rc == SCIP_PLUGINNOTFOUND:
232  raise Exception('SCIP: a required plugin was not found !')
233  elif rc == SCIP_PARAMETERUNKNOWN:
234  raise KeyError('SCIP: the parameter with the given name was not found!')
235  elif rc == SCIP_PARAMETERWRONGTYPE:
236  raise LookupError('SCIP: the parameter is not of the expected type!')
237  elif rc == SCIP_PARAMETERWRONGVAL:
238  raise ValueError('SCIP: the value is invalid for the given parameter!')
239  elif rc == SCIP_KEYALREADYEXISTING:
240  raise KeyError('SCIP: the given key is already existing in table!')
241  elif rc == SCIP_MAXDEPTHLEVEL:
242  raise Exception('SCIP: maximal branching depth level exceeded!')
243  else:
244  raise Exception('SCIP: unknown return code!')
245 
246 cdef class Event:
247  cdef SCIP_EVENT* event
248 
249  @staticmethod
250  cdef create(SCIP_EVENT* scip_event):
251  event = Event()
252  event.event = scip_event
253  return event
254 
255  def getType(self):
256  """gets type of event"""
257  return SCIPeventGetType(self.event)
258 
259  def __repr__(self):
260  return self.getType()
261 
262  def getNewBound(self):
263  """gets new bound for a bound change event"""
264  return SCIPeventGetNewbound(self.event)
265 
266  def getOldBound(self):
267  """gets old bound for a bound change event"""
268  return SCIPeventGetOldbound(self.event)
269 
270  def getVar(self):
271  """gets variable for a variable event (var added, var deleted, var fixed, objective value or domain change, domain hole added or removed)"""
272  cdef SCIP_VAR* var = SCIPeventGetVar(self.event)
273  return Variable.create(var)
274 
275  def getNode(self):
276  """gets node for a node or LP event"""
277  cdef SCIP_NODE* node = SCIPeventGetNode(self.event)
278  return Node.create(node)
279 
280 cdef class Column:
281  """Base class holding a pointer to corresponding SCIP_COL"""
282  cdef SCIP_COL* col
283 
284  @staticmethod
285  cdef create(SCIP_COL* scip_col):
286  col = Column()
287  col.col = scip_col
288  return col
289 
290  def getLPPos(self):
291  """gets position of column in current LP, or -1 if it is not in LP"""
292  return SCIPcolGetLPPos(self.col)
293 
294  def getBasisStatus(self):
295  """gets the basis status of a column in the LP solution, Note: returns basis status `zero` for columns not in the current SCIP LP"""
296  cdef SCIP_BASESTAT stat = SCIPcolGetBasisStatus(self.col)
297  if stat == SCIP_BASESTAT_LOWER:
298  return "lower"
299  elif stat == SCIP_BASESTAT_BASIC:
300  return "basic"
301  elif stat == SCIP_BASESTAT_UPPER:
302  return "upper"
303  elif stat == SCIP_BASESTAT_ZERO:
304  return "zero"
305  else:
306  raise Exception('SCIP returned unknown base status!')
307 
308  def isIntegral(self):
309  """returns whether the associated variable is of integral type (binary, integer, implicit integer)"""
310  return SCIPcolIsIntegral(self.col)
311 
312  def getVar(self):
313  """gets variable this column represents"""
314  cdef SCIP_VAR* var = SCIPcolGetVar(self.col)
315  return Variable.create(var)
316 
317  def getPrimsol(self):
318  """gets the primal LP solution of a column"""
319  return SCIPcolGetPrimsol(self.col)
320 
321  def getLb(self):
322  """gets lower bound of column"""
323  return SCIPcolGetLb(self.col)
324 
325  def getUb(self):
326  """gets upper bound of column"""
327  return SCIPcolGetUb(self.col)
328 
329 cdef class Row:
330  """Base class holding a pointer to corresponding SCIP_ROW"""
331  cdef SCIP_ROW* row
332 
333  @staticmethod
334  cdef create(SCIP_ROW* scip_row):
335  row = Row()
336  row.row = scip_row
337  return row
338 
339  def getLhs(self):
340  """returns the left hand side of row"""
341  return SCIProwGetLhs(self.row)
342 
343  def getRhs(self):
344  """returns the right hand side of row"""
345  return SCIProwGetRhs(self.row)
346 
347  def getConstant(self):
348  """gets constant shift of row"""
349  return SCIProwGetConstant(self.row)
350 
351  def getLPPos(self):
352  """gets position of row in current LP, or -1 if it is not in LP"""
353  return SCIProwGetLPPos(self.row)
354 
355  def getBasisStatus(self):
356  """gets the basis status of a row in the LP solution, Note: returns basis status `basic` for rows not in the current SCIP LP"""
357  cdef SCIP_BASESTAT stat = SCIProwGetBasisStatus(self.row)
358  if stat == SCIP_BASESTAT_LOWER:
359  return "lower"
360  elif stat == SCIP_BASESTAT_BASIC:
361  return "basic"
362  elif stat == SCIP_BASESTAT_UPPER:
363  return "upper"
364  elif stat == SCIP_BASESTAT_ZERO:
365  # this shouldn't happen!
366  raise Exception('SCIP returned base status zero for a row!')
367  else:
368  raise Exception('SCIP returned unknown base status!')
369 
370  def isIntegral(self):
371  """returns TRUE iff the activity of the row (without the row's constant) is always integral in a feasible solution """
372  return SCIProwIsIntegral(self.row)
373 
374  def isModifiable(self):
375  """returns TRUE iff row is modifiable during node processing (subject to column generation) """
376  return SCIProwIsModifiable(self.row)
377 
378  def getNNonz(self):
379  """get number of nonzero entries in row vector"""
380  return SCIProwGetNNonz(self.row)
381 
382  def getNLPNonz(self):
383  """get number of nonzero entries in row vector that correspond to columns currently in the SCIP LP"""
384  return SCIProwGetNLPNonz(self.row)
385 
386  def getCols(self):
387  """gets list with columns of nonzero entries"""
388  cdef SCIP_COL** cols = SCIProwGetCols(self.row)
389  return [Column.create(cols[i]) for i in range(self.getNNonz())]
390 
391  def getVals(self):
392  """gets list with coefficients of nonzero entries"""
393  cdef SCIP_Real* vals = SCIProwGetVals(self.row)
394  return [vals[i] for i in range(self.getNNonz())]
395 
396 cdef class Solution:
397  """Base class holding a pointer to corresponding SCIP_SOL"""
398  cdef SCIP_SOL* sol
399 
400  @staticmethod
401  cdef create(SCIP_SOL* scip_sol):
402  sol = Solution()
403  sol.sol = scip_sol
404  return sol
405 
406 cdef class Node:
407  """Base class holding a pointer to corresponding SCIP_NODE"""
408  cdef SCIP_NODE* node
409 
410  @staticmethod
411  cdef create(SCIP_NODE* scip_node):
412  node = Node()
413  node.node = scip_node
414  return node
415 
416  def getParent(self):
417  """Retrieve parent node."""
418  return Node.create(SCIPnodeGetParent(self.node))
419 
420  def getNumber(self):
421  """Retrieve number of node."""
422  return SCIPnodeGetNumber(self.node)
423 
424  def getDepth(self):
425  """Retrieve depth of node."""
426  return SCIPnodeGetDepth(self.node)
427 
428  def getType(self):
429  """Retrieve type of node."""
430  return SCIPnodeGetType(self.node)
431 
432  def getLowerbound(self):
433  """Retrieve lower bound of node."""
434  return SCIPnodeGetLowerbound(self.node)
435 
436  def getEstimate(self):
437  """Retrieve the estimated value of the best feasible solution in subtree of the node"""
438  return SCIPnodeGetEstimate(self.node)
439 
440  def getNAddedConss(self):
441  """Retrieve number of added constraints at this node"""
442  return SCIPnodeGetNAddedConss(self.node)
443 
444  def isActive(self):
445  """Is the node in the path to the current node?"""
446  return SCIPnodeIsActive(self.node)
447 
448  def isPropagatedAgain(self):
449  """Is the node marked to be propagated again?"""
450  return SCIPnodeIsPropagatedAgain(self.node)
451 
452 
453 cdef class Variable(Expr):
454  """Is a linear expression and has SCIP_VAR*"""
455  cdef SCIP_VAR* var
456 
457  @staticmethod
458  cdef create(SCIP_VAR* scipvar):
459  var = Variable()
460  var.var = scipvar
461  Expr.__init__(var, {Term(var) : 1.0})
462  return var
463 
464  property name:
465  def __get__(self):
466  cname = bytes( SCIPvarGetName(self.var) )
467  return cname.decode('utf-8')
468 
469  def ptr(self):
470  """ """
471  return <size_t>(self.var)
472 
473  def __repr__(self):
474  return self.name
475 
476  def vtype(self):
477  """Retrieve the variables type (BINARY, INTEGER or CONTINUOUS)"""
478  vartype = SCIPvarGetType(self.var)
479  if vartype == SCIP_VARTYPE_BINARY:
480  return "BINARY"
481  elif vartype == SCIP_VARTYPE_INTEGER:
482  return "INTEGER"
483  elif vartype == SCIP_VARTYPE_CONTINUOUS or vartype == SCIP_VARTYPE_IMPLINT:
484  return "CONTINUOUS"
485 
486  def isOriginal(self):
487  """Retrieve whether the variable belongs to the original problem"""
488  return SCIPvarIsOriginal(self.var)
489 
490  def isInLP(self):
491  """Retrieve whether the variable is a COLUMN variable that is member of the current LP"""
492  return SCIPvarIsInLP(self.var)
493 
494  def getCol(self):
495  """Retrieve column of COLUMN variable"""
496  cdef SCIP_COL* scip_col
497  scip_col = SCIPvarGetCol(self.var)
498  return Column.create(scip_col)
499 
500  def getLbOriginal(self):
501  """Retrieve original lower bound of variable"""
502  return SCIPvarGetLbOriginal(self.var)
503 
504  def getUbOriginal(self):
505  """Retrieve original upper bound of variable"""
506  return SCIPvarGetUbOriginal(self.var)
507 
508  def getLbGlobal(self):
509  """Retrieve global lower bound of variable"""
510  return SCIPvarGetLbGlobal(self.var)
511 
512  def getUbGlobal(self):
513  """Retrieve global upper bound of variable"""
514  return SCIPvarGetUbGlobal(self.var)
515 
516  def getLbLocal(self):
517  """Retrieve current lower bound of variable"""
518  return SCIPvarGetLbLocal(self.var)
519 
520  def getUbLocal(self):
521  """Retrieve current upper bound of variable"""
522  return SCIPvarGetUbLocal(self.var)
523 
524  def getObj(self):
525  """Retrieve current objective value of variable"""
526  return SCIPvarGetObj(self.var)
527 
528  def getLPSol(self):
529  """Retrieve the current LP solution value of variable"""
530  return SCIPvarGetLPSol(self.var)
531 
532 
533 cdef class Constraint:
534  cdef SCIP_CONS* cons
535  cdef public object data #storage for python user
536 
537  @staticmethod
538  cdef create(SCIP_CONS* scipcons):
539  if scipcons == NULL:
540  raise Warning("cannot create Constraint with SCIP_CONS* == NULL")
541  cons = Constraint()
542  cons.cons = scipcons
543  return cons
544 
545  property name:
546  def __get__(self):
547  cname = bytes( SCIPconsGetName(self.cons) )
548  return cname.decode('utf-8')
549 
550  def __repr__(self):
551  return self.name
552 
553  def isOriginal(self):
554  """Retrieve whether the constraint belongs to the original problem"""
555  return SCIPconsIsOriginal(self.cons)
556 
557  def isInitial(self):
558  """Retrieve True if the relaxation of the constraint should be in the initial LP"""
559  return SCIPconsIsInitial(self.cons)
560 
561  def isSeparated(self):
562  """Retrieve True if constraint should be separated during LP processing"""
563  return SCIPconsIsSeparated(self.cons)
564 
565  def isEnforced(self):
566  """Retrieve True if constraint should be enforced during node processing"""
567  return SCIPconsIsEnforced(self.cons)
568 
569  def isChecked(self):
570  """Retrieve True if constraint should be checked for feasibility"""
571  return SCIPconsIsChecked(self.cons)
572 
573  def isPropagated(self):
574  """Retrieve True if constraint should be propagated during node processing"""
575  return SCIPconsIsPropagated(self.cons)
576 
577  def isLocal(self):
578  """Retrieve True if constraint is only locally valid or not added to any (sub)problem"""
579  return SCIPconsIsLocal(self.cons)
580 
581  def isModifiable(self):
582  """Retrieve True if constraint is modifiable (subject to column generation)"""
583  return SCIPconsIsModifiable(self.cons)
584 
585  def isDynamic(self):
586  """Retrieve True if constraint is subject to aging"""
587  return SCIPconsIsDynamic(self.cons)
588 
589  def isRemovable(self):
590  """Retrieve True if constraint's relaxation should be removed from the LP due to aging or cleanup"""
591  return SCIPconsIsRemovable(self.cons)
592 
593  def isStickingAtNode(self):
594  """Retrieve True if constraint is only locally valid or not added to any (sub)problem"""
595  return SCIPconsIsStickingAtNode(self.cons)
596 
597  def isLinear(self):
598  """Retrieve True if constraint is linear"""
599  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self.cons))).decode('UTF-8')
600  return constype == 'linear'
601 
602  def isQuadratic(self):
603  """Retrieve True if constraint is quadratic"""
604  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(self.cons))).decode('UTF-8')
605  return constype == 'quadratic'
606 
607 
608 cdef void relayMessage(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *msg):
609  sys.stdout.write(msg.decode('UTF-8'))
610 
611 cdef void relayErrorMessage(void *messagehdlr, FILE *file, const char *msg):
612  sys.stderr.write(msg.decode('UTF-8'))
613 
614 # - remove create(), includeDefaultPlugins(), createProbBasic() methods
615 # - replace free() by "destructor"
616 # - interface SCIPfreeProb()
617 
620 cdef class Model:
621  cdef SCIP* _scip
622  # store best solution to get the solution values easier
623  cdef Solution _bestSol
624  # can be used to store problem data
625  cdef public object data
626  # make Model weak referentiable
627  cdef object __weakref__
628 
629  def __init__(self, problemName='model', defaultPlugins=True):
630  """
631  :param problemName: name of the problem (default 'model')
632  :param defaultPlugins: use default plugins? (default True)
633  """
634  if self.version() < MAJOR:
635  raise Exception("linked SCIP is not compatible to this version of PySCIPOpt - use at least version", MAJOR)
636  if self.version() < MAJOR + MINOR/10.0 + PATCH/100.0:
637  warnings.warn("linked SCIP {} is not recommended for this version of PySCIPOpt - use version {}.{}.{}".format(self.version(), MAJOR, MINOR, PATCH))
638  self.create()
639  self._bestSol = None
640  if defaultPlugins:
641  self.includeDefaultPlugins()
642  self.createProbBasic(problemName)
643 
644  def __dealloc__(self):
645  # call C function directly, because we can no longer call this object's methods, according to
646  # http://docs.cython.org/src/reference/extension_types.html#finalization-dealloc
647  PY_SCIP_CALL( SCIPfree(&self._scip) )
648 
649  def create(self):
650  """Create a new SCIP instance"""
651  PY_SCIP_CALL(SCIPcreate(&self._scip))
652 
654  """Includes all default plug-ins into SCIP"""
655  PY_SCIP_CALL(SCIPincludeDefaultPlugins(self._scip))
656 
657  def createProbBasic(self, problemName='model'):
658  """Create new problem instance with given name
659 
660  :param problemName: name of model or problem (Default value = 'model')
661 
662  """
663  n = str_conversion(problemName)
664  PY_SCIP_CALL(SCIPcreateProbBasic(self._scip, n))
665 
666  def freeProb(self):
667  """Frees problem and solution process data"""
668  PY_SCIP_CALL(SCIPfreeProb(self._scip))
669 
670  def freeTransform(self):
671  """Frees all solution process data including presolving and transformed problem, only original problem is kept"""
672  PY_SCIP_CALL(SCIPfreeTransform(self._scip))
673 
674  def version(self):
675  """Retrieve SCIP version"""
676  return SCIPversion()
677 
678  def printVersion(self):
679  """Print version, copyright information and compile mode"""
680  SCIPprintVersion(self._scip, NULL)
681 
682  def getProbName(self):
683  """Retrieve problem name"""
684  return bytes(SCIPgetProbName(self._scip)).decode('UTF-8')
685 
686  def getTotalTime(self):
687  """Retrieve the current total SCIP time in seconds, i.e. the total time since the SCIP instance has been created"""
688  return SCIPgetTotalTime(self._scip)
689 
690  def getSolvingTime(self):
691  """Retrieve the current solving time in seconds"""
692  return SCIPgetSolvingTime(self._scip)
693 
694  def getReadingTime(self):
695  """Retrieve the current reading time in seconds"""
696  return SCIPgetReadingTime(self._scip)
697 
698  def getPresolvingTime(self):
699  """Retrieve the curernt presolving time in seconds"""
700  return SCIPgetPresolvingTime(self._scip)
701 
702  def getNNodes(self):
703  """Retrieve the total number of processed nodes."""
704  return SCIPgetNNodes(self._scip)
705 
706  def getCurrentNode(self):
707  """Retrieve current node."""
708  return Node.create(SCIPgetCurrentNode(self._scip))
709 
710  def getGap(self):
711  """Retrieve the gap, i.e. |(primalbound - dualbound)/min(|primalbound|,|dualbound|)|."""
712  return SCIPgetGap(self._scip)
713 
714  def getDepth(self):
715  """Retrieve the depth of the current node"""
716  return SCIPgetDepth(self._scip)
717 
718  def infinity(self):
719  """Retrieve SCIP's infinity value"""
720  return SCIPinfinity(self._scip)
721 
722  def epsilon(self):
723  """Retrieve epsilon for e.g. equality checks"""
724  return SCIPepsilon(self._scip)
725 
726  def feastol(self):
727  """Retrieve feasibility tolerance"""
728  return SCIPfeastol(self._scip)
729 
730  def feasFrac(self, value):
731  """returns fractional part of value, i.e. x - floor(x) in feasible tolerance: x - floor(x+feastol)"""
732  return SCIPfeasFrac(self._scip, value)
733 
734  def frac(self, value):
735  """returns fractional part of value, i.e. x - floor(x) in epsilon tolerance: x - floor(x+eps)"""
736  return SCIPfrac(self._scip, value)
737 
738  def isZero(self, value):
739  """returns whether abs(value) < eps"""
740  return SCIPisZero(self._scip, value)
741 
742  def isFeasZero(self, value):
743  """returns whether abs(value) < feastol"""
744  return SCIPisFeasZero(self._scip, value)
745 
746  def isInfinity(self, value):
747  """returns whether value is SCIP's infinity"""
748  return SCIPisInfinity(self._scip, value)
749 
750  def isFeasNegative(self, value):
751  """returns whether value < -feastol"""
752  return SCIPisFeasNegative(self._scip, value)
753 
754  def isLE(self, val1, val2):
755  """returns whether val1 <= val2 + eps"""
756  return SCIPisLE(self._scip, val1, val2)
757 
758  def isLT(self, val1, val2):
759  """returns whether val1 < val2 - eps"""
760  return SCIPisLT(self._scip, val1, val2)
761 
762  def isGE(self, val1, val2):
763  """returns whether val1 >= val2 - eps"""
764  return SCIPisGE(self._scip, val1, val2)
765 
766  def isGT(self, val1, val2):
767  """returns whether val1 > val2 + eps"""
768  return SCIPisGT(self._scip, val1, val2)
769 
770  def getCondition(self, exact=False):
771  """Get the current LP's condition number
772 
773  :param exact: whether to get an estimate or the exact value (Default value = False)
774 
775  """
776  cdef SCIP_LPI* lpi
777  PY_SCIP_CALL(SCIPgetLPI(self._scip, &lpi))
778  cdef SCIP_Real quality = 0
779  if exact:
780  PY_SCIP_CALL(SCIPlpiGetRealSolQuality(lpi, SCIP_LPSOLQUALITY_EXACTCONDITION, &quality))
781  else:
782  PY_SCIP_CALL(SCIPlpiGetRealSolQuality(lpi, SCIP_LPSOLQUALITY_ESTIMCONDITION, &quality))
783 
784  return quality
785 
786  # Objective function
787 
788  def setMinimize(self):
789  """Set the objective sense to minimization."""
790  PY_SCIP_CALL(SCIPsetObjsense(self._scip, SCIP_OBJSENSE_MINIMIZE))
791 
792  def setMaximize(self):
793  """Set the objective sense to maximization."""
794  PY_SCIP_CALL(SCIPsetObjsense(self._scip, SCIP_OBJSENSE_MAXIMIZE))
795 
796  def setObjlimit(self, objlimit):
797  """Set a limit on the objective function.
798  Only solutions with objective value better than this limit are accepted.
799 
800  :param objlimit: limit on the objective function
801 
802  """
803  PY_SCIP_CALL(SCIPsetObjlimit(self._scip, objlimit))
804 
805  def getObjlimit(self):
806  """returns current limit on objective function."""
807  return SCIPgetObjlimit(self._scip)
808 
809  def setObjective(self, coeffs, sense = 'minimize', clear = 'true'):
810  """Establish the objective function as a linear expression.
811 
812  :param coeffs: the coefficients
813  :param sense: the objective sense (Default value = 'minimize')
814  :param clear: set all other variables objective coefficient to zero (Default value = 'true')
815 
816  """
817  cdef SCIP_VAR** _vars
818  cdef int _nvars
819 
820  # turn the constant value into an Expr instance for further processing
821  if not isinstance(coeffs, Expr):
822  assert(_is_number(coeffs)), "given coefficients are neither Expr or number but %s" % coeffs.__class__.__name__
823  coeffs = Expr() + coeffs
824 
825  if coeffs.degree() > 1:
826  raise ValueError("Nonlinear objective functions are not supported!")
827  if coeffs[CONST] != 0.0:
828  self.addObjoffset(coeffs[CONST])
829 
830  if clear:
831  # clear existing objective function
832  _vars = SCIPgetOrigVars(self._scip)
833  _nvars = SCIPgetNOrigVars(self._scip)
834  for i in range(_nvars):
835  PY_SCIP_CALL(SCIPchgVarObj(self._scip, _vars[i], 0.0))
836 
837  for term, coef in coeffs.terms.items():
838  # avoid CONST term of Expr
839  if term != CONST:
840  assert len(term) == 1
841  var = <Variable>term[0]
842  PY_SCIP_CALL(SCIPchgVarObj(self._scip, var.var, coef))
843 
844  if sense == "minimize":
845  self.setMinimize()
846  elif sense == "maximize":
847  self.setMaximize()
848  else:
849  raise Warning("unrecognized optimization sense: %s" % sense)
850 
851  def getObjective(self):
852  """Retrieve objective function as Expr"""
853  variables = self.getVars()
854  objective = Expr()
855  for var in variables:
856  coeff = var.getObj()
857  if coeff != 0:
858  objective += coeff * var
859  objective.normalize()
860  return objective
861 
862  def addObjoffset(self, offset, solutions = False):
863  """Add constant offset to objective
864 
865  :param offset: offset to add
866  :param solutions: add offset also to existing solutions (Default value = False)
867 
868  """
869  if solutions:
870  PY_SCIP_CALL(SCIPaddObjoffset(self._scip, offset))
871  else:
872  PY_SCIP_CALL(SCIPaddOrigObjoffset(self._scip, offset))
873 
874  def getObjoffset(self, original = True):
875  """Retrieve constant objective offset
876 
877  :param original: offset of original or transformed problem (Default value = True)
878 
879  """
880  if original:
881  return SCIPgetOrigObjoffset(self._scip)
882  else:
883  return SCIPgetTransObjoffset(self._scip)
884 
885  # Setting parameters
886  def setPresolve(self, setting):
887  """Set presolving parameter settings.
888 
889  :param setting: the parameter settings (SCIP_PARAMSETTING)
890 
891  """
892  PY_SCIP_CALL(SCIPsetPresolving(self._scip, setting, True))
893 
894  def setProbName(self, name):
895  """Set problem name"""
896  n = str_conversion(name)
897  PY_SCIP_CALL(SCIPsetProbName(self._scip, n))
898 
899  def setSeparating(self, setting):
900  """Set separating parameter settings.
901 
902  :param setting: the parameter settings (SCIP_PARAMSETTING)
903 
904  """
905  PY_SCIP_CALL(SCIPsetSeparating(self._scip, setting, True))
906 
907  def setHeuristics(self, setting):
908  """Set heuristics parameter settings.
909 
910  :param setting: the parameter setting (SCIP_PARAMSETTING)
911 
912  """
913  PY_SCIP_CALL(SCIPsetHeuristics(self._scip, setting, True))
914 
915  def disablePropagation(self, onlyroot=False):
916  """Disables propagation in SCIP to avoid modifying the original problem during transformation.
917 
918  :param onlyroot: use propagation when root processing is finished (Default value = False)
919 
920  """
921  self.setIntParam("propagating/maxroundsroot", 0)
922  if not onlyroot:
923  self.setIntParam("propagating/maxrounds", 0)
924 
925  def writeProblem(self, filename='model.cip', trans=False):
926  """Write current model/problem to a file.
927 
928  :param filename: the name of the file to be used (Default value = 'model.cip')
929  :param trans: indicates whether the transformed problem is written to file (Default value = False)
930 
931  """
932  fn = str_conversion(filename)
933  fn, ext = splitext(fn)
934  if len(ext) == 0:
935  ext = str_conversion('.cip')
936  fn = fn + ext
937  ext = ext[1:]
938  if trans:
939  PY_SCIP_CALL(SCIPwriteTransProblem(self._scip, fn, ext, False))
940  else:
941  PY_SCIP_CALL(SCIPwriteOrigProblem(self._scip, fn, ext, False))
942  print('wrote problem to file ' + str(fn))
943 
944  # Variable Functions
945 
946  def addVar(self, name='', vtype='C', lb=0.0, ub=None, obj=0.0, pricedVar = False):
947  """Create a new variable. Default variable is non-negative and continuous.
948 
949  :param name: name of the variable, generic if empty (Default value = '')
950  :param vtype: type of the variable (Default value = 'C')
951  :param lb: lower bound of the variable, use None for -infinity (Default value = 0.0)
952  :param ub: upper bound of the variable, use None for +infinity (Default value = None)
953  :param obj: objective value of variable (Default value = 0.0)
954  :param pricedVar: is the variable a pricing candidate? (Default value = False)
955 
956  """
957 
958  # replace empty name with generic one
959  if name == '':
960  name = 'x'+str(SCIPgetNVars(self._scip)+1)
961 
962  cname = str_conversion(name)
963  if ub is None:
964  ub = SCIPinfinity(self._scip)
965  if lb is None:
966  lb = -SCIPinfinity(self._scip)
967  cdef SCIP_VAR* scip_var
968  vtype = vtype.upper()
969  if vtype in ['C', 'CONTINUOUS']:
970  PY_SCIP_CALL(SCIPcreateVarBasic(self._scip, &scip_var, cname, lb, ub, obj, SCIP_VARTYPE_CONTINUOUS))
971  elif vtype in ['B', 'BINARY']:
972  lb = 0.0
973  ub = 1.0
974  PY_SCIP_CALL(SCIPcreateVarBasic(self._scip, &scip_var, cname, lb, ub, obj, SCIP_VARTYPE_BINARY))
975  elif vtype in ['I', 'INTEGER']:
976  PY_SCIP_CALL(SCIPcreateVarBasic(self._scip, &scip_var, cname, lb, ub, obj, SCIP_VARTYPE_INTEGER))
977  else:
978  raise Warning("unrecognized variable type")
979 
980  if pricedVar:
981  PY_SCIP_CALL(SCIPaddPricedVar(self._scip, scip_var, 1.0))
982  else:
983  PY_SCIP_CALL(SCIPaddVar(self._scip, scip_var))
984 
985  pyVar = Variable.create(scip_var)
986 
987  #setting the variable data
988  SCIPvarSetData(scip_var, <SCIP_VARDATA*>pyVar)
989  PY_SCIP_CALL(SCIPreleaseVar(self._scip, &scip_var))
990  return pyVar
991 
992  def releaseVar(self, Variable var):
993  """Release the variable.
994 
995  :param Variable var: variable to be released
996 
997  """
998  PY_SCIP_CALL(SCIPreleaseVar(self._scip, &var.var))
999 
1000  def getTransformedVar(self, Variable var):
1001  """Retrieve the transformed variable.
1002 
1003  :param Variable var: original variable to get the transformed of
1004 
1005  """
1006  cdef SCIP_VAR* _tvar
1007  PY_SCIP_CALL(SCIPtransformVar(self._scip, var.var, &_tvar))
1008  return Variable.create(_tvar)
1009 
1010  def addVarLocks(self, Variable var, nlocksdown, nlocksup):
1011  """adds given values to lock numbers of variable for rounding
1012 
1013  :param Variable var: variable to adjust the locks for
1014  :param nlocksdown: new number of down locks
1015  :param nlocksup: new number of up locks
1016 
1017  """
1018  PY_SCIP_CALL(SCIPaddVarLocks(self._scip, var.var, nlocksdown, nlocksup))
1019 
1020  def fixVar(self, Variable var, val):
1021  """Fixes the variable var to the value val if possible.
1022 
1023  :param Variable var: variable to fix
1024  :param val: float, the fix value
1025  :return: tuple (infeasible, fixed) of booleans
1026 
1027  """
1028  cdef SCIP_Bool infeasible
1029  cdef SCIP_Bool fixed
1030  PY_SCIP_CALL(SCIPfixVar(self._scip, var.var, val, &infeasible, &fixed))
1031  return infeasible, fixed
1032 
1033  def delVar(self, Variable var):
1034  """Delete a variable.
1035 
1036  :param var: the variable which shall be deleted
1037  :return: bool, was deleting succesful
1038 
1039  """
1040  cdef SCIP_Bool deleted
1041  PY_SCIP_CALL(SCIPdelVar(self._scip, var.var, &deleted))
1042  return deleted
1043 
1044  def tightenVarLb(self, Variable var, lb, force=False):
1045  """Tighten the lower bound in preprocessing or current node, if the bound is tighter.
1046 
1047  :param var: SCIP variable
1048  :param lb: possible new lower bound
1049  :param force: force tightening even if below bound strengthening tolerance
1050  :return: tuple of bools, (infeasible, tightened)
1051  infeasible: whether new domain is empty
1052  tightened: whether the bound was tightened
1053 
1054  """
1055  cdef SCIP_Bool infeasible
1056  cdef SCIP_Bool tightened
1057  PY_SCIP_CALL(SCIPtightenVarLb(self._scip, var.var, lb, force, &infeasible, &tightened))
1058  return infeasible, tightened
1059 
1060 
1061  def tightenVarUb(self, Variable var, ub, force=False):
1062  """Tighten the upper bound in preprocessing or current node, if the bound is tighter.
1063 
1064  :param var: SCIP variable
1065  :param ub: possible new upper bound
1066  :param force: force tightening even if below bound strengthening tolerance
1067  :return: tuple of bools, (infeasible, tightened)
1068  infeasible: whether new domain is empty
1069  tightened: whether the bound was tightened
1070 
1071  """
1072  cdef SCIP_Bool infeasible
1073  cdef SCIP_Bool tightened
1074  PY_SCIP_CALL(SCIPtightenVarUb(self._scip, var.var, ub, force, &infeasible, &tightened))
1075  return infeasible, tightened
1076 
1077 
1078  def tightenVarUbGlobal(self, Variable var, ub, force=False):
1079  """Tighten the global upper bound, if the bound is tighter.
1080 
1081  :param var: SCIP variable
1082  :param ub: possible new upper bound
1083  :param force: force tightening even if below bound strengthening tolerance
1084  :return: tuple of bools, (infeasible, tightened)
1085  infeasible: whether new domain is empty
1086  tightened: whether the bound was tightened
1087 
1088  """
1089  cdef SCIP_Bool infeasible
1090  cdef SCIP_Bool tightened
1091  PY_SCIP_CALL(SCIPtightenVarUbGlobal(self._scip, var.var, ub, force, &infeasible, &tightened))
1092  return infeasible, tightened
1093 
1094  def tightenVarLbGlobal(self, Variable var, lb, force=False):
1095  """Tighten the global upper bound, if the bound is tighter.
1096 
1097  :param var: SCIP variable
1098  :param lb: possible new upper bound
1099  :param force: force tightening even if below bound strengthening tolerance
1100  :return: tuple of bools, (infeasible, tightened)
1101  infeasible: whether new domain is empty
1102  tightened: whether the bound was tightened
1103 
1104  """
1105  cdef SCIP_Bool infeasible
1106  cdef SCIP_Bool tightened
1107  PY_SCIP_CALL(SCIPtightenVarLbGlobal(self._scip, var.var, lb, force, &infeasible, &tightened))
1108  return infeasible, tightened
1109 
1110  def chgVarLb(self, Variable var, lb):
1111  """Changes the lower bound of the specified variable.
1112 
1113  :param Variable var: variable to change bound of
1114  :param lb: new lower bound (set to None for -infinity)
1115 
1116  """
1117  if lb is None:
1118  lb = -SCIPinfinity(self._scip)
1119  PY_SCIP_CALL(SCIPchgVarLb(self._scip, var.var, lb))
1120 
1121  def chgVarUb(self, Variable var, ub):
1122  """Changes the upper bound of the specified variable.
1123 
1124  :param Variable var: variable to change bound of
1125  :param ub: new upper bound (set to None for +infinity)
1126 
1127  """
1128  if ub is None:
1129  ub = SCIPinfinity(self._scip)
1130  PY_SCIP_CALL(SCIPchgVarUb(self._scip, var.var, ub))
1131 
1132 
1133  def chgVarLbGlobal(self, Variable var, lb):
1134  """Changes the global lower bound of the specified variable.
1135 
1136  :param Variable var: variable to change bound of
1137  :param lb: new lower bound (set to None for -infinity)
1138 
1139  """
1140  if lb is None:
1141  lb = -SCIPinfinity(self._scip)
1142  PY_SCIP_CALL(SCIPchgVarLbGlobal(self._scip, var.var, lb))
1143 
1144  def chgVarUbGlobal(self, Variable var, ub):
1145  """Changes the global upper bound of the specified variable.
1146 
1147  :param Variable var: variable to change bound of
1148  :param ub: new upper bound (set to None for +infinity)
1149 
1150  """
1151  if ub is None:
1152  ub = SCIPinfinity(self._scip)
1153  PY_SCIP_CALL(SCIPchgVarUbGlobal(self._scip, var.var, ub))
1154 
1155  def chgVarLbNode(self, Node node, Variable var, lb):
1156  """Changes the lower bound of the specified variable at the given node.
1157 
1158  :param Variable var: variable to change bound of
1159  :param lb: new lower bound (set to None for -infinity)
1160  """
1161 
1162  if lb is None:
1163  lb = -SCIPinfinity(self._scip)
1164  PY_SCIP_CALL(SCIPchgVarLbNode(self._scip, node.node, var.var, lb))
1165 
1166  def chgVarUbNode(self, Node node, Variable var, ub):
1167  """Changes the upper bound of the specified variable at the given node.
1168 
1169  :param Variable var: variable to change bound of
1170  :param ub: new upper bound (set to None for +infinity)
1171 
1172  """
1173  if ub is None:
1174  ub = SCIPinfinity(self._scip)
1175  PY_SCIP_CALL(SCIPchgVarUbNode(self._scip, node.node, var.var, ub))
1176 
1177  def chgVarType(self, Variable var, vtype):
1178  """Changes the type of a variable
1179 
1180  :param Variable var: variable to change type of
1181  :param vtype: new variable type
1182 
1183  """
1184  cdef SCIP_Bool infeasible
1185  if vtype in ['C', 'CONTINUOUS']:
1186  PY_SCIP_CALL(SCIPchgVarType(self._scip, var.var, SCIP_VARTYPE_CONTINUOUS, &infeasible))
1187  elif vtype in ['B', 'BINARY']:
1188  PY_SCIP_CALL(SCIPchgVarType(self._scip, var.var, SCIP_VARTYPE_BINARY, &infeasible))
1189  elif vtype in ['I', 'INTEGER']:
1190  PY_SCIP_CALL(SCIPchgVarType(self._scip, var.var, SCIP_VARTYPE_INTEGER, &infeasible))
1191  else:
1192  raise Warning("unrecognized variable type")
1193  if infeasible:
1194  print('could not change variable type of variable %s' % var)
1195 
1196  def getVars(self, transformed=False):
1197  """Retrieve all variables.
1198 
1199  :param transformed: get transformed variables instead of original (Default value = False)
1200 
1201  """
1202  cdef SCIP_VAR** _vars
1203  cdef SCIP_VAR* _var
1204  cdef int _nvars
1205  vars = []
1206 
1207  if transformed:
1208  _vars = SCIPgetVars(self._scip)
1209  _nvars = SCIPgetNVars(self._scip)
1210  else:
1211  _vars = SCIPgetOrigVars(self._scip)
1212  _nvars = SCIPgetNOrigVars(self._scip)
1213 
1214  return [Variable.create(_vars[i]) for i in range(_nvars)]
1215 
1216  def getNVars(self):
1217  """Retrieve number of variables in the problems"""
1218  return SCIPgetNVars(self._scip)
1219 
1220  def getNConss(self):
1221  """Retrieve the number of constraints."""
1222  return SCIPgetNConss(self._scip)
1223 
1224  def updateNodeLowerbound(self, Node node, lb):
1225  """if given value is larger than the node's lower bound (in transformed problem),
1226  sets the node's lower bound to the new value
1227 
1228  :param node: Node, the node to update
1229  :param newbound: float, new bound (if greater) for the node
1230 
1231  """
1232  PY_SCIP_CALL(SCIPupdateNodeLowerbound(self._scip, node.node, lb))
1233 
1234  # LP Methods
1235  def getLPSolstat(self):
1236  """Gets solution status of current LP"""
1237  return SCIPgetLPSolstat(self._scip)
1238 
1239 
1240  def constructLP(self):
1241  """makes sure that the LP of the current node is loaded and
1242  may be accessed through the LP information methods
1243 
1244  :return: bool cutoff, i.e. can the node be cut off?
1245 
1246  """
1247  cdef SCIP_Bool cutoff
1248  PY_SCIP_CALL(SCIPconstructLP(self._scip, &cutoff))
1249  return cutoff
1250 
1251  def getLPObjVal(self):
1252  """gets objective value of current LP (which is the sum of column and loose objective value)"""
1253 
1254  return SCIPgetLPObjval(self._scip)
1255 
1256  def getLPColsData(self):
1257  """Retrieve current LP columns"""
1258  cdef SCIP_COL** cols
1259  cdef int ncols
1260 
1261  PY_SCIP_CALL(SCIPgetLPColsData(self._scip, &cols, &ncols))
1262  return [Column.create(cols[i]) for i in range(ncols)]
1263 
1264  def getLPRowsData(self):
1265  """Retrieve current LP rows"""
1266  cdef SCIP_ROW** rows
1267  cdef int nrows
1268 
1269  PY_SCIP_CALL(SCIPgetLPRowsData(self._scip, &rows, &nrows))
1270  return [Row.create(rows[i]) for i in range(nrows)]
1271 
1272  def getNLPRows(self):
1273  """Retrieve the number of rows currently in the LP"""
1274  return SCIPgetNLPRows(self._scip)
1275 
1276  def getNLPCols(self):
1277  """Retrieve the number of cols currently in the LP"""
1278  return SCIPgetNLPCols(self._scip)
1279 
1280  def getLPBasisInd(self):
1281  """Gets all indices of basic columns and rows: index i >= 0 corresponds to column i, index i < 0 to row -i-1"""
1282  cdef int nrows = SCIPgetNLPRows(self._scip)
1283  cdef int* inds = <int *> malloc(nrows * sizeof(int))
1284 
1285  PY_SCIP_CALL(SCIPgetLPBasisInd(self._scip, inds))
1286  result = [inds[i] for i in range(nrows)]
1287  free(inds)
1288  return result
1289 
1290  def getLPBInvRow(self, row):
1291  """gets a row from the inverse basis matrix B^-1"""
1292  # TODO: sparsity information
1293  cdef int nrows = SCIPgetNLPRows(self._scip)
1294  cdef SCIP_Real* coefs = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
1295 
1296  PY_SCIP_CALL(SCIPgetLPBInvRow(self._scip, row, coefs, NULL, NULL))
1297  result = [coefs[i] for i in range(nrows)]
1298  free(coefs)
1299  return result
1300 
1301  def getLPBInvARow(self, row):
1302  """gets a row from B^-1 * A"""
1303  # TODO: sparsity information
1304  cdef int ncols = SCIPgetNLPCols(self._scip)
1305  cdef SCIP_Real* coefs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
1306 
1307  PY_SCIP_CALL(SCIPgetLPBInvARow(self._scip, row, NULL, coefs, NULL, NULL))
1308  result = [coefs[i] for i in range(ncols)]
1309  free(coefs)
1310  return result
1311 
1312  def isLPSolBasic(self):
1313  """returns whether the current LP solution is basic, i.e. is defined by a valid simplex basis"""
1314  return SCIPisLPSolBasic(self._scip)
1315 
1316  #TODO: documentation!!
1317  # LP Row Methods
1318  def createEmptyRowSepa(self, Sepa sepa, name="row", lhs = 0.0, rhs = None, local = True, modifiable = False, removable = True):
1319  """creates and captures an LP row without any coefficients from a separator
1320 
1321  :param sepa: separator that creates the row
1322  :param name: name of row (Default value = "row")
1323  :param lhs: left hand side of row (Default value = 0)
1324  :param rhs: right hand side of row (Default value = None)
1325  :param local: is row only valid locally? (Default value = True)
1326  :param modifiable: is row modifiable during node processing (subject to column generation)? (Default value = False)
1327  :param removable: should the row be removed from the LP due to aging or cleanup? (Default value = True)
1328  """
1329  cdef SCIP_ROW* row
1330  lhs = -SCIPinfinity(self._scip) if lhs is None else lhs
1331  rhs = SCIPinfinity(self._scip) if rhs is None else rhs
1332  scip_sepa = SCIPfindSepa(self._scip, str_conversion(sepa.name))
1333  PY_SCIP_CALL(SCIPcreateEmptyRowSepa(self._scip, &row, scip_sepa, str_conversion(name), lhs, rhs, local, modifiable, removable))
1334  PyRow = Row.create(row)
1335  return PyRow
1336 
1337  def createEmptyRowUnspec(self, name="row", lhs = 0.0, rhs = None, local = True, modifiable = False, removable = True):
1338  """creates and captures an LP row without any coefficients from an unspecified source
1339 
1340  :param name: name of row (Default value = "row")
1341  :param lhs: left hand side of row (Default value = 0)
1342  :param rhs: right hand side of row (Default value = None)
1343  :param local: is row only valid locally? (Default value = True)
1344  :param modifiable: is row modifiable during node processing (subject to column generation)? (Default value = False)
1345  :param removable: should the row be removed from the LP due to aging or cleanup? (Default value = True)
1346  """
1347  cdef SCIP_ROW* row
1348  lhs = -SCIPinfinity(self._scip) if lhs is None else lhs
1349  rhs = SCIPinfinity(self._scip) if rhs is None else rhs
1350  PY_SCIP_CALL(SCIPcreateEmptyRowUnspec(self._scip, &row, str_conversion(name), lhs, rhs, local, modifiable, removable))
1351  PyRow = Row.create(row)
1352  return PyRow
1353 
1354  def getRowActivity(self, Row row):
1355  """returns the activity of a row in the last LP or pseudo solution"""
1356  return SCIPgetRowActivity(self._scip, row.row)
1357 
1358  def getRowLPActivity(self, Row row):
1359  """returns the activity of a row in the last LP solution"""
1360  return SCIPgetRowLPActivity(self._scip, row.row)
1361 
1362  # TODO: do we need this? (also do we need release var??)
1363  def releaseRow(self, Row row not None):
1364  """decreases usage counter of LP row, and frees memory if necessary"""
1365  PY_SCIP_CALL(SCIPreleaseRow(self._scip, &row.row))
1366 
1367  def cacheRowExtensions(self, Row row not None):
1368  """informs row, that all subsequent additions of variables to the row should be cached and not directly applied;
1369  after all additions were applied, flushRowExtensions() must be called;
1370  while the caching of row extensions is activated, information methods of the row give invalid results;
1371  caching should be used, if a row is build with addVarToRow() calls variable by variable to increase the performance"""
1372  PY_SCIP_CALL(SCIPcacheRowExtensions(self._scip, row.row))
1373 
1374  def flushRowExtensions(self, Row row not None):
1375  """flushes all cached row extensions after a call of cacheRowExtensions() and merges coefficients with equal columns into a single coefficient"""
1376  PY_SCIP_CALL(SCIPflushRowExtensions(self._scip, row.row))
1377 
1378  def addVarToRow(self, Row row not None, Variable var not None, value):
1379  """resolves variable to columns and adds them with the coefficient to the row"""
1380  PY_SCIP_CALL(SCIPaddVarToRow(self._scip, row.row, var.var, value))
1381 
1382  def printRow(self, Row row not None):
1383  """Prints row."""
1384  PY_SCIP_CALL(SCIPprintRow(self._scip, row.row, NULL))
1385 
1386  # Cutting Plane Methods
1387  def addPoolCut(self, Row row not None):
1388  """if not already existing, adds row to global cut pool"""
1389  PY_SCIP_CALL(SCIPaddPoolCut(self._scip, row.row))
1390 
1391  def getCutEfficacy(self, Row cut not None, Solution sol = None):
1392  """returns efficacy of the cut with respect to the given primal solution or the current LP solution: e = -feasibility/norm"""
1393  return SCIPgetCutEfficacy(self._scip, NULL if sol is None else sol.sol, cut.row)
1394 
1395  def isCutEfficacious(self, Row cut not None, Solution sol = None):
1396  """ 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"""
1397  return SCIPisCutEfficacious(self._scip, NULL if sol is None else sol.sol, cut.row)
1398 
1399  def addCut(self, Row cut not None, forcecut = False):
1400  """adds cut to separation storage and returns whether cut has been detected to be infeasible for local bounds"""
1401  cdef SCIP_Bool infeasible
1402  PY_SCIP_CALL(SCIPaddRow(self._scip, cut.row, forcecut, &infeasible))
1403  return infeasible
1404 
1405  def getNCuts(self):
1406  """Retrieve total number of cuts in storage"""
1407  return SCIPgetNCuts(self._scip)
1408 
1409  def getNCutsApplied(self):
1410  """Retrieve number of currently applied cuts"""
1411  return SCIPgetNCutsApplied(self._scip)
1412 
1413  # Constraint functions
1414  def addCons(self, cons, name='', initial=True, separate=True,
1415  enforce=True, check=True, propagate=True, local=False,
1416  modifiable=False, dynamic=False, removable=False,
1417  stickingatnode=False):
1418  """Add a linear or quadratic constraint.
1419 
1420  :param cons: list of coefficients
1421  :param name: the name of the constraint, generic name if empty (Default value = '')
1422  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1423  :param separate: should the constraint be separated during LP processing? (Default value = True)
1424  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1425  :param check: should the constraint be checked during for feasibility? (Default value = True)
1426  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1427  :param local: is the constraint only valid locally? (Default value = False)
1428  :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False)
1429  :param dynamic: is the constraint subject to aging? (Default value = False)
1430  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1431  :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)
1432 
1433  """
1434  assert isinstance(cons, ExprCons), "given constraint is not ExprCons but %s" % cons.__class__.__name__
1435 
1436  # replace empty name with generic one
1437  if name == '':
1438  name = 'c'+str(SCIPgetNConss(self._scip)+1)
1439 
1440  kwargs = dict(name=name, initial=initial, separate=separate,
1441  enforce=enforce, check=check,
1442  propagate=propagate, local=local,
1443  modifiable=modifiable, dynamic=dynamic,
1444  removable=removable,
1445  stickingatnode=stickingatnode)
1446  kwargs['lhs'] = -SCIPinfinity(self._scip) if cons.lhs is None else cons.lhs
1447  kwargs['rhs'] = SCIPinfinity(self._scip) if cons.rhs is None else cons.rhs
1448 
1449  deg = cons.expr.degree()
1450  if deg <= 1:
1451  return self._addLinCons(cons, **kwargs)
1452  elif deg <= 2:
1453  return self._addQuadCons(cons, **kwargs)
1454  elif deg == float('inf'): # general nonlinear
1455  return self._addGenNonlinearCons(cons, **kwargs)
1456  else:
1457  return self._addNonlinearCons(cons, **kwargs)
1458 
1459  def _addLinCons(self, ExprCons lincons, **kwargs):
1460  assert isinstance(lincons, ExprCons), "given constraint is not ExprCons but %s" % lincons.__class__.__name__
1461 
1462  assert lincons.expr.degree() <= 1, "given constraint is not linear, degree == %d" % lincons.expr.degree()
1463  terms = lincons.expr.terms
1464 
1465  cdef SCIP_CONS* scip_cons
1466  PY_SCIP_CALL(SCIPcreateConsLinear(
1467  self._scip, &scip_cons, str_conversion(kwargs['name']), 0, NULL, NULL,
1468  kwargs['lhs'], kwargs['rhs'], kwargs['initial'],
1469  kwargs['separate'], kwargs['enforce'], kwargs['check'],
1470  kwargs['propagate'], kwargs['local'], kwargs['modifiable'],
1471  kwargs['dynamic'], kwargs['removable'], kwargs['stickingatnode']))
1472 
1473  for key, coeff in terms.items():
1474  var = <Variable>key[0]
1475  PY_SCIP_CALL(SCIPaddCoefLinear(self._scip, scip_cons, var.var, <SCIP_Real>coeff))
1476 
1477  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1478  PyCons = Constraint.create(scip_cons)
1479  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1480 
1481  return PyCons
1482 
1483  def _addQuadCons(self, ExprCons quadcons, **kwargs):
1484  terms = quadcons.expr.terms
1485  assert quadcons.expr.degree() <= 2, "given constraint is not quadratic, degree == %d" % quadcons.expr.degree()
1486 
1487  cdef SCIP_CONS* scip_cons
1488  PY_SCIP_CALL(SCIPcreateConsQuadratic(
1489  self._scip, &scip_cons, str_conversion(kwargs['name']),
1490  0, NULL, NULL, # linear
1491  0, NULL, NULL, NULL, # quadratc
1492  kwargs['lhs'], kwargs['rhs'],
1493  kwargs['initial'], kwargs['separate'], kwargs['enforce'],
1494  kwargs['check'], kwargs['propagate'], kwargs['local'],
1495  kwargs['modifiable'], kwargs['dynamic'], kwargs['removable']))
1496 
1497  for v, c in terms.items():
1498  if len(v) == 1: # linear
1499  var = <Variable>v[0]
1500  PY_SCIP_CALL(SCIPaddLinearVarQuadratic(self._scip, scip_cons, var.var, c))
1501  else: # quadratic
1502  assert len(v) == 2, 'term length must be 1 or 2 but it is %s' % len(v)
1503  var1, var2 = <Variable>v[0], <Variable>v[1]
1504  PY_SCIP_CALL(SCIPaddBilinTermQuadratic(self._scip, scip_cons, var1.var, var2.var, c))
1505 
1506  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1507  PyCons = Constraint.create(scip_cons)
1508  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1509  return PyCons
1510 
1511  def _addNonlinearCons(self, ExprCons cons, **kwargs):
1512  cdef SCIP_EXPR* expr
1513  cdef SCIP_EXPR** varexprs
1514  cdef SCIP_EXPRDATA_MONOMIAL** monomials
1515  cdef int* idxs
1516  cdef SCIP_EXPRTREE* exprtree
1517  cdef SCIP_VAR** vars
1518  cdef SCIP_CONS* scip_cons
1519 
1520  terms = cons.expr.terms
1521 
1522  # collect variables
1523  variables = {var.ptr():var for term in terms for var in term}
1524  variables = list(variables.values())
1525  varindex = {var.ptr():idx for (idx,var) in enumerate(variables)}
1526 
1527  # create variable expressions
1528  varexprs = <SCIP_EXPR**> malloc(len(varindex) * sizeof(SCIP_EXPR*))
1529  for idx in varindex.values():
1530  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &expr, SCIP_EXPR_VARIDX, <int>idx) )
1531  varexprs[idx] = expr
1532 
1533  # create monomials for terms
1534  monomials = <SCIP_EXPRDATA_MONOMIAL**> malloc(len(terms) * sizeof(SCIP_EXPRDATA_MONOMIAL*))
1535  for i, (term, coef) in enumerate(terms.items()):
1536  idxs = <int*> malloc(len(term) * sizeof(int))
1537  for j, var in enumerate(term):
1538  idxs[j] = varindex[var.ptr()]
1539  PY_SCIP_CALL( SCIPexprCreateMonomial(SCIPblkmem(self._scip), &monomials[i], <SCIP_Real>coef, <int>len(term), idxs, NULL) )
1540  free(idxs)
1541 
1542  # create polynomial from monomials
1543  PY_SCIP_CALL( SCIPexprCreatePolynomial(SCIPblkmem(self._scip), &expr,
1544  <int>len(varindex), varexprs,
1545  <int>len(terms), monomials, 0.0, <SCIP_Bool>True) )
1546 
1547  # create expression tree
1548  PY_SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(self._scip), &exprtree, expr, <int>len(variables), 0, NULL) )
1549  vars = <SCIP_VAR**> malloc(len(variables) * sizeof(SCIP_VAR*))
1550  for idx, var in enumerate(variables): # same as varindex
1551  vars[idx] = (<Variable>var).var
1552  PY_SCIP_CALL( SCIPexprtreeSetVars(exprtree, <int>len(variables), vars) )
1553 
1554  # create nonlinear constraint for exprtree
1555  PY_SCIP_CALL( SCIPcreateConsNonlinear(
1556  self._scip, &scip_cons, str_conversion(kwargs['name']),
1557  0, NULL, NULL, # linear
1558  1, &exprtree, NULL, # nonlinear
1559  kwargs['lhs'], kwargs['rhs'],
1560  kwargs['initial'], kwargs['separate'], kwargs['enforce'],
1561  kwargs['check'], kwargs['propagate'], kwargs['local'],
1562  kwargs['modifiable'], kwargs['dynamic'], kwargs['removable'],
1563  kwargs['stickingatnode']) )
1564  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1565  PyCons = Constraint.create(scip_cons)
1566  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1567  PY_SCIP_CALL( SCIPexprtreeFree(&exprtree) )
1568  free(vars)
1569  free(monomials)
1570  free(varexprs)
1571  return PyCons
1572 
1573  def _addGenNonlinearCons(self, ExprCons cons, **kwargs):
1574  cdef SCIP_EXPR** childrenexpr
1575  cdef SCIP_EXPR** scipexprs
1576  cdef SCIP_EXPRTREE* exprtree
1577  cdef SCIP_CONS* scip_cons
1578  cdef int nchildren
1579 
1580  # get arrays from python's expression tree
1581  expr = cons.expr
1582  nodes = expr_to_nodes(expr)
1583  op2idx = Operator.operatorIndexDic
1584 
1585  # in nodes we have a list of tuples: each tuple is of the form
1586  # (operator, [indices]) where indices are the indices of the tuples
1587  # that are the children of this operator. This is sorted,
1588  # so we are going to do is:
1589  # loop over the nodes and create the expression of each
1590  # Note1: when the operator is SCIP_EXPR_CONST, [indices] stores the value
1591  # Note2: we need to compute the number of variable operators to find out
1592  # how many variables are there.
1593  nvars = 0
1594  for node in nodes:
1595  if op2idx[node[0]] == SCIP_EXPR_VARIDX:
1596  nvars += 1
1597  vars = <SCIP_VAR**> malloc(nvars * sizeof(SCIP_VAR*))
1598 
1599  varpos = 0
1600  scipexprs = <SCIP_EXPR**> malloc(len(nodes) * sizeof(SCIP_EXPR*))
1601  for i,node in enumerate(nodes):
1602  op = node[0]
1603  opidx = op2idx[op]
1604  if opidx == SCIP_EXPR_VARIDX:
1605  assert len(node[1]) == 1
1606  pyvar = node[1][0] # for vars we store the actual var!
1607  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &scipexprs[i], opidx, <int>varpos) )
1608  vars[varpos] = (<Variable>pyvar).var
1609  varpos += 1
1610  continue
1611  if opidx == SCIP_EXPR_CONST:
1612  assert len(node[1]) == 1
1613  value = node[1][0]
1614  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &scipexprs[i], opidx, <SCIP_Real>value) )
1615  continue
1616  if opidx == SCIP_EXPR_SUM or opidx == SCIP_EXPR_PRODUCT:
1617  nchildren = len(node[1])
1618  childrenexpr = <SCIP_EXPR**> malloc(nchildren * sizeof(SCIP_EXPR*))
1619  for c, pos in enumerate(node[1]):
1620  childrenexpr[c] = scipexprs[pos]
1621  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &scipexprs[i], opidx, nchildren, childrenexpr) )
1622 
1623  free(childrenexpr);
1624  continue
1625  if opidx == SCIP_EXPR_REALPOWER:
1626  # the second child is the exponent which is a const
1627  valuenode = nodes[node[1][1]]
1628  assert op2idx[valuenode[0]] == SCIP_EXPR_CONST
1629  exponent = valuenode[1][0]
1630  if float(exponent).is_integer():
1631  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &scipexprs[i], SCIP_EXPR_INTPOWER, scipexprs[node[1][0]], <int>exponent) )
1632  else:
1633  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &scipexprs[i], opidx, scipexprs[node[1][0]], <SCIP_Real>exponent) )
1634  continue
1635  if opidx == SCIP_EXPR_EXP or opidx == SCIP_EXPR_LOG or opidx == SCIP_EXPR_SQRT or opidx == SCIP_EXPR_ABS:
1636  assert len(node[1]) == 1
1637  PY_SCIP_CALL( SCIPexprCreate(SCIPblkmem(self._scip), &scipexprs[i], opidx, scipexprs[node[1][0]]) )
1638  continue
1639  # default:
1640  raise NotImplementedError
1641  assert varpos == nvars
1642 
1643  # create expression tree
1644  PY_SCIP_CALL( SCIPexprtreeCreate(SCIPblkmem(self._scip), &exprtree, scipexprs[len(nodes) - 1], nvars, 0, NULL) );
1645  PY_SCIP_CALL( SCIPexprtreeSetVars(exprtree, <int>nvars, vars) );
1646 
1647  # create nonlinear constraint for exprtree
1648  PY_SCIP_CALL( SCIPcreateConsNonlinear(
1649  self._scip, &scip_cons, str_conversion(kwargs['name']),
1650  0, NULL, NULL, # linear
1651  1, &exprtree, NULL, # nonlinear
1652  kwargs['lhs'], kwargs['rhs'],
1653  kwargs['initial'], kwargs['separate'], kwargs['enforce'],
1654  kwargs['check'], kwargs['propagate'], kwargs['local'],
1655  kwargs['modifiable'], kwargs['dynamic'], kwargs['removable'],
1656  kwargs['stickingatnode']) )
1657  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1658  PyCons = Constraint.create(scip_cons)
1659  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1660  PY_SCIP_CALL( SCIPexprtreeFree(&exprtree) )
1661 
1662  # free more memory
1663  free(scipexprs)
1664  free(vars)
1665 
1666  return PyCons
1667 
1668  def addConsCoeff(self, Constraint cons, Variable var, coeff):
1669  """Add coefficient to the linear constraint (if non-zero).
1670 
1671  :param Constraint cons: constraint to be changed
1672  :param Variable var: variable to be added
1673  :param coeff: coefficient of new variable
1674 
1675  """
1676  PY_SCIP_CALL(SCIPaddCoefLinear(self._scip, cons.cons, var.var, coeff))
1677 
1678  def addConsSOS1(self, vars, weights=None, name="SOS1cons",
1679  initial=True, separate=True, enforce=True, check=True,
1680  propagate=True, local=False, dynamic=False,
1681  removable=False, stickingatnode=False):
1682  """Add an SOS1 constraint.
1683 
1684  :param vars: list of variables to be included
1685  :param weights: list of weights (Default value = None)
1686  :param name: name of the constraint (Default value = "SOS1cons")
1687  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1688  :param separate: should the constraint be separated during LP processing? (Default value = True)
1689  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1690  :param check: should the constraint be checked for feasibility? (Default value = True)
1691  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1692  :param local: is the constraint only valid locally? (Default value = False)
1693  :param dynamic: is the constraint subject to aging? (Default value = False)
1694  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1695  :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)
1696 
1697  """
1698  cdef SCIP_CONS* scip_cons
1699  cdef int _nvars
1700 
1701  PY_SCIP_CALL(SCIPcreateConsSOS1(self._scip, &scip_cons, str_conversion(name), 0, NULL, NULL,
1702  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
1703 
1704  if weights is None:
1705  for v in vars:
1706  var = <Variable>v
1707  PY_SCIP_CALL(SCIPappendVarSOS1(self._scip, scip_cons, var.var))
1708  else:
1709  nvars = len(vars)
1710  for i in range(nvars):
1711  var = <Variable>vars[i]
1712  PY_SCIP_CALL(SCIPaddVarSOS1(self._scip, scip_cons, var.var, weights[i]))
1713 
1714  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1715  return Constraint.create(scip_cons)
1716 
1717  def addConsSOS2(self, vars, weights=None, name="SOS2cons",
1718  initial=True, separate=True, enforce=True, check=True,
1719  propagate=True, local=False, dynamic=False,
1720  removable=False, stickingatnode=False):
1721  """Add an SOS2 constraint.
1722 
1723  :param vars: list of variables to be included
1724  :param weights: list of weights (Default value = None)
1725  :param name: name of the constraint (Default value = "SOS2cons")
1726  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1727  :param separate: should the constraint be separated during LP processing? (Default value = True)
1728  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1729  :param check: should the constraint be checked for feasibility? (Default value = True)
1730  :param propagate: is the constraint only valid locally? (Default value = True)
1731  :param local: is the constraint only valid locally? (Default value = False)
1732  :param dynamic: is the constraint subject to aging? (Default value = False)
1733  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1734  :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)
1735 
1736  """
1737  cdef SCIP_CONS* scip_cons
1738  cdef int _nvars
1739 
1740  PY_SCIP_CALL(SCIPcreateConsSOS2(self._scip, &scip_cons, str_conversion(name), 0, NULL, NULL,
1741  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
1742 
1743  if weights is None:
1744  for v in vars:
1745  var = <Variable>v
1746  PY_SCIP_CALL(SCIPappendVarSOS2(self._scip, scip_cons, var.var))
1747  else:
1748  nvars = len(vars)
1749  for i in range(nvars):
1750  var = <Variable>vars[i]
1751  PY_SCIP_CALL(SCIPaddVarSOS2(self._scip, scip_cons, var.var, weights[i]))
1752 
1753  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1754  return Constraint.create(scip_cons)
1755 
1756  def addConsAnd(self, vars, resvar, name="ANDcons",
1757  initial=True, separate=True, enforce=True, check=True,
1758  propagate=True, local=False, modifiable=False, dynamic=False,
1759  removable=False, stickingatnode=False):
1760  """Add an AND-constraint.
1761  :param vars: list of BINARY variables to be included (operators)
1762  :param resvar: BINARY variable (resultant)
1763  :param name: name of the constraint (Default value = "ANDcons")
1764  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1765  :param separate: should the constraint be separated during LP processing? (Default value = True)
1766  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1767  :param check: should the constraint be checked for feasibility? (Default value = True)
1768  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1769  :param local: is the constraint only valid locally? (Default value = False)
1770  :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False)
1771  :param dynamic: is the constraint subject to aging? (Default value = False)
1772  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1773  :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)
1774  """
1775  cdef SCIP_CONS* scip_cons
1776 
1777  nvars = len(vars)
1778 
1779  _vars = <SCIP_VAR**> malloc(len(vars) * sizeof(SCIP_VAR*))
1780  for idx, var in enumerate(vars):
1781  _vars[idx] = (<Variable>var).var
1782  _resVar = (<Variable>resvar).var
1783 
1784  PY_SCIP_CALL(SCIPcreateConsAnd(self._scip, &scip_cons, str_conversion(name), _resVar, nvars, _vars,
1785  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
1786 
1787  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1788  pyCons = Constraint.create(scip_cons)
1789  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1790 
1791  free(_vars)
1792 
1793  return pyCons
1794 
1795  def addConsOr(self, vars, resvar, name="ORcons",
1796  initial=True, separate=True, enforce=True, check=True,
1797  propagate=True, local=False, modifiable=False, dynamic=False,
1798  removable=False, stickingatnode=False):
1799  """Add an OR-constraint.
1800  :param vars: list of BINARY variables to be included (operators)
1801  :param resvar: BINARY variable (resultant)
1802  :param name: name of the constraint (Default value = "ORcons")
1803  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1804  :param separate: should the constraint be separated during LP processing? (Default value = True)
1805  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1806  :param check: should the constraint be checked for feasibility? (Default value = True)
1807  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1808  :param local: is the constraint only valid locally? (Default value = False)
1809  :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False)
1810  :param dynamic: is the constraint subject to aging? (Default value = False)
1811  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1812  :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)
1813  """
1814  cdef SCIP_CONS* scip_cons
1815 
1816  nvars = len(vars)
1817 
1818  _vars = <SCIP_VAR**> malloc(len(vars) * sizeof(SCIP_VAR*))
1819  for idx, var in enumerate(vars):
1820  _vars[idx] = (<Variable>var).var
1821  _resVar = (<Variable>resvar).var
1822 
1823  PY_SCIP_CALL(SCIPcreateConsOr(self._scip, &scip_cons, str_conversion(name), _resVar, nvars, _vars,
1824  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
1825 
1826  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1827  pyCons = Constraint.create(scip_cons)
1828  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1829 
1830  free(_vars)
1831 
1832  return pyCons
1833 
1834  def addConsXor(self, vars, rhsvar, name="XORcons",
1835  initial=True, separate=True, enforce=True, check=True,
1836  propagate=True, local=False, modifiable=False, dynamic=False,
1837  removable=False, stickingatnode=False):
1838  """Add a XOR-constraint.
1839  :param vars: list of BINARY variables to be included (operators)
1840  :param rhsvar: BOOLEAN value, explicit True, False or bool(obj) is needed (right-hand side)
1841  :param name: name of the constraint (Default value = "XORcons")
1842  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1843  :param separate: should the constraint be separated during LP processing? (Default value = True)
1844  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1845  :param check: should the constraint be checked for feasibility? (Default value = True)
1846  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1847  :param local: is the constraint only valid locally? (Default value = False)
1848  :param modifiable: is the constraint modifiable (subject to column generation)? (Default value = False)
1849  :param dynamic: is the constraint subject to aging? (Default value = False)
1850  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1851  :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)
1852  """
1853  cdef SCIP_CONS* scip_cons
1854 
1855  nvars = len(vars)
1856 
1857  assert type(rhsvar) is type(bool()), "Provide BOOLEAN value as rhsvar, you gave %s." % type(rhsvar)
1858  _vars = <SCIP_VAR**> malloc(len(vars) * sizeof(SCIP_VAR*))
1859  for idx, var in enumerate(vars):
1860  _vars[idx] = (<Variable>var).var
1861 
1862  PY_SCIP_CALL(SCIPcreateConsXor(self._scip, &scip_cons, str_conversion(name), rhsvar, nvars, _vars,
1863  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
1864 
1865  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1866  pyCons = Constraint.create(scip_cons)
1867  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1868 
1869  free(_vars)
1870 
1871  return pyCons
1872 
1873  def addConsCardinality(self, consvars, cardval, indvars=None, weights=None, name="CardinalityCons",
1874  initial=True, separate=True, enforce=True, check=True,
1875  propagate=True, local=False, dynamic=False,
1876  removable=False, stickingatnode=False):
1877  """Add a cardinality constraint that allows at most 'cardval' many nonzero variables.
1878 
1879  :param consvars: list of variables to be included
1880  :param cardval: nonnegative integer
1881  :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)
1882  :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)
1883  :param name: name of the constraint (Default value = "CardinalityCons")
1884  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1885  :param separate: should the constraint be separated during LP processing? (Default value = True)
1886  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1887  :param check: should the constraint be checked for feasibility? (Default value = True)
1888  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1889  :param local: is the constraint only valid locally? (Default value = False)
1890  :param dynamic: is the constraint subject to aging? (Default value = False)
1891  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1892  :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)
1893 
1894  """
1895  cdef SCIP_CONS* scip_cons
1896  cdef SCIP_VAR* indvar
1897 
1898  PY_SCIP_CALL(SCIPcreateConsCardinality(self._scip, &scip_cons, str_conversion(name), 0, NULL, cardval, NULL, NULL,
1899  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
1900 
1901  # circumvent an annoying bug in SCIP 4.0.0 that does not allow uninitialized weights
1902  if weights is None:
1903  weights = list(range(1, len(consvars) + 1))
1904 
1905  for i, v in enumerate(consvars):
1906  var = <Variable>v
1907  if indvars:
1908  indvar = (<Variable>indvars[i]).var
1909  else:
1910  indvar = NULL
1911  if weights is None:
1912  PY_SCIP_CALL(SCIPappendVarCardinality(self._scip, scip_cons, var.var, indvar))
1913  else:
1914  PY_SCIP_CALL(SCIPaddVarCardinality(self._scip, scip_cons, var.var, indvar, <SCIP_Real>weights[i]))
1915 
1916  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1917  pyCons = Constraint.create(scip_cons)
1918 
1919  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1920 
1921  return pyCons
1922 
1923 
1924  def addConsIndicator(self, cons, binvar=None, name="IndicatorCons",
1925  initial=True, separate=True, enforce=True, check=True,
1926  propagate=True, local=False, dynamic=False,
1927  removable=False, stickingatnode=False):
1928  """Add an indicator constraint for the linear inequality 'cons'.
1929 
1930  The 'binvar' argument models the redundancy of the linear constraint. A solution for which
1931  'binvar' is 1 must satisfy the constraint.
1932 
1933  :param cons: a linear inequality of the form "<="
1934  :param binvar: binary indicator variable, or None if it should be created (Default value = None)
1935  :param name: name of the constraint (Default value = "IndicatorCons")
1936  :param initial: should the LP relaxation of constraint be in the initial LP? (Default value = True)
1937  :param separate: should the constraint be separated during LP processing? (Default value = True)
1938  :param enforce: should the constraint be enforced during node processing? (Default value = True)
1939  :param check: should the constraint be checked for feasibility? (Default value = True)
1940  :param propagate: should the constraint be propagated during node processing? (Default value = True)
1941  :param local: is the constraint only valid locally? (Default value = False)
1942  :param dynamic: is the constraint subject to aging? (Default value = False)
1943  :param removable: should the relaxation be removed from the LP due to aging or cleanup? (Default value = False)
1944  :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)
1945 
1946  """
1947  assert isinstance(cons, ExprCons), "given constraint is not ExprCons but %s" % cons.__class__.__name__
1948  cdef SCIP_CONS* scip_cons
1949  cdef SCIP_VAR* _binVar
1950  if cons.lhs is not None and cons.rhs is not None:
1951  raise ValueError("expected inequality that has either only a left or right hand side")
1952 
1953  if cons.expr.degree() > 1:
1954  raise ValueError("expected linear inequality, expression has degree %d" % cons.expr.degree())
1955 
1956 
1957  if cons.rhs is not None:
1958  rhs = cons.rhs
1959  negate = False
1960  else:
1961  rhs = -cons.lhs
1962  negate = True
1963 
1964  _binVar = (<Variable>binvar).var if binvar is not None else NULL
1965 
1966  PY_SCIP_CALL(SCIPcreateConsIndicator(self._scip, &scip_cons, str_conversion(name), _binVar, 0, NULL, NULL, rhs,
1967  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode))
1968  terms = cons.expr.terms
1969 
1970  for key, coeff in terms.items():
1971  var = <Variable>key[0]
1972  if negate:
1973  coeff = -coeff
1974  PY_SCIP_CALL(SCIPaddVarIndicator(self._scip, scip_cons, var.var, <SCIP_Real>coeff))
1975 
1976  PY_SCIP_CALL(SCIPaddCons(self._scip, scip_cons))
1977  pyCons = Constraint.create(scip_cons)
1978 
1979  PY_SCIP_CALL(SCIPreleaseCons(self._scip, &scip_cons))
1980 
1981  return pyCons
1982 
1983  def addPyCons(self, Constraint cons):
1984  """Adds a customly created cons.
1985 
1986  :param Constraint cons: constraint to add
1987 
1988  """
1989  PY_SCIP_CALL(SCIPaddCons(self._scip, cons.cons))
1990  Py_INCREF(cons)
1991 
1992  def addVarSOS1(self, Constraint cons, Variable var, weight):
1993  """Add variable to SOS1 constraint.
1994 
1995  :param Constraint cons: SOS1 constraint
1996  :param Variable var: new variable
1997  :param weight: weight of new variable
1998 
1999  """
2000  PY_SCIP_CALL(SCIPaddVarSOS1(self._scip, cons.cons, var.var, weight))
2001 
2002  def appendVarSOS1(self, Constraint cons, Variable var):
2003  """Append variable to SOS1 constraint.
2004 
2005  :param Constraint cons: SOS1 constraint
2006  :param Variable var: variable to append
2007 
2008  """
2009  PY_SCIP_CALL(SCIPappendVarSOS1(self._scip, cons.cons, var.var))
2010 
2011  def addVarSOS2(self, Constraint cons, Variable var, weight):
2012  """Add variable to SOS2 constraint.
2013 
2014  :param Constraint cons: SOS2 constraint
2015  :param Variable var: new variable
2016  :param weight: weight of new variable
2017 
2018  """
2019  PY_SCIP_CALL(SCIPaddVarSOS2(self._scip, cons.cons, var.var, weight))
2020 
2021  def appendVarSOS2(self, Constraint cons, Variable var):
2022  """Append variable to SOS2 constraint.
2023 
2024  :param Constraint cons: SOS2 constraint
2025  :param Variable var: variable to append
2026 
2027  """
2028  PY_SCIP_CALL(SCIPappendVarSOS2(self._scip, cons.cons, var.var))
2029 
2030  def setInitial(self, Constraint cons, newInit):
2031  """Set "initial" flag of a constraint.
2032 
2033  Keyword arguments:
2034  cons -- constraint
2035  newInit -- new initial value
2036  """
2037  PY_SCIP_CALL(SCIPsetConsInitial(self._scip, cons.cons, newInit))
2038 
2039  def setRemovable(self, Constraint cons, newRem):
2040  """Set "removable" flag of a constraint.
2041 
2042  Keyword arguments:
2043  cons -- constraint
2044  newRem -- new removable value
2045  """
2046  PY_SCIP_CALL(SCIPsetConsRemovable(self._scip, cons.cons, newRem))
2047 
2048  def setEnforced(self, Constraint cons, newEnf):
2049  """Set "enforced" flag of a constraint.
2050 
2051  Keyword arguments:
2052  cons -- constraint
2053  newEnf -- new enforced value
2054  """
2055  PY_SCIP_CALL(SCIPsetConsEnforced(self._scip, cons.cons, newEnf))
2056 
2057  def setCheck(self, Constraint cons, newCheck):
2058  """Set "check" flag of a constraint.
2059 
2060  Keyword arguments:
2061  cons -- constraint
2062  newCheck -- new check value
2063  """
2064  PY_SCIP_CALL(SCIPsetConsChecked(self._scip, cons.cons, newCheck))
2065 
2066  def chgRhs(self, Constraint cons, rhs):
2067  """Change right hand side value of a constraint.
2068 
2069  :param Constraint cons: linear or quadratic constraint
2070  :param rhs: new ride hand side (set to None for +infinity)
2071 
2072  """
2073 
2074  if rhs is None:
2075  rhs = SCIPinfinity(self._scip)
2076 
2077  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2078  if constype == 'linear':
2079  PY_SCIP_CALL(SCIPchgRhsLinear(self._scip, cons.cons, rhs))
2080  elif constype == 'quadratic':
2081  PY_SCIP_CALL(SCIPchgRhsQuadratic(self._scip, cons.cons, rhs))
2082  else:
2083  raise Warning("method cannot be called for constraints of type " + constype)
2084 
2085  def chgLhs(self, Constraint cons, lhs):
2086  """Change left hand side value of a constraint.
2087 
2088  :param Constraint cons: linear or quadratic constraint
2089  :param lhs: new left hand side (set to None for -infinity)
2090 
2091  """
2092 
2093  if lhs is None:
2094  lhs = -SCIPinfinity(self._scip)
2095 
2096  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2097  if constype == 'linear':
2098  PY_SCIP_CALL(SCIPchgLhsLinear(self._scip, cons.cons, lhs))
2099  elif constype == 'quadratic':
2100  PY_SCIP_CALL(SCIPchgLhsQuadratic(self._scip, cons.cons, lhs))
2101  else:
2102  raise Warning("method cannot be called for constraints of type " + constype)
2103 
2104  def getRhs(self, Constraint cons):
2105  """Retrieve right hand side value of a constraint.
2106 
2107  :param Constraint cons: linear or quadratic constraint
2108 
2109  """
2110  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2111  if constype == 'linear':
2112  return SCIPgetRhsLinear(self._scip, cons.cons)
2113  elif constype == 'quadratic':
2114  return SCIPgetRhsQuadratic(self._scip, cons.cons)
2115  else:
2116  raise Warning("method cannot be called for constraints of type " + constype)
2117 
2118  def getLhs(self, Constraint cons):
2119  """Retrieve left hand side value of a constraint.
2120 
2121  :param Constraint cons: linear or quadratic constraint
2122 
2123  """
2124  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2125  if constype == 'linear':
2126  return SCIPgetLhsLinear(self._scip, cons.cons)
2127  elif constype == 'quadratic':
2128  return SCIPgetLhsQuadratic(self._scip, cons.cons)
2129  else:
2130  raise Warning("method cannot be called for constraints of type " + constype)
2131 
2132  def getActivity(self, Constraint cons, Solution sol = None):
2133  """Retrieve activity of given constraint.
2134  Can only be called after solving is completed.
2135 
2136  :param Constraint cons: linear or quadratic constraint
2137  :param Solution sol: solution to compute activity of, None to use current node's solution (Default value = None)
2138 
2139  """
2140  cdef SCIP_Real activity
2141  cdef SCIP_SOL* scip_sol
2142 
2143  if not self.getStage() >= SCIP_STAGE_SOLVING:
2144  raise Warning("method cannot be called before problem is solved")
2145 
2146  if isinstance(sol, Solution):
2147  scip_sol = sol.sol
2148  else:
2149  scip_sol = NULL
2150 
2151  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2152  if constype == 'linear':
2153  activity = SCIPgetActivityLinear(self._scip, cons.cons, scip_sol)
2154  elif constype == 'quadratic':
2155  PY_SCIP_CALL(SCIPgetActivityQuadratic(self._scip, cons.cons, scip_sol, &activity))
2156  else:
2157  raise Warning("method cannot be called for constraints of type " + constype)
2158 
2159  return activity
2160 
2161 
2162  def getSlack(self, Constraint cons, Solution sol = None, side = None):
2163  """Retrieve slack of given constraint.
2164  Can only be called after solving is completed.
2165 
2166 
2167  :param Constraint cons: linear or quadratic constraint
2168  :param Solution sol: solution to compute slack of, None to use current node's solution (Default value = None)
2169  :param side: whether to use 'lhs' or 'rhs' for ranged constraints, None to return minimum (Default value = None)
2170 
2171  """
2172  cdef SCIP_Real activity
2173  cdef SCIP_SOL* scip_sol
2174 
2175 
2176  if not self.getStage() >= SCIP_STAGE_SOLVING:
2177  raise Warning("method cannot be called before problem is solved")
2178 
2179  if isinstance(sol, Solution):
2180  scip_sol = sol.sol
2181  else:
2182  scip_sol = NULL
2183 
2184  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2185  if constype == 'linear':
2186  lhs = SCIPgetLhsLinear(self._scip, cons.cons)
2187  rhs = SCIPgetRhsLinear(self._scip, cons.cons)
2188  activity = SCIPgetActivityLinear(self._scip, cons.cons, scip_sol)
2189  elif constype == 'quadratic':
2190  lhs = SCIPgetLhsQuadratic(self._scip, cons.cons)
2191  rhs = SCIPgetRhsQuadratic(self._scip, cons.cons)
2192  PY_SCIP_CALL(SCIPgetActivityQuadratic(self._scip, cons.cons, scip_sol, &activity))
2193  else:
2194  raise Warning("method cannot be called for constraints of type " + constype)
2195 
2196  lhsslack = activity - lhs
2197  rhsslack = rhs - activity
2198 
2199  if side == 'lhs':
2200  return lhsslack
2201  elif side == 'rhs':
2202  return rhsslack
2203  else:
2204  return min(lhsslack, rhsslack)
2205 
2206  def getTransformedCons(self, Constraint cons):
2207  """Retrieve transformed constraint.
2208 
2209  :param Constraint cons: constraint
2210 
2211  """
2212  cdef SCIP_CONS* transcons
2213  PY_SCIP_CALL(SCIPgetTransformedCons(self._scip, cons.cons, &transcons))
2214  return Constraint.create(transcons)
2215 
2216  def getTermsQuadratic(self, Constraint cons):
2217  """Retrieve bilinear, quadratic, and linear terms of a quadratic constraint.
2218 
2219  :param Constraint cons: constraint
2220 
2221  """
2222  cdef SCIP_QUADVARTERM* _quadterms
2223  cdef SCIP_BILINTERM* _bilinterms
2224  cdef SCIP_VAR** _linvars
2225  cdef SCIP_Real* _lincoefs
2226  cdef int _nbilinterms
2227  cdef int _nquadterms
2228  cdef int _nlinvars
2229 
2230  assert cons.isQuadratic(), "constraint is not quadratic"
2231 
2232  bilinterms = []
2233  quadterms = []
2234  linterms = []
2235 
2236  # bilinear terms
2237  _bilinterms = SCIPgetBilinTermsQuadratic(self._scip, cons.cons)
2238  _nbilinterms = SCIPgetNBilinTermsQuadratic(self._scip, cons.cons)
2239 
2240  for i in range(_nbilinterms):
2241  var1 = Variable.create(_bilinterms[i].var1)
2242  var2 = Variable.create(_bilinterms[i].var2)
2243  bilinterms.append((var1,var2,_bilinterms[i].coef))
2244 
2245  # quadratic terms
2246  _quadterms = SCIPgetQuadVarTermsQuadratic(self._scip, cons.cons)
2247  _nquadterms = SCIPgetNQuadVarTermsQuadratic(self._scip, cons.cons)
2248 
2249  for i in range(_nquadterms):
2250  var = Variable.create(_quadterms[i].var)
2251  quadterms.append((var,_quadterms[i].sqrcoef,_quadterms[i].lincoef))
2252 
2253  # linear terms
2254  _linvars = SCIPgetLinearVarsQuadratic(self._scip, cons.cons)
2255  _lincoefs = SCIPgetCoefsLinearVarsQuadratic(self._scip, cons.cons)
2256  _nlinvars = SCIPgetNLinearVarsQuadratic(self._scip, cons.cons)
2257 
2258  for i in range(_nlinvars):
2259  var = Variable.create(_linvars[i])
2260  linterms.append((var,_lincoefs[i]))
2261 
2262  return (bilinterms, quadterms, linterms)
2263 
2264  def setRelaxSolVal(self, Variable var, val):
2265  """sets the value of the given variable in the global relaxation solution"""
2266  PY_SCIP_CALL(SCIPsetRelaxSolVal(self._scip, var.var, val))
2267 
2268  def getConss(self):
2269  """Retrieve all constraints."""
2270  cdef SCIP_CONS** _conss
2271  cdef int _nconss
2272  conss = []
2273 
2274  _conss = SCIPgetConss(self._scip)
2275  _nconss = SCIPgetNConss(self._scip)
2276  return [Constraint.create(_conss[i]) for i in range(_nconss)]
2277 
2278  def getNConss(self):
2279  """Retrieve number of all constraints"""
2280  return SCIPgetNConss(self._scip)
2281 
2282  def delCons(self, Constraint cons):
2283  """Delete constraint from the model
2284 
2285  :param Constraint cons: constraint to be deleted
2286 
2287  """
2288  PY_SCIP_CALL(SCIPdelCons(self._scip, cons.cons))
2289 
2290  def delConsLocal(self, Constraint cons):
2291  """Delete constraint from the current node and it's children
2292 
2293  :param Constraint cons: constraint to be deleted
2294 
2295  """
2296  PY_SCIP_CALL(SCIPdelConsLocal(self._scip, cons.cons))
2297 
2298  def getValsLinear(self, Constraint cons):
2299  """Retrieve the coefficients of a linear constraint
2300 
2301  :param Constraint cons: linear constraint to get the coefficients of
2302 
2303  """
2304  cdef SCIP_Real* _vals
2305  cdef SCIP_VAR** _vars
2306 
2307  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2308  if not constype == 'linear':
2309  raise Warning("coefficients not available for constraints of type ", constype)
2310 
2311  _vals = SCIPgetValsLinear(self._scip, cons.cons)
2312  _vars = SCIPgetVarsLinear(self._scip, cons.cons)
2313 
2314  valsdict = {}
2315  for i in range(SCIPgetNVarsLinear(self._scip, cons.cons)):
2316  valsdict[bytes(SCIPvarGetName(_vars[i])).decode('utf-8')] = _vals[i]
2317  return valsdict
2318 
2319  def getDualMultiplier(self, Constraint cons):
2320  """Retrieve the dual multiplier to a linear constraint.
2321 
2322  :param Constraint cons: linear constraint
2323 
2324  """
2325  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2326  if not constype == 'linear':
2327  raise Warning("dual solution values not available for constraints of type ", constype)
2328  if cons.isOriginal():
2329  transcons = <Constraint>self.getTransformedCons(cons)
2330  else:
2331  transcons = cons
2332  return SCIPgetDualsolLinear(self._scip, transcons.cons)
2333 
2334  def getDualsolLinear(self, Constraint cons):
2335  """Retrieve the dual solution to a linear constraint.
2336 
2337  :param Constraint cons: linear constraint
2338 
2339  """
2340  cdef SCIP_Real dualsolval
2341  cdef SCIP_Bool boundconstraint
2342  cdef int _nvars
2343  cdef SCIP_VAR** _vars
2344  cdef SCIP_Real* _vals
2345  cdef SCIP_Bool _success
2346 
2347  if self.version() > 6.0:
2348  PY_SCIP_CALL( SCIPgetDualSolVal(self._scip, cons.cons, &dualsolval, &boundconstraint) )
2349  return dualsolval
2350  else:
2351  dual = 0.0
2352 
2353  constype = bytes(SCIPconshdlrGetName(SCIPconsGetHdlr(cons.cons))).decode('UTF-8')
2354  if not constype == 'linear':
2355  raise Warning("dual solution values not available for constraints of type ", constype)
2356 
2357  try:
2358  _nvars = SCIPgetNVarsLinear(self._scip, cons.cons)
2359  if cons.isOriginal():
2360  transcons = <Constraint>self.getTransformedCons(cons)
2361  else:
2362  transcons = cons
2363  dual = SCIPgetDualsolLinear(self._scip, transcons.cons)
2364  if dual == 0.0 and _nvars == 1:
2365  _vars = SCIPgetVarsLinear(self._scip, transcons.cons)
2366  _vals = SCIPgetValsLinear(self._scip, transcons.cons)
2367  activity = SCIPvarGetLPSol(_vars[0]) * _vals[0]
2368  rhs = SCIPgetRhsLinear(self._scip, transcons.cons)
2369  lhs = SCIPgetLhsLinear(self._scip, transcons.cons)
2370  if (activity == rhs) or (activity == lhs):
2371  dual = SCIPgetVarRedcost(self._scip, _vars[0])
2372 
2373  if self.getObjectiveSense() == "maximize" and not dual == 0.0:
2374  dual = -dual
2375  except:
2376  raise Warning("no dual solution available for constraint " + cons.name)
2377  return dual
2378 
2379  def getDualfarkasLinear(self, Constraint cons):
2380  """Retrieve the dual farkas value to a linear constraint.
2381 
2382  :param Constraint cons: linear constraint
2383 
2384  """
2385  # TODO this should ideally be handled on the SCIP side
2386  if cons.isOriginal():
2387  transcons = <Constraint>self.getTransformedCons(cons)
2388  return SCIPgetDualfarkasLinear(self._scip, transcons.cons)
2389  else:
2390  return SCIPgetDualfarkasLinear(self._scip, cons.cons)
2391 
2392  def getVarRedcost(self, Variable var):
2393  """Retrieve the reduced cost of a variable.
2394 
2395  :param Variable var: variable to get the reduced cost of
2396 
2397  """
2398  redcost = None
2399  try:
2400  redcost = SCIPgetVarRedcost(self._scip, var.var)
2401  if self.getObjectiveSense() == "maximize":
2402  redcost = -redcost
2403  except:
2404  raise Warning("no reduced cost available for variable " + var.name)
2405  return redcost
2406 
2407  def optimize(self):
2408  """Optimize the problem."""
2409  PY_SCIP_CALL(SCIPsolve(self._scip))
2410  self._bestSol = Solution.create(SCIPgetBestSol(self._scip))
2411 
2412  def presolve(self):
2413  """Presolve the problem."""
2414  PY_SCIP_CALL(SCIPpresolve(self._scip))
2415 
2416  # Benders' decomposition methods
2417  def initBendersDefault(self, subproblems):
2418  """initialises the default Benders' decomposition with a dictionary of subproblems
2419 
2420  Keyword arguments:
2421  subproblems -- a single Model instance or dictionary of Model instances
2422  """
2423  cdef SCIP** subprobs
2424  cdef SCIP_BENDERS* benders
2425 
2426  # checking whether subproblems is a dictionary
2427  if isinstance(subproblems, dict):
2428  isdict = True
2429  nsubproblems = len(subproblems)
2430  else:
2431  isdict = False
2432  nsubproblems = 1
2433 
2434  # create array of SCIP instances for the subproblems
2435  subprobs = <SCIP**> malloc(nsubproblems * sizeof(SCIP*))
2436 
2437  # if subproblems is a dictionary, then the dictionary is turned into a c array
2438  if isdict:
2439  for idx, subprob in enumerate(subproblems.values()):
2440  subprobs[idx] = (<Model>subprob)._scip
2441  else:
2442  subprobs[0] = (<Model>subproblems)._scip
2443 
2444  # creating the default Benders' decomposition
2445  PY_SCIP_CALL(SCIPcreateBendersDefault(self._scip, subprobs, nsubproblems))
2446  benders = SCIPfindBenders(self._scip, "default")
2447 
2448  # activating the Benders' decomposition constraint handlers
2449  self.setBoolParam("constraints/benderslp/active", True)
2450  self.setBoolParam("constraints/benders/active", True)
2451  #self.setIntParam("limits/maxorigsol", 0)
2452 
2454  """Solves the subproblems with the best solution to the master problem.
2455  Afterwards, the best solution from each subproblem can be queried to get
2456  the solution to the original problem.
2457 
2458  If the user wants to resolve the subproblems, they must free them by
2459  calling freeBendersSubproblems()
2460  """
2461  cdef SCIP_BENDERS** _benders
2462  cdef SCIP_Bool _infeasible
2463  cdef int nbenders
2464  cdef int nsubproblems
2465 
2466  solvecip = True
2467 
2468  nbenders = SCIPgetNActiveBenders(self._scip)
2469  _benders = SCIPgetBenders(self._scip)
2470 
2471  # solving all subproblems from all Benders' decompositions
2472  for i in range(nbenders):
2473  nsubproblems = SCIPbendersGetNSubproblems(_benders[i])
2474  for j in range(nsubproblems):
2475  PY_SCIP_CALL(SCIPsetupBendersSubproblem(self._scip,
2476  _benders[i], self._bestSol.sol, j))
2477  PY_SCIP_CALL(SCIPsolveBendersSubproblem(self._scip,
2478  _benders[i], self._bestSol.sol, j, &_infeasible,
2479  SCIP_BENDERSENFOTYPE_CHECK, solvecip, NULL))
2480 
2482  """Calls the free subproblem function for the Benders' decomposition.
2483  This will free all subproblems for all decompositions.
2484  """
2485  cdef SCIP_BENDERS** _benders
2486  cdef int nbenders
2487  cdef int nsubproblems
2488 
2489  nbenders = SCIPgetNActiveBenders(self._scip)
2490  _benders = SCIPgetBenders(self._scip)
2491 
2492  # solving all subproblems from all Benders' decompositions
2493  for i in range(nbenders):
2494  nsubproblems = SCIPbendersGetNSubproblems(_benders[i])
2495  for j in range(nsubproblems):
2496  PY_SCIP_CALL(SCIPfreeBendersSubproblem(self._scip, _benders[i],
2497  j))
2498 
2499  def updateBendersLowerbounds(self, lowerbounds, Benders benders=None):
2500  """"updates the subproblem lower bounds for benders using
2501  the lowerbounds dict. If benders is None, then the default
2502  Benders' decomposition is updated
2503  """
2504  cdef SCIP_BENDERS* _benders
2505 
2506  assert type(lowerbounds) is dict
2507 
2508  if benders is None:
2509  _benders = SCIPfindBenders(self._scip, "default")
2510  else:
2511  n = str_conversion(benders.name)
2512  _benders = SCIPfindBenders(self._scip, n)
2513 
2514  for d in lowerbounds.keys():
2515  SCIPbendersUpdateSubproblemLowerbound(_benders, d, lowerbounds[d])
2516 
2517  def activateBenders(self, str name, int nsubproblems):
2518  """Activates the Benders' decomposition plugin with the input name
2519 
2520  Keyword arguments:
2521  name -- the name of the Benders' decomposition plugin
2522  nsubproblems -- the number of subproblems in the Benders' decomposition
2523  """
2524  n = str_conversion(name)
2525  cdef SCIP_BENDERS* benders
2526  benders = SCIPfindBenders(self._scip, n)
2527  PY_SCIP_CALL(SCIPactivateBenders(self._scip, benders, nsubproblems))
2528 
2529  def addBendersSubproblem(self, str name, subproblem):
2530  """adds a subproblem to the Benders' decomposition given by the input
2531  name.
2532 
2533  Keyword arguments:
2534  name -- the Benders' decomposition that the subproblem is added to
2535  subproblem -- the subproblem to add to the decomposition
2536  """
2537  cdef SCIP_BENDERS* benders
2538  n = str_conversion(name)
2539  benders = SCIPfindBenders(self._scip, n)
2540  PY_SCIP_CALL(SCIPaddBendersSubproblem(self._scip, benders, (<Model>subproblem)._scip))
2541 
2542  def getBendersVar(self, Variable var, Benders benders = None, probnumber = -1):
2543  """Returns the variable for the subproblem or master problem
2544  depending on the input probnumber
2545 
2546  Keyword arguments:
2547  var -- the source variable for which the target variable is requested
2548  benders -- the Benders' decomposition to which the subproblem variables belong to
2549  probnumber -- the problem number for which the target variable belongs, -1 for master problem
2550  """
2551  cdef SCIP_BENDERS* _benders
2552  cdef SCIP_VAR* _mappedvar
2553 
2554  if benders is None:
2555  _benders = SCIPfindBenders(self._scip, "default")
2556  else:
2557  n = str_conversion(benders.name)
2558  _benders = SCIPfindBenders(self._scip, n)
2559 
2560  if probnumber == -1:
2561  PY_SCIP_CALL(SCIPgetBendersMasterVar(self._scip, _benders, var.var, &_mappedvar))
2562  else:
2563  PY_SCIP_CALL(SCIPgetBendersSubproblemVar(self._scip, _benders, var.var, &_mappedvar, probnumber))
2564 
2565  if _mappedvar == NULL:
2566  mappedvar = None
2567  else:
2568  mappedvar = Variable.create(_mappedvar)
2569 
2570  return mappedvar
2571 
2572 
2573  def includeEventhdlr(self, Eventhdlr eventhdlr, name, desc):
2574  """Include an event handler.
2575 
2576  Keyword arguments:
2577  eventhdlr -- event handler
2578  name -- name of event handler
2579  desc -- description of event handler
2580  """
2581  n = str_conversion(name)
2582  d = str_conversion(desc)
2583  PY_SCIP_CALL(SCIPincludeEventhdlr(self._scip, n, d,
2584  PyEventCopy,
2585  PyEventFree,
2586  PyEventInit,
2587  PyEventExit,
2588  PyEventInitsol,
2589  PyEventExitsol,
2590  PyEventDelete,
2591  PyEventExec,
2592  <SCIP_EVENTHDLRDATA*>eventhdlr))
2593  eventhdlr.model = <Model>weakref.proxy(self)
2594  eventhdlr.name = name
2595  Py_INCREF(eventhdlr)
2596 
2597  def includePricer(self, Pricer pricer, name, desc, priority=1, delay=True):
2598  """Include a pricer.
2599 
2600  :param Pricer pricer: pricer
2601  :param name: name of pricer
2602  :param desc: description of pricer
2603  :param priority: priority of pricer (Default value = 1)
2604  :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)
2605 
2606  """
2607  n = str_conversion(name)
2608  d = str_conversion(desc)
2609  PY_SCIP_CALL(SCIPincludePricer(self._scip, n, d,
2610  priority, delay,
2611  PyPricerCopy, PyPricerFree, PyPricerInit, PyPricerExit, PyPricerInitsol, PyPricerExitsol, PyPricerRedcost, PyPricerFarkas,
2612  <SCIP_PRICERDATA*>pricer))
2613  cdef SCIP_PRICER* scip_pricer
2614  scip_pricer = SCIPfindPricer(self._scip, n)
2615  PY_SCIP_CALL(SCIPactivatePricer(self._scip, scip_pricer))
2616  pricer.model = <Model>weakref.proxy(self)
2617  Py_INCREF(pricer)
2618 
2619  def includeConshdlr(self, Conshdlr conshdlr, name, desc, sepapriority=0,
2620  enfopriority=0, chckpriority=0, sepafreq=-1, propfreq=-1,
2621  eagerfreq=100, maxprerounds=-1, delaysepa=False,
2622  delayprop=False, needscons=True,
2623  proptiming=PY_SCIP_PROPTIMING.BEFORELP,
2624  presoltiming=PY_SCIP_PRESOLTIMING.MEDIUM):
2625  """Include a constraint handler
2626 
2627  :param Conshdlr conshdlr: constraint handler
2628  :param name: name of constraint handler
2629  :param desc: description of constraint handler
2630  :param sepapriority: priority for separation (Default value = 0)
2631  :param enfopriority: priority for constraint enforcing (Default value = 0)
2632  :param chckpriority: priority for checking feasibility (Default value = 0)
2633  :param sepafreq: frequency for separating cuts; 0 = only at root node (Default value = -1)
2634  :param propfreq: frequency for propagating domains; 0 = only preprocessing propagation (Default value = -1)
2635  :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)
2636  :param maxprerounds: maximal number of presolving rounds the constraint handler participates in (Default value = -1)
2637  :param delaysepa: should separation method be delayed, if other separators found cuts? (Default value = False)
2638  :param delayprop: should propagation method be delayed, if other propagators found reductions? (Default value = False)
2639  :param needscons: should the constraint handler be skipped, if no constraints are available? (Default value = True)
2640  :param proptiming: positions in the node solving loop where propagation method of constraint handlers should be executed (Default value = SCIP_PROPTIMING.BEFORELP)
2641  :param presoltiming: timing mask of the constraint handler's presolving method (Default value = SCIP_PRESOLTIMING.MEDIUM)
2642 
2643  """
2644  n = str_conversion(name)
2645  d = str_conversion(desc)
2646  PY_SCIP_CALL(SCIPincludeConshdlr(self._scip, n, d, sepapriority, enfopriority, chckpriority, sepafreq, propfreq, eagerfreq,
2647  maxprerounds, delaysepa, delayprop, needscons, proptiming, presoltiming,
2648  PyConshdlrCopy, PyConsFree, PyConsInit, PyConsExit, PyConsInitpre, PyConsExitpre,
2649  PyConsInitsol, PyConsExitsol, PyConsDelete, PyConsTrans, PyConsInitlp, PyConsSepalp, PyConsSepasol,
2650  PyConsEnfolp, PyConsEnforelax, PyConsEnfops, PyConsCheck, PyConsProp, PyConsPresol, PyConsResprop, PyConsLock,
2651  PyConsActive, PyConsDeactive, PyConsEnable, PyConsDisable, PyConsDelvars, PyConsPrint, PyConsCopy,
2652  PyConsParse, PyConsGetvars, PyConsGetnvars, PyConsGetdivebdchgs,
2653  <SCIP_CONSHDLRDATA*>conshdlr))
2654  conshdlr.model = <Model>weakref.proxy(self)
2655  conshdlr.name = name
2656  Py_INCREF(conshdlr)
2657 
2658  def createCons(self, Conshdlr conshdlr, name, initial=True, separate=True, enforce=True, check=True, propagate=True,
2659  local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False):
2660  """Create a constraint of a custom constraint handler
2661 
2662  :param Conshdlr conshdlr: constraint handler
2663  :param name: name of constraint
2664  :param initial: (Default value = True)
2665  :param separate: (Default value = True)
2666  :param enforce: (Default value = True)
2667  :param check: (Default value = True)
2668  :param propagate: (Default value = True)
2669  :param local: (Default value = False)
2670  :param modifiable: (Default value = False)
2671  :param dynamic: (Default value = False)
2672  :param removable: (Default value = False)
2673  :param stickingatnode: (Default value = False)
2674 
2675  """
2676 
2677  n = str_conversion(name)
2678  cdef SCIP_CONSHDLR* scip_conshdlr
2679  scip_conshdlr = SCIPfindConshdlr(self._scip, str_conversion(conshdlr.name))
2680  constraint = Constraint()
2681  PY_SCIP_CALL(SCIPcreateCons(self._scip, &(constraint.cons), n, scip_conshdlr, <SCIP_CONSDATA*>constraint,
2682  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode))
2683  return constraint
2684 
2685  def includePresol(self, Presol presol, name, desc, priority, maxrounds, timing=SCIP_PRESOLTIMING_FAST):
2686  """Include a presolver
2687 
2688  :param Presol presol: presolver
2689  :param name: name of presolver
2690  :param desc: description of presolver
2691  :param priority: priority of the presolver (>= 0: before, < 0: after constraint handlers)
2692  :param maxrounds: maximal number of presolving rounds the presolver participates in (-1: no limit)
2693  :param timing: timing mask of presolver (Default value = SCIP_PRESOLTIMING_FAST)
2694 
2695  """
2696  n = str_conversion(name)
2697  d = str_conversion(desc)
2698  PY_SCIP_CALL(SCIPincludePresol(self._scip, n, d, priority, maxrounds, timing, PyPresolCopy, PyPresolFree, PyPresolInit,
2699  PyPresolExit, PyPresolInitpre, PyPresolExitpre, PyPresolExec, <SCIP_PRESOLDATA*>presol))
2700  presol.model = <Model>weakref.proxy(self)
2701  Py_INCREF(presol)
2702 
2703  def includeSepa(self, Sepa sepa, name, desc, priority=0, freq=10, maxbounddist=1.0, usessubscip=False, delay=False):
2704  """Include a separator
2705 
2706  :param Sepa sepa: separator
2707  :param name: name of separator
2708  :param desc: description of separator
2709  :param priority: priority of separator (>= 0: before, < 0: after constraint handlers)
2710  :param freq: frequency for calling separator
2711  :param maxbounddist: maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for applying separation
2712  :param usessubscip: does the separator use a secondary SCIP instance? (Default value = False)
2713  :param delay: should separator be delayed, if other separators found cuts? (Default value = False)
2714 
2715  """
2716  n = str_conversion(name)
2717  d = str_conversion(desc)
2718  PY_SCIP_CALL(SCIPincludeSepa(self._scip, n, d, priority, freq, maxbounddist, usessubscip, delay, PySepaCopy, PySepaFree,
2719  PySepaInit, PySepaExit, PySepaInitsol, PySepaExitsol, PySepaExeclp, PySepaExecsol, <SCIP_SEPADATA*>sepa))
2720  sepa.model = <Model>weakref.proxy(self)
2721  sepa.name = name
2722  Py_INCREF(sepa)
2723 
2724  def includeProp(self, Prop prop, name, desc, presolpriority, presolmaxrounds,
2725  proptiming, presoltiming=SCIP_PRESOLTIMING_FAST, priority=1, freq=1, delay=True):
2726  """Include a propagator.
2727 
2728  :param Prop prop: propagator
2729  :param name: name of propagator
2730  :param desc: description of propagator
2731  :param presolpriority: presolving priority of the propgator (>= 0: before, < 0: after constraint handlers)
2732  :param presolmaxrounds: maximal number of presolving rounds the propagator participates in (-1: no limit)
2733  :param proptiming: positions in the node solving loop where propagation method of constraint handlers should be executed
2734  :param presoltiming: timing mask of the constraint handler's presolving method (Default value = SCIP_PRESOLTIMING_FAST)
2735  :param priority: priority of the propagator (Default value = 1)
2736  :param freq: frequency for calling propagator (Default value = 1)
2737  :param delay: should propagator be delayed if other propagators have found reductions? (Default value = True)
2738 
2739  """
2740  n = str_conversion(name)
2741  d = str_conversion(desc)
2742  PY_SCIP_CALL(SCIPincludeProp(self._scip, n, d,
2743  priority, freq, delay,
2744  proptiming, presolpriority, presolmaxrounds,
2745  presoltiming, PyPropCopy, PyPropFree, PyPropInit, PyPropExit,
2746  PyPropInitpre, PyPropExitpre, PyPropInitsol, PyPropExitsol,
2747  PyPropPresol, PyPropExec, PyPropResProp,
2748  <SCIP_PROPDATA*> prop))
2749  prop.model = <Model>weakref.proxy(self)
2750  Py_INCREF(prop)
2751 
2752  def includeHeur(self, Heur heur, name, desc, dispchar, priority=10000, freq=1, freqofs=0,
2753  maxdepth=-1, timingmask=SCIP_HEURTIMING_BEFORENODE, usessubscip=False):
2754  """Include a primal heuristic.
2755 
2756  :param Heur heur: heuristic
2757  :param name: name of heuristic
2758  :param desc: description of heuristic
2759  :param dispchar: display character of heuristic
2760  :param priority: priority of the heuristic (Default value = 10000)
2761  :param freq: frequency for calling heuristic (Default value = 1)
2762  :param freqofs: frequency offset for calling heuristic (Default value = 0)
2763  :param maxdepth: maximal depth level to call heuristic at (Default value = -1)
2764  :param timingmask: positions in the node solving loop where heuristic should be executed (Default value = SCIP_HEURTIMING_BEFORENODE)
2765  :param usessubscip: does the heuristic use a secondary SCIP instance? (Default value = False)
2766 
2767  """
2768  nam = str_conversion(name)
2769  des = str_conversion(desc)
2770  dis = ord(str_conversion(dispchar))
2771  PY_SCIP_CALL(SCIPincludeHeur(self._scip, nam, des, dis,
2772  priority, freq, freqofs,
2773  maxdepth, timingmask, usessubscip,
2774  PyHeurCopy, PyHeurFree, PyHeurInit, PyHeurExit,
2775  PyHeurInitsol, PyHeurExitsol, PyHeurExec,
2776  <SCIP_HEURDATA*> heur))
2777  heur.model = <Model>weakref.proxy(self)
2778  heur.name = name
2779  Py_INCREF(heur)
2780 
2781  def includeRelax(self, Relax relax, name, desc, priority=10000, freq=1):
2782  """Include a relaxation handler.
2783 
2784  :param Relax relax: relaxation handler
2785  :param name: name of relaxation handler
2786  :param desc: description of relaxation handler
2787  :param priority: priority of the relaxation handler (negative: after LP, non-negative: before LP, Default value = 10000)
2788  :param freq: frequency for calling relaxation handler
2789 
2790  """
2791  nam = str_conversion(name)
2792  des = str_conversion(desc)
2793  PY_SCIP_CALL(SCIPincludeRelax(self._scip, nam, des, priority, freq, PyRelaxCopy, PyRelaxFree, PyRelaxInit, PyRelaxExit,
2794  PyRelaxInitsol, PyRelaxExitsol, PyRelaxExec, <SCIP_RELAXDATA*> relax))
2795  relax.model = <Model>weakref.proxy(self)
2796  relax.name = name
2797 
2798  Py_INCREF(relax)
2799 
2800  def includeBranchrule(self, Branchrule branchrule, name, desc, priority, maxdepth, maxbounddist):
2801  """Include a branching rule.
2802 
2803  :param Branchrule branchrule: branching rule
2804  :param name: name of branching rule
2805  :param desc: description of branching rule
2806  :param priority: priority of branching rule
2807  :param maxdepth: maximal depth level up to which this branching rule should be used (or -1)
2808  :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)
2809 
2810  """
2811  nam = str_conversion(name)
2812  des = str_conversion(desc)
2813  PY_SCIP_CALL(SCIPincludeBranchrule(self._scip, nam, des,
2814  priority, maxdepth, maxbounddist,
2815  PyBranchruleCopy, PyBranchruleFree, PyBranchruleInit, PyBranchruleExit,
2816  PyBranchruleInitsol, PyBranchruleExitsol, PyBranchruleExeclp, PyBranchruleExecext,
2817  PyBranchruleExecps, <SCIP_BRANCHRULEDATA*> branchrule))
2818  branchrule.model = <Model>weakref.proxy(self)
2819  Py_INCREF(branchrule)
2820 
2821  def includeBenders(self, Benders benders, name, desc, priority=1, cutlp=True, cutpseudo=True, cutrelax=True,
2822  shareaux=False):
2823  """Include a Benders' decomposition.
2824 
2825  Keyword arguments:
2826  benders -- the Benders decomposition
2827  name -- the name
2828  desc -- the description
2829  priority -- priority of the Benders' decomposition
2830  cutlp -- should Benders' cuts be generated from LP solutions
2831  cutpseudo -- should Benders' cuts be generated from pseudo solutions
2832  cutrelax -- should Benders' cuts be generated from relaxation solutions
2833  shareaux -- should the Benders' decomposition share the auxiliary variables of the highest priority Benders' decomposition
2834  """
2835  n = str_conversion(name)
2836  d = str_conversion(desc)
2837  PY_SCIP_CALL(SCIPincludeBenders(self._scip, n, d,
2838  priority, cutlp, cutrelax, cutpseudo, shareaux,
2839  PyBendersCopy, PyBendersFree, PyBendersInit, PyBendersExit, PyBendersInitpre,
2840  PyBendersExitpre, PyBendersInitsol, PyBendersExitsol, PyBendersGetvar,
2841  PyBendersCreatesub, PyBendersPresubsolve, PyBendersSolvesubconvex,
2842  PyBendersSolvesub, PyBendersPostsolve, PyBendersFreesub,
2843  <SCIP_BENDERSDATA*>benders))
2844  cdef SCIP_BENDERS* scip_benders
2845  scip_benders = SCIPfindBenders(self._scip, n)
2846  benders.model = <Model>weakref.proxy(self)
2847  benders.name = name
2848  Py_INCREF(benders)
2849 
2850 
2851  def getLPBranchCands(self):
2852  """gets branching candidates for LP solution branching (fractional variables) along with solution values,
2853  fractionalities, and number of branching candidates; The number of branching candidates does NOT account
2854  for fractional implicit integer variables which should not be used for branching decisions. Fractional
2855  implicit integer variables are stored at the positions *nlpcands to *nlpcands + *nfracimplvars - 1
2856  branching rules should always select the branching candidate among the first npriolpcands of the candidate list
2857 
2858  :return tuple (lpcands, lpcandssol, lpcadsfrac, nlpcands, npriolpcands, nfracimplvars) where
2859 
2860  lpcands: list of variables of LP branching candidates
2861  lpcandssol: list of LP candidate solution values
2862  lpcandsfrac list of LP candidate fractionalities
2863  nlpcands: number of LP branching candidates
2864  npriolpcands: number of candidates with maximal priority
2865  nfracimplvars: number of fractional implicit integer variables
2866 
2867  """
2868  cdef int ncands
2869  cdef int nlpcands
2870  cdef int npriolpcands
2871  cdef int nfracimplvars
2872 
2873  ncands = SCIPgetNLPBranchCands(self._scip)
2874  cdef SCIP_VAR** lpcands = <SCIP_VAR**> malloc(ncands * sizeof(SCIP_VAR*))
2875  cdef SCIP_Real* lpcandssol = <SCIP_Real*> malloc(ncands * sizeof(SCIP_Real))
2876  cdef SCIP_Real* lpcandsfrac = <SCIP_Real*> malloc(ncands * sizeof(SCIP_Real))
2877 
2878  PY_SCIP_CALL(SCIPgetLPBranchCands(self._scip, &lpcands, &lpcandssol, &lpcandsfrac,
2879  &nlpcands, &npriolpcands, &nfracimplvars))
2880 
2881  return ([Variable.create(lpcands[i]) for i in range(ncands)], [lpcandssol[i] for i in range(ncands)],
2882  [lpcandsfrac[i] for i in range(ncands)], nlpcands, npriolpcands, nfracimplvars)
2883 
2884 
2885  def branchVar(self, variable):
2886  """Branch on a non-continuous variable.
2887 
2888  :param variable: Variable to branch on
2889  :return: tuple(downchild, eqchild, upchild) of Nodes of the left, middle and right child.
2890 
2891  """
2892  cdef SCIP_NODE* downchild = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2893  cdef SCIP_NODE* eqchild = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2894  cdef SCIP_NODE* upchild = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2895 
2896  PY_SCIP_CALL(SCIPbranchVar(self._scip, (<Variable>variable).var, &downchild, &eqchild, &upchild))
2897  return Node.create(downchild), Node.create(eqchild), Node.create(upchild)
2898 
2899 
2900  def branchVarVal(self, variable, value):
2901  """Branches on variable using a value which separates the domain of the variable.
2902 
2903  :param variable: Variable to branch on
2904  :param value: float, value to branch on
2905  :return: tuple(downchild, eqchild, upchild) of Nodes of the left, middle and right child. Middle child only exists
2906  if branch variable is integer
2907 
2908  """
2909  cdef SCIP_NODE* downchild = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2910  cdef SCIP_NODE* eqchild = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2911  cdef SCIP_NODE* upchild = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2912 
2913  PY_SCIP_CALL(SCIPbranchVarVal(self._scip, (<Variable>variable).var, value, &downchild, &eqchild, &upchild))
2914  # TODO should the stuff be freed and how?
2915  return Node.create(downchild), Node.create(eqchild), Node.create(upchild)
2916 
2917  def calcNodeselPriority(self, Variable variable, branchdir, targetvalue):
2918  """calculates the node selection priority for moving the given variable's LP value
2919  to the given target value;
2920  this node selection priority can be given to the SCIPcreateChild() call
2921 
2922  :param variable: variable on which the branching is applied
2923  :param branchdir: type of branching that was performed
2924  :param targetvalue: new value of the variable in the child node
2925  :return: node selection priority for moving the given variable's LP value to the given target value
2926 
2927  """
2928  return SCIPcalcNodeselPriority(self._scip, variable.var, branchdir, targetvalue)
2929 
2930  def calcChildEstimate(self, Variable variable, targetvalue):
2931  """Calculates an estimate for the objective of the best feasible solution
2932  contained in the subtree after applying the given branching;
2933  this estimate can be given to the SCIPcreateChild() call
2934 
2935  :param variable: Variable to compute the estimate for
2936  :param targetvalue: new value of the variable in the child node
2937  :return: objective estimate of the best solution in the subtree after applying the given branching
2938 
2939  """
2940  return SCIPcalcChildEstimate(self._scip, variable.var, targetvalue)
2941 
2942  def createChild(self, nodeselprio, estimate):
2943  """Create a child node of the focus node.
2944 
2945  :param nodeselprio: float, node selection priority of new node
2946  :param estimate: float, estimate for(transformed) objective value of best feasible solution in subtree
2947  :return: Node, the child which was created
2948 
2949  """
2950  cdef SCIP_NODE* child = <SCIP_NODE*> malloc(sizeof(SCIP_NODE))
2951  PY_SCIP_CALL(SCIPcreateChild(self._scip, &child, nodeselprio, estimate))
2952  return Node.create(child)
2953 
2954  # Diving methods (Diving is LP related)
2955  def startDive(self):
2956  """Initiates LP diving
2957  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,
2958  SCIP will undo all changes done and recover the LP it had before startDive
2959  """
2960  PY_SCIP_CALL(SCIPstartDive(self._scip))
2961 
2962  def endDive(self):
2963  """Quits probing and resets bounds and constraints to the focus node's environment"""
2964  PY_SCIP_CALL(SCIPendDive(self._scip))
2965 
2966  def chgVarObjDive(self, Variable var, newobj):
2967  """changes (column) variable's objective value in current dive"""
2968  PY_SCIP_CALL(SCIPchgVarObjDive(self._scip, var.var, newobj))
2969 
2970  def chgVarLbDive(self, Variable var, newbound):
2971  """changes variable's current lb in current dive"""
2972  PY_SCIP_CALL(SCIPchgVarLbDive(self._scip, var.var, newbound))
2973 
2974  def chgVarUbDive(self, Variable var, newbound):
2975  """changes variable's current ub in current dive"""
2976  PY_SCIP_CALL(SCIPchgVarUbDive(self._scip, var.var, newbound))
2977 
2978  def getVarLbDive(self, Variable var):
2979  """returns variable's current lb in current dive"""
2980  return SCIPgetVarLbDive(self._scip, var.var)
2981 
2982  def getVarUbDive(self, Variable var):
2983  """returns variable's current ub in current dive"""
2984  return SCIPgetVarUbDive(self._scip, var.var)
2985 
2986  def chgRowLhsDive(self, Row row, newlhs):
2987  """changes row lhs in current dive, change will be undone after diving
2988  ends, for permanent changes use SCIPchgRowLhs()
2989  """
2990  PY_SCIP_CALL(SCIPchgRowLhsDive(self._scip, row.row, newlhs))
2991 
2992  def chgRowRhsDive(self, Row row, newrhs):
2993  """changes row rhs in current dive, change will be undone after diving
2994  ends, for permanent changes use SCIPchgRowLhs()
2995  """
2996  PY_SCIP_CALL(SCIPchgRowRhsDive(self._scip, row.row, newrhs))
2997 
2998  def addRowDive(self, Row row):
2999  """adds a row to the LP in current dive"""
3000  PY_SCIP_CALL(SCIPaddRowDive(self._scip, row.row))
3001 
3002  def solveDiveLP(self, itlim = -1):
3003  """solves the LP of the current dive no separation or pricing is applied
3004  no separation or pricing is applied
3005  :param itlim: maximal number of LP iterations to perform (Default value = -1, that is, no limit)
3006  returns two booleans:
3007  lperror -- if an unresolved lp error occured
3008  cutoff -- whether the LP was infeasible or the objective limit was reached
3009  """
3010  cdef SCIP_Bool lperror
3011  cdef SCIP_Bool cutoff
3012 
3013  PY_SCIP_CALL(SCIPsolveDiveLP(self._scip, itlim, &lperror, &cutoff))
3014  return lperror, cutoff
3015 
3016  def inRepropagation(self):
3017  """returns if the current node is already solved and only propagated again."""
3018  return SCIPinRepropagation(self._scip)
3019 
3020  # Probing methods (Probing is tree based)
3021  def startProbing(self):
3022  """Initiates probing, making methods SCIPnewProbingNode(), SCIPbacktrackProbing(), SCIPchgVarLbProbing(),
3023  SCIPchgVarUbProbing(), SCIPfixVarProbing(), SCIPpropagateProbing(), SCIPsolveProbingLP(), etc available
3024  """
3025  PY_SCIP_CALL(SCIPstartProbing(self._scip))
3026 
3027  def endProbing(self):
3028  """Quits probing and resets bounds and constraints to the focus node's environment"""
3029  PY_SCIP_CALL(SCIPendProbing(self._scip))
3030 
3031  def chgVarObjProbing(self, Variable var, newobj):
3032  """changes (column) variable's objective value during probing mode"""
3033  PY_SCIP_CALL(SCIPchgVarObjProbing(self._scip, var.var, newobj))
3034 
3035  def fixVarProbing(self, Variable var, fixedval):
3036  """Fixes a variable at the current probing node."""
3037  PY_SCIP_CALL(SCIPfixVarProbing(self._scip, var.var, fixedval))
3038 
3040  """returns whether the objective function has changed during probing mode"""
3041  return SCIPisObjChangedProbing(self._scip)
3042 
3043  def inProbing(self):
3044  """returns whether we are in probing mode; probing mode is activated via startProbing() and stopped via endProbing()"""
3045  return SCIPinProbing(self._scip)
3046 
3047  def solveProbingLP(self, itlim = -1):
3048  """solves the LP at the current probing node (cannot be applied at preprocessing stage)
3049  no separation or pricing is applied
3050  :param itlim: maximal number of LP iterations to perform (Default value = -1, that is, no limit)
3051  returns two booleans:
3052  lperror -- if an unresolved lp error occured
3053  cutoff -- whether the LP was infeasible or the objective limit was reached
3054  """
3055  cdef SCIP_Bool lperror
3056  cdef SCIP_Bool cutoff
3057 
3058  PY_SCIP_CALL(SCIPsolveProbingLP(self._scip, itlim, &lperror, &cutoff))
3059  return lperror, cutoff
3060 
3061  def interruptSolve(self):
3062  """Interrupt the solving process as soon as possible."""
3063  PY_SCIP_CALL(SCIPinterruptSolve(self._scip))
3064 
3065  # Solution functions
3066 
3067  def createSol(self, Heur heur = None):
3068  """Create a new primal solution.
3069 
3070  :param Heur heur: heuristic that found the solution (Default value = None)
3071 
3072  """
3073  cdef SCIP_HEUR* _heur
3074 
3075  if isinstance(heur, Heur):
3076  n = str_conversion(heur.name)
3077  _heur = SCIPfindHeur(self._scip, n)
3078  else:
3079  _heur = NULL
3080  solution = Solution()
3081  PY_SCIP_CALL(SCIPcreateSol(self._scip, &solution.sol, _heur))
3082  return solution
3083 
3084  def printBestSol(self, write_zeros=False):
3085  """Prints the best feasible primal solution."""
3086  PY_SCIP_CALL(SCIPprintBestSol(self._scip, NULL, write_zeros))
3087 
3088  def printSol(self, Solution solution, write_zeros=False):
3089  """Print the given primal solution.
3090 
3091  Keyword arguments:
3092  solution -- solution to print
3093  write_zeros -- include variables that are set to zero
3094  """
3095  PY_SCIP_CALL(SCIPprintSol(self._scip, solution.sol, NULL, write_zeros))
3096 
3097  def writeBestSol(self, filename="origprob.sol", write_zeros=False):
3098  """Write the best feasible primal solution to a file.
3099 
3100  Keyword arguments:
3101  filename -- name of the output file
3102  write_zeros -- include variables that are set to zero
3103  """
3104  # use this doubled opening pattern to ensure that IOErrors are
3105  # triggered early and in Python not in C,Cython or SCIP.
3106  with open(filename, "w") as f:
3107  cfile = fdopen(f.fileno(), "w")
3108  PY_SCIP_CALL(SCIPprintBestSol(self._scip, cfile, write_zeros))
3109 
3110  def writeSol(self, Solution solution, filename="origprob.sol", write_zeros=False):
3111  """Write the given primal solution to a file.
3112 
3113  Keyword arguments:
3114  solution -- solution to write
3115  filename -- name of the output file
3116  write_zeros -- include variables that are set to zero
3117  """
3118  # use this doubled opening pattern to ensure that IOErrors are
3119  # triggered early and in Python not in C,Cython or SCIP.
3120  with open(filename, "w") as f:
3121  cfile = fdopen(f.fileno(), "w")
3122  PY_SCIP_CALL(SCIPprintSol(self._scip, solution.sol, cfile, write_zeros))
3123 
3124  # perhaps this should not be included as it implements duplicated functionality
3125  # (as does it's namesake in SCIP)
3126  def readSol(self, filename):
3127  """Reads a given solution file, problem has to be transformed in advance.
3128 
3129  Keyword arguments:
3130  filename -- name of the input file
3131  """
3132  fn = str_conversion(filename)
3133  PY_SCIP_CALL(SCIPreadSol(self._scip, fn))
3134 
3135  def readSolFile(self, filename):
3136  """Reads a given solution file.
3137 
3138  Solution is created but not added to storage/the model.
3139  Use 'addSol' OR 'trySol' to add it.
3140 
3141  Keyword arguments:
3142  filename -- name of the input file
3143  """
3144  cdef SCIP_Bool partial
3145  cdef SCIP_Bool error
3146  cdef SCIP_Bool stored
3147  cdef Solution solution
3148 
3149  fn = str_conversion(filename)
3150  solution = self.createSol()
3151  PY_SCIP_CALL(SCIPreadSolFile(self._scip, fn, solution.sol, False, &partial, &error))
3152  if error:
3153  raise Exception("SCIP: reading solution from file failed!")
3154 
3155  return solution
3156 
3157  def setSolVal(self, Solution solution, Variable var, val):
3158  """Set a variable in a solution.
3159 
3160  :param Solution solution: solution to be modified
3161  :param Variable var: variable in the solution
3162  :param val: value of the specified variable
3163 
3164  """
3165  cdef SCIP_SOL* _sol
3166  _sol = <SCIP_SOL*>solution.sol
3167  PY_SCIP_CALL(SCIPsetSolVal(self._scip, _sol, var.var, val))
3168 
3169  def trySol(self, Solution solution, printreason=True, completely=False, checkbounds=True, checkintegrality=True, checklprows=True, free=True):
3170  """Check given primal solution for feasibility and try to add it to the storage.
3171 
3172  :param Solution solution: solution to store
3173  :param printreason: should all reasons of violations be printed? (Default value = True)
3174  :param completely: should all violation be checked? (Default value = False)
3175  :param checkbounds: should the bounds of the variables be checked? (Default value = True)
3176  :param checkintegrality: has integrality to be checked? (Default value = True)
3177  :param checklprows: have current LP rows (both local and global) to be checked? (Default value = True)
3178  :param free: should solution be freed? (Default value = True)
3179 
3180  """
3181  cdef SCIP_Bool stored
3182  if free:
3183  PY_SCIP_CALL(SCIPtrySolFree(self._scip, &solution.sol, printreason, completely, checkbounds, checkintegrality, checklprows, &stored))
3184  else:
3185  PY_SCIP_CALL(SCIPtrySol(self._scip, solution.sol, printreason, completely, checkbounds, checkintegrality, checklprows, &stored))
3186  return stored
3187 
3188  def checkSol(self, Solution solution, printreason=True, completely=False, checkbounds=True, checkintegrality=True, checklprows=True, original=False):
3189  """Check given primal solution for feasibility without adding it to the storage.
3190 
3191  :param Solution solution: solution to store
3192  :param printreason: should all reasons of violations be printed? (Default value = True)
3193  :param completely: should all violation be checked? (Default value = False)
3194  :param checkbounds: should the bounds of the variables be checked? (Default value = True)
3195  :param checkintegrality: has integrality to be checked? (Default value = True)
3196  :param checklprows: have current LP rows (both local and global) to be checked? (Default value = True)
3197  :param original: must the solution be checked against the original problem (Default value = False)
3198 
3199  """
3200  cdef SCIP_Bool feasible
3201  if original:
3202  PY_SCIP_CALL(SCIPcheckSolOrig(self._scip, solution.sol, &feasible, printreason, completely))
3203  else:
3204  PY_SCIP_CALL(SCIPcheckSol(self._scip, solution.sol, printreason, completely, checkbounds, checkintegrality, checklprows, &feasible))
3205  return feasible
3206 
3207  def addSol(self, Solution solution, free=True):
3208  """Try to add a solution to the storage.
3209 
3210  :param Solution solution: solution to store
3211  :param free: should solution be freed afterwards? (Default value = True)
3212 
3213  """
3214  cdef SCIP_Bool stored
3215  if free:
3216  PY_SCIP_CALL(SCIPaddSolFree(self._scip, &solution.sol, &stored))
3217  else:
3218  PY_SCIP_CALL(SCIPaddSol(self._scip, solution.sol, &stored))
3219  return stored
3220 
3221  def freeSol(self, Solution solution):
3222  """Free given solution
3223 
3224  :param Solution solution: solution to be freed
3225 
3226  """
3227  PY_SCIP_CALL(SCIPfreeSol(self._scip, &solution.sol))
3228 
3229  def getSols(self):
3230  """Retrieve list of all feasible primal solutions stored in the solution storage."""
3231  cdef SCIP_SOL** _sols
3232  cdef SCIP_SOL* _sol
3233  _sols = SCIPgetSols(self._scip)
3234  nsols = SCIPgetNSols(self._scip)
3235  sols = []
3236 
3237  for i in range(nsols):
3238  sols.append(Solution.create(_sols[i]))
3239 
3240  return sols
3241 
3242  def getBestSol(self):
3243  """Retrieve currently best known feasible primal solution."""
3244  self._bestSol = Solution.create(SCIPgetBestSol(self._scip))
3245  return self._bestSol
3246 
3247  def getSolObjVal(self, Solution sol, original=True):
3248  """Retrieve the objective value of the solution.
3249 
3250  :param Solution sol: solution
3251  :param original: objective value in original space (Default value = True)
3252 
3253  """
3254  if sol == None:
3255  sol = Solution.create(NULL)
3256  if original:
3257  objval = SCIPgetSolOrigObj(self._scip, sol.sol)
3258  else:
3259  objval = SCIPgetSolTransObj(self._scip, sol.sol)
3260  return objval
3261 
3262  def getObjVal(self, original=True):
3263  """Retrieve the objective value of value of best solution.
3264  Can only be called after solving is completed.
3265 
3266  :param original: objective value in original space (Default value = True)
3267 
3268  """
3269  if not self.getStage() >= SCIP_STAGE_SOLVING:
3270  raise Warning("method cannot be called before problem is solved")
3271  return self.getSolObjVal(self._bestSol, original)
3272 
3273  def getSolVal(self, Solution sol, Variable var):
3274  """Retrieve value of given variable in the given solution or in
3275  the LP/pseudo solution if sol == None
3276 
3277  :param Solution sol: solution
3278  :param Variable var: variable to query the value of
3279 
3280  """
3281  if sol == None:
3282  sol = Solution.create(NULL)
3283  return SCIPgetSolVal(self._scip, sol.sol, var.var)
3284 
3285  def getVal(self, Variable var):
3286  """Retrieve the value of the best known solution.
3287  Can only be called after solving is completed.
3288 
3289  :param Variable var: variable to query the value of
3290 
3291  """
3292  if not self.getStage() >= SCIP_STAGE_SOLVING:
3293  raise Warning("method cannot be called before problem is solved")
3294  return self.getSolVal(self._bestSol, var)
3295 
3296  def getPrimalbound(self):
3297  """Retrieve the best primal bound."""
3298  return SCIPgetPrimalbound(self._scip)
3299 
3300  def getDualbound(self):
3301  """Retrieve the best dual bound."""
3302  return SCIPgetDualbound(self._scip)
3303 
3304  def getDualboundRoot(self):
3305  """Retrieve the best root dual bound."""
3306  return SCIPgetDualboundRoot(self._scip)
3307 
3308  def writeName(self, Variable var):
3309  """Write the name of the variable to the std out.
3310 
3311  :param Variable var: variable
3312 
3313  """
3314  PY_SCIP_CALL(SCIPwriteVarName(self._scip, NULL, var.var, False))
3315 
3316  def getStage(self):
3317  """Retrieve current SCIP stage"""
3318  return SCIPgetStage(self._scip)
3319 
3320  def getStatus(self):
3321  """Retrieve solution status."""
3322  cdef SCIP_STATUS stat = SCIPgetStatus(self._scip)
3323  if stat == SCIP_STATUS_OPTIMAL:
3324  return "optimal"
3325  elif stat == SCIP_STATUS_TIMELIMIT:
3326  return "timelimit"
3327  elif stat == SCIP_STATUS_INFEASIBLE:
3328  return "infeasible"
3329  elif stat == SCIP_STATUS_UNBOUNDED:
3330  return "unbounded"
3331  else:
3332  return "unknown"
3333 
3335  """Retrieve objective sense."""
3336  cdef SCIP_OBJSENSE sense = SCIPgetObjsense(self._scip)
3337  if sense == SCIP_OBJSENSE_MAXIMIZE:
3338  return "maximize"
3339  elif sense == SCIP_OBJSENSE_MINIMIZE:
3340  return "minimize"
3341  else:
3342  return "unknown"
3343 
3344  def catchEvent(self, eventtype, Eventhdlr eventhdlr):
3345  """catches a global (not variable or row dependent) event"""
3346  cdef SCIP_EVENTHDLR* _eventhdlr
3347  if isinstance(eventhdlr, Eventhdlr):
3348  n = str_conversion(eventhdlr.name)
3349  _eventhdlr = SCIPfindEventhdlr(self._scip, n)
3350  else:
3351  raise Warning("event handler not found")
3352  PY_SCIP_CALL(SCIPcatchEvent(self._scip, eventtype, _eventhdlr, NULL, NULL))
3353 
3354  def dropEvent(self, eventtype, Eventhdlr eventhdlr):
3355  """drops a global event (stops to track event)"""
3356  cdef SCIP_EVENTHDLR* _eventhdlr
3357  if isinstance(eventhdlr, Eventhdlr):
3358  n = str_conversion(eventhdlr.name)
3359  _eventhdlr = SCIPfindEventhdlr(self._scip, n)
3360  else:
3361  raise Warning("event handler not found")
3362  PY_SCIP_CALL(SCIPdropEvent(self._scip, eventtype, _eventhdlr, NULL, -1))
3363 
3364  def catchVarEvent(self, Variable var, eventtype, Eventhdlr eventhdlr):
3365  """catches an objective value or domain change event on the given transformed variable"""
3366  cdef SCIP_EVENTHDLR* _eventhdlr
3367  if isinstance(eventhdlr, Eventhdlr):
3368  n = str_conversion(eventhdlr.name)
3369  _eventhdlr = SCIPfindEventhdlr(self._scip, n)
3370  else:
3371  raise Warning("event handler not found")
3372  PY_SCIP_CALL(SCIPcatchVarEvent(self._scip, var.var, eventtype, _eventhdlr, NULL, NULL))
3373 
3374  def dropVarEvent(self, Variable var, eventtype, Eventhdlr eventhdlr):
3375  """drops an objective value or domain change event (stops to track event) on the given transformed variable"""
3376  cdef SCIP_EVENTHDLR* _eventhdlr
3377  if isinstance(eventhdlr, Eventhdlr):
3378  n = str_conversion(eventhdlr.name)
3379  _eventhdlr = SCIPfindEventhdlr(self._scip, n)
3380  else:
3381  raise Warning("event handler not found")
3382  PY_SCIP_CALL(SCIPdropVarEvent(self._scip, var.var, eventtype, _eventhdlr, NULL, -1))
3383 
3384  def catchRowEvent(self, Row row, eventtype, Eventhdlr eventhdlr):
3385  """catches a row coefficient, constant, or side change event on the given row"""
3386  cdef SCIP_EVENTHDLR* _eventhdlr
3387  if isinstance(eventhdlr, Eventhdlr):
3388  n = str_conversion(eventhdlr.name)
3389  _eventhdlr = SCIPfindEventhdlr(self._scip, n)
3390  else:
3391  raise Warning("event handler not found")
3392  PY_SCIP_CALL(SCIPcatchRowEvent(self._scip, row.row, eventtype, _eventhdlr, NULL, NULL))
3393 
3394  def dropRowEvent(self, Row row, eventtype, Eventhdlr eventhdlr):
3395  """drops a row coefficient, constant, or side change event (stops to track event) on the given row"""
3396  cdef SCIP_EVENTHDLR* _eventhdlr
3397  if isinstance(eventhdlr, Eventhdlr):
3398  n = str_conversion(eventhdlr.name)
3399  _eventhdlr = SCIPfindEventhdlr(self._scip, n)
3400  else:
3401  raise Warning("event handler not found")
3402  PY_SCIP_CALL(SCIPdropRowEvent(self._scip, row.row, eventtype, _eventhdlr, NULL, -1))
3403 
3404  # Statistic Methods
3405 
3406  def printStatistics(self):
3407  """Print statistics."""
3408  PY_SCIP_CALL(SCIPprintStatistics(self._scip, NULL))
3409 
3410  def writeStatistics(self, filename="origprob.stats"):
3411  """Write statistics to a file.
3412 
3413  Keyword arguments:
3414  filename -- name of the output file
3415  """
3416  # use this doubled opening pattern to ensure that IOErrors are
3417  # triggered early and in Python not in C,Cython or SCIP.
3418  with open(filename, "w") as f:
3419  cfile = fdopen(f.fileno(), "w")
3420  PY_SCIP_CALL(SCIPprintStatistics(self._scip, cfile))
3421 
3422  def getNLPs(self):
3423  """gets total number of LPs solved so far"""
3424  return SCIPgetNLPs(self._scip)
3425 
3426  # Verbosity Methods
3427 
3428  def hideOutput(self, quiet = True):
3429  """Hide the output.
3430 
3431  :param quiet: hide output? (Default value = True)
3432 
3433  """
3434  SCIPsetMessagehdlrQuiet(self._scip, quiet)
3435 
3436  # Output Methods
3437 
3438  def redirectOutput(self):
3439  """Send output to python instead of terminal."""
3440 
3441  cdef SCIP_MESSAGEHDLR *myMessageHandler
3442 
3443  PY_SCIP_CALL(SCIPmessagehdlrCreate(&myMessageHandler, False, NULL, False, relayMessage, relayMessage, relayMessage, NULL, NULL))
3444  PY_SCIP_CALL(SCIPsetMessagehdlr(self._scip, myMessageHandler))
3445  SCIPmessageSetErrorPrinting(relayErrorMessage, NULL)
3446 
3447  # Parameter Methods
3448 
3449  def setBoolParam(self, name, value):
3450  """Set a boolean-valued parameter.
3451 
3452  :param name: name of parameter
3453  :param value: value of parameter
3454 
3455  """
3456  n = str_conversion(name)
3457  PY_SCIP_CALL(SCIPsetBoolParam(self._scip, n, value))
3458 
3459  def setIntParam(self, name, value):
3460  """Set an int-valued parameter.
3461 
3462  :param name: name of parameter
3463  :param value: value of parameter
3464 
3465  """
3466  n = str_conversion(name)
3467  PY_SCIP_CALL(SCIPsetIntParam(self._scip, n, value))
3468 
3469  def setLongintParam(self, name, value):
3470  """Set a long-valued parameter.
3471 
3472  :param name: name of parameter
3473  :param value: value of parameter
3474 
3475  """
3476  n = str_conversion(name)
3477  PY_SCIP_CALL(SCIPsetLongintParam(self._scip, n, value))
3478 
3479  def setRealParam(self, name, value):
3480  """Set a real-valued parameter.
3481 
3482  :param name: name of parameter
3483  :param value: value of parameter
3484 
3485  """
3486  n = str_conversion(name)
3487  PY_SCIP_CALL(SCIPsetRealParam(self._scip, n, value))
3488 
3489  def setCharParam(self, name, value):
3490  """Set a char-valued parameter.
3491 
3492  :param name: name of parameter
3493  :param value: value of parameter
3494 
3495  """
3496  n = str_conversion(name)
3497  PY_SCIP_CALL(SCIPsetCharParam(self._scip, n, ord(value)))
3498 
3499  def setStringParam(self, name, value):
3500  """Set a string-valued parameter.
3501 
3502  :param name: name of parameter
3503  :param value: value of parameter
3504 
3505  """
3506  n = str_conversion(name)
3507  v = str_conversion(value)
3508  PY_SCIP_CALL(SCIPsetStringParam(self._scip, n, v))
3509 
3510  def setParam(self, name, value):
3511  """Set a parameter with value in int, bool, real, long, char or str.
3512 
3513  :param name: name of parameter
3514  :param value: value of parameter
3515  """
3516  cdef SCIP_PARAM* param
3517 
3518  n = str_conversion(name)
3519  param = SCIPgetParam(self._scip, n)
3520 
3521  if param == NULL:
3522  raise KeyError("Not a valid parameter name")
3523 
3524  paramtype = SCIPparamGetType(param)
3525 
3526  if paramtype == SCIP_PARAMTYPE_BOOL:
3527  PY_SCIP_CALL(SCIPsetBoolParam(self._scip, n, bool(int(value))))
3528  elif paramtype == SCIP_PARAMTYPE_INT:
3529  PY_SCIP_CALL(SCIPsetIntParam(self._scip, n, int(value)))
3530  elif paramtype == SCIP_PARAMTYPE_LONGINT:
3531  PY_SCIP_CALL(SCIPsetLongintParam(self._scip, n, int(value)))
3532  elif paramtype == SCIP_PARAMTYPE_REAL:
3533  PY_SCIP_CALL(SCIPsetRealParam(self._scip, n, float(value)))
3534  elif paramtype == SCIP_PARAMTYPE_CHAR:
3535  PY_SCIP_CALL(SCIPsetCharParam(self._scip, n, value))
3536  elif paramtype == SCIP_PARAMTYPE_STRING:
3537  PY_SCIP_CALL(SCIPsetStringParam(self._scip, n, value))
3538 
3539 
3540  def getParam(self, name):
3541  """Get the value of a parameter of type
3542  int, bool, real, long, char or str.
3543 
3544  :param name: name of parameter
3545  """
3546  cdef SCIP_PARAM* param
3547 
3548  n = str_conversion(name)
3549  param = SCIPgetParam(self._scip, n)
3550 
3551  if param == NULL:
3552  raise KeyError("Not a valid parameter name")
3553 
3554  paramtype = SCIPparamGetType(param)
3555 
3556  if paramtype == SCIP_PARAMTYPE_BOOL:
3557  return SCIPparamGetBool(param)
3558  elif paramtype == SCIP_PARAMTYPE_INT:
3559  return SCIPparamGetInt(param)
3560  elif paramtype == SCIP_PARAMTYPE_LONGINT:
3561  return SCIPparamGetLongint(param)
3562  elif paramtype == SCIP_PARAMTYPE_REAL:
3563  return SCIPparamGetReal(param)
3564  elif paramtype == SCIP_PARAMTYPE_CHAR:
3565  return chr(SCIPparamGetChar(param))
3566  elif paramtype == SCIP_PARAMTYPE_STRING:
3567  return SCIPparamGetString(param)
3568 
3569 
3570  def readParams(self, file):
3571  """Read an external parameter file.
3572 
3573  :param file: file to be read
3574 
3575  """
3576  absfile = str_conversion(abspath(file))
3577  PY_SCIP_CALL(SCIPreadParams(self._scip, absfile))
3578 
3579  def writeParams(self, filename='param.set', comments = True, onlychanged = True):
3580  """Write parameter settings to an external file.
3581 
3582  :param filename: file to be written (Default value = 'param.set')
3583  :param comments: write parameter descriptions as comments? (Default value = True)
3584  :param onlychanged: write only modified parameters (Default value = True)
3585 
3586  """
3587  fn = str_conversion(filename)
3588  PY_SCIP_CALL(SCIPwriteParams(self._scip, fn, comments, onlychanged))
3589  print('wrote parameter settings to file ' + filename)
3590 
3591  def resetParam(self, name):
3592  """Reset parameter setting to its default value
3593 
3594  :param name: parameter to reset
3595 
3596  """
3597  n = str_conversion(name)
3598  PY_SCIP_CALL(SCIPresetParam(self._scip, n))
3599 
3600  def resetParams(self):
3601  """Reset parameter settings to their default values"""
3602  PY_SCIP_CALL(SCIPresetParams(self._scip))
3603 
3604  def setEmphasis(self, paraemphasis, quiet = True):
3605  """Set emphasis settings
3606 
3607  :param paraemphasis: emphasis to set
3608  :param quiet: hide output? (Default value = True)
3609 
3610  """
3611  PY_SCIP_CALL(SCIPsetEmphasis(self._scip, paraemphasis, quiet))
3612 
3613  def readProblem(self, file, extension = None):
3614  """Read a problem instance from an external file.
3615 
3616  :param file: file to be read
3617  :param extension: specify file extension/type (Default value = None)
3618 
3619  """
3620  absfile = str_conversion(abspath(file))
3621  if extension is None:
3622  PY_SCIP_CALL(SCIPreadProb(self._scip, absfile, NULL))
3623  else:
3624  extension = str_conversion(extension)
3625  PY_SCIP_CALL(SCIPreadProb(self._scip, absfile, extension))
3626 
3627  # Counting functions
3628 
3629  def count(self):
3630  """Counts the number of feasible points of problem."""
3631  PY_SCIP_CALL(SCIPcount(self._scip))
3632 
3633  def getNCountedSols(self):
3634  """Get number of feasible solution."""
3635  cdef SCIP_Bool valid
3636  cdef SCIP_Longint nsols
3637 
3638  nsols = SCIPgetNCountedSols(self._scip, &valid)
3639  if not valid:
3640  print('total number of solutions found is not valid!')
3641  return nsols
3642 
3644  """Sets SCIP parameters such that a valid counting process is possible."""
3645  PY_SCIP_CALL(SCIPsetParamsCountsols(self._scip))
3646 
3647  def freeReoptSolve(self):
3648  """Frees all solution process data and prepares for reoptimization"""
3649  PY_SCIP_CALL(SCIPfreeReoptSolve(self._scip))
3650 
3651  def chgReoptObjective(self, coeffs, sense = 'minimize'):
3652  """Establish the objective function as a linear expression.
3653 
3654  :param coeffs: the coefficients
3655  :param sense: the objective sense (Default value = 'minimize')
3656 
3657  """
3658 
3659  cdef SCIP_OBJSENSE objsense
3660 
3661  if sense == "minimize":
3662  objsense = SCIP_OBJSENSE_MINIMIZE
3663  elif sense == "maximize":
3664  objsense = SCIP_OBJSENSE_MAXIMIZE
3665  else:
3666  raise Warning("unrecognized optimization sense: %s" % sense)
3667 
3668  assert isinstance(coeffs, Expr), "given coefficients are not Expr but %s" % coeffs.__class__.__name__
3669 
3670  if coeffs.degree() > 1:
3671  raise ValueError("Nonlinear objective functions are not supported!")
3672  if coeffs[CONST] != 0.0:
3673  raise ValueError("Constant offsets in objective are not supported!")
3674 
3675  cdef SCIP_VAR** _vars
3676  cdef int _nvars
3677  _vars = SCIPgetOrigVars(self._scip)
3678  _nvars = SCIPgetNOrigVars(self._scip)
3679  _coeffs = <SCIP_Real*> malloc(_nvars * sizeof(SCIP_Real))
3680 
3681  for i in range(_nvars):
3682  _coeffs[i] = 0.0
3683 
3684  for term, coef in coeffs.terms.items():
3685  # avoid CONST term of Expr
3686  if term != CONST:
3687  assert len(term) == 1
3688  var = <Variable>term[0]
3689  for i in range(_nvars):
3690  if _vars[i] == var.var:
3691  _coeffs[i] = coef
3692 
3693  PY_SCIP_CALL(SCIPchgReoptObjective(self._scip, objsense, _vars, &_coeffs[0], _nvars))
3694 
3695  free(_coeffs)
3696 
3697 # debugging memory management
3698 def is_memory_freed():
3699  return BMSgetMemoryUsed() == 0
3700 
3701 def print_memory_in_use():
3702  BMScheckEmptyMemory()
SCIP_RETCODE SCIPfreeProb(SCIP *scip)
int SCIPgetNConss(SCIP *scip)
def trySol(self, Solution, solution, printreason=True, completely=False, checkbounds=True, checkintegrality=True, checklprows=True, free=True)
Definition: scip.pyx:3169
def startProbing(self)
Definition: scip.pyx:3021
def dropVarEvent(self, Variable, var, eventtype, Eventhdlr, eventhdlr)
Definition: scip.pyx:3374
def getDepth(self)
Definition: scip.pyx:714
def getVar(self)
Definition: scip.pyx:270
SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
def setHeuristics(self, setting)
Definition: scip.pyx:907
def getVarRedcost(self, Variable, var)
Definition: scip.pyx:2392
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
def printBestSol(self, write_zeros=False)
Definition: scip.pyx:3084
SCIP_RETCODE SCIPsetStringParam(SCIP *scip, const char *name, const char *value)
def optimize(self)
Definition: scip.pyx:2407
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
SCIP_RETCODE SCIPincludeEventhdlr(SCIP *scip, const char *name, const char *desc, SCIP_DECL_EVENTCOPY((*eventcopy)), SCIP_DECL_EVENTFREE((*eventfree)), SCIP_DECL_EVENTINIT((*eventinit)), SCIP_DECL_EVENTEXIT((*eventexit)), SCIP_DECL_EVENTINITSOL((*eventinitsol)), SCIP_DECL_EVENTEXITSOL((*eventexitsol)), SCIP_DECL_EVENTDELETE((*eventdelete)), SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
def getLPObjVal(self)
Definition: scip.pyx:1251
def getLbLocal(self)
Definition: scip.pyx:516
def appendVarSOS2(self, Constraint, cons, Variable, var)
Definition: scip.pyx:2021
def getReadingTime(self)
Definition: scip.pyx:694
def getNCutsApplied(self)
Definition: scip.pyx:1409
SCIP_RETCODE SCIPaddSolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool *stored)
SCIP_Real SCIPgetGap(SCIP *scip)
SCIP_RETCODE SCIPcreateConsQuadratic(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoeffs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable)
SCIP_RETCODE SCIPchgVarObjDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
SCIP_Bool SCIPnodeIsPropagatedAgain(SCIP_NODE *node)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
def getLhs(self)
Definition: scip.pyx:339
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddPricedVar(SCIP *scip, SCIP_VAR *var, SCIP_Real score)
SCIP_RETCODE SCIPsetLongintParam(SCIP *scip, const char *name, SCIP_Longint value)
int SCIPgetDepth(SCIP *scip)
SCIP_RETCODE SCIPprintStatistics(SCIP *scip, FILE *file)
def getType(self)
Definition: scip.pyx:428
def getBasisStatus(self)
Definition: scip.pyx:294
def includeHeur(self, Heur, heur, name, desc, dispchar, priority=10000, freq=1, freqofs=0, maxdepth=-1, timingmask=SCIP_HEURTIMING_BEFORENODE, usessubscip=False)
Definition: scip.pyx:2753
def getDualboundRoot(self)
Definition: scip.pyx:3304
SCIP_RETCODE SCIPgetActivityQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Real *activity)
def chgVarLb(self, Variable, var, lb)
Definition: scip.pyx:1110
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
def addConsOr(self, vars, resvar, name="ORcons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1798
void SCIPprintVersion(SCIP *scip, FILE *file)
SCIP_RETCODE SCIPgetDualSolVal(SCIP *scip, SCIP_CONS *cons, SCIP_Real *dualsolval, SCIP_Bool *boundconstraint)
def setRemovable(self, Constraint, cons, newRem)
Definition: scip.pyx:2039
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
def getLhs(self, Constraint, cons)
Definition: scip.pyx:2118
def chgVarObjProbing(self, Variable, var, newobj)
Definition: scip.pyx:3031
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
def chgVarUbDive(self, Variable, var, newbound)
Definition: scip.pyx:2974
SCIP_BASESTAT SCIPcolGetBasisStatus(SCIP_COL *col)
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
SCIP_RETCODE SCIPtightenVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
def isFeasZero(self, value)
Definition: scip.pyx:742
def isLPSolBasic(self)
Definition: scip.pyx:1312
def endProbing(self)
Definition: scip.pyx:3027
def getUbLocal(self)
Definition: scip.pyx:520
SCIP_SOL * SCIPgetBestSol(SCIP *scip)
int SCIPgetNVars(SCIP *scip)
def isOriginal(self)
Definition: scip.pyx:553
def tightenVarUb(self, Variable, var, ub, force=False)
Definition: scip.pyx:1061
def addRowDive(self, Row, row)
Definition: scip.pyx:2998
SCIP_Real SCIPfeasFrac(SCIP *scip, SCIP_Real val)
int SCIPnodeGetNAddedConss(SCIP_NODE *node)
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
def isModifiable(self)
Definition: scip.pyx:374
void SCIPsetMessagehdlrQuiet(SCIP *scip, SCIP_Bool quiet)
def checkSol(self, Solution, solution, printreason=True, completely=False, checkbounds=True, checkintegrality=True, checklprows=True, original=False)
Definition: scip.pyx:3188
def getLPPos(self)
Definition: scip.pyx:351
def addConsCardinality(self, consvars, cardval, indvars=None, weights=None, name="CardinalityCons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1876
def getBasisStatus(self)
Definition: scip.pyx:355
def count(self)
Definition: scip.pyx:3629
SCIP_RETCODE SCIPsolveDiveLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Real SCIPgetDualboundRoot(SCIP *scip)
def getNCuts(self)
Definition: scip.pyx:1405
def setProbName(self, name)
Definition: scip.pyx:894
SCIP_Real SCIPnodeGetEstimate(SCIP_NODE *node)
def freeReoptSolve(self)
Definition: scip.pyx:3647
def dropEvent(self, eventtype, Eventhdlr, eventhdlr)
Definition: scip.pyx:3354
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
def getNLPCols(self)
Definition: scip.pyx:1276
def catchEvent(self, eventtype, Eventhdlr, eventhdlr)
Definition: scip.pyx:3344
SCIP_RETCODE SCIPincludeBenders(SCIP *scip, const char *name, const char *desc, int priority, SCIP_Bool cutlp, SCIP_Bool cutpseudo, SCIP_Bool cutrelax, SCIP_Bool shareauxvars, SCIP_DECL_BENDERSCOPY((*benderscopy)), SCIP_DECL_BENDERSFREE((*bendersfree)), SCIP_DECL_BENDERSINIT((*bendersinit)), SCIP_DECL_BENDERSEXIT((*bendersexit)), SCIP_DECL_BENDERSINITPRE((*bendersinitpre)), SCIP_DECL_BENDERSEXITPRE((*bendersexitpre)), SCIP_DECL_BENDERSINITSOL((*bendersinitsol)), SCIP_DECL_BENDERSEXITSOL((*bendersexitsol)), SCIP_DECL_BENDERSGETVAR((*bendersgetvar)), SCIP_DECL_BENDERSCREATESUB((*benderscreatesub)), SCIP_DECL_BENDERSPRESUBSOLVE((*benderspresubsolve)), SCIP_DECL_BENDERSSOLVESUBCONVEX((*benderssolvesubconvex)), SCIP_DECL_BENDERSSOLVESUB((*benderssolvesub)), SCIP_DECL_BENDERSPOSTSOLVE((*benderspostsolve)), SCIP_DECL_BENDERSFREESUB((*bendersfreesub)), SCIP_BENDERSDATA *bendersdata)
SCIP_NODETYPE SCIPnodeGetType(SCIP_NODE *node)
SCIP_RETCODE SCIPresetParams(SCIP *scip)
SCIP_RETCODE SCIPcreateConsNonlinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nexprtrees, SCIP_EXPRTREE **exprtrees, SCIP_Real *nonlincoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_Real SCIPgetCutEfficacy(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
def readParams(self, file)
Definition: scip.pyx:3570
def releaseRow(self, Row, row, not, None)
Definition: scip.pyx:1363
def writeSol(self, Solution, solution, filename="origprob.sol", write_zeros=False)
Definition: scip.pyx:3110
def includeBranchrule(self, Branchrule, branchrule, name, desc, priority, maxdepth, maxbounddist)
Definition: scip.pyx:2800
def addConsCoeff(self, Constraint, cons, Variable, var, coeff)
Definition: scip.pyx:1668
SCIP_Bool SCIPvarIsInLP(SCIP_VAR *var)
def getCondition(self, exact=False)
Definition: scip.pyx:770
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
def getObjVal(self, original=True)
Definition: scip.pyx:3262
SCIP_RETCODE SCIPtightenVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
def getObjectiveSense(self)
Definition: scip.pyx:3334
def setBoolParam(self, name, value)
Definition: scip.pyx:3449
def writeStatistics(self, filename="origprob.stats")
Definition: scip.pyx:3410
SCIP_Real SCIPgetPresolvingTime(SCIP *scip)
int SCIPgetNBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_SOL ** SCIPgetSols(SCIP *scip)
def getActivity(self, Constraint, cons, Solution, sol=None)
Definition: scip.pyx:2132
def isQuadratic(self)
Definition: scip.pyx:602
SCIP_RETCODE SCIPincludeSepa(SCIP *scip, const char *name, const char *desc, int priority, int freq, SCIP_Real maxbounddist, SCIP_Bool usessubscip, SCIP_Bool delay, SCIP_DECL_SEPACOPY((*sepacopy)), SCIP_DECL_SEPAFREE((*sepafree)), SCIP_DECL_SEPAINIT((*sepainit)), SCIP_DECL_SEPAEXIT((*sepaexit)), SCIP_DECL_SEPAINITSOL((*sepainitsol)), SCIP_DECL_SEPAEXITSOL((*sepaexitsol)), SCIP_DECL_SEPAEXECLP((*sepaexeclp)), SCIP_DECL_SEPAEXECSOL((*sepaexecsol)), SCIP_SEPADATA *sepadata)
def branchVarVal(self, variable, value)
Definition: scip.pyx:2900
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
SCIP_Bool SCIPinProbing(SCIP *scip)
def addObjoffset(self, offset, solutions=False)
Definition: scip.pyx:862
def setObjective(self, coeffs, sense='minimize', clear='true')
Definition: scip.pyx:809
SCIP_RETCODE SCIPcheckSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *feasible)
SCIP_RETCODE SCIPcreateConsOr(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
def setLongintParam(self, name, value)
Definition: scip.pyx:3469
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPsetupBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber)
def isIntegral(self)
Definition: scip.pyx:308
def getLbOriginal(self)
Definition: scip.pyx:500
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
def getPrimsol(self)
Definition: scip.pyx:317
def chgReoptObjective(self, coeffs, sense='minimize')
Definition: scip.pyx:3651
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
def cacheRowExtensions(self, Row, row, not, None)
Definition: scip.pyx:1367
def getPrimalbound(self)
Definition: scip.pyx:3296
SCIP_RETCODE SCIPincludePricer(SCIP *scip, const char *name, const char *desc, int priority, SCIP_Bool delay, SCIP_DECL_PRICERCOPY((*pricercopy)), SCIP_DECL_PRICERFREE((*pricerfree)), SCIP_DECL_PRICERINIT((*pricerinit)), SCIP_DECL_PRICEREXIT((*pricerexit)), SCIP_DECL_PRICERINITSOL((*pricerinitsol)), SCIP_DECL_PRICEREXITSOL((*pricerexitsol)), SCIP_DECL_PRICERREDCOST((*pricerredcost)), SCIP_DECL_PRICERFARKAS((*pricerfarkas)), SCIP_PRICERDATA *pricerdata)
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
SCIP_RETCODE SCIPreadSol(SCIP *scip, const char *filename)
def isOriginal(self)
Definition: scip.pyx:486
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
def setSeparating(self, setting)
Definition: scip.pyx:899
def addConsXor(self, vars, rhsvar, name="XORcons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1837
def setEmphasis(self, paraemphasis, quiet=True)
Definition: scip.pyx:3604
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
def getConstant(self)
Definition: scip.pyx:347
SCIP_RETCODE SCIPsetIntParam(SCIP *scip, const char *name, int value)
def addPyCons(self, Constraint, cons)
Definition: scip.pyx:1983
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
def getTransformedVar(self, Variable, var)
Definition: scip.pyx:1000
def writeBestSol(self, filename="origprob.sol", write_zeros=False)
Definition: scip.pyx:3097
def addConsSOS2(self, vars, weights=None, name="SOS2cons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1720
def getObjlimit(self)
Definition: scip.pyx:805
SCIP_Real SCIPcolGetUb(SCIP_COL *col)
SCIP_RETCODE SCIPchgVarObjProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
def includeConshdlr(self, Conshdlr, conshdlr, name, desc, sepapriority=0, enfopriority=0, chckpriority=0, sepafreq=-1, propfreq=-1, eagerfreq=100, maxprerounds=-1, delaysepa=False, delayprop=False, needscons=True, proptiming=PY_SCIP_PROPTIMING.BEFORELP, presoltiming=PY_SCIP_PRESOLTIMING.MEDIUM)
Definition: scip.pyx:2624
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
def getNConss(self)
Definition: scip.pyx:1220
def writeParams(self, filename='param.set', comments=True, onlychanged=True)
Definition: scip.pyx:3579
SCIP_RETCODE SCIPsetParamsCountsols(SCIP *scip)
def delVar(self, Variable, var)
Definition: scip.pyx:1033
SCIP_Real SCIPgetTransObjoffset(SCIP *scip)
SCIP_RETCODE SCIPcatchEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
int SCIPgetNLPBranchCands(SCIP *scip)
def epsilon(self)
Definition: scip.pyx:722
def getPresolvingTime(self)
Definition: scip.pyx:698
SCIP_RETCODE SCIPaddPoolCut(SCIP *scip, SCIP_ROW *row)
def isLE(self, val1, val2)
Definition: scip.pyx:754
const char * SCIPconsGetName(SCIP_CONS *cons)
SCIP_Longint SCIPgetNCountedSols(SCIP *scip, SCIP_Bool *valid)
SCIP_Real SCIPgetSolOrigObj(SCIP *scip, SCIP_SOL *sol)
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
def createCons(self, Conshdlr, conshdlr, name, initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:2659
def setParamsCountsols(self)
Definition: scip.pyx:3643
int SCIProwGetNLPNonz(SCIP_ROW *row)
SCIP_RETCODE SCIPgetLPBInvRow(SCIP *scip, int r, SCIP_Real *coefs, int *inds, int *ninds)
SCIP_Real SCIProwGetRhs(SCIP_ROW *row)
def isIntegral(self)
Definition: scip.pyx:370
SCIP_RETCODE SCIPbranchVarVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
int SCIPbendersGetNSubproblems(SCIP_BENDERS *benders)
SCIP_RETCODE SCIPfreeReoptSolve(SCIP *scip)
def getRowLPActivity(self, Row, row)
Definition: scip.pyx:1358
def chgRowRhsDive(self, Row, row, newrhs)
Definition: scip.pyx:2992
SCIP_Longint SCIPgetNNodes(SCIP *scip)
def setParam(self, name, value)
Definition: scip.pyx:3510
def setMinimize(self)
Definition: scip.pyx:788
SCIP_BASESTAT SCIProwGetBasisStatus(SCIP_ROW *row)
SCIP_RETCODE SCIPfreeBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, int probnumber)
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
def createEmptyRowSepa(self, Sepa, sepa, name="row", lhs=0.0, rhs=None, local=True, modifiable=False, removable=True)
Definition: scip.pyx:1318
SCIP_RETCODE SCIPcacheRowExtensions(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPsetMessagehdlr(SCIP *scip, SCIP_MESSAGEHDLR *messagehdlr)
def getEstimate(self)
Definition: scip.pyx:436
SCIP_RETCODE SCIPgetBendersMasterVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar)
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
def frac(self, value)
Definition: scip.pyx:734
def setSolVal(self, Solution, solution, Variable, var, val)
Definition: scip.pyx:3157
SCIP_RETCODE SCIPaddVarCardinality(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_VAR *indvar, SCIP_Real weight)
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
SCIP_RETCODE SCIPsetEmphasis(SCIP *scip, SCIP_PARAMEMPHASIS paramemphasis, SCIP_Bool quiet)
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
def createSol(self, Heur, heur=None)
Definition: scip.pyx:3067
SCIP_RETCODE SCIPfreeSol(SCIP *scip, SCIP_SOL **sol)
SCIP_Bool SCIPcolIsIntegral(SCIP_COL *col)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
def solveDiveLP(self, itlim=-1)
Definition: scip.pyx:3002
def getSols(self)
Definition: scip.pyx:3229
def updateNodeLowerbound(self, Node, node, lb)
Definition: scip.pyx:1224
def isPropagatedAgain(self)
Definition: scip.pyx:448
def resetParam(self, name)
Definition: scip.pyx:3591
def getObjective(self)
Definition: scip.pyx:851
SCIP_BILINTERM * SCIPgetBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
def getNLPs(self)
Definition: scip.pyx:3422
def branchVar(self, variable)
Definition: scip.pyx:2885
void SCIPbendersUpdateSubproblemLowerbound(SCIP_BENDERS *benders, int probnumber, SCIP_Real lowerbound)
SCIP_COL * SCIPvarGetCol(SCIP_VAR *var)
def freeProb(self)
Definition: scip.pyx:666
SCIP_VAR ** SCIPgetOrigVars(SCIP *scip)
SCIP_RETCODE SCIPfree(SCIP **scip)
def delConsLocal(self, Constraint, cons)
Definition: scip.pyx:2290
def getParam(self, name)
Definition: scip.pyx:3540
SCIP_RETCODE SCIPdropRowEvent(SCIP *scip, SCIP_ROW *row, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
def isStickingAtNode(self)
Definition: scip.pyx:593
def calcNodeselPriority(self, Variable, variable, branchdir, targetvalue)
Definition: scip.pyx:2917
SCIP_LPSOLSTAT SCIPgetLPSolstat(SCIP *scip)
SCIP_Real SCIPgetSolTransObj(SCIP *scip, SCIP_SOL *sol)
SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
SCIP_STATUS SCIPgetStatus(SCIP *scip)
SCIP_RETCODE SCIPgetBendersSubproblemVar(SCIP *scip, SCIP_BENDERS *benders, SCIP_VAR *var, SCIP_VAR **mappedvar, int probnumber)
SCIP_Real SCIPgetVarUbDive(SCIP *scip, SCIP_VAR *var)
def feasFrac(self, value)
Definition: scip.pyx:730
def fixVar(self, Variable, var, val)
Definition: scip.pyx:1020
int SCIPnodeGetDepth(SCIP_NODE *node)
SCIP_Real SCIPgetRowLPActivity(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPstartDive(SCIP *scip)
def getLPPos(self)
Definition: scip.pyx:290
SCIP_RETCODE SCIPcreateEmptyRowSepa(SCIP *scip, SCIP_ROW **row, SCIP_SEPA *sepa, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
def getTotalTime(self)
Definition: scip.pyx:686
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
def addVarLocks(self, Variable, var, nlocksdown, nlocksup)
Definition: scip.pyx:1010
SCIP_RETCODE SCIPendDive(SCIP *scip)
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
def getBendersVar(self, Variable, var, Benders, benders=None, probnumber=-1)
Definition: scip.pyx:2542
def interruptSolve(self)
Definition: scip.pyx:3061
SCIP_COL ** SCIProwGetCols(SCIP_ROW *row)
SCIP_RETCODE SCIPdropEvent(SCIP *scip, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
SCIP_RETCODE SCIPcreateBendersDefault(SCIP *scip, SCIP **subproblems, int nsubproblems)
def addVarSOS1(self, Constraint, cons, Variable, var, weight)
Definition: scip.pyx:1992
SCIP_RETCODE SCIPappendVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
SCIP_RETCODE SCIPpresolve(SCIP *scip)
def chgRowLhsDive(self, Row, row, newlhs)
Definition: scip.pyx:2986
def getNewBound(self)
Definition: scip.pyx:262
def getUbOriginal(self)
Definition: scip.pyx:504
SCIP_RETCODE SCIPsetConsRemovable(SCIP *scip, SCIP_CONS *cons, SCIP_Bool removable)
def isActive(self)
Definition: scip.pyx:444
def delCons(self, Constraint, cons)
Definition: scip.pyx:2282
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
SCIP_RETCODE SCIPaddLinearVarQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real coef)
SCIP_RETCODE SCIPstartProbing(SCIP *scip)
SCIP_RETCODE SCIPsetObjlimit(SCIP *scip, SCIP_Real objlimit)
def hideOutput(self, quiet=True)
Definition: scip.pyx:3428
SCIP_RETCODE SCIPaddBilinTermQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var1, SCIP_VAR *var2, SCIP_Real coef)
SCIP_Bool SCIPisCutEfficacious(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut)
def chgVarUb(self, Variable, var, ub)
Definition: scip.pyx:1121
def getVals(self)
Definition: scip.pyx:391
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
int SCIPgetNCutsApplied(SCIP *scip)
SCIP_CONS ** SCIPgetConss(SCIP *scip)
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
def getType(self)
Definition: scip.pyx:255
SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPbranchVar(SCIP *scip, SCIP_VAR *var, SCIP_NODE **downchild, SCIP_NODE **eqchild, SCIP_NODE **upchild)
def addCons(self, cons, name='', initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1417
SCIP_RETCODE SCIPdelVar(SCIP *scip, SCIP_VAR *var, SCIP_Bool *deleted)
def calcChildEstimate(self, Variable, variable, targetvalue)
Definition: scip.pyx:2930
SCIP_Real SCIPgetPrimalbound(SCIP *scip)
SCIP_RETCODE SCIPfixVarProbing(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval)
SCIP_RETCODE SCIPreadProb(SCIP *scip, const char *filename, const char *extension)
def getLPSolstat(self)
Definition: scip.pyx:1235
SCIP_RETCODE SCIPupdateNodeLowerbound(SCIP *scip, SCIP_NODE *node, SCIP_Real newbound)
def printSol(self, Solution, solution, write_zeros=False)
Definition: scip.pyx:3088
def feastol(self)
Definition: scip.pyx:726
SCIP_Real SCIPgetSolvingTime(SCIP *scip)
def getCol(self)
Definition: scip.pyx:494
SCIP_RETCODE SCIPsetPresolving(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
def resetParams(self)
Definition: scip.pyx:3600
SCIP_RETCODE SCIPsetBoolParam(SCIP *scip, const char *name, SCIP_Bool value)
SCIP_RETCODE SCIPactivateBenders(SCIP *scip, SCIP_BENDERS *benders, int nsubproblems)
int SCIPgetNActiveBenders(SCIP *scip)
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
int SCIPgetNCuts(SCIP *scip)
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
SCIP_RETCODE SCIPaddSol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *stored)
SCIP_QUADVARTERM * SCIPgetQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
def getLbGlobal(self)
Definition: scip.pyx:508
def getSolVal(self, Solution, sol, Variable, var)
Definition: scip.pyx:3273
def getDualsolLinear(self, Constraint, cons)
Definition: scip.pyx:2334
SCIP_Bool SCIPisObjChangedProbing(SCIP *scip)
SCIP_Real SCIPcolGetLb(SCIP_COL *col)
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
SCIP_RETCODE SCIPendProbing(SCIP *scip)
def getLPBranchCands(self)
Definition: scip.pyx:2851
def getStatus(self)
Definition: scip.pyx:3320
def getConss(self)
Definition: scip.pyx:2268
def addCut(self, Row, cut, not, None, forcecut=False)
Definition: scip.pyx:1399
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
def version(self)
Definition: scip.pyx:674
def create(self)
Definition: scip.pyx:649
def isInfinity(self, value)
Definition: scip.pyx:746
SCIP_Real SCIPgetOrigObjoffset(SCIP *scip)
SCIP_RETCODE SCIPcreateConsCardinality(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, int cardval, SCIP_VAR **indvars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
def isObjChangedProbing(self)
Definition: scip.pyx:3039
SCIP_RETCODE SCIPgetLPI(SCIP *scip, SCIP_LPI **lpi)
def chgVarLbGlobal(self, Variable, var, lb)
Definition: scip.pyx:1133
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
def getLPBInvRow(self, row)
Definition: scip.pyx:1290
SCIP_RETCODE SCIPappendVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
SCIP_Real SCIPcalcNodeselPriority(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdir, SCIP_Real targetvalue)
SCIP_RETCODE SCIPconstructLP(SCIP *scip, SCIP_Bool *cutoff)
SCIP_Real SCIPfrac(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPcreateSol(SCIP *scip, SCIP_SOL **sol, SCIP_HEUR *heur)
def chgVarUbNode(self, Node, node, Variable, var, ub)
Definition: scip.pyx:1166
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
int SCIPcolGetLPPos(SCIP_COL *col)
def setStringParam(self, name, value)
Definition: scip.pyx:3499
def includeEventhdlr(self, Eventhdlr, eventhdlr, name, desc)
Definition: scip.pyx:2573
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
def appendVarSOS1(self, Constraint, cons, Variable, var)
Definition: scip.pyx:2002
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
SCIP_Real SCIPvarGetLPSol(SCIP_VAR *var)
SCIP_RETCODE SCIPchgVarLbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
SCIP_Real SCIPnodeGetLowerbound(SCIP_NODE *node)
def setCharParam(self, name, value)
Definition: scip.pyx:3489
def isModifiable(self)
Definition: scip.pyx:581
def readSolFile(self, filename)
Definition: scip.pyx:3135
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
SCIP_RETCODE SCIPcreateVarBasic(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype)
def getRhs(self)
Definition: scip.pyx:343
def isInLP(self)
Definition: scip.pyx:490
def getRowActivity(self, Row, row)
Definition: scip.pyx:1354
def setInitial(self, Constraint, cons, newInit)
Definition: scip.pyx:2030
SCIP_Real SCIPgetDualbound(SCIP *scip)
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
SCIP_RETCODE SCIPlpiGetRealSolQuality(SCIP_LPI *lpi, SCIP_LPSOLQUALITY qualityindicator, SCIP_Real *quality)
SCIP_PARAM * SCIPgetParam(SCIP *scip, const char *name)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
def getLPRowsData(self)
Definition: scip.pyx:1264
def readSol(self, filename)
Definition: scip.pyx:3126
def computeBestSolSubproblems(self)
Definition: scip.pyx:2453
SCIP_RETCODE SCIPsetRelaxSolVal(SCIP *scip, SCIP_VAR *var, SCIP_Real val)
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
def setPresolve(self, setting)
Definition: scip.pyx:886
SCIP_RETCODE SCIPchgReoptObjective(SCIP *scip, SCIP_OBJSENSE objsense, SCIP_VAR **vars, SCIP_Real *coefs, int nvars)
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_VAR * SCIPcolGetVar(SCIP_COL *col)
SCIP_RETCODE SCIPflushRowExtensions(SCIP *scip, SCIP_ROW *row)
def getNode(self)
Definition: scip.pyx:275
SCIP_RETCODE SCIPchgRowLhsDive(SCIP *scip, SCIP_ROW *row, SCIP_Real newlhs)
def getTermsQuadratic(self, Constraint, cons)
Definition: scip.pyx:2216
SCIP_Real SCIPcalcChildEstimate(SCIP *scip, SCIP_VAR *var, SCIP_Real targetvalue)
def isCutEfficacious(self, Row, cut, not, None, Solution, sol=None)
Definition: scip.pyx:1395
def activateBenders(self, str, name, int, nsubproblems)
Definition: scip.pyx:2517
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_BENDERS ** SCIPgetBenders(SCIP *scip)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetLPBranchCands(SCIP *scip, SCIP_VAR ***lpcands, SCIP_Real **lpcandssol, SCIP_Real **lpcandsfrac, int *nlpcands, int *npriolpcands, int *nfracimplvars)
SCIP_BENDERS * SCIPfindBenders(SCIP *scip, const char *name)
SCIP_RETCODE SCIPreadParams(SCIP *scip, const char *filename)
def solveProbingLP(self, itlim=-1)
Definition: scip.pyx:3047
def setCheck(self, Constraint, cons, newCheck)
Definition: scip.pyx:2057
def getOldBound(self)
Definition: scip.pyx:266
def chgVarUbGlobal(self, Variable, var, ub)
Definition: scip.pyx:1144
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
def writeProblem(self, filename='model.cip', trans=False)
Definition: scip.pyx:925
def getObj(self)
Definition: scip.pyx:524
def addConsSOS1(self, vars, weights=None, name="SOS1cons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1681
def getCutEfficacy(self, Row, cut, not, None, Solution, sol=None)
Definition: scip.pyx:1391
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
def getUb(self)
Definition: scip.pyx:325
def printRow(self, Row, row, not, None)
Definition: scip.pyx:1382
int SCIPgetNSols(SCIP *scip)
SCIP_RETCODE SCIPincludePresol(SCIP *scip, const char *name, const char *desc, int priority, int maxrounds, SCIP_PRESOLTIMING timing, SCIP_DECL_PRESOLCOPY((*presolcopy)), SCIP_DECL_PRESOLFREE((*presolfree)), SCIP_DECL_PRESOLINIT((*presolinit)), SCIP_DECL_PRESOLEXIT((*presolexit)), SCIP_DECL_PRESOLINITPRE((*presolinitpre)), SCIP_DECL_PRESOLEXITPRE((*presolexitpre)), SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
def getCols(self)
Definition: scip.pyx:386
int SCIProwGetLPPos(SCIP_ROW *row)
SCIP_RETCODE SCIPchgVarUbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
def getGap(self)
Definition: scip.pyx:710
SCIP_RETCODE SCIPsetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_Real val)
SCIP_SEPA * SCIPfindSepa(SCIP *scip, const char *name)
def infinity(self)
Definition: scip.pyx:718
int SCIPgetNLPRows(SCIP *scip)
def addSol(self, Solution, solution, free=True)
Definition: scip.pyx:3207
def getLPColsData(self)
Definition: scip.pyx:1256
def getRhs(self, Constraint, cons)
Definition: scip.pyx:2104
SCIP_OBJSENSE SCIPgetObjsense(SCIP *scip)
def chgRhs(self, Constraint, cons, rhs)
Definition: scip.pyx:2066
SCIP_Real SCIProwGetConstant(SCIP_ROW *row)
def catchRowEvent(self, Row, row, eventtype, Eventhdlr, eventhdlr)
Definition: scip.pyx:3384
SCIP_NODE * SCIPnodeGetParent(SCIP_NODE *node)
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
def getNLPNonz(self)
Definition: scip.pyx:382
SCIP_Bool SCIProwIsIntegral(SCIP_ROW *row)
SCIP_RETCODE SCIPcreateEmptyRowUnspec(SCIP *scip, SCIP_ROW **row, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
def getDualfarkasLinear(self, Constraint, cons)
Definition: scip.pyx:2379
def setEnforced(self, Constraint, cons, newEnf)
Definition: scip.pyx:2048
def disablePropagation(self, onlyroot=False)
Definition: scip.pyx:915
def setMaximize(self)
Definition: scip.pyx:792
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetObjlimit(SCIP *scip)
def getNLPRows(self)
Definition: scip.pyx:1272
def tightenVarUbGlobal(self, Variable, var, ub, force=False)
Definition: scip.pyx:1078
SCIP_Real SCIPgetLPObjval(SCIP *scip)
SCIP_HEUR * SCIPfindHeur(SCIP *scip, const char *name)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
SCIP_RETCODE SCIPtrySolFree(SCIP *scip, SCIP_SOL **sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
def createProbBasic(self, problemName='model')
Definition: scip.pyx:657
SCIP_RETCODE SCIPchgRowRhsDive(SCIP *scip, SCIP_ROW *row, SCIP_Real newrhs)
int SCIPgetNOrigVars(SCIP *scip)
SCIP_Longint SCIPgetNLPs(SCIP *scip)
def freeTransform(self)
Definition: scip.pyx:670
SCIP_RETCODE SCIPwriteParams(SCIP *scip, const char *filename, SCIP_Bool comments, SCIP_Bool onlychanged)
def freeSol(self, Solution, solution)
Definition: scip.pyx:3221
SCIP_Real SCIPgetTotalTime(SCIP *scip)
def addVarSOS2(self, Constraint, cons, Variable, var, weight)
Definition: scip.pyx:2011
def getVarUbDive(self, Variable, var)
Definition: scip.pyx:2982
SCIP_RETCODE SCIPtrySol(SCIP *scip, SCIP_SOL *sol, SCIP_Bool printreason, SCIP_Bool completely, SCIP_Bool checkbounds, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool *stored)
def addConsIndicator(self, cons, binvar=None, name="IndicatorCons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1927
def constructLP(self)
Definition: scip.pyx:1240
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
def setObjlimit(self, objlimit)
Definition: scip.pyx:796
def inProbing(self)
Definition: scip.pyx:3043
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
SCIP_RETCODE SCIPreadSolFile(SCIP *scip, const char *filename, SCIP_SOL *sol, SCIP_Bool xml, SCIP_Bool *partial, SCIP_Bool *error)
def redirectOutput(self)
Definition: scip.pyx:3438
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
SCIP_Longint SCIPnodeGetNumber(SCIP_NODE *node)
const char * SCIPgetProbName(SCIP *scip)
SCIP_RETCODE SCIPincludeRelax(SCIP *scip, const char *name, const char *desc, int priority, int freq, SCIP_DECL_RELAXCOPY((*relaxcopy)), SCIP_DECL_RELAXFREE((*relaxfree)), SCIP_DECL_RELAXINIT((*relaxinit)), SCIP_DECL_RELAXEXIT((*relaxexit)), SCIP_DECL_RELAXINITSOL((*relaxinitsol)), SCIP_DECL_RELAXEXITSOL((*relaxexitsol)), SCIP_DECL_RELAXEXEC((*relaxexec)), SCIP_RELAXDATA *relaxdata)
def getValsLinear(self, Constraint, cons)
Definition: scip.pyx:2298
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
def addConsAnd(self, vars, resvar, name="ANDcons", initial=True, separate=True, enforce=True, check=True, propagate=True, local=False, modifiable=False, dynamic=False, removable=False, stickingatnode=False)
Definition: scip.pyx:1759
def getParent(self)
Definition: scip.pyx:416
def printStatistics(self)
Definition: scip.pyx:3406
def presolve(self)
Definition: scip.pyx:2412
def getLPBasisInd(self)
Definition: scip.pyx:1280
def chgVarObjDive(self, Variable, var, newobj)
Definition: scip.pyx:2966
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
def isSeparated(self)
Definition: scip.pyx:561
SCIP_RETCODE SCIPcreate(SCIP **scip)
int SCIProwGetNNonz(SCIP_ROW *row)
SCIP_RETCODE SCIPsetRealParam(SCIP *scip, const char *name, SCIP_Real value)
SCIP_RETCODE SCIPincludeHeur(SCIP *scip, const char *name, const char *desc, char dispchar, int priority, int freq, int freqofs, int maxdepth, SCIP_HEURTIMING timingmask, SCIP_Bool usessubscip, SCIP_DECL_HEURCOPY((*heurcopy)), SCIP_DECL_HEURFREE((*heurfree)), SCIP_DECL_HEURINIT((*heurinit)), SCIP_DECL_HEUREXIT((*heurexit)), SCIP_DECL_HEURINITSOL((*heurinitsol)), SCIP_DECL_HEUREXITSOL((*heurexitsol)), SCIP_DECL_HEUREXEC((*heurexec)), SCIP_HEURDATA *heurdata)
def getLPBInvARow(self, row)
Definition: scip.pyx:1301
SCIP_RETCODE SCIPwriteOrigProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
def isGE(self, val1, val2)
Definition: scip.pyx:762
def getUbGlobal(self)
Definition: scip.pyx:512
SCIP_RETCODE SCIPfreeTransform(SCIP *scip)
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
SCIP_RETCODE SCIPprintBestSol(SCIP *scip, FILE *file, SCIP_Bool printzeros)
def setIntParam(self, name, value)
Definition: scip.pyx:3459
SCIP_Real * SCIProwGetVals(SCIP_ROW *row)
def getLb(self)
Definition: scip.pyx:321
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
def isGT(self, val1, val2)
Definition: scip.pyx:766
SCIP_RETCODE SCIPsolveProbingLP(SCIP *scip, int itlim, SCIP_Bool *lperror, SCIP_Bool *cutoff)
def inRepropagation(self)
Definition: scip.pyx:3016
int SCIPgetNLPCols(SCIP *scip)
SCIP_Real SCIPgetReadingTime(SCIP *scip)
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcheckSolOrig(SCIP *scip, SCIP_SOL *sol, SCIP_Bool *feasible, SCIP_Bool printreason, SCIP_Bool completely)
SCIP_RETCODE SCIPsolveBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP_SOL *sol, int probnumber, SCIP_Bool *infeasible, SCIP_BENDERSENFOTYPE type, SCIP_Bool solvecip, SCIP_Real *objective)
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
def getCurrentNode(self)
Definition: scip.pyx:706
def isZero(self, value)
Definition: scip.pyx:738
SCIP_RETCODE SCIPaddVarIndicator(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
def addVar(self, name='', vtype='C', lb=0.0, ub=None, obj=0.0, pricedVar=False)
Definition: scip.pyx:946
def getDepth(self)
Definition: scip.pyx:424
SCIP_RETCODE SCIPtransformVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
def includeRelax(self, Relax, relax, name, desc, priority=10000, freq=1)
Definition: scip.pyx:2781
SCIP_RETCODE SCIPgetLPColsData(SCIP *scip, SCIP_COL ***cols, int *ncols)
SCIP_RETCODE SCIPcreateProbBasic(SCIP *scip, const char *name)
SCIP_RETCODE SCIPincludeConshdlr(SCIP *scip, const char *name, const char *desc, int sepapriority, int enfopriority, int chckpriority, int sepafreq, int propfreq, int eagerfreq, int maxprerounds, SCIP_Bool delaysepa, SCIP_Bool delayprop, SCIP_Bool needscons, SCIP_PROPTIMING proptiming, SCIP_PRESOLTIMING presoltiming, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSFREE((*consfree)), SCIP_DECL_CONSINIT((*consinit)), SCIP_DECL_CONSEXIT((*consexit)), SCIP_DECL_CONSINITPRE((*consinitpre)), SCIP_DECL_CONSEXITPRE((*consexitpre)), SCIP_DECL_CONSINITSOL((*consinitsol)), SCIP_DECL_CONSEXITSOL((*consexitsol)), SCIP_DECL_CONSDELETE((*consdelete)), SCIP_DECL_CONSTRANS((*constrans)), SCIP_DECL_CONSINITLP((*consinitlp)), SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFORELAX((*consenforelax)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSPROP((*consprop)), SCIP_DECL_CONSPRESOL((*conspresol)), SCIP_DECL_CONSRESPROP((*consresprop)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_DECL_CONSACTIVE((*consactive)), SCIP_DECL_CONSDEACTIVE((*consdeactive)), SCIP_DECL_CONSENABLE((*consenable)), SCIP_DECL_CONSDISABLE((*consdisable)), SCIP_DECL_CONSDELVARS((*consdelvars)), SCIP_DECL_CONSPRINT((*consprint)), SCIP_DECL_CONSCOPY((*conscopy)), SCIP_DECL_CONSPARSE((*consparse)), SCIP_DECL_CONSGETVARS((*consgetvars)), SCIP_DECL_CONSGETNVARS((*consgetnvars)), SCIP_DECL_CONSGETDIVEBDCHGS((*consgetdivebdchgs)), SCIP_CONSHDLRDATA *conshdlrdata)
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
def getSolObjVal(self, Solution, sol, original=True)
Definition: scip.pyx:3247
def dropRowEvent(self, Row, row, eventtype, Eventhdlr, eventhdlr)
Definition: scip.pyx:3394
SCIP_NODE * SCIPeventGetNode(SCIP_EVENT *event)
def isPropagated(self)
Definition: scip.pyx:573
SCIP_NODE * SCIPgetCurrentNode(SCIP *scip)
def catchVarEvent(self, Variable, var, eventtype, Eventhdlr, eventhdlr)
Definition: scip.pyx:3364
SCIP_RETCODE SCIPwriteTransProblem(SCIP *scip, const char *filename, const char *extension, SCIP_Bool genericnames)
SCIP_RETCODE SCIPchgLhsQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
def getVal(self, Variable, var)
Definition: scip.pyx:3285
SCIP_RETCODE SCIPsetCharParam(SCIP *scip, const char *name, char value)
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
SCIP_RETCODE SCIPsetProbName(SCIP *scip, const char *name)
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
def getNCountedSols(self)
Definition: scip.pyx:3633
def getObjoffset(self, original=True)
Definition: scip.pyx:874
def endDive(self)
Definition: scip.pyx:2962
def getNumber(self)
Definition: scip.pyx:420
def getProbName(self)
Definition: scip.pyx:682
def getNVars(self)
Definition: scip.pyx:1216
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
SCIP_Real SCIPgetRowActivity(SCIP *scip, SCIP_ROW *row)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
def addVarToRow(self, Row, row, not, None, Variable, var, not, None, value)
Definition: scip.pyx:1378
void SCIPvarSetData(SCIP_VAR *var, SCIP_VARDATA *vardata)
def readProblem(self, file, extension=None)
Definition: scip.pyx:3613
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
def getDualMultiplier(self, Constraint, cons)
Definition: scip.pyx:2319
def getVars(self, transformed=False)
Definition: scip.pyx:1196
def getVarLbDive(self, Variable, var)
Definition: scip.pyx:2978
def setRelaxSolVal(self, Variable, var, val)
Definition: scip.pyx:2264
def isRemovable(self)
Definition: scip.pyx:589
def printVersion(self)
Definition: scip.pyx:678
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
SCIP_RETCODE SCIPresetParam(SCIP *scip, const char *name)
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
def getNNonz(self)
Definition: scip.pyx:378
SCIP_RETCODE SCIPsolve(SCIP *scip)
SCIP_PRICER * SCIPfindPricer(SCIP *scip, const char *name)
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
SCIP_Real SCIProwGetLhs(SCIP_ROW *row)
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
SCIP_RETCODE SCIPinterruptSolve(SCIP *scip)
def includePricer(self, Pricer, pricer, name, desc, priority=1, delay=True)
Definition: scip.pyx:2597
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
const char * SCIPvarGetName(SCIP_VAR *var)
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
def getNAddedConss(self)
Definition: scip.pyx:440
def getNNodes(self)
Definition: scip.pyx:702
SCIP_Bool SCIPisLPSolBasic(SCIP *scip)
def includePresol(self, Presol, presol, name, desc, priority, maxrounds, timing=SCIP_PRESOLTIMING_FAST)
Definition: scip.pyx:2685
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
def addBendersSubproblem(self, str, name, subproblem)
Definition: scip.pyx:2529
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
SCIP_Bool SCIPinRepropagation(SCIP *scip)
def includeDefaultPlugins(self)
Definition: scip.pyx:653
def setRealParam(self, name, value)
Definition: scip.pyx:3479
def updateBendersLowerbounds(self, lowerbounds, Benders, benders=None)
Definition: scip.pyx:2499
SCIP_RETCODE SCIPincludeProp(SCIP *scip, const char *name, const char *desc, int priority, int freq, SCIP_Bool delay, SCIP_PROPTIMING timingmask, int presolpriority, int presolmaxrounds, SCIP_PRESOLTIMING presoltiming, SCIP_DECL_PROPCOPY((*propcopy)), SCIP_DECL_PROPFREE((*propfree)), SCIP_DECL_PROPINIT((*propinit)), SCIP_DECL_PROPEXIT((*propexit)), SCIP_DECL_PROPINITPRE((*propinitpre)), SCIP_DECL_PROPEXITPRE((*propexitpre)), SCIP_DECL_PROPINITSOL((*propinitsol)), SCIP_DECL_PROPEXITSOL((*propexitsol)), SCIP_DECL_PROPPRESOL((*proppresol)), SCIP_DECL_PROPEXEC((*propexec)), SCIP_DECL_PROPRESPROP((*propresprop)), SCIP_PROPDATA *propdata)
def isLT(self, val1, val2)
Definition: scip.pyx:758
SCIP_Real SCIPgetVarRedcost(SCIP *scip, SCIP_VAR *var)
def isEnforced(self)
Definition: scip.pyx:565
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
SCIP_Real SCIPcolGetPrimsol(SCIP_COL *col)
def chgVarLbDive(self, Variable, var, newbound)
Definition: scip.pyx:2970
def releaseVar(self, Variable, var)
Definition: scip.pyx:992
SCIP_EVENTHDLR * SCIPfindEventhdlr(SCIP *scip, const char *name)
def getDualbound(self)
Definition: scip.pyx:3300
SCIP_RETCODE SCIPcount(SCIP *scip)
SCIP_RETCODE SCIPchgVarUbDive(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
def initBendersDefault(self, subproblems)
Definition: scip.pyx:2417
def createEmptyRowUnspec(self, name="row", lhs=0.0, rhs=None, local=True, modifiable=False, removable=True)
Definition: scip.pyx:1337
SCIP_Real SCIPversion(void)
SCIP_RETCODE SCIPaddBendersSubproblem(SCIP *scip, SCIP_BENDERS *benders, SCIP *subproblem)
def getVar(self)
Definition: scip.pyx:312
def getTransformedCons(self, Constraint, cons)
Definition: scip.pyx:2206
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
SCIP_RETCODE SCIPappendVarCardinality(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_VAR *indvar)
SCIP_RETCODE SCIPsetSeparating(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
SCIP_RETCODE SCIPcatchRowEvent(SCIP *scip, SCIP_ROW *row, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
def chgVarType(self, Variable, var, vtype)
Definition: scip.pyx:1177
def getStage(self)
Definition: scip.pyx:3316
SCIP_RETCODE SCIPactivatePricer(SCIP *scip, SCIP_PRICER *pricer)
SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
def getLowerbound(self)
Definition: scip.pyx:432
SCIP_RETCODE SCIPaddRowDive(SCIP *scip, SCIP_ROW *row)
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
SCIP_RETCODE SCIPgetLPBasisInd(SCIP *scip, int *basisind)
def addPoolCut(self, Row, row, not, None)
Definition: scip.pyx:1387
def includeSepa(self, Sepa, sepa, name, desc, priority=0, freq=10, maxbounddist=1.0, usessubscip=False, delay=False)
Definition: scip.pyx:2703
def getSlack(self, Constraint, cons, Solution, sol=None, side=None)
Definition: scip.pyx:2162
SCIP_RETCODE SCIPexprtreeSetVars(SCIP_EXPRTREE *tree, int nvars, SCIP_VAR **vars)
SCIP_RETCODE SCIPgetLPRowsData(SCIP *scip, SCIP_ROW ***rows, int *nrows)
def chgLhs(self, Constraint, cons, lhs)
Definition: scip.pyx:2085
def startDive(self)
Definition: scip.pyx:2955
def freeBendersSubproblems(self)
Definition: scip.pyx:2481
def writeName(self, Variable, var)
Definition: scip.pyx:3308
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
def fixVarProbing(self, Variable, var, fixedval)
Definition: scip.pyx:3035
def includeBenders(self, Benders, benders, name, desc, priority=1, cutlp=True, cutpseudo=True, cutrelax=True, shareaux=False)
Definition: scip.pyx:2822
def getSolvingTime(self)
Definition: scip.pyx:690
def tightenVarLb(self, Variable, var, lb, force=False)
Definition: scip.pyx:1044
def isFeasNegative(self, value)
Definition: scip.pyx:750
SCIP_RETCODE SCIPcreateConsXor(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_Bool rhs, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPsetHeuristics(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
def getLPSol(self)
Definition: scip.pyx:528
def includeProp(self, Prop, prop, name, desc, presolpriority, presolmaxrounds, proptiming, presoltiming=SCIP_PRESOLTIMING_FAST, priority=1, freq=1, delay=True)
Definition: scip.pyx:2725
SCIP_RETCODE SCIPchgRhsQuadratic(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_RETCODE SCIPchgVarLbGlobal(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
def getBestSol(self)
Definition: scip.pyx:3242
def createChild(self, nodeselprio, estimate)
Definition: scip.pyx:2942
def flushRowExtensions(self, Row, row, not, None)
Definition: scip.pyx:1374
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
SCIP_RETCODE SCIPgetLPBInvARow(SCIP *scip, int r, SCIP_Real *binvrow, SCIP_Real *coefs, int *inds, int *ninds)
SCIP_Real SCIPgetVarLbDive(SCIP *scip, SCIP_VAR *var)
def tightenVarLbGlobal(self, Variable, var, lb, force=False)
Definition: scip.pyx:1094
SCIP_RETCODE SCIPincludeBranchrule(SCIP *scip, const char *name, const char *desc, int priority, int maxdepth, SCIP_Real maxbounddist, SCIP_DECL_BRANCHCOPY((*branchcopy)), SCIP_DECL_BRANCHFREE((*branchfree)), SCIP_DECL_BRANCHINIT((*branchinit)), SCIP_DECL_BRANCHEXIT((*branchexit)), SCIP_DECL_BRANCHINITSOL((*branchinitsol)), SCIP_DECL_BRANCHEXITSOL((*branchexitsol)), SCIP_DECL_BRANCHEXECLP((*branchexeclp)), SCIP_DECL_BRANCHEXECEXT((*branchexecext)), SCIP_DECL_BRANCHEXECPS((*branchexecps)), SCIP_BRANCHRULEDATA *branchruledata)
SCIP_Bool SCIPnodeIsActive(SCIP_NODE *node)
def chgVarLbNode(self, Node, node, Variable, var, lb)
Definition: scip.pyx:1155