7 def __init__(self, name="LP", sense="minimize"):
10 name -- the name of the problem (default 'LP') 11 sense -- objective sense (default minimize) 14 n = str_conversion(name)
15 if sense ==
"minimize":
16 PY_SCIP_CALL(
SCIPlpiCreate(&(self.lpi), NULL, n, SCIP_OBJSENSE_MINIMIZE))
17 elif sense ==
"maximize":
18 PY_SCIP_CALL(
SCIPlpiCreate(&(self.lpi), NULL, n, SCIP_OBJSENSE_MAXIMIZE))
20 raise Warning(
"unrecognized objective sense")
22 def __dealloc__(self):
28 def writeLP(self, filename):
29 """Writes LP to a file. 32 filename -- the name of the file to be used 36 def readLP(self, filename):
37 """Reads LP from a file. 40 filename -- the name of the file to be used 45 """Returns infinity value of the LP. 49 def isInfinity(self, val):
50 """Checks if a given value is equal to the infinity value of the LP. 53 val -- value that should be checked 57 def addCol(self, entries, obj = 0.0, lb = 0.0, ub = None):
58 """Adds a single column to the LP. 61 entries -- list of tuples, each tuple consists of a row index and a coefficient 62 obj -- objective coefficient (default 0.0) 63 lb -- lower bound (default 0.0) 64 ub -- upper bound (default infinity) 68 cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
69 cdef int* c_inds = <int*>malloc(nnonz * sizeof(int))
77 c_ub = ub
if ub !=
None else self.infinity()
80 for i,entry
in enumerate(entries):
84 PY_SCIP_CALL(
SCIPlpiAddCols(self.lpi, 1, &c_obj, &c_lb, &c_ub, NULL, nnonz, &c_beg, c_inds, c_coefs))
89 def addCols(self, entrieslist, objs = None, lbs = None, ubs = None):
90 """Adds multiple columns to the LP. 93 entrieslist -- list containing lists of tuples, each tuple contains a coefficient and a row index 94 objs -- objective coefficient (default 0.0) 95 lbs -- lower bounds (default 0.0) 96 ubs -- upper bounds (default infinity) 99 ncols = len(entrieslist)
100 nnonz = sum(len(entries)
for entries
in entrieslist)
102 cdef SCIP_Real* c_objs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
103 cdef SCIP_Real* c_lbs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
104 cdef SCIP_Real* c_ubs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
105 cdef SCIP_Real* c_coefs
111 c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
112 c_inds = <int*>malloc(nnonz * sizeof(int))
113 c_beg = <int*>malloc(ncols * sizeof(int))
116 for i,entries
in enumerate(entrieslist):
117 c_objs[i] = objs[i]
if objs !=
None else 0.0
118 c_lbs[i] = lbs[i]
if lbs !=
None else 0.0
119 c_ubs[i] = ubs[i]
if ubs !=
None else self.infinity()
122 for entry
in entries:
123 c_inds[tmp] = entry[0]
124 c_coefs[tmp] = entry[1]
127 PY_SCIP_CALL(
SCIPlpiAddCols(self.lpi, ncols, c_objs, c_lbs, c_ubs, NULL, nnonz, c_beg, c_inds, c_coefs))
133 for i
in range(len(entrieslist)):
134 c_objs[i] = objs[i]
if objs !=
None else 0.0
135 c_lbs[i] = lbs[i]
if lbs !=
None else 0.0
136 c_ubs[i] = ubs[i]
if ubs !=
None else self.infinity()
138 PY_SCIP_CALL(
SCIPlpiAddCols(self.lpi, ncols, c_objs, c_lbs, c_ubs, NULL, 0, NULL, NULL, NULL))
144 def delCols(self, firstcol, lastcol):
145 """Deletes a range of columns from the LP. 148 firstcol -- first column to delete 149 lastcol -- last column to delete 153 def addRow(self, entries, lhs=0.0, rhs=None):
154 """Adds a single row to the LP. 157 entries -- list of tuples, each tuple contains a coefficient and a column index 158 lhs -- left-hand side of the row (default 0.0) 159 rhs -- right-hand side of the row (default infinity) 164 cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
165 cdef int* c_inds = <int*>malloc(nnonz * sizeof(int))
171 c_rhs = rhs
if rhs !=
None else self.infinity()
174 for i,entry
in enumerate(entries):
176 c_coefs[i] = entry[1]
178 PY_SCIP_CALL(
SCIPlpiAddRows(self.lpi, 1, &c_lhs, &c_rhs, NULL, nnonz, &c_beg, c_inds, c_coefs))
183 def addRows(self, entrieslist, lhss = None, rhss = None):
184 """Adds multiple rows to the LP. 187 entrieslist -- list containing lists of tuples, each tuple contains a coefficient and a column index 188 lhss -- left-hand side of the row (default 0.0) 189 rhss -- right-hand side of the row (default infinity) 191 nrows = len(entrieslist)
192 nnonz = sum(len(entries)
for entries
in entrieslist)
194 cdef SCIP_Real* c_lhss = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
195 cdef SCIP_Real* c_rhss = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
196 cdef SCIP_Real* c_coefs = <SCIP_Real*> malloc(nnonz * sizeof(SCIP_Real))
197 cdef int* c_inds = <int*>malloc(nnonz * sizeof(int))
198 cdef int* c_beg = <int*>malloc(nrows * sizeof(int))
201 for i,entries
in enumerate(entrieslist):
202 c_lhss[i] = lhss[i]
if lhss !=
None else 0.0
203 c_rhss[i] = rhss[i]
if rhss !=
None else self.infinity()
206 for entry
in entries:
207 c_inds[tmp] = entry[0]
208 c_coefs[tmp] = entry[1]
211 PY_SCIP_CALL(
SCIPlpiAddRows(self.lpi, nrows, c_lhss, c_rhss, NULL, nnonz, c_beg, c_inds, c_coefs))
219 def delRows(self, firstrow, lastrow):
220 """Deletes a range of rows from the LP. 223 firstrow -- first row to delete 224 lastrow -- last row to delete 228 def getBounds(self, firstcol = 0, lastcol = None):
229 """Returns all lower and upper bounds for a range of columns. 232 firstcol -- first column (default 0) 233 lastcol -- last column (default ncols - 1) 235 lastcol = lastcol
if lastcol !=
None else self.ncols() - 1
237 if firstcol > lastcol:
240 ncols = lastcol - firstcol + 1
241 cdef SCIP_Real* c_lbs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
242 cdef SCIP_Real* c_ubs = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
248 for i
in range(ncols):
257 def getSides(self, firstrow = 0, lastrow = None):
258 """Returns all left- and right-hand sides for a range of rows. 261 firstrow -- first row (default 0) 262 lastrow -- last row (default nrows - 1) 264 lastrow = lastrow
if lastrow !=
None else self.nrows() - 1
266 if firstrow > lastrow:
269 nrows = lastrow - firstrow + 1
270 cdef SCIP_Real* c_lhss = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
271 cdef SCIP_Real* c_rhss = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
272 PY_SCIP_CALL(
SCIPlpiGetSides(self.lpi, firstrow, lastrow, c_lhss, c_rhss))
277 for i
in range(firstrow, lastrow + 1):
278 lhss.append(c_lhss[i])
279 rhss.append(c_rhss[i])
286 def chgObj(self, col, obj):
287 """Changes objective coefficient of a single column. 290 col -- column to change 291 obj -- new objective coefficient 294 cdef SCIP_Real c_obj = obj
297 def chgCoef(self, row, col, newval):
298 """Changes a single coefficient in the LP. 302 col -- column to change 303 newval -- new coefficient 307 def chgBound(self, col, lb, ub):
308 """Changes the lower and upper bound of a single column. 311 col -- column to change 312 lb -- new lower bound 313 ub -- new upper bound 316 cdef SCIP_Real c_lb = lb
317 cdef SCIP_Real c_ub = ub
320 def chgSide(self, row, lhs, rhs):
321 """Changes the left- and right-hand side of a single row. 325 lhs -- new left-hand side 326 rhs -- new right-hand side 329 cdef SCIP_Real c_lhs = lhs
330 cdef SCIP_Real c_rhs = rhs
334 """Clears the whole LP.""" 338 """Returns the number of rows.""" 344 """Returns the number of columns.""" 349 def solve(self, dual=True):
350 """Solves the current LP. 353 dual -- use the dual or primal Simplex method (default: dual) 360 cdef SCIP_Real objval
365 """Returns the primal solution of the last LP solve.""" 367 cdef SCIP_Real* c_primalsol = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
368 PY_SCIP_CALL(
SCIPlpiGetSol(self.lpi, NULL, c_primalsol, NULL, NULL, NULL))
369 primalsol = [0.0] * ncols
370 for i
in range(ncols):
371 primalsol[i] = c_primalsol[i]
376 def isPrimalFeasible(self):
377 """Returns True iff LP is proven to be primal feasible.""" 381 """Returns the dual solution of the last LP solve.""" 383 cdef SCIP_Real* c_dualsol = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
384 PY_SCIP_CALL(
SCIPlpiGetSol(self.lpi, NULL, NULL, c_dualsol, NULL, NULL))
385 dualsol = [0.0] * nrows
386 for i
in range(nrows):
387 dualsol[i] = c_dualsol[i]
392 def isDualFeasible(self):
393 """Returns True iff LP is proven to be dual feasible.""" 396 def getPrimalRay(self):
397 """Returns a primal ray if possible, None otherwise.""" 401 cdef SCIP_Real* c_ray = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
404 for i
in range(ncols):
410 def getDualRay(self):
411 """Returns a dual ray if possible, None otherwise.""" 415 cdef SCIP_Real* c_ray = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
418 for i
in range(nrows):
424 def getNIterations(self):
425 """Returns the number of LP iterations of the last LP solve.""" 430 def getRedcost(self):
431 """Returns the reduced cost vector of the last LP solve.""" 434 cdef SCIP_Real* c_redcost = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
435 PY_SCIP_CALL(
SCIPlpiGetSol(self.lpi, NULL, NULL, NULL, NULL, c_redcost))
438 for i
in range(ncols):
439 redcost[i].append(c_redcost[i])
444 def getBasisInds(self):
445 """Returns the indices of the basic columns and rows; index i >= 0 corresponds to column i, index i < 0 to row -i-1""" 447 cdef int* c_binds = <int*> malloc(nrows * sizeof(int))
452 for i
in range(nrows):
453 binds.append(c_binds[i])
SCIP_RETCODE SCIPlpiReadLP(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI *lpi, SCIP_Real *objval)
SCIP_Bool SCIPlpiIsDualFeasible(SCIP_LPI *lpi)
SCIP_Bool SCIPlpiHasPrimalRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiFree(SCIP_LPI **lpi)
SCIP_RETCODE SCIPlpiGetBounds(SCIP_LPI *lpi, int firstcol, int lastcol, SCIP_Real *lbs, SCIP_Real *ubs)
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI *lpi, int *ncols)
SCIP_RETCODE SCIPlpiChgSides(SCIP_LPI *lpi, int nrows, const int *ind, const SCIP_Real *lhs, const SCIP_Real *rhs)
SCIP_RETCODE SCIPlpiGetBasisInd(SCIP_LPI *lpi, int *bind)
SCIP_RETCODE SCIPlpiAddRows(SCIP_LPI *lpi, int nrows, const SCIP_Real *lhs, const SCIP_Real *rhs, char **rownames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI *lpi, SCIP_Real *objval, SCIP_Real *primsol, SCIP_Real *dualsol, SCIP_Real *activity, SCIP_Real *redcost)
SCIP_RETCODE SCIPlpiGetNRows(SCIP_LPI *lpi, int *nrows)
SCIP_RETCODE SCIPlpiGetDualfarkas(SCIP_LPI *lpi, SCIP_Real *dualfarkas)
SCIP_RETCODE SCIPlpiDelRows(SCIP_LPI *lpi, int firstrow, int lastrow)
SCIP_RETCODE SCIPlpiClear(SCIP_LPI *lpi)
SCIP_Real SCIPlpiInfinity(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiAddCols(SCIP_LPI *lpi, int ncols, const SCIP_Real *obj, const SCIP_Real *lb, const SCIP_Real *ub, char **colnames, int nnonz, const int *beg, const int *ind, const SCIP_Real *val)
SCIP_Bool SCIPlpiHasDualRay(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI *lpi, int *iterations)
SCIP_RETCODE SCIPlpiGetSides(SCIP_LPI *lpi, int firstrow, int lastrow, SCIP_Real *lhss, SCIP_Real *rhss)
SCIP_RETCODE SCIPlpiDelCols(SCIP_LPI *lpi, int firstcol, int lastcol)
SCIP_Bool SCIPlpiIsInfinity(SCIP_LPI *lpi, SCIP_Real val)
SCIP_Bool SCIPlpiIsPrimalFeasible(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiChgBounds(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *lb, const SCIP_Real *ub)
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI *lpi)
SCIP_RETCODE SCIPlpiGetPrimalRay(SCIP_LPI *lpi, SCIP_Real *ray)
SCIP_RETCODE SCIPlpiWriteLP(SCIP_LPI *lpi, const char *fname)
SCIP_RETCODE SCIPlpiCreate(SCIP_LPI **lpi, SCIP_MESSAGEHDLR *messagehdlr, const char *name, SCIP_OBJSEN objsen)
SCIP_RETCODE SCIPlpiChgObj(SCIP_LPI *lpi, int ncols, const int *ind, const SCIP_Real *obj)
SCIP_RETCODE SCIPlpiChgCoef(SCIP_LPI *lpi, int row, int col, SCIP_Real newval)