Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased
### Added
- Wrapper SCIPdeactivatePricer and added deactivatePricer and test
- Added getLinearConsIndicator
- Added SCIP_LPPARAM, setIntParam, setRealParam, getIntParam, getRealParam, isOptimal, getObjVal, getRedcost for lpi
- Added isFeasPositive
Expand Down
1 change: 1 addition & 0 deletions src/pyscipopt/scip.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,7 @@ cdef extern from "scip/scip.h":
SCIP_PRICERDATA* pricerdata)
SCIP_PRICER* SCIPfindPricer(SCIP* scip, const char* name)
SCIP_RETCODE SCIPactivatePricer(SCIP* scip, SCIP_PRICER* pricer)
SCIP_RETCODE SCIPdeactivatePricer(SCIP* scip, SCIP_PRICER* pricer)
SCIP_PRICERDATA* SCIPpricerGetData(SCIP_PRICER* pricer)

# Constraint handler plugin
Expand Down
14 changes: 14 additions & 0 deletions src/pyscipopt/scip.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@
if rc == SCIP_OKAY:
pass
elif rc == SCIP_ERROR:
raise Exception('SCIP: unspecified error!')

Check failure on line 301 in src/pyscipopt/scip.pxi

View workflow job for this annotation

GitHub Actions / test-coverage (3.11)

SCIP: unspecified error!
elif rc == SCIP_NOMEMORY:
raise MemoryError('SCIP: insufficient memory error!')
elif rc == SCIP_READERROR:
Expand Down Expand Up @@ -7593,6 +7593,7 @@
PY_SCIP_CALL(SCIPactivatePricer(self._scip, scip_pricer))
pricer.model = <Model>weakref.proxy(self)
Py_INCREF(pricer)
pricer._name = name
Comment thread
Joao-Dionisio marked this conversation as resolved.
Outdated

def includeConshdlr(self, Conshdlr conshdlr, name, desc, sepapriority=0,
enfopriority=0, chckpriority=0, sepafreq=-1, propfreq=-1,
Expand Down Expand Up @@ -7654,6 +7655,19 @@
conshdlr.name = name
Py_INCREF(conshdlr)

def deactivatePricer(self, Pricer pricer):
"""
Deactivate the given pricer.

Parameters
----------
pricer : Pricer
the pricer to deactivate
"""
cdef SCIP_PRICER* scip_pricer
scip_pricer = SCIPfindPricer(self._scip, str_conversion(pricer._name))
PY_SCIP_CALL(SCIPdeactivatePricer(self._scip, scip_pricer))

def copyLargeNeighborhoodSearch(self, to_fix, fix_vals) -> Model:
"""
Creates a configured copy of the transformed problem and applies provided fixings intended for LNS heuristics.
Expand Down
64 changes: 63 additions & 1 deletion tests/test_pricer.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ def pricerredcost(self):
self.data['patterns'].append(newPattern)
self.data['var'].append(newVar)

if self.data["deactivate"]:
# Testing deactivatePricer
self.model.deactivatePricer(self)

return {'result':SCIP_RESULT.SUCCESS}

# The initialisation function for the variable pricer to retrieve the transformed constraints of the problem
Expand Down Expand Up @@ -124,6 +128,7 @@ def test_cuttingstock():
pricer.data['rollLength'] = rollLength
pricer.data['patterns'] = patterns
pricer.data['redcosts'] = []
pricer.data["deactivate"] = False
Comment thread
mmghannam marked this conversation as resolved.

# solve problem
s.optimize()
Expand Down Expand Up @@ -174,4 +179,61 @@ class IncompletePricer(Pricer):
model.includePricer(pricer, "", "")

with pytest.raises(Exception):
model.optimize()
model.optimize()

def test_deactivate_pricer():
# create solver instance
s = Model("CuttingStock")

s.setPresolve(0)
s.data = {}
s.data["nSols"] = 0

# creating a pricer
pricer = CutPricer()
s.includePricer(pricer, "CuttingStockPricer", "Pricer to identify new cutting stock patterns")

# item widths
widths = [14, 31, 36, 45]
# width demand
demand = [211, 395, 610, 97]
# roll length
rollLength = 100
assert len(widths) == len(demand)

# adding the initial variables
cutPatternVars = []
varNames = []
varBaseName = "Pattern"
patterns = []

for i in range(len(widths)):
varNames.append(varBaseName + "_" + str(i))
cutPatternVars.append(s.addVar(varNames[i], obj = 1.0))

# adding a linear constraint for the knapsack constraint
demandCons = []
for i in range(len(widths)):
numWidthsPerRoll = float(int(rollLength/widths[i]))
demandCons.append(s.addCons(numWidthsPerRoll*cutPatternVars[i] >= demand[i],
separate = False, modifiable = True))
newPattern = [0]*len(widths)
newPattern[i] = numWidthsPerRoll
patterns.append(newPattern)

# Setting the pricer_data for use in the init and redcost functions
pricer.data = {}
pricer.data['var'] = cutPatternVars
pricer.data['cons'] = demandCons
pricer.data['widths'] = widths
pricer.data['demand'] = demand
pricer.data['rollLength'] = rollLength
pricer.data['patterns'] = patterns
pricer.data['redcosts'] = []
pricer.data["deactivate"] = True

# solve problem
s.optimize()

# the optimal solution with normal pricing
assert s.isGT(s.getObjVal(), 452.25)