Scippy

GCG

Branch-and-Price & Column Generation for Everyone

dec_constype.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file dec_constype.cpp
29  * @ingroup DETECTORS
30  * @brief detector constype (put your description here)
31  * @author Michael Bastubbe
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 
36 #include "dec_constype.h"
37 #include "cons_decomp.h"
38 #include "class_partialdecomp.h"
39 #include "class_detprobdata.h"
40 #include "gcg.h"
41 #include "scip/cons_setppc.h"
42 #include "scip/scip.h"
43 #include "scip_misc.h"
44 #include "scip/clock.h"
45 
46 #include <iostream>
47 
48 /* constraint handler properties */
49 #define DEC_DETECTORNAME "constype" /**< name of detector */
50 #define DEC_DESC "detector constype" /**< description of detector*/
51 #define DEC_FREQCALLROUND 1 /** frequency the detector gets called in detection loop ,ie it is called in round r if and only if minCallRound <= r <= maxCallRound AND (r - minCallRound) mod freqCallRound == 0 */
52 #define DEC_MAXCALLROUND 0 /** last round the detector gets called */
53 #define DEC_MINCALLROUND 0 /** first round the detector gets called */
54 #define DEC_FREQCALLROUNDORIGINAL 1 /** frequency the detector gets called in detection loop while detecting the original problem */
55 #define DEC_MAXCALLROUNDORIGINAL 0 /** last round the detector gets called while detecting the original problem */
56 #define DEC_MINCALLROUNDORIGINAL 0 /** first round the detector gets called while detecting the original problem */
57 #define DEC_PRIORITY 0 /**< priority of the constraint handler for separation */
58 #define DEC_DECCHAR 't' /**< display character of detector */
59 #define DEC_ENABLED FALSE /**< should the detection be enabled */
60 #define DEC_ENABLEDFINISHING FALSE /**< should the finishing be enabled */
61 #define DEC_ENABLEDPOSTPROCESSING FALSE /**< should the finishing be enabled */
62 #define DEC_SKIP FALSE /**< should detector be skipped if other detectors found decompositions */
63 #define DEC_USEFULRECALL FALSE /**< is it useful to call this detector on a descendant of the propagated partialdec */
64 /*
65  * Data structures
66  */
67 
68 /** @todo fill in the necessary detector data */
69 
70 /** detector handler data */
71 struct DEC_DetectorData
72 {
73 };
74 
75 /*
76  * Local methods
77  */
78 
79 /* put your local methods here, and declare them static */
80 
81 /** method to enumerate all subsets */
82 std::vector< std::vector<int> > getSubsets(std::vector<int> set)
83 {
84  std::vector< std::vector<int> > subset;
85  std::vector<int> empty;
86  subset.push_back( empty );
87 
88  for ( size_t i = 0; i < set.size(); ++i )
89  {
90  std::vector< std::vector<int> > subsetTemp = subset;
91 
92  for (size_t j = 0; j < subsetTemp.size(); ++j)
93  subsetTemp[j].push_back( set[i] );
94 
95  for (size_t j = 0; j < subsetTemp.size(); ++j)
96  subset.push_back( subsetTemp[j] );
97  }
98  return subset;
99 }
100 
101 /*
102  * detector callback methods
103  */
104 
105 /** destructor of detector to free user data (called when GCG is exiting) */
106 #define freeConstype NULL
107 
108 /** destructor of detector to free detector data (called before the solving process begins) */
109 #define exitConstype NULL
110 
111 /** detection initialization function of detector (called before solving is about to begin) */
112 #define initConstype NULL
113 
114 static DEC_DECL_PROPAGATEPARTIALDEC(propagatePartialdecConstype)
115 {
116  *result = SCIP_DIDNOTFIND;
117  char decinfo[SCIP_MAXSTRLEN];
118 
119  SCIP_CLOCK* temporaryClock;
120  SCIP_CALL_ABORT(SCIPcreateClock(scip, &temporaryClock) );
121  SCIP_CALL_ABORT( SCIPstartClock(scip, temporaryClock) );
122 
123  SCIP_CONS* cons;
124 
125  int partialdecCounter = 0;
126  gcg::PARTIALDECOMP* partialdecOrig;
127  gcg::PARTIALDECOMP* partialdec;
128 
129  std::vector<consType> foundConstypes(0);
130  std::vector<int> constypesIndices(0);
131 
132  partialdecOrig = partialdecdetectiondata->workonpartialdec;
133 
134  for( int i = 0; i < partialdecOrig->getNOpenconss(); ++i)
135  {
136  cons = partialdecdetectiondata->detprobdata->getCons(partialdecOrig->getOpenconss()[i]);
137  consType cT = GCGconsGetType(scip, cons);
138 
139  /* find constype or not */
140  std::vector<consType>::const_iterator constypeIter = foundConstypes.begin();
141  for(; constypeIter != foundConstypes.end(); ++constypeIter)
142  {
143  if(*constypeIter == cT)
144  break;
145  }
146 
147  if( constypeIter == foundConstypes.end() )
148  {
149  foundConstypes.push_back(GCGconsGetType(scip, cons) );
150  }
151  }
152 
153  for(size_t i = 0; i < foundConstypes.size(); ++i)
154  {
155  constypesIndices.push_back(i);
156  }
157 
158  std::vector< std::vector<int> > subsetsOfConstypes = getSubsets(constypesIndices);
159 
160  SCIP_CALL( SCIPallocMemoryArray(scip, &(partialdecdetectiondata->newpartialdecs), subsetsOfConstypes.size() - 1) );
161  partialdecdetectiondata->nnewpartialdecs = subsetsOfConstypes.size() - 1;
162 
163  for(size_t subset = 0; subset < subsetsOfConstypes.size(); ++subset)
164  {
165  if(subsetsOfConstypes[subset].size() == 0)
166  continue;
167 
168  partialdec = new gcg::PARTIALDECOMP(partialdecOrig);
169  /* set open cons that have type of the current subset to Master */
170  auto& openconss = partialdec->getOpenconssVec();
171  for( auto itr = openconss.cbegin(); itr != openconss.cend(); )
172  {
173  cons = partialdecdetectiondata->detprobdata->getCons(*itr);
174  bool found = false;
175  for(size_t constypeId = 0; constypeId < subsetsOfConstypes[subset].size(); ++constypeId )
176  {
177  if( GCGconsGetType(scip, cons) == foundConstypes[subsetsOfConstypes[subset][constypeId]] )
178  {
179  itr = partialdec->fixConsToMaster(itr);
180  found = true;
181  break;
182  }
183  }
184  if( !found )
185  {
186  ++itr;
187  }
188  }
189  partialdec->sort();
190  (void) SCIPsnprintf(decinfo, SCIP_MAXSTRLEN, "constype-%llu", subset);
191  partialdec->addDetectorChainInfo(decinfo);
192  partialdecdetectiondata->newpartialdecs[partialdecCounter] = partialdec;
193  partialdecCounter++;
194  }
195 
196  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock) );
197  partialdecdetectiondata->detectiontime = SCIPgetClockTime(scip, temporaryClock);
198  for( int s = 0; s < partialdecdetectiondata->nnewpartialdecs; ++s )
199  {
200  partialdecdetectiondata->newpartialdecs[s]->addClockTime(partialdecdetectiondata->detectiontime / partialdecdetectiondata->nnewpartialdecs);
201  }
202  SCIP_CALL_ABORT(SCIPfreeClock(scip, &temporaryClock) );
203 
204  *result = SCIP_SUCCESS;
205 
206  return SCIP_OKAY;
207 }
208 
209 #define finishPartialdecConstype NULL
210 #define detectorPostprocessPartialdecConstype NULL
211 static
212 DEC_DECL_SETPARAMAGGRESSIVE(setParamAggressiveConstype)
213 {
214  char setstr[SCIP_MAXSTRLEN];
215  const char* name = DECdetectorGetName(detector);
216 
217  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
218  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE) );
219 
220  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
221  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE ) );
222 
223  return SCIP_OKAY;
224 }
225 
226 
227 static
228 DEC_DECL_SETPARAMDEFAULT(setParamDefaultConstype)
229 {
230  char setstr[SCIP_MAXSTRLEN];
231  const char* name = DECdetectorGetName(detector);
232 
233  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
234  SCIP_CALL( SCIPsetBoolParam(scip, setstr, DEC_ENABLED) );
235 
236  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
237  SCIP_CALL( SCIPsetBoolParam(scip, setstr, DEC_ENABLEDFINISHING ) );
238 
239  return SCIP_OKAY;
240 }
241 
242 static
243 DEC_DECL_SETPARAMFAST(setParamFastConstype)
244 {
245  char setstr[SCIP_MAXSTRLEN];
246 
247  const char* name = DECdetectorGetName(detector);
248 
249  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
250  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE) );
251 
252  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
253  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE ) );
254 
255 
256  return SCIP_OKAY;
257 
258 }
259 
260 
261 /*
262  * detector specific interface methods
263  */
264 
265 /** creates the handler for constype detector and includes it in SCIP */
266 SCIP_RETCODE SCIPincludeDetectorConstype(SCIP* scip /**< SCIP data structure */
267 )
268 {
269  DEC_DETECTORDATA* detectordata;
270 
271  /**@todo create constype detector data here*/
272  detectordata = NULL;
273 
274  SCIP_CALL(
277  freeConstype, initConstype, exitConstype, propagatePartialdecConstype, finishPartialdecConstype, detectorPostprocessPartialdecConstype, setParamAggressiveConstype, setParamDefaultConstype, setParamFastConstype));
278 
279  /**@todo add constype detector parameters */
280 
281  return SCIP_OKAY;
282 }
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
#define freeConstype
GCG interface methods.
#define detectorPostprocessPartialdecConstype
std::vector< int >::const_iterator fixConsToMaster(std::vector< int >::const_iterator itr)
fixes a constraint to the master constraints
void addDetectorChainInfo(const char *decinfo)
add information about the detector chain
std::vector< int > & getOpenconssVec()
Gets a vector containing constraint ids not assigned yet as vector.
constraint handler for structure detection
#define exitConstype
#define DEC_MINCALLROUNDORIGINAL
#define finishPartialdecConstype
static DEC_DECL_SETPARAMDEFAULT(setParamDefaultConstype)
#define DEC_FREQCALLROUNDORIGINAL
various SCIP helper methods
#define DEC_ENABLEDPOSTPROCESSING
#define DEC_FREQCALLROUND
static DEC_DECL_SETPARAMFAST(setParamFastConstype)
SCIP_RETCODE SCIPincludeDetectorConstype(SCIP *scip)
#define DEC_SKIP
#define DEC_DETECTORNAME
#define DEC_DECCHAR
bool sort()
sorts the vars and conss data structures by their indices
const int * getOpenconss()
Gets array containing constraints not assigned yet.
#define DEC_PRIORITY
consType GCGconsGetType(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:51
#define DEC_DESC
#define DEC_MINCALLROUND
static DEC_DECL_SETPARAMAGGRESSIVE(setParamAggressiveConstype)
class to manage partial decompositions
struct gcg::subset subset
std::vector< std::vector< int > > getSubsets(std::vector< int > set)
static DEC_DECL_PROPAGATEPARTIALDEC(propagatePartialdecConstype)
SCIP_RETCODE DECincludeDetector(SCIP *scip, const char *name, const char decchar, const char *description, int freqCallRound, int maxCallRound, int minCallRound, int freqCallRoundOriginal, int maxCallRoundOriginal, int minCallRoundOriginal, int priority, SCIP_Bool enabled, SCIP_Bool enabledFinishing, SCIP_Bool enabledPostprocessing, SCIP_Bool skip, SCIP_Bool usefulRecall, DEC_DETECTORDATA *detectordata, DEC_DECL_FREEDETECTOR((*freeDetector)), DEC_DECL_INITDETECTOR((*initDetector)), DEC_DECL_EXITDETECTOR((*exitDetector)), DEC_DECL_PROPAGATEPARTIALDEC((*propagatePartialdecDetector)), DEC_DECL_FINISHPARTIALDEC((*finishPartialdecDetector)), DEC_DECL_POSTPROCESSPARTIALDEC((*postprocessPartialdecDetector)), DEC_DECL_SETPARAMAGGRESSIVE((*setParamAggressiveDetector)), DEC_DECL_SETPARAMDEFAULT((*setParamDefaultDetector)),)
int getNOpenconss()
Gets size of vector containing constraints not assigned yet.
#define DEC_ENABLED
#define initConstype
constype detector
#define DEC_MAXCALLROUND
#define DEC_ENABLEDFINISHING
class storing (potentially incomplete) decompositions
#define DEC_MAXCALLROUNDORIGINAL
consType
Definition: scip_misc.h:47
class storing partialdecs and the problem matrix
#define DEC_USEFULRECALL