Skip to content
Merged
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
## Unreleased
### Added
- Added getLinearConsIndicator
<<<<<<< HEAD
- Added SCIP_LPPARAM, setIntParam, setRealParam, getIntParam, getRealParam, isOptimal, getObjVal, getRedcost for lpi
=======
- Added SCIP_LPPARAM, setIntParam, setRealParam, getIntParam, getRealParam for lpi
>>>>>>> upstream/master
- Added isFeasPositive
### Fixed
### Changed
Expand Down
75 changes: 70 additions & 5 deletions src/pyscipopt/lp.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -361,8 +361,39 @@ cdef class LP:

return objval

def isOptimal(self):
"""
returns true iff LP was solved to optimality.

Returns
-------
bool

"""
return SCIPlpiIsOptimal(self.lpi)

def getObjVal(self):
"""
Returns the objective value of the last LP solve.
If the value does not exists, None will be returned.
"""
if not self.isOptimal():
return None

cdef SCIP_Real objval

PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, &objval, NULL, NULL, NULL, NULL))

return objval

def getPrimal(self):
"""Returns the primal solution of the last LP solve."""
"""
Returns the primal solution of the last LP solve.
If the solution does not exists, None will be returned.
"""
if not self.isOptimal():
return None

cdef int ncols = self.ncols()
cdef SCIP_Real* c_primalsol = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
cdef int i
Expand All @@ -380,7 +411,13 @@ cdef class LP:
return SCIPlpiIsPrimalFeasible(self.lpi)

def getDual(self):
"""Returns the dual solution of the last LP solve."""
"""
Returns the dual solution of the last LP solve.
If the solution does not exists, None will be returned.
"""
if not self.isOptimal():
return None

cdef int nrows = self.nrows()
cdef SCIP_Real* c_dualsol = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
cdef int i
Expand Down Expand Up @@ -445,17 +482,45 @@ cdef class LP:

return niters

def getActivity(self):
"""
Returns the row activity vector of the last LP solve.
If the vecotr does not exists, None will be returned.
"""
if not self.isOptimal():
return None

cdef int nrows = self.nrows()
cdef SCIP_Real* c_activity = <SCIP_Real*> malloc(nrows * sizeof(SCIP_Real))
cdef int i

PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, NULL, NULL, c_activity, NULL))

activity = [0.0] * nrows
for i in range(nrows):
activity[i] = c_activity[i]

free(c_activity)

return activity

def getRedcost(self):
"""Returns the reduced cost vector of the last LP solve."""
"""
Returns the reduced cost vector of the last LP solve.
If the vecotr does not exists, None will be returned.
"""
if not self.isOptimal():
return None

cdef int ncols = self.ncols()
cdef SCIP_Real* c_redcost = <SCIP_Real*> malloc(ncols * sizeof(SCIP_Real))
cdef int i

PY_SCIP_CALL(SCIPlpiGetSol(self.lpi, NULL, NULL, NULL, NULL, c_redcost))

redcost = []
redcost = [0.0] * ncols
for i in range(ncols):
redcost[i].append(c_redcost[i])
redcost[i] = c_redcost[i]

free(c_redcost)

Expand Down
1 change: 1 addition & 0 deletions src/pyscipopt/scip.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,7 @@ cdef extern from "scip/scip.h":
SCIP_RETCODE SCIPlpiGetNCols(SCIP_LPI* lpi, int* ncols)
SCIP_RETCODE SCIPlpiSolveDual(SCIP_LPI* lpi)
SCIP_RETCODE SCIPlpiSolvePrimal(SCIP_LPI* lpi)
SCIP_RETCODE SCIPlpiIsOptimal(SCIP_LPI* lpi)
SCIP_RETCODE SCIPlpiGetObjval(SCIP_LPI* lpi, SCIP_Real* objval)
SCIP_RETCODE SCIPlpiGetSol(SCIP_LPI* lpi, SCIP_Real* objval, SCIP_Real* primsol, SCIP_Real* dualsol, SCIP_Real* activity, SCIP_Real* redcost)
SCIP_RETCODE SCIPlpiGetIterations(SCIP_LPI* lpi, int* iterations)
Expand Down
7 changes: 7 additions & 0 deletions tests/test_lp.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,11 @@ def test_lp():

solval = myLP.solve()

assert(myLP.isOptimal())
assert(myLP.getPrimal() is not None)
assert(myLP.getDual() is not None)
assert(myLP.getActivity() is not None)
assert(myLP.getRedcost() is not None)
assert round(myLP.getObjVal() == solval)

assert round(5.0 == solval)
Loading