Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Score plugin #12

Merged
merged 5 commits into from
Jul 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
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 src/pygcgopt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from pygcgopt.gcg import PricingSolver
from pygcgopt.gcg import ConsClassifier
from pygcgopt.gcg import VarClassifier
from pygcgopt.gcg import Score
from pygcgopt.gcg import PY_GCG_PRICINGSTATUS as GCG_PRICINGSTATUS
from pygcgopt.gcg import PY_CONS_DECOMPINFO as CONS_DECOMPINFO
from pygcgopt.gcg import PY_VAR_DECOMPINFO as VAR_DECOMPINFO
178 changes: 3 additions & 175 deletions src/pygcgopt/decomposition.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -158,42 +158,10 @@ cdef class PartialDecomposition:
def setUsergiven(self, USERGIVEN value=COMPLETED_CONSTOMASTER):
self.thisptr.setUsergiven(value)

@property
def classic_score(self):
return self.thisptr.getClassicScore()

@property
def border_area_score(self):
return self.thisptr.getBorderAreaScore()

@property
def max_white_score(self):
return self.thisptr.getMaxWhiteScore()

@property
def max_for_white_score(self):
return self.thisptr.getMaxForWhiteScore()

@property
def set_part_for_white_score(self):
return self.thisptr.getSetPartForWhiteScore()

@property
def max_for_white_agg_score(self):
return self.thisptr.getMaxForWhiteAggScore()

@property
def set_part_for_white_agg_score(self):
return self.thisptr.getSetPartForWhiteAggScore()

@property
def benders_score(self):
return self.thisptr.getBendersScore()

@property
def strong_decomp_score(self):
return self.thisptr.getStrongDecompScore()

# BEGIN AUTOGENERATED BLOCK

def addBlock(PartialDecomposition self):
Expand Down Expand Up @@ -1381,6 +1349,9 @@ cdef class PartialDecomposition:
cdef bool cpp_fromorig = fromorig
self.thisptr.setStemsFromOrig(cpp_fromorig)

def getScore(PartialDecomposition self, Score score):
return self.thisptr.getScore(GCGfindScore(self.thisptr.getDetprobdata().getScip(), str_conversion(score.scorename)))

# def setUsergiven(PartialDecomposition self, cpp.USERGIVEN usergiven):
# """sets whether this partialdec is user given

Expand Down Expand Up @@ -1630,40 +1601,6 @@ cdef class PartialDecomposition:
cdef vector[double] cpp_newvector = newvector
self.thisptr.setDetectorClockTimes(cpp_newvector)

@property
def classicScore(PartialDecomposition self):
"""gets the classic score

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcClassicScore
:return: border area score.
"""
cdef double result = self.thisptr.getClassicScore()
return result

@classicScore.setter
def classicScore(PartialDecomposition self, double score):
"""set the classic score.
"""
cdef double cpp_score = score
self.thisptr.setClassicScore(cpp_score)

@property
def borderAreaScore(PartialDecomposition self):
"""gets the border area score

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcBorderAreaScore
:return: border area score.
"""
cdef double result = self.thisptr.getBorderAreaScore()
return result

@borderAreaScore.setter
def borderAreaScore(PartialDecomposition self, double score):
"""set the border area score.
"""
cdef double cpp_score = score
self.thisptr.setBorderAreaScore(cpp_score)

@property
def maxWhiteScore(PartialDecomposition self):
"""gets the maximum white area score
Expand All @@ -1675,115 +1612,6 @@ cdef class PartialDecomposition:
cdef double result = self.thisptr.getMaxWhiteScore()
return result

@maxWhiteScore.setter
def maxWhiteScore(PartialDecomposition self, double score):
"""set the maximum white area score.
"""
cdef double cpp_score = score
self.thisptr.setMaxWhiteScore(cpp_score)

@property
def maxForWhiteScore(PartialDecomposition self):
"""gets the maximum foreseeing white area score

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcMaxForseeingWhiteScore
:return: maximum foreseeing white area score
"""
cdef double result = self.thisptr.getMaxForWhiteScore()
return result

@maxForWhiteScore.setter
def maxForWhiteScore(PartialDecomposition self, double score):
"""set the maximum foreseeing white area score.
"""
cdef double cpp_score = score
self.thisptr.setMaxForWhiteScore(cpp_score)

@property
def partForWhiteScore(PartialDecomposition self):
"""gets the setpartitioning maximum foreseeing white area score

.. note:: -1 iff not calculated yet, .. seealso:: GGCGconshdlrDecompCalcSetPartForseeingWhiteScore
:return: setpartitioning maximum foreseeing white area score
"""
cdef double result = self.thisptr.getSetPartForWhiteScore()
return result

@partForWhiteScore.setter
def partForWhiteScore(PartialDecomposition self, double score):
"""set the setpartitioning maximum foreseeing white area score.
"""
cdef double cpp_score = score
self.thisptr.setSetPartForWhiteScore(cpp_score)

@property
def maxForWhiteAggScore(PartialDecomposition self):
"""gets the maximum foreseeing white area score with respect to aggregatable blocks

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcMaxForeseeingWhiteAggScore
:return: maximum foreseeing white area score with respect to aggregatable blocks
"""
cdef double result = self.thisptr.getMaxForWhiteAggScore()
return result

@maxForWhiteAggScore.setter
def maxForWhiteAggScore(PartialDecomposition self, double score):
"""set the maximum foreseeing white area score with respect to aggregatable blocks.
"""
cdef double cpp_score = score
self.thisptr.setMaxForWhiteAggScore(cpp_score)

@property
def partForWhiteAggScore(PartialDecomposition self):
"""gets the setpartitioning maximum foreseeing white area score with respect to aggregateable

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcSetPartForWhiteAggScore
:return: setpartitioning maximum foreseeing white area score with respect to aggregateable.
"""
cdef double result = self.thisptr.getSetPartForWhiteAggScore()
return result

@partForWhiteAggScore.setter
def partForWhiteAggScore(PartialDecomposition self, double score):
"""set the setpartitioning maximum foreseeing white area score with respect to aggregateable.
"""
cdef double cpp_score = score
self.thisptr.setSetPartForWhiteAggScore(cpp_score)

@property
def bendersScore(PartialDecomposition self):
"""gets the benders score

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcBendersScore
:return: benders score.
"""
cdef double result = self.thisptr.getBendersScore()
return result

@bendersScore.setter
def bendersScore(PartialDecomposition self, double score):
"""set the benders score.
"""
cdef double cpp_score = score
self.thisptr.setBendersScore(cpp_score)

@property
def strongDecompScore(PartialDecomposition self):
"""gets the strong decomposition score

.. note:: -1 iff not calculated yet, .. seealso:: GCGconshdlrDecompCalcStrongDecompositionScore
:return: strong decomposition score.
"""
cdef double result = self.thisptr.getStrongDecompScore()
return result

@strongDecompScore.setter
def strongDecompScore(PartialDecomposition self, double score):
"""set the strong decomposition score.
"""
cdef double cpp_score = score
self.thisptr.setStrongDecompScore(cpp_score)

def prepare(PartialDecomposition self):
"""sorts the partialdec and calculates a its implicit assignments, hashvalue and evaluation

Expand Down
32 changes: 14 additions & 18 deletions src/pygcgopt/gcg.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ cdef extern from "gcg/gcg.h":
ctypedef struct DEC_DETECTOR:
pass

ctypedef struct DEC_SCOREDATA:
pass

ctypedef struct DEC_SCORE:
pass

ctypedef struct PARTIALDEC_DETECTION_DATA:
DETPROBDATA* detprobdata
PARTIALDECOMP* workonpartialdec
Expand Down Expand Up @@ -76,6 +82,13 @@ cdef extern from "gcg/gcg.h":
GP_OUTPUT_FORMAT_PNG
GP_OUTPUT_FORMAT_SVG

SCIP_RETCODE GCGincludeScore(SCIP* scip, const char* name, const char* shortname,const char* description, DEC_SCOREDATA* scoredata, SCIP_RETCODE (*scorefree) (SCIP* scip, DEC_SCORE* score), SCIP_RETCODE (*scorecalc) (SCIP* scip, DEC_SCORE* score, int partialdecid, SCIP_Real* scorevalue))
DEC_SCOREDATA* GCGscoreGetData(DEC_SCORE* score)
int GCGgetNScores(SCIP* scip)
DEC_SCORE** GCGgetScores(SCIP* scip)
const char* GCGscoreGetName(DEC_SCORE* score)
DEC_SCORE* GCGfindScore(SCIP* scip, const char* name)


cdef extern from "gcg/pub_gcgsepa.h":
SCIP_RETCODE GCGsetSeparators(SCIP* scip, SCIP_PARAMSETTING paramsetting)
Expand Down Expand Up @@ -321,34 +334,17 @@ cdef extern from "gcg/class_partialdecomp.h" namespace "gcg":
void setPctVarsToBlockVector(vector[double] newvector) except +
void setPctVarsFromFreeVector(vector[double] newvector) except +
void setDetectorClockTimes(vector[double] newvector) except +
double getClassicScore() except +
void setClassicScore(double score) except +
double getBorderAreaScore() except +
void setBorderAreaScore(double score) except +
double getMaxWhiteScore() except +
void setMaxWhiteScore(double score) except +
double getMaxForWhiteScore() except +
void setMaxForWhiteScore(double score) except +
double getSetPartForWhiteScore() except +
void setSetPartForWhiteScore(double score) except +
double getMaxForWhiteAggScore() except +
void setMaxForWhiteAggScore(double score) except +
double getSetPartForWhiteAggScore() except +
void setSetPartForWhiteAggScore(double score) except +
double getBendersScore() except +
void setBendersScore(double score) except +
double getStrongDecompScore() except +
void setStrongDecompScore(double score) except +
void prepare() except +
bool aggInfoCalculated() except +
void calcAggregationInformation(bool ignoreDetectionLimits) except +
vector[vector[int]] getConssForBlocks() except +
int getTranslatedpartialdecid() except +
void setTranslatedpartialdecid(int decid) except +
void buildDecChainString(char * buffer) except +

bool fixConsToBlock(SCIP_CONS* cons, int block)
bool fixConsToMaster(SCIP_CONS* cons)
SCIP_Real getScore(DEC_SCORE* score) except +


cdef extern from "gcg/class_detprobdata.h" namespace "gcg":
Expand Down
40 changes: 40 additions & 0 deletions src/pygcgopt/gcg.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ from collections.abc import Iterable

include "detector.pxi"
include "pricing_solver.pxi"
include "score.pxi"
include "partition.pxi"
include "decomposition.pxi"
include "detprobdata.pxi"
Expand Down Expand Up @@ -149,6 +150,16 @@ cdef class Model(SCIPModel):

return decomps

def getPartDecompFromID(self, id):
"""returns a partial decomposition regarding to the given partialdecomp id

:param id: patial decomposition id as int
:return: PartialDecomposition object
"""
cdef PartialDecomposition pd = PartialDecomposition.create(GCGconshdlrDecompGetPartialdecFromID(self._scip, id))

return pd

def addDecompositionFromConss(self, master_conss, *block_conss):
"""Adds a user specified decomposition to GCG based on constraints.

Expand Down Expand Up @@ -370,6 +381,25 @@ cdef class Model(SCIPModel):
detector.detectorname = detectorname
Py_INCREF(detector)

def includeScore(self, Score score, scorename, shortname, desc):
"""includes a score

:param detector: An object of a subclass of detector#Detector.
:param detectorname: name of the detector

For an explanation for all arguments, see :meth:`DECincludeDetector()`.
"""
c_scorename = str_conversion(scorename)
c_shortname = str_conversion(shortname)
c_desc = str_conversion(desc)
PY_SCIP_CALL(GCGincludeScore(
self._scip, c_scorename, c_shortname, c_desc,
<DEC_SCOREDATA*>score, PyScoreFree, PyScoreCalculate))

score.model = <SCIPModel>weakref.proxy(self)
score.scorename = scorename
Py_INCREF(score)

def listDetectors(self):
"""Lists all detectors that are currently included

Expand All @@ -386,6 +416,16 @@ cdef class Model(SCIPModel):

return [DECdetectorGetName(detectors[i]).decode('utf-8') for i in range(n_detectors)]

def listScores(self):
"""Lists all scores that are currently included

:return: A list of strings of the score names
"""
cdef int n_scores = GCGgetNScores(self._scip)
cdef DEC_SCORE** scores = GCGgetScores(self._scip)

return [GCGscoreGetName(scores[i]).decode('utf-8') for i in range(n_scores)]

def setDetectorEnabled(self, detector_name, is_enabled=True):
"""Enables or disables a detector for detecting partial decompositions.

Expand Down
30 changes: 30 additions & 0 deletions src/pygcgopt/score.pxi
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cdef class Score:
"""Base class of the Score Plugin"""

cdef public SCIPModel model
cdef public str scorename

def scorefree(self):
'''calls destructor and frees memory of score'''
pass

def scorecalculate(self, partialdec):
'''calls calculate method of score'''
return {}

cdef SCIP_RETCODE PyScoreFree(SCIP* scip, DEC_SCORE* score) with gil:
cdef DEC_SCOREDATA* scoredata
scoredata = GCGscoreGetData(score)
py_score = <Score>scoredata
py_score.scorefree()
Py_DECREF(py_score)
return SCIP_OKAY

cdef SCIP_RETCODE PyScoreCalculate(SCIP* scip, DEC_SCORE* score, int partialdecid, SCIP_Real* scorevalue) with gil:
cdef DEC_SCOREDATA* scoredata
scoredata = GCGscoreGetData(score)
py_score = <Score>scoredata
partialdec = py_score.model.getPartDecompFromID(partialdecid)
result_dict = py_score.scorecalculate(partialdec)
scorevalue[0] = result_dict.get("scorevalue", scorevalue[0])
return SCIP_OKAY
Loading