7 def __init__(self, name="LP", sense="minimize"):
10 name -- the name of the problem (default 'LP')
11 sense -- objective sense (default minimize)
15 if sense ==
"minimize":
16 PY_SCIP_CALL(
SCIPlpiCreate(&(self.lpi), NULL, n, SCIP_OBJSEN_MINIMIZE))
17 elif sense ==
"maximize":
18 PY_SCIP_CALL(
SCIPlpiCreate(&(self.lpi), NULL, n, SCIP_OBJSEN_MAXIMIZE))
20 raise Warning(
"unrecognized objective sense")
29 """Writes LP to a file.
32 filename -- the name of the file to be used
37 """Reads LP from a file.
40 filename -- the name of the file to be used
45 """Returns infinity value of the LP.
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))
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))
220 """Deletes a range of rows from the LP.
223 firstrow -- first row to delete
224 lastrow -- last row to delete
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):
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])
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
298 """Changes a single coefficient in the LP.
302 col -- column to change
303 newval -- new coefficient
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
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."""
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]
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]
393 """Returns True iff LP is proven to be dual feasible."""
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):
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):
425 """Returns the number of LP iterations of the last LP solve."""
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])
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])