Scippy

GCG

Branch-and-Price & Column Generation for Everyone

cons_decomp.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 cons_decomp.cpp
29  * @ingroup CONSHDLRS
30  * @brief constraint handler for structure detection
31  * @author Martin Bergner
32  * @author Christian Puchert
33  * @author Michael Bastubbe
34  * @author Hanna Franzen
35  * @author William Ma
36  *
37  * This constraint handler will run all registered structure detectors in a loop. They will find partial decompositions in a loop iteration until the decompositions are full
38  * or the maximum number of detection rounds is reached.
39  *
40  */
41 
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43 
44 //#define SCIP_DEBUG
45 
46 #include <cassert>
47 #include <cstddef>
48 #include <cstdio>
49 #include <cstring>
50 #include <algorithm>
51 #include <deque>
52 #include <iomanip>
53 #include <sstream>
54 #include <utility>
55 #include <regex>
56 #include <vector>
57 #include <list>
58 
59 #include <scip/clock.h>
60 #include <scip/pub_cons.h>
61 #include <scip/pub_misc.h>
62 #include <scip/type_paramset.h>
63 #include <scip/scipdefplugins.h>
64 
65 #include "class_partialdecomp.h"
66 #include "class_detprobdata.h"
67 #include "miscvisualization.h"
68 #include "wrapper_partialdecomp.h"
69 #include "scip_misc.h"
70 #include "relax_gcg.h"
71 #include "decomp.h"
72 #include "cons_decomp.hpp"
73 #include "struct_consclassifier.h"
74 #include "struct_varclassifier.h"
75 #include "struct_decomp.h"
76 
77 /* constraint handler properties */
78 #define CONSHDLR_NAME "decomp" /**< name of constraint handler */
79 #define CONSHDLR_DESC "constraint handler for structure detection" /**< description of constraint handler */
80 #define CONSHDLR_ENFOPRIORITY 0 /**< priority of the constraint handler for constraint enforcing */
81 #define CONSHDLR_CHECKPRIORITY 0 /**< priority of the constraint handler for checking feasibility */
82 #define CONSHDLR_EAGERFREQ -1 /**< frequency for using all instead of only the useful constraints in separation,
83  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
84 #define CONSHDLR_NEEDSCONS FALSE /**< should the constraint handler be skipped, if no constraints are available? */
85 
86 #define DEFAULT_ENABLED TRUE /**< indicates whether detection is enabled */
87 
88 #define DEFAULT_DUALVALRANDOMMETHOD 1 /**< default value for method to dual initialization of dual values for strong decomposition: 1) naive, 2) expected equal, 3) expected overestimation */
89 #define DEFAULT_COEFFACTORORIGVSRANDOM 0.5 /**< default value for convex coefficient for orig dual val (1-this coef is factor for random dual value) */
90 
91 #define DEFAULT_BLOCKNUMBERCANDSMEDIANVARSPERCONS FALSE /**< should for block number candidates calculation the medianvarspercons calculation be considered */
92 
93 #define DEFAULT_MAXDETECTIONROUNDS 1 /**< maximal number of detection rounds */
94 #define DEFAULT_MAXDETECTIONTIME 600 /**< maximum detection time in seconds */
95 #define DEFAULT_POSTPROCESS TRUE /**< indicates whether to postprocess full decompositions */
96 #define DEFAULT_MAXNCLASSESLARGEPROBS 5 /**< maximum number of classes allowed for large (nvars+nconss > 50000) MIPs for detectors, partitions with more classes are reduced to the maximum number of classes */
97 #define DEFAULT_MAXNCLASSES 9 /**< maximum number of classes allowed for detectors, partitions with more classes are reduced to the maximum number of classes */
98 #define DEFAULT_MAXNCLASSESFORNBLOCKCANDIDATES 18 /**< maximum number of classes a partition can have to be used for voting nblockcandidates */
99 #define DEFAULT_ENABLEORIGDETECTION TRUE /**< indicates whether to start detection for the original problem */
100 
101 /* classifier */
102 
103 #define DEFAULT_ALLOWPARTITIONDUPLICATES FALSE /**< if false each new (conss- and vars-) partitions is checked for being a duplicate of an existing one, if so it is not added and NBOT statistically recognized*/
104 #define DEFAULT_CLASSIFY TRUE /**< indicates whether classification is enabled */
105 #define DEFAULT_ENABLEORIGCLASSIFICATION TRUE /**< indicates whether to start detection for the original problem */
106 
107 #define DEFAULT_AGGREGATIONLIMITNCONSSPERBLOCK 300 /**< if this limit on the number of constraints of a block is exceeded the aggregation information for this block is not calculated */
108 #define DEFAULT_AGGREGATIONLIMITNVARSPERBLOCK 300 /**< if this limit on the number of variables of a block is exceeded the aggregation information for this block is not calculated */
109 
110 #define DEFAULT_BENDERSONLYCONTSUBPR FALSE /**< indicates whether only decomposition with only continuous variables in the subproblems should be searched*/
111 #define DEFAULT_BENDERSONLYBINMASTER FALSE /**< indicates whether only decomposition with only binary variables in the master should be searched */
112 
113 #define DEFAULT_LEVENSHTEIN_MAXMATRIXHALFPERIMETER 10000 /**< deactivate levenshtein constraint classifier if nrows + ncols exceeds this value for emphasis default */
114 #define AGGRESSIVE_LEVENSHTEIN_MAXMATRIXHALFPERIMETER 80000 /**< deactivate levenshtein constraint classifier if nrows + ncols exceeds this value for emphasis aggressive */
115 #define FAST_LEVENSHTEIN_MAXMATRIXHALFPERIMETER 2000 /**< deactivate levenshtein constraint classifier if nrows + ncols exceeds this value for emphasis fast */
116 
117 #define DEFAULT_DETECTBENDERS FALSE /**< indicates whether benders detection mode is enabled */
118 
119 #define DEFAULT_RANDPARTIALDEC 23 /**< initial random partialdec */
120 
121 /* scores */
122 #define DEFAULT_STRONGTIMELIMIT 30. /**< timelimit for strong decompotition score calculation per partialdec */
123 
124 #define DEFAULT_SCORECOEF_FASTBENEFICIAL 1. /**< coefficient for fast & beneficial in strong decomposition score computation */
125 #define DEFAULT_SCORECOEF_MEDIUMBENEFICIAL 0.75 /**< coefficient for not fast but beneficial in strong decomposition score computation */
126 #define DEFAULT_SCORECOEF_FASTNOTBENEFICIAL 0.3 /**< coefficient for fast & not beneficial in strong decomposition score computation */
127 #define DEFAULT_SCORECOEF_MEDIUMNOTBENEFICIAL 0.1 /**< coefficient for not & not beneficial in strong decomposition score computation */
128 
129 /*
130  * Data structures
131  */
132 
133 /** constraint handler data */
135 {
136  SCIP_Bool enabled; /**< indicates whether detection is enabled */
137 
138  std::vector<PARTIALDECOMP*>* partialdecs; /**< list of all existing partialdecs */
139  std::unordered_map<int, PARTIALDECOMP*>* partialdecsbyid; /**< list of all existing partialdecs */
140  int partialdeccounter; /**< counts the number of created partialdecs, used to determine next partialdec id
141  (NOT amount of currently existing partialdecs as partialdecs might be deleted) */
142  DEC_DECOMP** decomps; /**< array of decomposition structures */
143  int ndecomps; /**< number of decomposition structures (size of decomps)*/
144 
145  DEC_CONSCLASSIFIER** consclassifiers; /**< array of cons classifiers */
146  int nconsclassifiers; /**< number of cons classifiers */
147  int* consclassifierpriorities; /**< priorities of the cons classifiers */
148  DEC_VARCLASSIFIER** varclassifiers; /**< array of var classifiers */
149  int nvarclassifiers; /**< number of var classifiers */
150  int* varclassifierpriorities; /**< priorities of the var classifiers */
151 
152  DEC_DETECTOR** detectors; /**< array of structure detectors */
153  int* priorities; /**< priorities of the detectors */
154  int ndetectors; /**< number of detectors */
155  DEC_DETECTOR** propagatingdetectors; /**< array of detectors able to propagate partial decompositions */
156  int npropagatingdetectors; /**< number of detectors able to propagate partial decompositions (size of propagatingdetectors) */
157  DEC_DETECTOR** finishingdetectors; /**< array of detectors able to finish partial decompositions */
158  int nfinishingdetectors; /**< number of detectors able to finish partial decompositions (size of finishingdetectors) */
159  DEC_DETECTOR** postprocessingdetectors; /**< array of detectors able to postprocess decompositions */
160  int npostprocessingdetectors; /**< number of detectors able to postprocess decompositions (size of postprocessingdetectors) */
161 
162  SCIP_CLOCK* detectorclock; /**< clock to measure detection time */
163  SCIP_CLOCK* completedetectionclock; /**< clock to measure detection time */
164  SCIP_Bool hasrunoriginal; /**< flag to indicate whether we have already detected (original problem) */
165  SCIP_Bool hasrun; /**< flag to indicate whether we have already detected */
166  int maxndetectionrounds; /**< maximum number of detection loop rounds */
167  int maxdetectiontime; /**< maximum detection time [sec] */
168  SCIP_Bool postprocess; /**< indicates whether to postprocess full decompositions */
169  int strongdetectiondualvalrandommethod; /**< method to dual initialization of dual values for strong decomposition: 1) naive, 2) expected equal, 3) expected overestimation */
170  SCIP_Real coeffactororigvsrandom; /**< convex coefficient for orig dual val (1-this coef is factor for random dual value) */
171  SCIP_Bool blocknumbercandsmedianvarspercons; /**< should for block number candidates calculation the medianvarspercons calculation be considered */
172  int maxnclassesfornblockcandidates; /**< maximum number of classes a partition can have to be used for voting nblockcandidates */
173  int maxnclassesperpartition; /**< maximum number of classes allowed for detectors, partition with more classes are reduced to the maximum number of classes */
174  int maxnclassesperpartitionforlargeprobs; /**< maximum number of classes allowed for large (nvars+nconss > 50000) MIPs for detectors, partition with more classes are reduced to the maximum number of classes */
175  int weightinggpresolvedoriginaldecomps; /**< weighing method for comparing presolved and original decompositions (see corresponding enum) */
176  int aggregationlimitnconssperblock; /**< if this limit on the number of constraints of a block is exceeded the aggregation information for this block is not calculated */
177  int aggregationlimitnvarsperblock; /**< if this limit on the number of variables of a block is exceeded the aggregation information for this block is not calculated */
178 
179  SCIP_Bool classify; /**< indicates whether classification should take place */
180  SCIP_Bool allowpartitionduplicates; /**< indicates whether partition duplicates are allowed (for statistical reasons) */
181  SCIP_Bool enableorigdetection; /**< indicates whether to start detection for the original problem */
182  SCIP_Bool enableorigclassification; /**< indicates whether to start constraint classification for the original problem */
183 
184  SCIP_Bool bendersonlycontsubpr; /**< indicates whether only decomposition with only continuous variables in the subproblems should be searched*/
185  SCIP_Bool bendersonlybinmaster; /**< indicates whether only decomposition with only binary variables in the master should be searched */
186  SCIP_Bool detectbenders; /**< indicates wethher or not benders detection mode is enabled */
187 
188  int ncallscreatedecomp; /**< debugging method for counting the number of calls of created decompositions */
189 
190  gcg::DETPROBDATA* detprobdatapres; /**< detprobdata containing data for the presolved transformed problem */
191  gcg::DETPROBDATA* detprobdataorig; /**< detprobdata containing data for the original problem */
192 
193  /* score data */
194  int currscoretype; /**< indicates which score should be used for comparing (partial) decompositions
195  0: max white,
196  1: border area,
197  2: classic,
198  3: max foreseeing white,
199  4: ppc max forseeing white,
200  5: max foreseeing white with aggregation info,
201  6: ppc max forseeing white with aggregation info,
202  7: experimental benders score,
203  8: strong decomposition score */
204  SCIP_Real scoretotaltime; /**< total score calculation time */
205  std::vector<SCIP_Real>* dualvalsrandom; /**< vector of random dual values, used for strong detection scores */
206  std::vector<SCIP_Real>* dualvalsoptimaloriglp; /**< vector of dual values of the optimal solved original lp, used for strong detection scores */
207  SCIP_Bool dualvalsoptimaloriglpcalculated; /**< are the optimal dual values from original lp calulated? used for strong detection scores */
208  SCIP_Bool dualvalsrandomset; /**< are the random dual values set, used for strong detection scores */
209  SCIP_Real strongtimelimit; /**< timelimit for calculating strong decomposition score for one partialdec */
210 
211  PARTIALDECOMP* partialdectowrite; /**< pointer enabling the use of SCIPs writeProb/writeTransProb function for writing partial decompositions*/
212 
213  SCIP_Bool consnamesalreadyrepaired; /**< stores whether or not */
214  std::vector<int>* userblocknrcandidates; /**< vector to store block number candidates that were given by user */
215  SCIP_Bool freeorig; /**< help bool to notify a nonfinal free transform (needed if presolving is revoked, e.g. if orig decomposition is used, and transformation is not successful) */
216 };
217 
218 
219 // TODO ref add comments! this is used in strong decomposition score calculation in @see shuffleDualvalsRandom()
221 {
225 };
227 
228 
229 /** parameter how to modify scores when comparing decompositions for original and presolved problem
230  * (which might differ in size) */
232  NO_MODIF = 0, /**< no modification */
233  FRACTION_OF_NNONZEROS, /**< scores are weighted according to ratio of number nonzeros, the more the worse */
234  FRACTION_OF_NROWS, /**< scores are weighted according to ratio of number rows, the more the worse */
235  FAVOUR_PRESOLVED /**< decompositions for presolved problems are always favoured over decompositions of original problem */
236 };
237 
238 
239 /** locally used macro to help with sorting, comparator */
240 struct sort_pred {
241  bool operator()(const std::pair<PARTIALDECOMP*, SCIP_Real> &left, const std::pair<PARTIALDECOMP*, SCIP_Real> &right) {
242  return left.second > right.second;
243  }
244 };
245 
246 
247 //////////////////////////////////////////////////
248 //////////////////////////////////////////////////
249 //////////////////////////////////////////////////
250 
251 /*
252  * Local methods
253  */
254 
255 
256 /**
257  * @brief local function to get the conshdlr data of the current conshdlr
258  *
259  * @returns the conshdlrdata iff it exists, else NULL
260  * @note returns NULL iff conshdlr or its data does not exist
261  */
262 static
263 SCIP_CONSHDLRDATA* getConshdlrdata(
264  SCIP* scip /**< SCIP data structure */
265  )
266 {
267  /* get current conshdlr, identified by the name define */
268  assert(scip != NULL);
269  SCIP_CONSHDLR* conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
270 
271  /* check if conshdlr was found */
272  if( conshdlr == NULL )
273  {
274  SCIPerrorMessage("Decomp constraint handler is not included, cannot get its data!\n");
275  return NULL;
276  }
277 
278  /* this will result in NULL if none is stored */
279  return SCIPconshdlrGetData(conshdlr);
280 }
281 
282 
283 /** @brief local method to handle store a partialdec in the correct detprobdata
284  *
285  * @returns SCIP status */
286 static
287 SCIP_RETCODE addPartialdec(
288  SCIP* scip, /**< SCIP data structure */
289  PARTIALDECOMP* partialdec /**< partialdec pointer */
290  )
291 {
292  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
293  bool success;
294 
295  if( partialdec->isComplete() )
296  {
297  if( partialdec->isAssignedToOrigProb() )
298  success = conshdlrdata->detprobdataorig->addPartialdecToFinished(partialdec);
299  else
300  success = conshdlrdata->detprobdatapres->addPartialdecToFinished(partialdec);
301  }
302  else
303  {
304  if( partialdec->isAssignedToOrigProb() )
305  success = conshdlrdata->detprobdataorig->addPartialdecToOpen(partialdec);
306  else
307  success = conshdlrdata->detprobdatapres->addPartialdecToOpen(partialdec);
308  }
309 
310  if( !success )
311  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "Decomposition to add is already known to gcg!\n");
312 
313  return SCIP_OKAY;
314 }
315 
316 
318  SCIP* scip, /**< SCIP data structure */
319  int partialdecid /**< partialdec id */
320  )
321 {
322  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
323 
324  auto itr = conshdlrdata->partialdecsbyid->find(partialdecid);
325  if( itr != conshdlrdata->partialdecsbyid->end() )
326  {
327  return itr->second;
328  }
329 
330  return NULL;
331 }
332 
333 
334 /** @brief translates a vector of PARTIALDECOMP pointers into an array of their ids
335  * @returns SCIP return code
336  */
337 static
339  std::vector<PARTIALDECOMP*>& partialdecs, /**< vector of partialdecs (input) */
340  int** idlist, /**< array of ids (output) */
341  int* listlength /**< length of id array (output) */
342  )
343 {
344  *listlength = (int) partialdecs.size();
345  int i;
346  for(i = 0; i < (int) partialdecs.size(); i++)
347  {
348  (*idlist)[i] = partialdecs[i]->getID();
349  }
350 
351  return SCIP_OKAY;
352 }
353 
354 
355 /** @brief gets all selected partialdecs
356  * @returns vector of all selected partialdecs */
357 static
358 std::vector<PARTIALDECOMP*> getSelectedPartialdecs(
359  SCIP* scip, /**< SCIP data structure */
360  std::vector<PARTIALDECOMP*>& selectedpartialdecs /**< vector of partialdecs (input) */
361  )
362 {
363  /* get all partialdecs */
364  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
365 
366  /* look for selected ones and add them */
367  for(auto partialdec : *conshdlrdata->partialdecs)
368  {
369  if(partialdec->isSelected())
370  {
371  selectedpartialdecs.push_back(partialdec);
372  }
373  }
374  return selectedpartialdecs;
375 }
376 
377 
378 /** @brief gets vector of all finished partialdecs
379  */
380 static
382  SCIP* scip, /**< SCIP data structure */
383  std::vector<PARTIALDECOMP*>& finishedpartialdecs /**< will contain finished partialdecs */
384  )
385 {
386  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
387 
388  for(auto partialdec : *conshdlrdata->partialdecs)
389  {
390  if(partialdec->isComplete())
391  finishedpartialdecs.push_back(partialdec);
392  }
393 }
394 
395 
396 /**
397  * method to unselect all decompositions, called in consexit, and when the partialdeclist is updated
398  * (especially if new (partial ones) are added )
399  *
400  *@returns SCIP return code
401  */
402 static
404  SCIP* scip /**< SCIP data structure */
405  )
406 {
407  /* get all partialdecs */
408  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
409 
410  /* set each partialdec to not selected */
411  for(auto partialdec : *conshdlrdata->partialdecs)
412  {
413  partialdec->setSelected(false);
414  }
415 
416  return SCIP_OKAY;
417 }
418 
419 
420 /** @brief initializes a new detection data structure
421  *
422  * @returns new detection data structure
423  */
424 static
426  gcg::DETPROBDATA *detprobdata, /**< detprobdata to point to */
427  PARTIALDECOMP* partialdec /**< partialdec to pass to detector */
428  )
429 {
430  PARTIALDEC_DETECTION_DATA *partialdecdetdata;
431  partialdecdetdata = new PARTIALDEC_DETECTION_DATA();
432  partialdecdetdata->detprobdata = detprobdata;
433  partialdecdetdata->nnewpartialdecs = 0;
434  partialdecdetdata->workonpartialdec = new gcg::PARTIALDECOMP( partialdec );
435  return partialdecdetdata;
436 }
437 
438 
439 /**
440  * @brief resets/creates the detprobdata for the given problem
441  * @returns scip return code
442  */
443 static
444 SCIP_RETCODE resetDetprobdata(
445  SCIP* scip, /**< SCIP data structure */
446  SCIP_Bool original /**< whether to do this for the original problem */
447 )
448 {
449  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
450  assert(conshdlrdata != NULL);
451 
452  if( SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED )
453  SCIP_CALL( SCIPtransformProb(scip) );
454 
455  // for the orig detprobdata, reset only the current partialdecs as the rest will stay the same in any case
456  if(original)
457  {
458  if( conshdlrdata->detprobdataorig == NULL )
459  conshdlrdata->detprobdataorig = new gcg::DETPROBDATA(scip, original);
460  conshdlrdata->detprobdataorig->clearCurrentPartialdecs();
461  }
462  // for the presolved problem, the detprobdata is deleted and a new one is created
463  else
464  {
465  assert(SCIPgetStage(scip) >= SCIP_STAGE_PRESOLVED);
466  if( conshdlrdata->detprobdatapres != NULL )
467  delete conshdlrdata->detprobdatapres;
468  conshdlrdata->detprobdatapres = new gcg::DETPROBDATA(scip, original);
469  }
470 
471  return SCIP_OKAY;
472 }
473 
474 
475 /** @brief delets the detection data structure
476  *
477  * frees all relevant data within the construct before deleting the main structure
478  * @returns SCIP return code
479  */
480 static
482  SCIP* scip, /**< SCIP data structure */
483  PARTIALDEC_DETECTION_DATA* data /**< data to delete */
484  )
485 {
486  SCIPfreeMemoryArrayNull( scip, &(data->newpartialdecs) );
487  delete data->workonpartialdec;
488  data->newpartialdecs = NULL;
489  data->nnewpartialdecs = 0;
490  delete data;
491 
492  return SCIP_OKAY;
493 }
494 
495 
496 /** @brief constructs partialdecs using the registered detectors
497  *
498  * Takes the current partialdecs in the detprobdata as root,
499  * propagates, finishes and postprocesses in rounds.
500  *
501  * @return user has to free partialdecs */
502 static
503 SCIP_Retcode detect(
504  SCIP* scip, /**< SCIP data structure */
505  gcg::DETPROBDATA *detprobdata /**< detprobdata for problem the detection should be performed on */
506  )
507 {
508  SCIP_RESULT result = SCIP_DIDNOTFIND;
509  int maxndetectionrounds;
510  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
511 
512  SCIP_CALL_ABORT( SCIPgetIntParam( scip, "detection/maxrounds", &maxndetectionrounds ) );
513 
514  // Fill partialdecs vector into deque
515  std::deque<PARTIALDECOMP*> partialdecqueue;
516  for( auto partialdecomp: detprobdata->getOpenPartialdecs() )
517  {
518  partialdecqueue.push_back(partialdecomp);
519  }
520 
521  // TODO while not strg-c
522  while (!partialdecqueue.empty() and (
523  conshdlrdata->maxdetectiontime == 0 or
524  SCIPgetClockTime(scip, conshdlrdata->detectorclock) < conshdlrdata->maxdetectiontime
525  ))
526  {
527  gcg::PARTIALDECOMP *partialdec = partialdecqueue.front();
528  partialdecqueue.pop_front();
529 
530  // Check if max round reached for this partialdec
531  if((int) partialdec->getDetectorchain().size() >= maxndetectionrounds)
532  {
533  continue;
534  }
535 
536  // TODO (priority for "promising pairs")
537  for (int j = 0; j < conshdlrdata->npropagatingdetectors; j++)
538  {
539  DEC_DETECTOR* detector;
540  detector = conshdlrdata->propagatingdetectors[j];
541 
542  if( !detector->enabled )
543  {
544  continue;
545  }
546 
547  /* skip detector if it should not be recalled */
548  if( !detector->usefulRecall && partialdec->isPropagatedBy( detector ) )
549  continue;
550 
551  PARTIALDEC_DETECTION_DATA* partialdecdetdata = createPartialdecDetectionData(detprobdata, partialdec);
552 
553  // PROPAGATE
554  SCIP_CALL( detector->propagatePartialdec(scip, detector, partialdecdetdata, &result) );
555  detector->dectime += partialdecdetdata->detectiontime;
556 
557  // Handle found Partialdecs
558  for( int k = 0; k < partialdecdetdata->nnewpartialdecs; ++ k )
559  {
560  PARTIALDECOMP* newpartialdec = partialdecdetdata->newpartialdecs[k];
561  newpartialdec->setDetectorPropagated(detector);
562  newpartialdec->prepare();
563  newpartialdec->addDecChangesFromAncestor(partialdec);
564 
565  // If is already complete => store for POSTPROCESSING
566  if( newpartialdec->isComplete() )
567  {
568  if( !detprobdata->addPartialdecToFinished(newpartialdec) )
569  {
570  delete newpartialdec;
571  newpartialdec = NULL;
572  }
573  }
574  else
575  {
576  // Store for further PROPAGATION
577  if( detprobdata->addPartialdecToOpen(newpartialdec) )
578  partialdecqueue.push_back(newpartialdec);
579  else
580  {
581  delete newpartialdec;
582  newpartialdec = NULL;
583  }
584  }
585  if( newpartialdec != NULL )
586  detprobdata->addPartialdecToAncestor(newpartialdec);
587  }
588  deletePartialdecDetectionData(scip, partialdecdetdata);
589  }
590  detprobdata->addPartialdecToAncestor(partialdec);
591  }
592 
593  // FINISH partialdecs
594  for( auto partialdecomp: detprobdata->getOpenPartialdecs() )
595  {
596  for(int l = 0; l < conshdlrdata->nfinishingdetectors; l++)
597  {
598  DEC_DETECTOR *finishingdetector = conshdlrdata->finishingdetectors[l];
599  if( !finishingdetector->enabledFinishing )
600  {
601  continue;
602  }
603 
604  PARTIALDEC_DETECTION_DATA *finishingdata = createPartialdecDetectionData(detprobdata, partialdecomp);
605  SCIP_CALL( finishingdetector->finishPartialdec(scip, finishingdetector, finishingdata, &result) );
606  finishingdetector->dectime += finishingdata->detectiontime;
607 
608  for(int finished = 0; finished < finishingdata->nnewpartialdecs; ++finished)
609  {
610  PARTIALDECOMP* newpartialdec = finishingdata->newpartialdecs[finished];
611  newpartialdec->deleteEmptyBlocks(false);
612  newpartialdec->setDetectorFinished(finishingdetector);
613 
614  newpartialdec->prepare();
615  newpartialdec->addDecChangesFromAncestor(partialdecomp);
616  if( !detprobdata->addPartialdecToFinished(newpartialdec) )
617  delete newpartialdec;
618  }
619  deletePartialdecDetectionData(scip, finishingdata);
620  }
621  }
622 
623  // POSTPROCESSING of finished partialdecs
624  if(conshdlrdata->postprocess)
625  {
626  SCIP_CLOCK* postprocessingclock;
627  SCIPcreateClock( scip, & postprocessingclock );
628  SCIP_CALL_ABORT( SCIPstartClock( scip, postprocessingclock ) );
629  auto& finishedpartialdecs = detprobdata->getFinishedPartialdecs();
630  int numpostprocessed = 0;
631  int nfinished = finishedpartialdecs.size();
632  for( int i = 0; i < nfinished; ++i )
633  {
634  auto postpartialdec = finishedpartialdecs[i];
635 
636  // Check if postprocessing is enabled globally
637  for( int d = 0; d < conshdlrdata->npostprocessingdetectors; ++d )
638  {
639  DEC_DETECTOR* postdetector = conshdlrdata->postprocessingdetectors[d];
640  /* if the postprocessing of the detector is not enabled go on with the next detector */
641  if( !postdetector->enabledPostprocessing )
642  {
643  continue;
644  }
645 
646  PARTIALDEC_DETECTION_DATA* partialdecdetdata = createPartialdecDetectionData(detprobdata, postpartialdec);
647 
648  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "call finisher for detector %s \n", DECdetectorGetName( postdetector ) );
649 
650  // POSTPROCESS
651  SCIP_CALL( postdetector->postprocessPartialdec( scip, postdetector, partialdecdetdata, &result ) );
652  postdetector->dectime += partialdecdetdata->detectiontime;
653 
654  for( int finished = 0; finished < partialdecdetdata->nnewpartialdecs; ++finished )
655  {
656  PARTIALDECOMP* newpartialdec = partialdecdetdata->newpartialdecs[finished];
657 
658  newpartialdec->setDetectorPropagated(postdetector);
659  newpartialdec->setFinishedByFinisher(true );
660  newpartialdec->prepare();
661  newpartialdec->addDecChangesFromAncestor(postpartialdec);
662 
663  if( !detprobdata->addPartialdecToFinished(newpartialdec) )
664  delete newpartialdec;
665  else
666  numpostprocessed += 1;
667 
668  }
669  deletePartialdecDetectionData(scip, partialdecdetdata);
670  }
671  }
672 
673  SCIP_CALL_ABORT( SCIPstopClock( scip, postprocessingclock ) );
674 
675  detprobdata->postprocessingtime += SCIPgetClockTime( scip, postprocessingclock );
676  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "POSTPROCESSING of decompositions. Added %d new decomps. \n", numpostprocessed);
677  SCIP_CALL_ABORT( SCIPfreeClock( scip, & postprocessingclock ) );
678  }
679  else
680  {
681  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "POSTPROCESSING disabled\n");
682  } // end for postprocessing finished partialdecs
683 
684  // STATS
685  // count the successful refinement calls for each detector
686 
687  // finished partialdecs
688  for( PARTIALDECOMP* partialdec: detprobdata->getFinishedPartialdecs() )
689  {
690  assert( partialdec->checkConsistency() );
691  assert( partialdec->getNOpenconss() == 0 );
692  assert( partialdec->getNOpenvars() == 0 );
693 
694  for( int d = 0; d < conshdlrdata->ndetectors; ++ d )
695  {
696  if( partialdec->isPropagatedBy(conshdlrdata->detectors[d]) )
697  {
698  conshdlrdata->detectors[d]->ndecomps += 1;
699  conshdlrdata->detectors[d]->ncompletedecomps += 1;
700  }
701  }
702  }
703 
704  // open partialdecs
705  for( PARTIALDECOMP* partialdec: detprobdata->getOpenPartialdecs() )
706  {
707  assert( partialdec->checkConsistency() );
708 
709  for( int d = 0; d < conshdlrdata->ndetectors; ++ d )
710  {
711  if( partialdec->isPropagatedBy(conshdlrdata->detectors[d]) )
712  conshdlrdata->detectors[d]->ndecomps += 1;
713  }
714  }
715 
716  /* preliminary output detector stats */
717  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Found %d finished decompositions.\n",
718  detprobdata->getNFinishedPartialdecs());
719  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Measured running time per detector:\n");
720 
721  for( int i = 0; i < conshdlrdata->ndetectors; ++ i )
722  {
723  if( conshdlrdata->detectors[i]->ncompletedecomps > 0 )
724  {
725  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL,
726  "Detector %-25.25s worked on %8d finished decompositions and took a total time of %10.3f\n",
727  DECdetectorGetName( conshdlrdata->detectors[i]), conshdlrdata->detectors[i]->ncompletedecomps,
728  conshdlrdata->detectors[i]->dectime);
729  }
730  }
731 
732  return SCIP_OKAY;
733 }
734 
735 
736 /** @brief initialization method of constraint handler (called after problem was transformed) */
737 static
738 SCIP_DECL_CONSINIT(consInitDecomp)
739 { /*lint --e{715}*/
740  SCIP_CONSHDLRDATA* conshdlrdata;
741  int i;
742  conshdlrdata = SCIPconshdlrGetData(conshdlr);
743  assert(conshdlrdata != NULL);
744 
745  /* the detection hast not run yet */
746  conshdlrdata->hasrun = FALSE;
747  conshdlrdata->hasrunoriginal = FALSE;
748 
749  for( i = 0; i < conshdlrdata->ndetectors; ++i )
750  {
751  DEC_DETECTOR *detector;
752  detector = conshdlrdata->detectors[i];
753  assert(detector != NULL);
754 
755  /* add the detector time of each detector to 0 */
756  detector->dectime = 0.;
757  /* init the detectors */
758  if( detector->initDetector != NULL )
759  {
760  SCIPdebugMessage("Calling initDetector of %s\n", detector->name);
761  SCIP_CALL( (*detector->initDetector)(scip, detector) );
762  }
763  }
764 
765  return SCIP_OKAY;
766 }
767 
768 
769 /** @brief deinitialization method of constraint handler (called before transformed problem is freed) */
770 static
771 SCIP_DECL_CONSEXIT(consExitDecomp)
772 { /*lint --e{715}*/
773  SCIP_CONSHDLRDATA* conshdlrdata;
774  int i;
775 
776  assert(conshdlr != NULL);
777  assert(scip != NULL);
778 
779  conshdlrdata = SCIPconshdlrGetData(conshdlr);
780  assert(conshdlrdata != NULL);
781 
782  /* remove all decomps */
783  if( conshdlrdata->ndecomps > 0 && conshdlrdata->decomps != NULL )
784  {
785  for( int dec = 0; dec < conshdlrdata->ndecomps; ++dec )
786  {
787  DECdecompFree(scip, &conshdlrdata->decomps[conshdlrdata->ndecomps - dec - 1]);
788  }
789 
790  /* remove decomp array structure */
791  SCIPfreeBlockMemoryArray(scip, &conshdlrdata->decomps, conshdlrdata->ndecomps);
792  conshdlrdata->ndecomps = 0;
793  conshdlrdata->decomps = NULL;
794  }
795 
796  /* reset the run */
797  conshdlrdata->hasrun = FALSE;
798 
799  /* release the detectors' data sets */
800  for( i = 0; i < conshdlrdata->ndetectors; ++i )
801  {
802  DEC_DETECTOR *detector;
803  detector = conshdlrdata->detectors[i];
804  assert(detector != NULL);
805 
806  if( detector->exitDetector != NULL )
807  {
808  SCIPdebugMessage("Calling exitDetector of %s\n", detector->name);
809  SCIP_CALL( (*detector->exitDetector)(scip, detector) );
810  }
811  }
812 
814 
815  /* remove selection of partialdecs */
817 
818  return SCIP_OKAY;
819 }
820 
821 
822 /** @brief destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
823 static
824 SCIP_DECL_CONSFREE(consFreeDecomp)
825 {
826  SCIP_CONSHDLRDATA* conshdlrdata;
827  int i;
828  conshdlrdata = SCIPconshdlrGetData(conshdlr);
829  assert(conshdlrdata != NULL);
830 
831  /* free detection time clocks */
832  SCIP_CALL( SCIPfreeClock(scip, &conshdlrdata->detectorclock) );
833  SCIP_CALL( SCIPfreeClock(scip, &conshdlrdata->completedetectionclock) );
834 
835  /* free all detectors */
836  for( i = 0; i < conshdlrdata->ndetectors; ++i )
837  {
838  DEC_DETECTOR *detector;
839  detector = conshdlrdata->detectors[i];
840  assert(detector != NULL);
841 
842  if( detector->freeDetector != NULL )
843  {
844  SCIPdebugMessage("Calling freeDetector of %s\n", detector->name);
845  SCIP_CALL( (*detector->freeDetector)(scip, detector) );
846  }
847 
848  BMSfreeMemoryArray(&detector->name);
849  BMSfreeMemoryArray(&detector->description);
850 
851  SCIPfreeBlockMemory(scip, &detector);
852  }
853 
854  /* free all consclassifiers */
855  for( i = 0; i < conshdlrdata->nconsclassifiers; ++i )
856  {
857  DEC_CONSCLASSIFIER *consclassifier = conshdlrdata->consclassifiers[i];
858  assert(consclassifier != NULL);
859 
860  if( consclassifier->freeClassifier != NULL )
861  {
862  SCIPdebugMessage("Calling freeClassifier of consclassifier %s\n", consclassifier->name);
863  SCIP_CALL( (*consclassifier->freeClassifier)(scip, consclassifier) );
864  }
865  SCIPfreeBlockMemory(scip, &conshdlrdata->consclassifiers[i]);
866  }
867 
868  /* free all varclassifiers */
869  for( i = 0; i < conshdlrdata->nvarclassifiers; ++i )
870  {
871  DEC_VARCLASSIFIER *varclassifier = conshdlrdata->varclassifiers[i];
872  assert(varclassifier != NULL);
873 
874  if( varclassifier->freeClassifier != NULL )
875  {
876  SCIPdebugMessage("Calling freeClassifier of varclassifier %s\n", varclassifier->name);
877  SCIP_CALL( (*varclassifier->freeClassifier)(scip, varclassifier) );
878  }
879  SCIPfreeBlockMemory(scip, &conshdlrdata->varclassifiers[i]);
880  }
881 
882  /* remove all remaining data */
883  SCIPfreeMemoryArray(scip, &conshdlrdata->priorities);
884  SCIPfreeMemoryArray(scip, &conshdlrdata->detectors);
885  SCIPfreeMemoryArray(scip, &conshdlrdata->propagatingdetectors);
886  SCIPfreeMemoryArray(scip, &conshdlrdata->finishingdetectors);
887  SCIPfreeMemoryArray(scip, &conshdlrdata->postprocessingdetectors);
888  SCIPfreeMemoryArray(scip, &conshdlrdata->consclassifiers);
889  SCIPfreeMemoryArray(scip, &conshdlrdata->consclassifierpriorities);
890  SCIPfreeMemoryArray(scip, &conshdlrdata->varclassifiers);
891  SCIPfreeMemoryArray(scip, &conshdlrdata->varclassifierpriorities);
892 
893  delete conshdlrdata->userblocknrcandidates;
894  delete conshdlrdata->partialdecs;
895  delete conshdlrdata->partialdecsbyid;
896  delete conshdlrdata->dualvalsoptimaloriglp;
897  delete conshdlrdata->dualvalsrandom;
898 
899  /* remove the data structure of the conshdlr */
900  SCIPfreeMemory(scip, &conshdlrdata);
901 
902  return SCIP_OKAY;
903 }
904 
905 
906 /** constraint enforcing method of constraint handler for LP solutions */
907 static
908 SCIP_DECL_CONSENFORELAX(consEnforeDecomp)
909 { /*lint --e{715}*/
910  *result = SCIP_FEASIBLE;
911  return SCIP_OKAY;
912 }
913 
914 
915 /** constraint enforcing method of constraint handler for LP solutions */
916 static
917 SCIP_DECL_CONSENFOLP(consEnfolpDecomp)
918 { /*lint --e{715}*/
919  *result = SCIP_FEASIBLE;
920  return SCIP_OKAY;
921 }
922 
923 
924 /** constraint enforcing method of constraint handler for pseudo solutions */
925 static
926 SCIP_DECL_CONSENFOPS(consEnfopsDecomp)
927 { /*lint --e{715}*/
928  *result = SCIP_FEASIBLE;
929  return SCIP_OKAY;
930 }
931 
932 
933 /** feasibility check method of constraint handler for integral solutions */
934 static
935 SCIP_DECL_CONSCHECK(consCheckDecomp)
936 {
937  /*lint --e{715}*/
938  *result = SCIP_FEASIBLE;
939  return SCIP_OKAY;
940 }
941 
942 
943 /** variable rounding lock method of constraint handler */
944 static
945 SCIP_DECL_CONSLOCK(consLockDecomp)
946 { /*lint --e{715}*/
947  return SCIP_OKAY;
948 }
949 
950 
951 /**
952  * @brief finds a non duplicate constraint name of the form c_{a} with minimal natural number {a}
953  * @return id of constraint
954  */
955 static
957  SCIP* scip, /**< SCIP data structure */
958  int startcount, /**< natural number, lowest candidate number to test */
959  char* consname, /**< char pointer to store the new non-duplicate name */
960  int namelength /**< max length of the name */
961  )
962 {
963  int candidatenumber;
964 
965  candidatenumber = startcount;
966 
967  /* terminates since there are only finitely many constraints and i (for c_i) increases every iteration */
968  while( TRUE )
969  {
970  /* create new name candidate */
971  char candidatename[SCIP_MAXSTRLEN] = "c_";
972  char number[20];
973  sprintf(number, "%d", candidatenumber );
974  strcat(candidatename, number );
975 
976  /* check candidate, if it is not free increase counter for candidate number */
977  if ( SCIPfindCons( scip, candidatename ) == NULL )
978  {
979  strncpy(consname, candidatename, namelength - 1);
980  return candidatenumber;
981  }
982  else
983  ++candidatenumber;
984  }
985  return -1;
986 }
987 
988 
989 /** @brief creates a partialdec for a given decomposition
990  *
991  * @returns SCIP return code
992  * */
993 static
995  SCIP* scip, /**< SCIP data structure */
996  DEC_DECOMP* decomp, /**< decomposition the partialdec is created for */
997  PARTIALDECOMP** newpartialdec /**< the new partialdec created from the decomp */
998  )
999 {
1000  assert( decomp != NULL );
1001  assert( DECdecompCheckConsistency( scip, decomp ) );
1002 
1003  /* get detprobdata for var & cons indices */
1005 
1006  /* create new partialdec and initialize its data */
1007  PARTIALDECOMP* partialdec = new PARTIALDECOMP(scip, !decomp->presolved);
1008  partialdec->setNBlocks( DECdecompGetNBlocks(decomp));
1009 
1010  SCIP_CONS** linkingconss = DECdecompGetLinkingconss(decomp);
1011  int nlinkingconss = DECdecompGetNLinkingconss(decomp);
1012  SCIP_HASHMAP* constoblock = DECdecompGetConstoblock(decomp);
1013  int nblock;
1014 
1015  /* set linking conss */
1016  for( int c = 0; c < nlinkingconss; ++c )
1017  {
1018  partialdec->fixConsToMaster(detprobdata->getIndexForCons(linkingconss[c]));
1019  }
1020 
1021  /* set block conss */
1022  for( int c = 0; c < detprobdata->getNConss(); ++c )
1023  {
1024  nblock = (int) (size_t) SCIPhashmapGetImage(constoblock, (void*) (size_t) detprobdata->getCons(c));
1025  if( nblock >= 1 && nblock <= partialdec->getNBlocks() )
1026  {
1027  partialdec->fixConsToBlock(c, nblock - 1);
1028  }
1029  }
1030 
1031  SCIP_VAR*** stairlinkingvars = DECdecompGetStairlinkingvars(decomp);
1032 
1033  if( stairlinkingvars != NULL )
1034  {
1035  int* nstairlinkingvars = DECdecompGetNStairlinkingvars(decomp);
1036  int varindex;
1037 
1038  /* set stairlinkingvars */
1039  for( int b = 0; b < partialdec->getNBlocks(); ++b )
1040  {
1041  for( int v = 0; v < nstairlinkingvars[b]; ++v )
1042  {
1043  if( stairlinkingvars[b][v] != NULL )
1044  {
1045  varindex = detprobdata->getIndexForVar(stairlinkingvars[b][v]);
1046  partialdec->fixVarToStairlinking(varindex, b);
1047  }
1048  }
1049  }
1050  }
1051 
1052  /* set other vars */
1053  SCIP_HASHMAP* vartoblock = DECdecompGetVartoblock(decomp);
1054  if( vartoblock != NULL )
1055  {
1056  for( int v = 0; v < detprobdata->getNVars(); ++v )
1057  {
1058  nblock = (int) (size_t) SCIPhashmapGetImage(vartoblock,
1059  (void*) (size_t) SCIPvarGetProbvar(detprobdata->getVar(v)));
1060  if( nblock == partialdec->getNBlocks() + 2 && !partialdec->isVarStairlinkingvar(v))
1061  {
1062  partialdec->fixVarToLinking(v);
1063  }
1064  else if( nblock == partialdec->getNBlocks() + 1 )
1065  {
1066  partialdec->fixVarToMaster(v);
1067  }
1068  else if( nblock >= 1 && nblock <= partialdec->getNBlocks())
1069  {
1070  partialdec->fixVarToBlock(v, nblock - 1);
1071  }
1072  }
1073  }
1074 
1075  partialdec->sort();
1076 
1077  /* now all conss and vars should be assigned */
1078  assert( partialdec->isComplete() );
1079 
1080  /*set all detector-related information*/
1081  for( int i = 0; i < DECdecompGetDetectorChainSize(decomp); ++i )
1082  {
1083  partialdec->setDetectorPropagated(DECdecompGetDetectorChain(decomp)[i]);
1084  partialdec->addClockTime(DECdecompGetDetectorClockTimes(decomp)[i]);
1085  partialdec->addPctConssFromFree(1 - *(DECdecompGetDetectorPctConssFromOpen(decomp)));
1088  partialdec->addPctVarsFromFree(1 - *(DECdecompGetDetectorPctVarsFromOpen(decomp)));
1089  partialdec->addPctVarsToBlock(*(DECdecompGetDetectorPctVarsToBlock(decomp)));
1091  partialdec->addNNewBlocks(*(DECdecompGetNNewBlocks(decomp)));
1092  }
1093 
1094  /* calc maxwhitescore and hashvalue */
1095  partialdec->prepare();
1096  partialdec->calcStairlinkingVars();
1097 
1098  *newpartialdec = partialdec;
1099  return SCIP_OKAY;
1100 }
1101 
1102 
1103 /**
1104  * @brief creates a decomposition DEC_DECOMP structure for a given partialdec
1105  * @returns scip return code
1106  */
1107 static
1109  SCIP* scip, /**< SCIP data structure */
1110  PARTIALDECOMP* partialdec, /**< partialdec the decomposition is created for */
1111  DEC_DECOMP** newdecomp /**< the new decomp created from the partialdec */
1112  )
1113 {
1114  SCIP_HASHMAP* vartoblock;
1115  SCIP_HASHMAP* constoblock;
1116  SCIP_HASHMAP* varindex;
1117  SCIP_HASHMAP* consindex;
1118  SCIP_VAR*** stairlinkingvars;
1119  SCIP_VAR*** subscipvars;
1120  SCIP_VAR** linkingvars;
1121  SCIP_CONS** linkingconss;
1122  SCIP_CONS*** subscipconss;
1123 
1124  int* nsubscipconss;
1125  int* nsubscipvars;
1126  int* nstairlinkingvars;
1127  int nlinkingvars;
1128 
1129  int varcounter = 1; /* in varindex counting starts with 1 */
1130  int conscounter = 1; /* in consindex counting starts with 1 */
1131  int counterstairlinkingvars = 0;
1132  int modifier;
1133  int nlinkingconss;
1134  int ndeletedblocks = 0;
1135  int nmastervarsfromdeleted = 0;
1136  int v;
1137  int c;
1138 
1139  assert( partialdec->checkConsistency() );
1140 
1141  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
1142  assert(detprobdata != NULL);
1143 
1144  std::vector<SCIP_Bool> isblockdeleted = std::vector<SCIP_Bool>(partialdec->getNBlocks(), FALSE);
1145  std::vector<int> ndeletedblocksbefore = std::vector<int>(partialdec->getNBlocks(), 0);
1146  std::vector<int> mastervaridsfromdeleted = std::vector<int>(0);
1147  std::vector<SCIP_Var*> mastervarsfromdeleted = std::vector<SCIP_VAR*>(0);
1148  std::vector<SCIP_CONS*> relevantconss = detprobdata->getRelevantConss();
1149  std::vector<SCIP_VAR*> relevantvars = detprobdata->getRelevantVars();
1150  std::vector<SCIP_VAR*> origfixedtozerovars = detprobdata->getOrigVarsFixedZero();
1151 
1152  /* create decomp data structure */
1153  SCIP_CALL_ABORT( DECdecompCreate( scip, newdecomp ) );
1154 
1155  DECdecompSetPresolved(*newdecomp, !partialdec->isAssignedToOrigProb());
1156 
1157  /* find out if for some blocks all conss have been deleted */
1158  for( int b = 0; b < partialdec->getNBlocks(); ++b )
1159  {
1160  SCIP_Bool iscurblockdeleted = TRUE;
1161  for( c = 0; c < partialdec->getNConssForBlock( b ); ++c )
1162  {
1163  int consid = partialdec->getConssForBlock( b )[c];
1164  SCIP_CONS* scipcons = relevantconss[consid];
1165 
1166  if( scipcons != NULL && !SCIPconsIsDeleted( scipcons) )
1167  {
1168  iscurblockdeleted = FALSE;
1169  break;
1170  }
1171  }
1172  if ( iscurblockdeleted )
1173  {
1174  ++ndeletedblocks;
1175  isblockdeleted[b] = TRUE;
1176  for( int b2 = b+1; b2 < partialdec->getNBlocks(); ++b2)
1177  {
1178  ++ndeletedblocksbefore[b2];
1179  }
1180  /* store deletion information of included vars */
1181  for( v = 0; v < partialdec->getNVarsForBlock( b ); ++v )
1182  {
1183  int varid = partialdec->getVarsForBlock( b )[v];
1184  SCIP_VAR* scipvar = relevantvars[varid];
1185  mastervaridsfromdeleted.push_back(varid);
1186  mastervarsfromdeleted.push_back(scipvar);
1187  ++nmastervarsfromdeleted;
1188  }
1189  }
1190  }
1191 
1192  /* set nblocks */
1193  DECdecompSetNBlocks( *newdecomp, partialdec->getNBlocks() - ndeletedblocks );
1194 
1195  if( partialdec->getNBlocks() - ndeletedblocks == 0 )
1196  {
1197  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "All blocks have been deleted since only deleted constraints are contained, no reformulation is done.\n");
1198  }
1199 
1200  /* prepare constraints data structures */
1201  if( partialdec->getNMasterconss() != 0 )
1202  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, &linkingconss, partialdec->getNMasterconss() ) );
1203  else
1204  linkingconss = NULL;
1205 
1206  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, &nsubscipconss, partialdec->getNBlocks() - ndeletedblocks ) );
1207  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, &subscipconss, partialdec->getNBlocks() - ndeletedblocks ) );
1208 
1209  SCIP_CALL_ABORT( SCIPhashmapCreate( &constoblock, SCIPblkmem( scip ), partialdec->getNConss() ) );
1210  SCIP_CALL_ABORT( SCIPhashmapCreate( &consindex, SCIPblkmem( scip ), partialdec->getNConss() ) );
1211 
1212  /* set linking constraints */
1213  modifier = 0;
1214  nlinkingconss = partialdec->getNMasterconss();
1215  for( c = 0; c < partialdec->getNMasterconss(); ++c )
1216  {
1217  int consid = partialdec->getMasterconss()[c];
1218  SCIP_CONS* scipcons = relevantconss[consid];
1219  if( partialdec->isAssignedToOrigProb() )
1220  SCIPgetTransformedCons(scip, scipcons, &scipcons);
1221 
1222  if( scipcons == NULL || SCIPconsIsDeleted(scipcons) || SCIPconsIsObsolete(scipcons) )
1223  {
1224  --nlinkingconss;
1225  ++modifier;
1226  }
1227  else
1228  {
1229  linkingconss[c-modifier] = scipcons;
1230  SCIP_CALL_ABORT( SCIPhashmapInsert( constoblock, scipcons, (void*) ( size_t )( partialdec->getNBlocks() + 1 - ndeletedblocks ) ) );
1231  SCIP_CALL_ABORT( SCIPhashmapInsert( consindex, scipcons, (void*) (size_t) conscounter ) );
1232  conscounter ++;
1233  }
1234  }
1235 
1236  if( nlinkingconss != 0 )
1237  DECdecompSetLinkingconss( scip, *newdecomp, linkingconss, nlinkingconss );
1238  else
1239  linkingconss = NULL;
1240 
1241  /* set block constraints */
1242  for( int b = 0; b < partialdec->getNBlocks(); ++ b )
1243  {
1244  if( isblockdeleted[b] )
1245  continue;
1246  modifier = 0;
1247  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & subscipconss[b-ndeletedblocksbefore[b]], partialdec->getNConssForBlock( b ) ) );
1248  nsubscipconss[b-ndeletedblocksbefore[b]] = partialdec->getNConssForBlock( b );
1249  for( c = 0; c < partialdec->getNConssForBlock( b ); ++c )
1250  {
1251  int consid = partialdec->getConssForBlock( b )[c];
1252  SCIP_CONS* scipcons = relevantconss[consid];
1253  if( partialdec->isAssignedToOrigProb() )
1254  SCIPgetTransformedCons(scip, scipcons, &scipcons);
1255 
1256  if( scipcons == NULL || SCIPconsIsDeleted(scipcons) )
1257  {
1258  --nsubscipconss[b-ndeletedblocksbefore[b]];
1259  ++modifier;
1260  }
1261  else
1262  {
1263  assert( scipcons != NULL );
1264  subscipconss[b-ndeletedblocksbefore[b]][c-modifier] = scipcons;
1265  SCIPdebugMessage("Set cons %s to block %d + 1 - %d in cons to block\n", SCIPconsGetName(scipcons), b, ndeletedblocksbefore[b] );
1266  SCIP_CALL_ABORT( SCIPhashmapInsert( constoblock, scipcons, (void*) ( size_t )( b + 1 - ndeletedblocksbefore[b] ) ) );
1267  SCIP_CALL_ABORT( SCIPhashmapInsert( consindex, scipcons, (void*) (size_t) conscounter ) );
1268  conscounter ++;
1269  }
1270  }
1271  }
1272 
1273  /* assign all open conss that might be left */
1274  for( c = 0; c < SCIPgetNConss(scip); ++c )
1275  {
1276  if( !GCGisConsGCGCons(SCIPgetConss(scip)[c]) )
1277  {
1278  if(!SCIPhashmapExists(constoblock, SCIPgetConss(scip)[c]))
1279  {
1280  SCIP_CONS* scipcons = SCIPgetConss(scip)[c];
1281  SCIP_CALL_ABORT( SCIPhashmapInsert( constoblock, scipcons, (void*) ( size_t )( partialdec->getNBlocks() + 1 - ndeletedblocks ) ) );
1282  SCIP_CALL_ABORT( SCIPhashmapInsert( consindex, scipcons, (void*) (size_t) conscounter ) );
1283  conscounter ++;
1284  }
1285  }
1286  }
1287 
1288  DECdecompSetSubscipconss( scip, *newdecomp, subscipconss, nsubscipconss );
1289  DECdecompSetConstoblock( *newdecomp, constoblock );
1290  DECdecompSetConsindex( *newdecomp, consindex );
1291  /* finished setting constraint data structures */
1292 
1293  /* prepare constraints data structures */
1294  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & nsubscipvars, partialdec->getNBlocks() - ndeletedblocks ) );
1295  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & subscipvars, partialdec->getNBlocks() - ndeletedblocks ) );
1296  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & nstairlinkingvars, partialdec->getNBlocks() - ndeletedblocks ) );
1297  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & stairlinkingvars, partialdec->getNBlocks() -ndeletedblocks ) );
1298 
1299  SCIP_CALL_ABORT( SCIPhashmapCreate( & vartoblock, SCIPblkmem( scip ), partialdec->getNVars() + (int) origfixedtozerovars.size() ) );
1300  SCIP_CALL_ABORT( SCIPhashmapCreate( & varindex, SCIPblkmem( scip ), partialdec->getNVars() + (int) origfixedtozerovars.size()) );
1301 
1302  /* set linkingvars */
1303  nlinkingvars = partialdec->getNLinkingvars() + partialdec->getNMastervars() + partialdec->getNTotalStairlinkingvars() + nmastervarsfromdeleted + (int) origfixedtozerovars.size();
1304 
1305  if( nlinkingvars != 0 )
1306  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & linkingvars, nlinkingvars ) );
1307  else
1308  linkingvars = NULL;
1309 
1310  for( v = 0; v < partialdec->getNLinkingvars(); ++ v )
1311  {
1312  int var = partialdec->getLinkingvars()[v];
1313  SCIP_VAR* scipvar = SCIPvarGetProbvar( relevantvars[var] );
1314  assert( scipvar != NULL );
1315 
1316  linkingvars[v] = scipvar;
1317  SCIPdebugMessage( "Set var %s to block %d + 2 - %d in var to block\n", SCIPvarGetName(scipvar), partialdec->getNBlocks(), ndeletedblocks );
1318  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, scipvar, (void*) ( size_t )( partialdec->getNBlocks() + 2 - ndeletedblocks ) ) );
1319  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, scipvar, (void*) (size_t) varcounter ) );
1320  varcounter ++;
1321  }
1322 
1323  for( v = 0; v < partialdec->getNMastervars(); ++ v )
1324  {
1325  int var = partialdec->getMastervars()[v];
1326  SCIP_VAR* scipvar = SCIPvarGetProbvar( relevantvars[var] );
1327  linkingvars[v + partialdec->getNLinkingvars()] = scipvar;
1328  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, scipvar, (void*) ( size_t )( partialdec->getNBlocks() + 1 - ndeletedblocks) ) );
1329  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, scipvar, (void*) (size_t) varcounter ) );
1330  varcounter ++;
1331  }
1332 
1333  for( v = 0; v < nmastervarsfromdeleted; ++v)
1334  {
1335  SCIP_VAR* var;
1336  var = SCIPvarGetProbvar(mastervarsfromdeleted[v]);
1337 
1338  linkingvars[partialdec->getNMastervars() + partialdec->getNLinkingvars() + v] = var;
1339  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, var, (void*) ( size_t )( partialdec->getNBlocks() + 1 - ndeletedblocks) ) );
1340  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, var, (void*) (size_t) varcounter ) );
1341  varcounter ++;
1342  }
1343 
1344  for( v = 0; v < (int) origfixedtozerovars.size(); ++v)
1345  {
1346  SCIP_VAR* var;
1347  var = origfixedtozerovars[v];
1348 
1349  linkingvars[partialdec->getNMastervars() + partialdec->getNLinkingvars() + nmastervarsfromdeleted + v] = var;
1350  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, var, (void*) ( size_t )( partialdec->getNBlocks() + 1 - ndeletedblocks) ) );
1351  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, var, (void*) (size_t) varcounter ) );
1352  varcounter ++;
1353  }
1354 
1355  /* set block variables */
1356  for( int b = 0; b < partialdec->getNBlocks(); ++ b )
1357  {
1358  if( isblockdeleted[b] )
1359  continue;
1360 
1361  if( partialdec->getNVarsForBlock( b ) > 0 )
1362  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & subscipvars[b -ndeletedblocksbefore[b]], partialdec->getNVarsForBlock( b ) ) );
1363  else
1364  subscipvars[b-ndeletedblocksbefore[b]] = NULL;
1365 
1366  if( partialdec->getNStairlinkingvars( b ) > 0 )
1367  SCIP_CALL_ABORT( SCIPallocBufferArray( scip, & stairlinkingvars[b-ndeletedblocksbefore[b]], partialdec->getNStairlinkingvars( b ) ) );
1368  else
1369  stairlinkingvars[b-ndeletedblocksbefore[b]] = NULL;
1370 
1371  nsubscipvars[b-ndeletedblocksbefore[b]] = partialdec->getNVarsForBlock( b );
1372  nstairlinkingvars[b-ndeletedblocksbefore[b]] = partialdec->getNStairlinkingvars( b );
1373 
1374  for( v = 0; v < partialdec->getNVarsForBlock( b ); ++ v )
1375  {
1376  int var = partialdec->getVarsForBlock( b )[v];
1377  SCIP_VAR* scipvar = SCIPvarGetProbvar( relevantvars[var] );
1378  assert( scipvar != NULL );
1379 
1380  subscipvars[b-ndeletedblocksbefore[b]][v] = scipvar;
1381  SCIPdebugMessage("Set var %s to block %d + 1 - %d in var to block\n", SCIPvarGetName(scipvar), b, ndeletedblocksbefore[b] );
1382  assert( !SCIPhashmapExists(vartoblock, scipvar) || SCIPhashmapGetImage(vartoblock, scipvar) == (void*) ( size_t )( b + 1 - ndeletedblocksbefore[b] ) );
1383  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, scipvar, (void*) ( size_t )( b + 1 - ndeletedblocksbefore[b] ) ) );
1384  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, scipvar, (void*) (size_t) varcounter ) );
1385  varcounter ++;
1386  }
1387 
1388  for( v = 0; v < partialdec->getNStairlinkingvars( b ); ++ v )
1389  {
1390  int var = partialdec->getStairlinkingvars( b )[v];
1391  SCIP_VAR* scipvar = SCIPvarGetProbvar( relevantvars[var] );
1392  assert( scipvar != NULL );
1393 
1394  stairlinkingvars[b-ndeletedblocksbefore[b]][v] = scipvar;
1395  linkingvars[partialdec->getNLinkingvars() + partialdec->getNMastervars() + nmastervarsfromdeleted + counterstairlinkingvars] = scipvar;
1396  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, scipvar, (void*) ( size_t )( partialdec->getNBlocks() + 2 - ndeletedblocks) ) );
1397  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, scipvar, (void*) (size_t) varcounter ) );
1398  varcounter ++;
1399  counterstairlinkingvars ++;
1400  }
1401  }
1402 
1403  /* if any var is open yet put it in master (in case they were not in relevantvars) */
1404  for( v = 0; v < SCIPgetNVars(scip); ++v )
1405  {
1406  if(!SCIPhashmapExists(vartoblock, SCIPgetVars(scip)[v]))
1407  {
1408  SCIP_VAR* scipvar = SCIPvarGetProbvar( SCIPgetVars(scip)[v] );
1409  SCIP_CALL_ABORT( SCIPhashmapInsert( vartoblock, scipvar, (void*) ( size_t )( partialdec->getNBlocks() + 1 - ndeletedblocks) ) );
1410  SCIP_CALL_ABORT( SCIPhashmapInsert( varindex, scipvar, (void*) (size_t) varcounter ) );
1411  varcounter ++;
1412  }
1413  }
1414 
1415  DECdecompSetSubscipvars( scip, *newdecomp, subscipvars, nsubscipvars );
1416  DECdecompSetStairlinkingvars( scip, *newdecomp, stairlinkingvars, nstairlinkingvars );
1417  DECdecompSetLinkingvars( scip, *newdecomp, linkingvars, nlinkingvars, (int) origfixedtozerovars.size(), partialdec->getNMastervars() + nmastervarsfromdeleted );
1418  DECdecompSetVarindex( *newdecomp, varindex );
1419  DECdecompSetVartoblock( *newdecomp, vartoblock );
1420 
1421  /* //////////////////// free stuff ////////////////////////////// */
1422 
1423  /* free vars stuff */
1424  SCIPfreeBufferArrayNull( scip, & ( linkingvars ) );
1425  for( int b = partialdec->getNBlocks() - 1 - ndeletedblocks; b >= 0; --b )
1426  {
1427  if( nstairlinkingvars[b] != 0 )
1428  {
1429  SCIPfreeBufferArrayNull( scip, & ( stairlinkingvars[b] ) );
1430  }
1431  }
1432 
1433  SCIPfreeBufferArrayNull( scip, & ( stairlinkingvars ) );
1434  SCIPfreeBufferArrayNull( scip, & ( nstairlinkingvars ) );
1435 
1436  for( int b = partialdec->getNBlocks() - 1 - ndeletedblocks; b >= 0; --b )
1437  {
1438  if( nsubscipvars[b] != 0 )
1439  {
1440  SCIPfreeBufferArrayNull( scip, & ( subscipvars[b] ) );
1441  }
1442  }
1443 
1444  SCIPfreeBufferArrayNull( scip, & ( subscipvars ) );
1445  SCIPfreeBufferArrayNull( scip, & ( nsubscipvars ) );
1446 
1447  /* free constraints */
1448  for( int b = partialdec->getNBlocks() - 1 - ndeletedblocks; b >= 0; --b )
1449  {
1450  SCIPfreeBufferArrayNull( scip, & ( subscipconss[b] ) );
1451  }
1452  SCIPfreeBufferArrayNull( scip, & ( subscipconss ) );
1453 
1454  SCIPfreeBufferArrayNull( scip, & nsubscipconss );
1455  SCIPfreeBufferArrayNull( scip, & linkingconss );
1456 
1457  /* set detectorchain */
1458  DECdecompSetDetectorChain(scip, (*newdecomp), partialdec->getDetectorchain().data(), (int) partialdec->getDetectorchain().size());
1459 
1460  /* set last detector in chain as detector that "found" this decomposition */
1461  if(partialdec->getNDetectors() > 0)
1462  DECdecompSetDetector(*newdecomp, partialdec->getDetectorchain().back());
1463 
1464  /* set statistical detector chain data */
1465  DECdecompSetPartialdecID(*newdecomp, partialdec->getID());
1466  if( partialdec->getNDetectors() > 0 )
1467  {
1468  DECdecompSetDetectorClockTimes(scip, *newdecomp, partialdec->getDetectorClockTimes().data());
1469  DECdecompSetDetectorPctVarsToBorder(scip, *newdecomp, partialdec->getPctVarsToBorderVector().data());
1470  DECdecompSetDetectorPctVarsToBlock(scip, *newdecomp, partialdec->getPctVarsToBlockVector().data());
1471  DECdecompSetDetectorPctVarsFromOpen(scip, *newdecomp, partialdec->getPctVarsFromFreeVector().data());
1472  DECdecompSetDetectorPctConssToBorder(scip, *newdecomp, partialdec->getPctConssToBorderVector().data());
1473  DECdecompSetDetectorPctConssToBlock(scip, *newdecomp, partialdec->getPctConssToBlockVector().data());
1474  DECdecompSetDetectorPctConssFromOpen(scip, *newdecomp, partialdec->getPctConssFromFreeVector().data());
1475  DECdecompSetNNewBlocks(scip, *newdecomp, partialdec->getNNewBlocksVector().data());
1476  }
1477 
1478  /* set dectype */
1479  int newnlinkingvars = DECdecompGetNLinkingvars((*newdecomp));
1480  int newnlinkingconss = DECdecompGetNLinkingconss((*newdecomp));
1481 
1482  if( newnlinkingvars == partialdec->getNTotalStairlinkingvars() && newnlinkingconss == 0 && newnlinkingvars > 0 )
1483  {
1484  DECdecompSetType((*newdecomp), DEC_DECTYPE_STAIRCASE);
1485  }
1486  else if( newnlinkingvars > 0 || partialdec->getNTotalStairlinkingvars() > 0 )
1487  {
1488  DECdecompSetType((*newdecomp), DEC_DECTYPE_ARROWHEAD);
1489  }
1490  else if( newnlinkingconss > 0 )
1491  {
1492  DECdecompSetType((*newdecomp), DEC_DECTYPE_BORDERED);
1493  }
1494  else if( newnlinkingconss == 0 && partialdec->getNTotalStairlinkingvars() == 0 )
1495  {
1496  DECdecompSetType((*newdecomp), DEC_DECTYPE_DIAGONAL);
1497  }
1498  else
1499  {
1500  DECdecompSetType((*newdecomp), DEC_DECTYPE_UNKNOWN);
1501  }
1502 
1503  /* set max white score */
1504  SCIPdebugMessage(" partialdec maxwhitescore: %f\n", partialdec->getMaxWhiteScore());
1505 
1506  DECsetMaxWhiteScore(scip, *newdecomp, partialdec->getMaxWhiteScore() );
1507 
1508  /* set detector string */
1509  char buffer[SCIP_MAXSTRLEN];
1510  partialdec->buildDecChainString(buffer);
1511  DECdecompSetDetectorChainString(scip, *newdecomp, buffer);
1512 
1513  if( !partialdec->isAssignedToOrigProb() )
1514  SCIP_CALL(DECdecompAddRemainingConss(scip, *newdecomp) );
1515 
1516  assert(DECdecompCheckConsistency(scip, *newdecomp) );
1517 
1518  return SCIP_OKAY;
1519 }
1520 
1521 
1522 /** @brief sorts all registered partialdecs according to score, descending */
1523 static
1525  SCIP* scip /**< SCIP data structure */
1526  )
1527 {
1528  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
1529  assert(conshdlrdata != NULL);
1530 
1531  SCORETYPE sctype = static_cast<scoretype>(conshdlrdata->currscoretype);
1532  std::sort(conshdlrdata->partialdecs->begin(), conshdlrdata->partialdecs->end(), [&](PARTIALDECOMP* a, PARTIALDECOMP* b) {return (a->getScore(sctype) > b->getScore(sctype)); });
1533 }
1534 
1535 
1536 /** @brief method to adapt score for orig decomps
1537  * @todo: change score for some parameter settings
1538  *
1539  * @returns new score */
1540 static
1542  SCIP* scip, /**< SCIP data structure */
1543  SCIP_Real oldscore /**< current score (to be updated) */
1544  )
1545 {
1546  SCIP_Real score = oldscore;
1547  int method;
1548 
1549  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
1550  assert(conshdlrdata != NULL);
1551 
1552  SCIP_CALL(SCIPgetIntParam(scip, "detection/origprob/weightinggpresolvedoriginaldecomps", &method) );
1553 
1554  if( method == FRACTION_OF_NNONZEROS )
1555  {
1556  if ( conshdlrdata->detprobdatapres == NULL || conshdlrdata->detprobdataorig == NULL )
1557  return score;
1558 
1559  score *= (SCIP_Real) conshdlrdata->detprobdataorig->getNNonzeros() / conshdlrdata->detprobdatapres->getNNonzeros();
1560  }
1561 
1562  if( method == FRACTION_OF_NROWS )
1563  {
1564  if ( conshdlrdata->detprobdatapres == NULL || conshdlrdata->detprobdataorig == NULL )
1565  return score;
1566 
1567  score *= (SCIP_Real) conshdlrdata->detprobdataorig->getNConss() / conshdlrdata->detprobdatapres->getNConss();
1568  }
1569 
1570  if( method == FAVOUR_PRESOLVED )
1571  {
1572  score += 1.;
1573  }
1574 
1575  return score;
1576 }
1577 
1578 
1579 /** @brief adds constraint partitions with a reduced number of classes */
1580 static
1582  SCIP* scip, /**< SCIP data structure */
1583  gcg::DETPROBDATA* detprobdata /**< classification is for problem to which these data correspond */
1584  )
1585 {
1586  /* set the number of classes the partitions should be reduced to */
1587  int maxnclasses = 0;
1588  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
1589 
1590  if( detprobdata->getNConss() + detprobdata->getNVars() >= 50000 )
1591  maxnclasses = conshdlrdata->maxnclassesperpartitionforlargeprobs;
1592  else
1593  maxnclasses = conshdlrdata->maxnclassesperpartition;
1594 
1595  for( int partitionid = 0; partitionid < detprobdata->getNConsPartitions(); ++ partitionid )
1596  {
1597  ConsPartition* newpartition = detprobdata->getConsPartition(partitionid)->reduceClasses(maxnclasses);
1598 
1599  if( newpartition != NULL )
1600  {
1601  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " Added reduced version of conspartition %s with %d different constraint classes \n",
1602  detprobdata->getConsPartition(partitionid)->getName(), maxnclasses);
1603  detprobdata->addConsPartition(newpartition);
1604  }
1605  }
1606 }
1607 
1608 
1609 /** @brief adds variable partitions with a reduced number of classes */
1610 static
1612  SCIP* scip, /**< SCIP data structure */
1613  gcg::DETPROBDATA *detprobdata /**< classification is for problem to which these data correspond */
1614  )
1615 {
1616  /* set the number of classes the partitions should be reduced to */
1617  int maxnclasses = 0;
1618  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
1619 
1620  if( detprobdata->getNConss() + detprobdata->getNVars() >= 50000 )
1621  maxnclasses = conshdlrdata->maxnclassesperpartitionforlargeprobs;
1622  else
1623  maxnclasses = conshdlrdata->maxnclassesperpartition;
1624 
1625  for( int partitionid = 0; partitionid < detprobdata->getNVarPartitions(); ++ partitionid )
1626  {
1627  VarPartition* newpartition = detprobdata->getVarPartition(partitionid)->reduceClasses(maxnclasses);
1628 
1629  if( newpartition != NULL )
1630  {
1631  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " Added reduced version of varpartition %s with %d different variable classes\n",
1632  detprobdata->getVarPartition(partitionid)->getName(), maxnclasses );
1633  detprobdata->addVarPartition(newpartition);
1634  }
1635  }
1636 }
1637 
1638 
1639 /** @brief sets detection/enabled setting
1640  * @returns SCIP return code */
1641 static
1642 SCIP_RETCODE setDetectionEnabled(
1643  SCIP* scip, /**< SCIP data structure */
1644  SCIP_Bool quiet, /**< should the parameter be set quietly (no output) */
1645  SCIP_Bool enabled /**< should the detection be enabled */
1646  )
1647 {
1648  SCIP_CALL( SCIPsetBoolParam(scip, "detection/enabled", enabled) );
1649  if( !quiet )
1650  {
1651  SCIPinfoMessage(scip, NULL, "detection/enabled = %s\n", enabled ? "TRUE" : "FALSE");
1652  }
1653  return SCIP_OKAY;
1654 }
1655 
1656 
1657 /** @brief resets the parameters to their default value
1658  * @returns SCIP return code */
1659 static
1660 SCIP_RETCODE setDetectionDefault(
1661  SCIP* scip, /**< SCIP data structure */
1662  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data structure */
1663  SCIP_Bool quiet /**< should the parameter be set quiet (no output) */
1664  )
1665 { /*lint --e{715}*/
1666  int i;
1667  assert(scip != NULL);
1668  assert(conshdlrdata != NULL);
1669 
1670  SCIP_CALL (SCIPsetIntParam(scip, "detection/maxrounds", 2) );
1671  SCIP_CALL (SCIPsetBoolParam(scip, "detection/origprob/enabled", FALSE) );
1672 
1673  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/nnonzeros/enabled", TRUE) );
1674  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/scipconstype/enabled", TRUE) );
1675  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/miplibconstype/enabled", TRUE) );
1676  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamenonumbers/enabled", TRUE) );
1677 
1678  if( SCIPgetStage(scip) >= SCIP_STAGE_PROBLEM && SCIPgetNVars(scip) + SCIPgetNConss(scip) < DEFAULT_LEVENSHTEIN_MAXMATRIXHALFPERIMETER )
1679  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamelevenshtein/enabled", TRUE) );
1680  else
1681  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamelevenshtein/enabled", FALSE) );
1682 
1683  for( i = 0; i < conshdlrdata->ndetectors; ++i )
1684  {
1685  SCIP_Result result;
1686 
1687  char paramname[SCIP_MAXSTRLEN];
1688  SCIP_Bool paramval;
1689  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1690  "detection/detectors/%s/enabled", conshdlrdata->detectors[i]->name);
1691 
1692  SCIP_CALL( SCIPresetParam(scip, paramname) );
1693 
1694  result = SCIP_DIDNOTRUN;
1695  if( conshdlrdata->detectors[i]->setParamDefault != NULL )
1696  conshdlrdata->detectors[i]->setParamDefault(scip, conshdlrdata->detectors[i], &result);
1697  if( !quiet )
1698  {
1699  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1700  "detection/detectors/%s/enabled", conshdlrdata->detectors[i]->name);
1701  SCIP_CALL( SCIPgetBoolParam(scip, paramname, &paramval) );
1702  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s = %s\n", paramname, paramval == TRUE ? "TRUE" : "FALSE");
1703 
1704  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1705  "detection/detectors/%s/finishingenabled", conshdlrdata->detectors[i]->name);
1706  SCIP_CALL( SCIPgetBoolParam(scip, paramname, &paramval) );
1707  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s = %s\n", paramname, paramval == TRUE ? "TRUE" : "FALSE");
1708  }
1709  }
1710 
1711  setDetectionEnabled(scip, quiet, TRUE);
1712 
1713  return SCIP_OKAY;
1714 }
1715 
1716 
1717 /** @brief sets the parameters to aggressive values
1718  *
1719  * @returns SCIP return code */
1720 static
1722  SCIP* scip, /**< SCIP data structure */
1723  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data structure */
1724  SCIP_Bool quiet /**< should the parameter be set quiet (no output) */
1725  )
1726 { /*lint --e{715}*/
1727  int i;
1728 
1729  assert(scip != NULL);
1730  assert(conshdlrdata != NULL);
1731 
1732 
1733  SCIP_CALL (SCIPsetIntParam(scip, "detection/maxrounds", 3) );
1734 
1735  SCIP_CALL (SCIPsetBoolParam(scip, "detection/origprob/enabled", TRUE) );
1736 
1737  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/nnonzeros/enabled", TRUE) );
1738  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/scipconstype/enabled", TRUE) );
1739  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/miplibconstype/enabled", TRUE) );
1740  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamenonumbers/enabled", TRUE) );
1741 
1742  if( SCIPgetStage(scip) >= SCIP_STAGE_PROBLEM && SCIPgetNVars(scip) + SCIPgetNConss(scip) < AGGRESSIVE_LEVENSHTEIN_MAXMATRIXHALFPERIMETER)
1743  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamelevenshtein/enabled", TRUE) );
1744  else
1745  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamelevenshtein/enabled", FALSE) );
1746 
1747  for( i = 0; i < conshdlrdata->ndetectors; ++i )
1748  {
1749  SCIP_Result result;
1750 
1751  result = SCIP_DIDNOTRUN;
1752  if( conshdlrdata->detectors[i]->setParamAggressive != NULL )
1753  conshdlrdata->detectors[i]->setParamAggressive(scip, conshdlrdata->detectors[i], &result);
1754 
1755  if( !quiet )
1756  {
1757  char paramname[SCIP_MAXSTRLEN];
1758  SCIP_Bool paramval;
1759 
1760  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1761  "detection/detectors/%s/enabled", conshdlrdata->detectors[i]->name);
1762  SCIP_CALL( SCIPgetBoolParam(scip, paramname, &paramval) );
1763  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s = %s\n", paramname, paramval == TRUE ? "TRUE" : "FALSE");
1764 
1765  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1766  "detection/detectors/%s/finishingenabled", conshdlrdata->detectors[i]->name);
1767  SCIP_CALL( SCIPgetBoolParam(scip, paramname, &paramval) );
1768  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s = %s\n", paramname, paramval == TRUE ? "TRUE" : "FALSE");
1769  }
1770  }
1771 
1772  setDetectionEnabled(scip, quiet, TRUE);
1773 
1774  return SCIP_OKAY;
1775 }
1776 
1777 
1778 /** @brief disables detectors
1779  *
1780  * @returns SCIP return code */
1781 static
1782 SCIP_RETCODE setDetectionOff(
1783  SCIP* scip, /**< SCIP data structure */
1784  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data structure */
1785  SCIP_Bool quiet /**< should the parameter be set quiet (no output) */
1786  )
1787 { /*lint --e{715}*/
1788  int i;
1789  assert(scip != NULL);
1790  assert(conshdlrdata != NULL);
1791 
1792  for( i = 0; i < conshdlrdata->ndetectors; ++i )
1793  {
1794  char paramname[SCIP_MAXSTRLEN];
1795  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", conshdlrdata->detectors[i]->name);
1796 
1797  SCIP_CALL( SCIPsetBoolParam(scip, paramname, FALSE) );
1798  if( !quiet )
1799  {
1800  SCIPinfoMessage(scip, NULL, "%s = FALSE\n", paramname);
1801  }
1802  }
1803 
1804  for( i = 0; i < conshdlrdata->ndetectors; ++i )
1805  {
1806  char paramname[SCIP_MAXSTRLEN];
1807  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", conshdlrdata->detectors[i]->name);
1808 
1809  SCIP_CALL( SCIPsetBoolParam(scip, paramname, FALSE) );
1810  if( !quiet )
1811  {
1812  SCIPinfoMessage(scip, NULL, "%s = FALSE\n", paramname);
1813  }
1814  }
1815 
1816  for( i = 0; i < conshdlrdata->ndetectors; ++i )
1817  {
1818  char paramname[SCIP_MAXSTRLEN];
1819  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "detection/detectors/%s/postprocessingenabled", conshdlrdata->detectors[i]->name);
1820 
1821  SCIP_CALL( SCIPsetBoolParam(scip, paramname, FALSE) );
1822  if( !quiet )
1823  {
1824  SCIPinfoMessage(scip, NULL, "%s = FALSE\n", paramname);
1825  }
1826  }
1827 
1828  setDetectionEnabled(scip, quiet, FALSE);
1829 
1830  return SCIP_OKAY;
1831 }
1832 
1833 
1834 /** @brief sets the parameters to fast values
1835  *
1836  * @returns SCIP return code */
1837 static
1838 SCIP_RETCODE setDetectionFast(
1839  SCIP* scip, /**< SCIP data structure */
1840  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data structure */
1841  SCIP_Bool quiet /**< should the parameter be set quiet (no output) */
1842  )
1843 { /*lint --e{715} */
1844  int i;
1845 
1846  assert(scip != NULL);
1847  assert(conshdlrdata != NULL);
1848 
1849  SCIP_CALL (SCIPsetIntParam(scip, "detection/maxrounds", 1) );
1850 
1851  SCIP_CALL (SCIPsetBoolParam(scip, "detection/origprob/enabled", FALSE) );
1852  SCIP_CALL (SCIPsetBoolParam(scip, "detection/origprob/classificationenabled", FALSE) );
1853 
1854  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/nnonzeros/enabled", TRUE) );
1855  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/scipconstype/enabled", TRUE) );
1856  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/miplibconstype/enabled", TRUE) );
1857  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamenonumbers/enabled", TRUE) );
1858 
1859  if( SCIPgetStage(scip) >= SCIP_STAGE_PROBLEM && SCIPgetNVars(scip) + SCIPgetNConss(scip) < FAST_LEVENSHTEIN_MAXMATRIXHALFPERIMETER )
1860  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamelevenshtein/enabled", TRUE) );
1861  else
1862  SCIP_CALL(SCIPsetBoolParam(scip, "detection/classification/consclassifier/consnamelevenshtein/enabled", FALSE) );
1863 
1864  for( i = 0; i < conshdlrdata->ndetectors; ++i )
1865  {
1866  SCIP_Result result;
1867 
1868  result = SCIP_DIDNOTRUN;
1869  if( conshdlrdata->detectors[i]->overruleemphasis )
1870  continue;
1871 
1872  if( conshdlrdata->detectors[i]->setParamFast != NULL )
1873  conshdlrdata->detectors[i]->setParamFast(scip, conshdlrdata->detectors[i], &result);
1874  if( !quiet )
1875  {
1876  char paramname[SCIP_MAXSTRLEN];
1877  SCIP_Bool paramval;
1878 
1879  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1880  "detection/detectors/%s/enabled", conshdlrdata->detectors[i]->name);
1881  SCIP_CALL( SCIPgetBoolParam(scip, paramname, &paramval) );
1882  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s = %s\n", paramname, paramval == TRUE ? "TRUE" : "FALSE");
1883 
1884  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN,
1885  "detection/detectors/%s/finishingenabled", conshdlrdata->detectors[i]->name);
1886  SCIP_CALL( SCIPgetBoolParam(scip, paramname, &paramval) );
1887  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "%s = %s\n", paramname, paramval == TRUE ? "TRUE" : "FALSE");
1888  }
1889  }
1890 
1891  setDetectionEnabled(scip, quiet, TRUE);
1892 
1893  return SCIP_OKAY;
1894 }
1895 
1896 
1897 /** @brief method to calculate the greatest common divisor
1898  * @returns greatest common divisor
1899  */
1900 static
1901 int gcd(
1902  int a, /**< first value */
1903  int b /**< second value */
1904  )
1905 {
1906  return b == 0 ? a : gcd( b, a % b );
1907 }
1908 
1909 
1910 /** @brief sets the pricing problem parameters
1911  * @returns scip return code
1912 */
1913 static
1915  SCIP* scip, /**< SCIP data structure of the pricing problem */
1916  int clocktype, /**< clocktype to use in the pricing problem */
1917  SCIP_Real infinity, /**< values larger than this are considered infinity in the pricing problem */
1918  SCIP_Real epsilon, /**< absolute values smaller than this are considered zero in the pricing problem */
1919  SCIP_Real sumepsilon, /**< absolute values of sums smaller than this are considered zero in the pricing problem */
1920  SCIP_Real feastol, /**< feasibility tolerance for constraints in the pricing problem */
1921  SCIP_Real lpfeastol, /**< primal feasibility tolerance of LP solver in the pricing problem */
1922  SCIP_Real dualfeastol, /**< feasibility tolerance for reduced costs in LP solution in the pricing problem */
1923  SCIP_Bool enableppcuts, /**< should ppcuts be stored for sepa_basis */
1924  SCIP_Real timelimit /**< limit of time */
1925  )
1926 {
1927  assert(scip != NULL);
1928 
1929  /* disable conflict analysis */
1930  SCIP_CALL( SCIPsetBoolParam(scip, "conflict/useprop", FALSE) );
1931  SCIP_CALL( SCIPsetCharParam(scip, "conflict/useinflp", 'o') );
1932  SCIP_CALL( SCIPsetCharParam(scip, "conflict/useboundlp", 'o') );
1933  SCIP_CALL( SCIPsetBoolParam(scip, "conflict/usesb", FALSE) );
1934  SCIP_CALL( SCIPsetBoolParam(scip, "conflict/usepseudo", FALSE) );
1935 
1936  /* reduce the effort spent for hash tables */
1937  SCIP_CALL( SCIPsetBoolParam(scip, "misc/usevartable", FALSE) );
1938  SCIP_CALL( SCIPsetBoolParam(scip, "misc/useconstable", FALSE) );
1939  SCIP_CALL( SCIPsetBoolParam(scip, "misc/usesmalltables", TRUE) );
1940 
1941  /* disable expensive presolving */
1942  /* @todo test whether this really helps, perhaps set presolving emphasis to fast? */
1943  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/linear/presolpairwise", FALSE) );
1944  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/setppc/presolpairwise", FALSE) );
1945  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/logicor/presolpairwise", FALSE) );
1946  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/linear/presolusehashing", FALSE) );
1947  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/setppc/presolusehashing", FALSE) );
1948  SCIP_CALL( SCIPsetBoolParam(scip, "constraints/logicor/presolusehashing", FALSE) );
1949 
1950  /* disable dual fixing presolver for the moment, because we want to avoid variables fixed to infinity */
1951  SCIP_CALL( SCIPsetIntParam(scip, "propagating/dualfix/freq", -1) );
1952  SCIP_CALL( SCIPsetIntParam(scip, "propagating/dualfix/maxprerounds", 0) );
1953  SCIP_CALL( SCIPfixParam(scip, "propagating/dualfix/freq") );
1954  SCIP_CALL( SCIPfixParam(scip, "propagating/dualfix/maxprerounds") );
1955 
1956  /* disable solution storage ! */
1957  SCIP_CALL( SCIPsetIntParam(scip, "limits/maxorigsol", 0) );
1958  SCIP_CALL( SCIPsetRealParam(scip, "limits/time", timelimit ) );
1959 
1960  /* disable multiaggregation because of infinite values */
1961  SCIP_CALL( SCIPsetBoolParam(scip, "presolving/donotmultaggr", TRUE) );
1962 
1963  /* @todo enable presolving and propagation of xor constraints if bug is fixed */
1964 
1965  /* disable presolving and propagation of xor constraints as work-around for a SCIP bug */
1966  SCIP_CALL( SCIPsetIntParam(scip, "constraints/xor/maxprerounds", 0) );
1967  SCIP_CALL( SCIPsetIntParam(scip, "constraints/xor/propfreq", -1) );
1968 
1969  /* disable output to console */
1970  SCIP_CALL( SCIPsetIntParam(scip, "display/verblevel", (int)SCIP_VERBLEVEL_NORMAL) );
1971 #if SCIP_VERSION > 210
1972  SCIP_CALL( SCIPsetBoolParam(scip, "misc/printreason", FALSE) );
1973 #endif
1974  SCIP_CALL( SCIPsetIntParam(scip, "limits/maxorigsol", 0) );
1975  SCIP_CALL( SCIPfixParam(scip, "limits/maxorigsol") );
1976 
1977  /* do not abort subproblem on CTRL-C */
1978  SCIP_CALL( SCIPsetBoolParam(scip, "misc/catchctrlc", FALSE) );
1979 
1980  /* set clock type */
1981  SCIP_CALL( SCIPsetIntParam(scip, "timing/clocktype", clocktype) );
1982 
1983  SCIP_CALL( SCIPsetBoolParam(scip, "misc/calcintegral", FALSE) );
1984  SCIP_CALL( SCIPsetBoolParam(scip, "misc/finitesolutionstore", TRUE) );
1985 
1986  SCIP_CALL( SCIPsetRealParam(scip, "numerics/infinity", infinity) );
1987  SCIP_CALL( SCIPsetRealParam(scip, "numerics/epsilon", epsilon) );
1988  SCIP_CALL( SCIPsetRealParam(scip, "numerics/sumepsilon", sumepsilon) );
1989  SCIP_CALL( SCIPsetRealParam(scip, "numerics/feastol", feastol) );
1990  SCIP_CALL( SCIPsetRealParam(scip, "numerics/lpfeastol", lpfeastol) );
1991  SCIP_CALL( SCIPsetRealParam(scip, "numerics/dualfeastol", dualfeastol) );
1992 
1993  /* jonas' stuff */
1994  if( enableppcuts )
1995  {
1996  int pscost;
1997  int prop;
1998 
1999  SCIP_CALL( SCIPgetIntParam(scip, "branching/pscost/priority", &pscost) );
2000  SCIP_CALL( SCIPgetIntParam(scip, "propagating/maxroundsroot", &prop) );
2001  SCIP_CALL( SCIPsetIntParam(scip, "branching/pscost/priority", 11000) );
2002  SCIP_CALL( SCIPsetIntParam(scip, "propagating/maxroundsroot", 0) );
2003  SCIP_CALL( SCIPsetPresolving(scip, SCIP_PARAMSETTING_OFF, TRUE) );
2004  }
2005  return SCIP_OKAY;
2006 }
2007 
2008 
2009 /**
2010  * @brief method to calculate and set the optimal dual values from original lp, used for strong detection score
2011  * @returns scip return code
2012  */
2013 static
2015  SCIP* scip, /**< SCIP data structure */
2016  SCIP_Bool transformed /**< whether the problem is transormed yet */
2017  )
2018 {
2019  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2020  SCIP* scipcopy;
2021  SCIP_HASHMAP* origtocopiedconss;
2022  SCIP_Bool valid;
2023  int nvars;
2024  SCIP_VAR** copiedvars;
2025  int nconss;
2026 
2027  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "started calculating optimal dual values for original lp\n");
2028 
2029  SCIPhashmapCreate(&origtocopiedconss, SCIPblkmem(scip), SCIPgetNConss(scip) );
2030 
2031  SCIPcreate(&scipcopy);
2032 
2033  SCIPcopy(scip, scipcopy, NULL, origtocopiedconss, "", FALSE, FALSE, FALSE, FALSE, &valid );
2034 
2035  nconss = SCIPgetNConss(scip);
2036  nvars = SCIPgetNVars(scipcopy);
2037  copiedvars = SCIPgetVars(scipcopy);
2038 
2039  conshdlrdata->dualvalsoptimaloriglp->clear();
2040  conshdlrdata->dualvalsoptimaloriglp->resize(nconss, 0.);
2041 
2042  for( int var = 0; var < nvars ; ++var )
2043  {
2044  SCIP_VAR* copyvar = copiedvars[var];
2045  SCIP_Bool infeasible;
2046 
2047  if( SCIPvarGetType(copyvar) == SCIP_VARTYPE_BINARY )
2048  SCIPchgVarUbGlobal(scipcopy, copyvar, 1. );
2049 
2050  SCIPchgVarType(scipcopy, copyvar, SCIP_VARTYPE_CONTINUOUS, &infeasible);
2051  }
2052 
2053  copiedvars = SCIPgetVars(scipcopy);
2054 
2055  /* deactivate presolving */
2056  SCIPsetIntParam(scipcopy, "presolving/maxrounds", 0);
2057 
2058  /* deactivate separating */
2059  SCIPsetIntParam(scipcopy, "separating/maxrounds", 0);
2060  SCIPsetIntParam(scipcopy, "separating/maxroundsroot", 0);
2061 
2062  /* deactivate propagating */
2063  SCIPsetIntParam(scipcopy, "propagating/maxrounds", 0);
2064  SCIPsetIntParam(scipcopy, "propagating/maxroundsroot", 0);
2065 
2066  /* solve lp */
2067  SCIPsetIntParam(scipcopy, "lp/solvefreq", 1);
2068 
2069  /* only root node */
2070  SCIPsetLongintParam(scipcopy, "limits/nodes", 1);
2071 
2072  SCIPsetIntParam(scipcopy, "display/verblevel", SCIP_VERBLEVEL_FULL);
2073 
2074  SCIPtransformProb(scipcopy);
2075 
2076  SCIPsolve(scipcopy);
2077 
2078  DETPROBDATA* detprobdata = (transformed) ? conshdlrdata->detprobdatapres : conshdlrdata->detprobdataorig;
2079 
2080  for( int c = 0; c < nconss; ++c )
2081  {
2082  SCIP_CONS* cons;
2083  SCIP_CONS* copiedcons;
2084  SCIP_CONS* transcons = NULL;
2085 
2086  cons = detprobdata->getCons(c);
2087  if( !transformed )
2088  {
2089  SCIPgetTransformedCons(scip, cons, &transcons);
2090  if( transcons )
2091  cons = transcons;
2092  else
2093  {
2094  SCIPwarningMessage(scip, "Could not find constraint for random dual variable initialization when calculating strong decomposition score; skipping cons: %s \n", SCIPconsGetName(cons));
2095  continue;
2096  }
2097  }
2098  copiedcons = (SCIP_CONS*) SCIPhashmapGetImage(origtocopiedconss, (void*) cons);
2099 
2100  assert(copiedcons != NULL);
2101  assert( !SCIPconsIsTransformed(copiedcons) );
2102 
2103  transcons = NULL;
2104  SCIPgetTransformedCons(scipcopy, copiedcons, &transcons);
2105  if( transcons != NULL)
2106  copiedcons = transcons;
2107 
2108  (*conshdlrdata->dualvalsoptimaloriglp)[c] = GCGconsGetDualsol(scipcopy, copiedcons);
2109  if( !SCIPisFeasEQ(scip, 0., (*conshdlrdata->dualvalsoptimaloriglp)[c]) )
2110  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "optimal dual sol of constraint %s is %f \n", SCIPconsGetName(cons), (*conshdlrdata->dualvalsoptimaloriglp)[c]);
2111  }
2112 
2113  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "finished calculating optimal dual values for original lp, start freeing\n");
2114 
2115  SCIPhashmapFree(&origtocopiedconss);
2116  SCIPfree(&scipcopy);
2117 
2118  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "finished freeing\n");
2119 
2120  return SCIP_OKAY;
2121 }
2122 
2123 
2124 /**
2125  * @brief method that shuffles randomly and set dual variable values, used for strong detection score
2126  * @returns scip return code
2127  */
2128 static
2130  SCIP* scip, /**< SCIP data structure */
2131  SCIP_Bool transformed /**< whether the problem is tranformed yet */
2132  )
2133 {
2134  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2135  GCG_RANDOM_DUAL_METHOD usedmethod;
2136  SCIP_RANDNUMGEN* randnumgen;
2137 
2138  int method;
2139  int nconss = SCIPgetNConss(scip);
2140 
2141  SCIPgetIntParam(scip, "detection/score/strong_detection/dualvalrandommethod", &method);
2142 
2143  /* default method == 1 */
2144  usedmethod = GCG_RANDOM_DUAL_NAIVE;
2145 
2146  if( method == 2 )
2147  usedmethod = GCG_RANDOM_DUAL_EXPECTED_EQUAL;
2148  else if( method == 3 )
2150 
2151  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "set dual val random method to %d. \n", method );
2152 
2153  conshdlrdata->dualvalsrandom->clear();
2154  conshdlrdata->dualvalsrandom->resize(nconss, 0.);
2155 
2156  /* create random number generator */
2157  // TODO ref replace default for random partialdec with parameter
2158  SCIP_CALL( SCIPcreateRandom(scip, &randnumgen, DEFAULT_RANDPARTIALDEC, TRUE) );
2159 
2160  DETPROBDATA* detprobdata = (transformed) ? conshdlrdata->detprobdatapres : conshdlrdata->detprobdataorig;
2161 
2162  /* shuffle dual multipliers of constraints*/
2163 
2164  /* 1) naive approach */
2165  if( usedmethod == GCG_RANDOM_DUAL_NAIVE )
2166  {
2167  for( int c = 0; c < nconss; ++c )
2168  {
2169  SCIP_Real dualval;
2170  SCIP_Real factor;
2171  SCIP_CONS* cons;
2172 
2173  cons = detprobdata->getCons(c);
2174  if( SCIPisInfinity( scip, -GCGconsGetLhs(scip, cons) ))
2175  {
2176  SCIP_Real modifier;
2177  modifier = 0.;
2178  if ( SCIPgetObjsense(scip) != SCIP_OBJSENSE_MAXIMIZE )
2179  modifier = -1.;
2180 
2181  factor = MAX(1., ABS(GCGconsGetRhs(scip, cons) ) );
2182  dualval = SCIPrandomGetReal(randnumgen, 0.+modifier, 1.+modifier ) * factor;
2183  }
2184  else if( SCIPisInfinity( scip, GCGconsGetRhs(scip, cons) ) )
2185  {
2186  SCIP_Real modifier;
2187  modifier = 0.;
2188  if ( SCIPgetObjsense(scip) != SCIP_OBJSENSE_MINIMIZE )
2189  modifier = -1.;
2190 
2191  factor = MAX(1., ABS(GCGconsGetLhs(scip, cons) ) );
2192  dualval = SCIPrandomGetReal(randnumgen, 0.+modifier, 1.+modifier ) * factor;
2193  }
2194  else
2195  {
2196  factor = MAX(1., ABS(GCGconsGetLhs(scip, cons) ) );
2197  factor = MAX( factor, ABS(GCGconsGetRhs(scip, cons) ) );
2198  dualval = SCIPrandomGetReal(randnumgen, -1., 1. ) * factor;
2199  }
2200 
2201  (*conshdlrdata->dualvalsrandom)[c] = dualval;
2202  }
2203 
2204  } /* end naive approach */
2205  /* expected equal and expected overestimated approach */
2206  else if( usedmethod == GCG_RANDOM_DUAL_EXPECTED_EQUAL || usedmethod == GCG_RANDOM_DUAL_EXPECTED_OVERESTIMATE)
2207  {
2208  SCIP_Real largec = 0.;
2209  for( int v = 0; v < SCIPgetNVars(scip); ++v )
2210  largec += ABS( SCIPvarGetObj(detprobdata->getVar(v)) );
2211 
2212  for( int c = 0; c < nconss; ++c )
2213  {
2214  SCIP_Real dualval;
2215  SCIP_CONS* cons;
2216  cons = detprobdata->getCons(c);
2217  double lambda;
2218 
2219  SCIP_Real divisor = 0.;
2220 
2221  SCIP_Real randomval;
2222  int nvarsincons = GCGconsGetNVars(scip, cons);
2223  SCIP_Real* valsincons;
2224 
2225  /* get values of variables in this constraint */
2226  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &valsincons, nvarsincons) );
2227  GCGconsGetVals(scip, cons, valsincons, nvarsincons);
2228 
2229  /* add coefficients to divisor */
2230  for( int v = 0; v < nvarsincons; ++v )
2231  {
2232  divisor += ABS( valsincons[v] );
2233  }
2234  if ( usedmethod == GCG_RANDOM_DUAL_EXPECTED_EQUAL )
2235  divisor *= nconss;
2236 
2237  /* 1/lambda is the expected value of the distribution */
2238  lambda = divisor / largec;
2239 
2240  /* formula for exponential distribution requires a uniform random number in (0,1). */
2241  do
2242  {
2243  randomval = SCIPrandomGetReal(randnumgen, 0.0, 1.0);
2244  }
2245  while (randomval == 0.0 || randomval == 1.0);
2246  randomval = -std::log(randomval) / lambda;
2247 
2248  if( SCIPisInfinity(scip, -GCGconsGetLhs(scip, cons)) )
2249  {
2250  SCIP_Real modifier;
2251  modifier = 1.;
2252  if ( SCIPgetObjsense(scip) != SCIP_OBJSENSE_MAXIMIZE )
2253  modifier = -1.;
2254 
2255  dualval = modifier * randomval;
2256  }
2257  else if( SCIPisInfinity(scip, GCGconsGetRhs(scip, cons)) )
2258  {
2259  SCIP_Real modifier;
2260  modifier = 1.;
2261  if ( SCIPgetObjsense(scip) != SCIP_OBJSENSE_MINIMIZE )
2262  modifier = -1.;
2263 
2264  dualval = modifier * randomval;
2265 
2266  }
2267  else
2268  {
2269  SCIP_Real helpval = SCIPrandomGetReal(randnumgen, -1., 1. );
2270 
2271  if ( helpval < 0. )
2272  dualval = -1. * randomval ;
2273  else dualval = randomval;
2274  }
2275 
2276  (*conshdlrdata->dualvalsrandom)[c] = dualval;
2277 
2278  /* free storage for variables in cons */
2279  SCIPfreeBufferArrayNull(scip, &valsincons);
2280  }
2281  }
2282 
2283  return SCIP_OKAY;
2284 }
2285 
2286 
2287 /**
2288  * @brief returns the value of the optimal lp relaxation dual value of the given constrainr rid correspondoning problem of the detprobdata; if it is not calculated yet it will be calculated
2289  * @returns the value of the optimal lp relaxation dual value of the given constraint rid correspondoning problem of the detprobdata
2290  */
2291 static
2293  SCIP* scip, /**< SCIP data structure */
2294  int consindex, /**< consindex index of constraint the value is asked for */
2295  SCIP_Bool transformed /**< is the problem transformed yet */
2296  )
2297 {
2298  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2299 
2300  if( !conshdlrdata->dualvalsoptimaloriglpcalculated )
2301  calculateDualvalsOptimalOrigLP(scip, transformed);
2302  conshdlrdata->dualvalsoptimaloriglpcalculated = TRUE;
2303 
2304  return (*conshdlrdata->dualvalsoptimaloriglp)[consindex];
2305 }
2306 
2307 
2308 /**
2309  * @brief return the a random value of the dual variable of the corresponding ; if it is not calculated yet it will be calculated
2310  * @returns the a random value of the dual variable of the corresponding
2311  */
2312 static
2314  SCIP* scip, /**< SCIP data structure */
2315  int consindex, /**< consindex index of constraint the value is asked for */
2316  SCIP_Bool transformed /**< is the problem transformed yet */
2317  )
2318 {
2319  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2320 
2321  if( !conshdlrdata->dualvalsrandomset )
2322  shuffleDualvalsRandom(scip, transformed);
2323  conshdlrdata->dualvalsrandomset = TRUE;
2324 
2325  return (*conshdlrdata->dualvalsrandom)[consindex];
2326 }
2327 
2328 
2329 /** @brief creates the pricing problem constraints
2330  * @returns scip return code
2331  */
2332 static
2334  SCIP* scip, /**< SCIP data structure */
2335  SCIP* subscip, /**< the relaxator data data structure */
2336  PARTIALDECOMP* partialdec, /**< partialdec corresponding to the decomposition to test */
2337  int block, /**< which pricing problem */
2338  SCIP_HASHMAP* hashorig2pricingvar /**< hashmap mapping original to corresponding pricing variables */
2339  )
2340 {
2341  SCIP_CONS* newcons;
2342  SCIP_HASHMAP* hashorig2pricingconstmp;
2343  int c;
2344  char name[SCIP_MAXSTRLEN];
2345  SCIP_Bool success;
2346 
2347  assert(scip != NULL);
2348 
2349  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
2350 
2351  SCIP_CALL( SCIPhashmapCreate(&hashorig2pricingconstmp, SCIPblkmem(scip), detprobdata->getNConss() ) ); /*lint !e613*/
2352 
2353  assert(hashorig2pricingvar != NULL);
2354 
2355  for( c = 0; c < partialdec->getNConssForBlock(block); ++c )
2356  {
2357  SCIP_CONS* cons;
2358 
2359  cons = detprobdata->getCons(partialdec->getConssForBlock(block)[c]);
2360 
2361  SCIPdebugMessage("copying %s to pricing problem %d\n", SCIPconsGetName(cons), block);
2362  if( !SCIPconsIsActive(cons) )
2363  {
2364  SCIPdebugMessage("skipping, cons <%s> inactive\n", SCIPconsGetName(cons) );
2365  continue;
2366  }
2367  SCIP_CALL( SCIPgetTransformedCons(scip, cons, &cons) );
2368  assert(cons != NULL);
2369 
2370  /* copy the constraint */
2371  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "p%d_%s", block, SCIPconsGetName(cons));
2372  SCIP_CALL( SCIPgetConsCopy(scip, subscip, cons, &newcons, SCIPconsGetHdlr(cons),
2373  hashorig2pricingvar, hashorig2pricingconstmp, name,
2374  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, &success) );
2375 
2376  /* constraint was successfully copied */
2377  assert(success);
2378 
2379  SCIP_CALL( SCIPaddCons(subscip, newcons) );
2380 #ifndef NDEBUG
2381  {
2382  SCIP_VAR** curvars;
2383  int ncurvars;
2384 
2385  ncurvars = GCGconsGetNVars(subscip, newcons);
2386  curvars = NULL;
2387  if( ncurvars > 0 )
2388  {
2389  SCIP_CALL( SCIPallocBufferArray(scip, &curvars, ncurvars) );
2390  SCIP_CALL( GCGconsGetVars(subscip, newcons, curvars, ncurvars) );
2391 
2392  SCIPfreeBufferArrayNull(scip, &curvars);
2393  }
2394  }
2395 #endif
2396 SCIP_CALL( SCIPreleaseCons(subscip, &newcons) );
2397  }
2398 
2399  SCIPhashmapFree(&hashorig2pricingconstmp);
2400 
2401  return SCIP_OKAY;
2402 }
2403 
2404 
2405 /**
2406  * @brief gets an intermediate score value for the blocks of a partialdec
2407  *
2408  * Used by several score calculations,
2409  * computed as (1 - fraction of block area to complete area)
2410  *
2411  * @returns intermediate score value
2412  */
2413 static
2415  SCIP* scip, /**< SCIP data structure */
2416  PARTIALDECOMP* partialdec /**< compute for this partialdec */
2417  )
2418 {
2419  unsigned long matrixarea;
2420  unsigned long blockarea;
2421 
2422  SCIP_CLOCK* clock;
2423  SCIP_CALL_ABORT( SCIPcreateClock( scip, &clock) );
2424  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
2425 
2426  matrixarea = (unsigned long) partialdec->getNVars() * (unsigned long) partialdec->getNConss() ;
2427  blockarea = 0;
2428 
2429  for( int i = 0; i < partialdec->getNBlocks(); ++ i )
2430  {
2431  blockarea += (unsigned long) partialdec->getNConssForBlock(i) * ( (unsigned long) partialdec->getNVarsForBlock(i) );
2432  }
2433 
2434  SCIP_Real blockareascore = 1. - (matrixarea == 0 ? 0 : ( (SCIP_Real) blockarea / (SCIP_Real) matrixarea ));
2435 
2436  SCIP_CALL_ABORT( SCIPstopClock(scip, clock) );
2437  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
2438  SCIP_CALL_ABORT( SCIPfreeClock(scip, &clock) );
2439 
2440  return blockareascore;
2441 }
2442 
2443 
2444 /* --------------- public functions --------------- */
2445 
2446 /* prints block candidate information (gcg.h) */
2448  SCIP* scip,
2449  FILE* file
2450  )
2451 {
2452  gcg::DETPROBDATA* detprobdata;
2453  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2454  assert(conshdlrdata != NULL);
2455 
2456  detprobdata = (conshdlrdata->detprobdatapres == NULL ? conshdlrdata->detprobdataorig : conshdlrdata->detprobdatapres );
2457 
2458  if( detprobdata == NULL )
2459  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), NULL, "No block number candidates are calculated yet, consider detecting first.. \n" );
2460  else
2461  detprobdata->printBlockcandidateInformation(scip, file);
2462 
2463  return SCIP_OKAY;
2464 }
2465 
2466 
2467 /* prints detection time (gcg.h) */
2469  SCIP* givenscip,
2470  FILE* file
2471  )
2472 {
2473  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(givenscip), file, "DETECTIONTIME \n" );
2474  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(givenscip), file, "%f \n", (SCIP_Real) GCGconshdlrDecompGetCompleteDetectionTime(givenscip) );
2475 
2476  return SCIP_OKAY;
2477 }
2478 
2479 
2480 /* prints partition information (gcg.h) */
2482  SCIP* scip,
2483  FILE* file
2484  )
2485 {
2486  gcg::DETPROBDATA* detprobdata;
2487  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2488  assert(conshdlrdata != NULL);
2489 
2490  detprobdata = (conshdlrdata->detprobdatapres == NULL ? conshdlrdata->detprobdataorig : conshdlrdata->detprobdatapres );
2491 
2492  detprobdata->printPartitionInformation(file);
2493 
2494  return SCIP_OKAY;
2495 }
2496 
2497 
2498 /* prints decomp information (gcg.h) */
2500  SCIP* scip,
2501  FILE* file
2502  )
2503 {
2504  std::vector<gcg::PARTIALDECOMP*>::const_iterator partialdeciter;
2505  std::vector<gcg::PARTIALDECOMP*>::const_iterator partialdeciterend;
2506 
2507  assert( GCGconshdlrDecompCheckConsistency(scip) );
2508 
2509  std::vector<PARTIALDECOMP*> partialdeclist;
2510  getFinishedPartialdecs(scip, partialdeclist);
2511  partialdeciter = partialdeclist.begin();
2512  partialdeciterend = partialdeclist.end();
2513 
2514  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "DECOMPINFO \n" );
2515  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", (int) partialdeclist.size() );
2516 
2517  for( ; partialdeciter != partialdeciterend; ++partialdeciter )
2518  {
2519  gcg::PARTIALDECOMP* partialdec;
2520  int nblocks = (*partialdeciter)->getNBlocks();
2521 
2522  partialdec = *partialdeciter;
2523 
2524  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "NEWDECOMP \n");
2525  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", (*partialdeciter)->getNBlocks());
2526  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", (*partialdeciter)->getID());
2527  for( int block = 0; block < nblocks; ++block )
2528  {
2529  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->getNConssForBlock(block));
2530  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->getNVarsForBlock(block));
2531  }
2532  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->getNMasterconss());
2533  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->getNLinkingvars());
2534  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->getNMastervars());
2535  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->getNTotalStairlinkingvars());
2536  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%f\n", partialdec->getMaxWhiteScore());
2537  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%f\n", partialdec->getScore(scoretype::CLASSIC));
2538  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%f\n", partialdec->getScore(scoretype::MAX_FORESSEEING_WHITE));
2539  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", partialdec->hasSetppccardMaster());
2540  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", (int) partialdec->getDetectorchain( ).size());
2541  for( int detector = 0; detector <(int) partialdec->getDetectorchain().size(); ++ detector )
2542  {
2543  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%s\n",
2544  DECdetectorGetName(partialdec->getDetectorchain()[detector]));
2545  }
2546  partialdec->printPartitionInformation(scip, file);
2547  }
2548 
2549  return SCIP_OKAY;
2550 }
2551 
2552 
2553 /* gets number of partialdecs for public interface (pub_decomp.h)*/
2555  SCIP* scip
2556  )
2557 {
2558  return GCGconshdlrDecompGetNDecomps(scip);
2559 }
2560 
2561 
2563  DEC_CONSCLASSIFIER* classifier
2564  )
2565 {
2566  assert(classifier != NULL);
2567  return classifier->clsdata;
2568 }
2569 
2570 
2572  DEC_CONSCLASSIFIER* classifier
2573  )
2574 {
2575  assert(classifier != NULL);
2576  return classifier->name;
2577 }
2578 
2579 
2581  DEC_VARCLASSIFIER* classifier
2582  )
2583 {
2584  assert(classifier != NULL);
2585  return classifier->clsdata;
2586 }
2587 
2588 
2590  DEC_VARCLASSIFIER* classifier
2591  )
2592 {
2593  assert(classifier != NULL);
2594  return classifier->name;
2595 }
2596 
2597 
2599  DEC_DETECTOR* detector
2600  )
2601 {
2602  if( detector == NULL )
2603  return '0';
2604  else
2605  return detector->decchar;
2606 }
2607 
2608 
2610  DEC_DETECTOR* detector
2611  )
2612 {
2613  assert(detector != NULL);
2614  return detector->decdata;
2615 }
2616 
2617 
2619  DEC_DETECTOR* detector
2620  )
2621 {
2622  assert(detector != NULL);
2623  return detector->name;
2624 }
2625 
2626 
2627 SCIP_RETCODE DECdetectStructure(
2628  SCIP* scip,
2629  SCIP_RESULT* result
2630  )
2631 {
2632  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2633 
2634  SCIP_CALL(SCIPresetClock(scip, conshdlrdata->completedetectionclock));
2635  SCIP_CALL(SCIPstartClock(scip, conshdlrdata->completedetectionclock));
2636 
2637  *result = SCIP_DIDNOTRUN;
2638 
2639  if( conshdlrdata->detprobdataorig == NULL )
2640  {
2641  resetDetprobdata(scip, TRUE);
2642  }
2643 
2644  /* if there are no entries there cannot be a structure */
2645  if( SCIPgetNOrigVars(scip) == 0 && SCIPgetNOrigConss(scip) == 0 )
2646  return SCIP_OKAY;
2647 
2648  /* if the original problem should be solved, then no decomposition will be performed */
2650  return SCIP_OKAY;
2651 
2652  /* if there should not be any detection, stop at this point */
2653  if(!conshdlrdata->enabled)
2654  {
2655  return SCIP_OKAY;
2656  }
2657 
2658  ////////////////////
2659  ///// ORIGINAL /////
2660  ////////////////////
2661 
2662  SCIP_Bool calculateOrigDecomps;
2663  SCIP_Bool classifyOrig;
2664 
2665  SCIPgetBoolParam(scip, "detection/origprob/enabled", &calculateOrigDecomps);
2666  SCIPgetBoolParam(scip, "detection/origprob/classificationenabled", &classifyOrig);
2667  if (SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED) {
2668  if (calculateOrigDecomps) {
2669  // if there is no root partialdec yet, add root partialdec
2670  if( conshdlrdata->detprobdataorig->getOpenPartialdecs().empty() )
2671  {
2672  PARTIALDECOMP* rootpartialdec = new PARTIALDECOMP(scip, true);
2673  bool success = conshdlrdata->detprobdataorig->addPartialdecToOpen(rootpartialdec);
2674  if( !success )
2675  {
2676  SCIPerrorMessage("Could not add root partialdecomp to the pool of open decompositions.");
2677  return SCIP_ERROR;
2678  }
2679  }
2680 
2681  SCIPdebugMessage("is stage < transformed ? %s -> do %s transformProb() ", (SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED ? "yes" : "no"), (SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED ? "" : "not") );
2682 
2683  if( SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED )
2684  SCIP_CALL(SCIPtransformProb(scip));
2685 
2686  // TODO ref classify (introduce flag for each detector and check whether this is needed)
2687 
2688  // CLASSIFICATION
2689  if( classifyOrig )
2690  {
2691  GCGconshdlrDecompClassify(scip, FALSE);
2692  if( SCIPgetVerbLevel(scip) >= SCIP_VERBLEVEL_FULL )
2693  conshdlrdata->detprobdataorig->printBlockcandidateInformation(scip, NULL);
2694  }
2695  else
2696  SCIPdebugMessage("classification for orig problem disabled \n" );
2697 
2698  // BLOCK CANDIDATES
2700 
2701  // FIND DECOMPOSITIONS
2702  SCIPdebugMessage("start finding decompositions for original problem!\n" );
2703  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "start finding decompositions for original problem!\n");
2704  SCIP_CALL(SCIPresetClock(scip, conshdlrdata->detectorclock));
2705  SCIP_CALL(SCIPstartClock(scip, conshdlrdata->detectorclock));
2706  detect(scip, conshdlrdata->detprobdataorig);
2707  SCIP_CALL(SCIPstopClock(scip, conshdlrdata->detectorclock));
2708  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "finished finding decompositions for original problem!\n");
2709  SCIPdebugMessage("finished finding decompositions for original problem!\n" );
2710  }
2711  else
2712  SCIPdebugMessage("finding decompositions for original problem is NOT enabled!\n");
2713 
2714  std::vector<SCIP_CONS*> indexToCons; /* stores the corresponding scip constraints pointer */
2715  std::vector<gcg::PARTIALDECOMP*> partialdecsorig(0); /* partialdecs that were found for the orig problem */
2716 
2717  SCIP_CALL(SCIPstopClock(scip, conshdlrdata->completedetectionclock));
2718  conshdlrdata->hasrunoriginal = TRUE;
2719  conshdlrdata->detprobdataorig->freeTemporaryData();
2720  }
2721  else
2722  { // SCIPgetStage(scip) >= SCIP_STAGE_PRESOLVED
2723  //////////////////////////////////////
2724  ///// TRANSFORMED / IS PRESOLVED /////
2725  //////////////////////////////////////
2726 
2727  /* detection for presolved problem */
2728 
2729  if( SCIPgetStage(scip) == SCIP_STAGE_INIT || SCIPgetNVars(scip) == 0 || SCIPgetNConss(scip) == 0 )
2730  {
2731  SCIPverbMessage(scip, SCIP_VERBLEVEL_DIALOG, NULL, "No problem exists, cannot detect structure!\n");
2732 
2733  /* presolving removed all constraints or variables */
2734  if (SCIPgetNVars(scip) == 0 || SCIPgetNConss(scip) == 0)
2735  conshdlrdata->hasrun = TRUE;
2736 
2737  *result = SCIP_DIDNOTRUN;
2738  return SCIP_OKAY;
2739  }
2740 
2741  /* start detection clocks */
2742  SCIP_CALL(SCIPresetClock(scip, conshdlrdata->completedetectionclock));
2743  SCIP_CALL(SCIPstartClock(scip, conshdlrdata->completedetectionclock));
2744 
2745  /* Classification */
2746  GCGconshdlrDecompClassify(scip, TRUE);
2748 
2749  /* add block number candidates of the original problem */
2750  if( conshdlrdata->detprobdataorig )
2751  {
2752  for( auto& candidatesNBlock : conshdlrdata->detprobdataorig->candidatesNBlocks )
2753  conshdlrdata->detprobdatapres->addCandidatesNBlocksNVotes(candidatesNBlock.first, candidatesNBlock.second);
2754  }
2755 
2756  /* add root partialdec */
2757  if( conshdlrdata->detprobdatapres->getOpenPartialdecs().empty() )
2758  {
2759  PARTIALDECOMP* rootpartialdec = new PARTIALDECOMP(scip, false);
2760 
2761  bool success = conshdlrdata->detprobdatapres->addPartialdecToOpen(rootpartialdec);
2762  assert(success);
2763  }
2764 
2765  SCIP_CALL(SCIPresetClock(scip, conshdlrdata->detectorclock));
2766  SCIP_CALL(SCIPstartClock(scip, conshdlrdata->detectorclock));
2767  detect(scip, conshdlrdata->detprobdatapres);
2768  SCIP_CALL(SCIPstopClock(scip, conshdlrdata->detectorclock));
2769  conshdlrdata->detprobdatapres->sortFinishedForScore();
2770  SCIP_CALL(SCIPstopClock(scip, conshdlrdata->completedetectionclock));
2771  conshdlrdata->hasrun = TRUE;
2772  conshdlrdata->detprobdatapres->freeTemporaryData();
2773  }
2774 
2775  /////////////////////////
2776  ///// EVAL SUCCESS //////
2777  /////////////////////////
2778 
2779  if( conshdlrdata->detprobdatapres != NULL && conshdlrdata->detprobdatapres->getNFinishedPartialdecs() > 0 )
2780  *result = SCIP_SUCCESS;
2781 
2782  if( conshdlrdata->detprobdataorig != NULL && conshdlrdata->detprobdataorig->getNFinishedPartialdecs() > 0 )
2783  *result = SCIP_SUCCESS;
2784 
2785  SCIPdebugMessage("Detection took %fs\n", SCIPgetClockTime( scip, conshdlrdata->detectorclock));
2786 
2787  if( conshdlrdata->detprobdatapres != NULL && SCIPgetVerbLevel(scip) >= SCIP_VERBLEVEL_FULL )
2788  conshdlrdata->detprobdatapres->printBlockcandidateInformation(scip, NULL);
2789 
2790  /* display timing statistics */
2791  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "Detection Time: %.2f\n", GCGconshdlrDecompGetCompleteDetectionTime(scip));
2792  /** @todo put this output to the statistics output */
2793 
2794  if( *result == SCIP_DIDNOTRUN )
2795  {
2796  return SCIP_OKAY;
2797  }
2798 
2799  /* show that we have done our duty */
2800  *result = SCIP_SUCCESS;
2801 
2802  return SCIP_OKAY;
2803 }
2804 
2805 
2807  SCIP* scip,
2808  const char* name
2809  )
2810 {
2811  SCIP_CONSHDLR* conshdlr;
2812  SCIP_CONSHDLRDATA* conshdlrdata;
2813  int i;
2814 
2815  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2816  if( conshdlr == NULL )
2817  return NULL;
2818 
2819  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2820  assert(conshdlrdata != NULL);
2821 
2822  for( i = 0; i < conshdlrdata->nconsclassifiers; ++i )
2823  {
2824  DEC_CONSCLASSIFIER *classifier;
2825  classifier = conshdlrdata->consclassifiers[i];
2826  assert(classifier != NULL);
2827  if( strcmp(classifier->name, name) == 0 )
2828  {
2829  return classifier;
2830  }
2831  }
2832 
2833  return NULL;
2834 }
2835 
2836 
2838  SCIP* scip,
2839  const char* name
2840  )
2841 {
2842  SCIP_CONSHDLR* conshdlr;
2843  SCIP_CONSHDLRDATA* conshdlrdata;
2844  int i;
2845 
2846  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2847  if( conshdlr == NULL )
2848  return NULL;
2849 
2850  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2851  assert(conshdlrdata != NULL);
2852 
2853  for( i = 0; i < conshdlrdata->nvarclassifiers; ++i )
2854  {
2855  DEC_VARCLASSIFIER *classifier;
2856  classifier = conshdlrdata->varclassifiers[i];
2857  assert(classifier != NULL);
2858  if( strcmp(classifier->name, name) == 0 )
2859  {
2860  return classifier;
2861  }
2862  }
2863 
2864  return NULL;
2865 }
2866 
2867 
2869  SCIP* scip,
2870  const char* name
2871  )
2872 {
2873  SCIP_CONSHDLR* conshdlr;
2874  SCIP_CONSHDLRDATA* conshdlrdata;
2875  int i;
2876  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2877  if( conshdlr == NULL )
2878  return NULL;
2879 
2880  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2881  assert(conshdlrdata != NULL);
2882 
2883  for( i = 0; i < conshdlrdata->ndetectors; ++i )
2884  {
2885  DEC_DETECTOR *detector;
2886  detector = conshdlrdata->detectors[i];
2887  assert(detector != NULL);
2888  if( strcmp(detector->name, name) == 0 )
2889  {
2890  return detector;
2891  }
2892  }
2893 
2894  return NULL;
2895 }
2896 
2897 
2899  SCIP* scip,
2900  SCIP_Bool printwarnings
2901  )
2902 {
2903  DEC_DECOMP* decomp;
2904  PARTIALDECOMP* partialdec;
2905  std::vector<std::pair<PARTIALDECOMP*, SCIP_Real> > candidates;
2906 
2907  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2908  assert(conshdlrdata != NULL);
2909 
2910  if ( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
2911  return NULL;
2912 
2913  GCGconshdlrDecompChooseCandidatesFromSelected(scip, candidates, FALSE, printwarnings);
2914  if ( candidates.empty() )
2915  return NULL;
2916 
2917  partialdec = candidates[0].first;
2918 
2919  assert( !partialdec->isAssignedToOrigProb() );
2920  assert( partialdec->isComplete() );
2921 
2922  createDecompFromPartialdec(scip, partialdec, &decomp);
2923 
2924  return decomp;
2925 }
2926 
2927 
2929  SCIP* scip,
2930  SCIP_Bool transformed
2931  )
2932 {
2933  int dec;
2934  std::vector<std::pair<PARTIALDECOMP*, SCIP_Real> > candidates;
2935  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
2936  assert(conshdlrdata != NULL);
2937 
2938  // see if this is a call from functions like e.g. /see DECwriteAllDecomps
2939  if( conshdlrdata->partialdectowrite != NULL )
2940  {
2941  return conshdlrdata->partialdectowrite;
2942  }
2943 
2944  GCGconshdlrDecompChooseCandidatesFromSelected(scip, candidates, !transformed, TRUE);
2945 
2946  // if none was found, output "pure" problem
2947  if( candidates.empty() )
2948  {
2949  int id = GCGconshdlrDecompAddMatrixPartialdec(scip, transformed);
2950  return GCGconshdlrDecompGetPartialdecFromID(scip, id);
2951  }
2952 
2953  // get the index of the next fitting candidate
2954  for( dec = 0; dec < (int) candidates.size(); ++dec )
2955  {
2956  if( candidates[dec].first->isAssignedToOrigProb() != transformed )
2957  break;
2958  }
2959  // return the candidate iff one was found
2960  if( dec != (int) candidates.size() )
2961  return candidates[dec].first;
2962 
2963  return NULL;
2964 }
2965 
2966 
2968  SCIP* scip,
2969  SCIP_Bool transformed,
2970  PARTIALDECOMP_WRAPPER* partialdecwrapper
2971  )
2972 {
2973  partialdecwrapper->partialdec = DECgetPartialdecToWrite(scip, transformed);
2974 
2975  return SCIP_OKAY;
2976 }
2977 
2978 
2980  SCIP* scip
2981  )
2982 {
2983  SCIP_Real timelimit;
2984  assert(scip != NULL);
2985  SCIP_CALL_ABORT(SCIPgetRealParam(scip, "limits/time", &timelimit));
2986  if( !SCIPisInfinity(scip, timelimit) )
2987  timelimit -= SCIPgetSolvingTime(scip);
2988  return timelimit;
2989 }
2990 
2991 
2993  SCIP* scip,
2994  const char* name,
2995  const char* description,
2996  int priority,
2997  SCIP_Bool enabled,
2998  DEC_CLASSIFIERDATA* classifierdata,
2999  DEC_DECL_FREECONSCLASSIFIER((*freeClassifier)),
3000  DEC_DECL_CONSCLASSIFY((*classify))
3001  )
3002 {
3003  DEC_CONSCLASSIFIER *classifier;
3004 
3005  assert(scip != NULL);
3006  assert(name != NULL);
3007  assert(description != NULL);
3008 
3009  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3010 
3011  SCIP_CALL( SCIPallocBlockMemory(scip, &classifier) );
3012  assert(classifier != NULL);
3013 
3014  SCIPdebugMessage("Adding classifier %i: %s\n", conshdlrdata->nconsclassifiers+1, name);
3015 
3016  classifier->name = name;
3017  classifier->description = description;
3018  classifier->priority = priority;
3019  classifier->enabled = enabled;
3020  classifier->clsdata = classifierdata;
3021 
3022  classifier->freeClassifier = freeClassifier;
3023  classifier->classify = classify;
3024 
3025  char setstr[SCIP_MAXSTRLEN];
3026  char descstr[SCIP_MAXSTRLEN];
3027  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/classification/consclassifier/%s/enabled", name);
3028  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether constraint classifier for <%s> is enabled", description);
3029  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(classifier->enabled), FALSE, enabled, NULL, NULL) );
3030 
3031  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->consclassifiers, (size_t)conshdlrdata->nconsclassifiers+1) );
3032  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->consclassifierpriorities,(size_t) conshdlrdata->nconsclassifiers+1) );
3033 
3034  conshdlrdata->consclassifiers[conshdlrdata->nconsclassifiers] = classifier;
3035  conshdlrdata->nconsclassifiers = conshdlrdata->nconsclassifiers+1;
3036 
3037  return SCIP_OKAY;
3038 }
3039 
3040 
3041 SCIP_RETCODE DECincludeDetector(
3042  SCIP* scip,
3043  const char* name,
3044  const char decchar,
3045  const char* description,
3046  int freqCallRound,
3047  int maxCallRound,
3048  int minCallRound,
3049  int freqCallRoundOriginal,
3050  int maxCallRoundOriginal,
3051  int minCallRoundOriginal,
3052  int priority,
3053  SCIP_Bool enabled,
3054  SCIP_Bool enabledFinishing,
3055  SCIP_Bool enabledPostprocessing,
3056  SCIP_Bool skip,
3057  SCIP_Bool usefulRecall,
3058  DEC_DETECTORDATA* detectordata,
3059  DEC_DECL_FREEDETECTOR((*freeDetector)),
3060  DEC_DECL_INITDETECTOR((*initDetector)),
3061  DEC_DECL_EXITDETECTOR((*exitDetector)),
3062  DEC_DECL_PROPAGATEPARTIALDEC((*propagatePartialdecDetector)),
3063  DEC_DECL_FINISHPARTIALDEC((*finishPartialdecDetector)),
3064  DEC_DECL_POSTPROCESSPARTIALDEC((*postprocessPartialdecDetector)),
3065  DEC_DECL_SETPARAMAGGRESSIVE((*setParamAggressiveDetector)),
3066  DEC_DECL_SETPARAMDEFAULT((*setParamDefaultDetector)),
3067  DEC_DECL_SETPARAMFAST((*setParamFastDetector))
3068  )
3069 {
3070  DEC_DETECTOR *detector;
3071  char setstr[SCIP_MAXSTRLEN];
3072  char descstr[SCIP_MAXSTRLEN];
3073 
3074  assert(scip != NULL);
3075  assert(name != NULL);
3076  assert(description != NULL);
3077  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3078 
3079  if( conshdlrdata == NULL )
3080  {
3081  SCIPerrorMessage("Decomp constraint handler is not included, cannot add detector!\n");
3082  return SCIP_ERROR;
3083  }
3084 
3085  SCIP_CALL( SCIPallocBlockMemory(scip, &detector) );
3086  assert(detector != NULL);
3087 
3088  SCIPdebugMessage("Adding detector %i: %s\n", conshdlrdata->ndetectors+1, name);
3089 
3090 #ifndef NDEBUG
3091  assert(DECfindDetector(scip, name) == NULL);
3092 #endif
3093 
3094  /* set meta data of detector */
3095  detector->decdata = detectordata;
3096  SCIP_ALLOC( BMSduplicateMemoryArray(&detector->name, name, strlen(name)+1) );
3097  SCIP_ALLOC( BMSduplicateMemoryArray(&detector->description, description, strlen(description)+1) );
3098  detector->decchar = decchar;
3099 
3100  /* set memory handling and detection functions */
3101  detector->freeDetector = freeDetector;
3102  detector->initDetector = initDetector;
3103  detector->exitDetector = exitDetector;
3104 
3105  /* set functions for editing partialdecs */
3106  detector->propagatePartialdec = propagatePartialdecDetector;
3107  detector->finishPartialdec = finishPartialdecDetector;
3108  detector->postprocessPartialdec = postprocessPartialdecDetector;
3109 
3110  /* initialize parameters */
3111  detector->setParamAggressive = setParamAggressiveDetector;
3112  detector->setParamDefault = setParamDefaultDetector;
3113  detector->setParamFast = setParamFastDetector;
3114  detector->freqCallRound = freqCallRound;
3115  detector->maxCallRound = maxCallRound;
3116  detector->minCallRound = minCallRound;
3117  detector->freqCallRoundOriginal = freqCallRoundOriginal;
3118  detector->maxCallRoundOriginal = maxCallRoundOriginal;
3119  detector->minCallRoundOriginal= minCallRoundOriginal;
3120  detector->priority = priority;
3121  detector->enabled = enabled;
3122  detector->enabledFinishing = enabledFinishing;
3123  detector->enabledPostprocessing = enabledPostprocessing;
3124  detector->skip = skip;
3125  detector->usefulRecall = usefulRecall;
3126  detector->overruleemphasis = FALSE;
3127  detector->ndecomps = 0;
3128  detector->ncompletedecomps = 0;
3129  detector->dectime = 0.;
3130 
3131  /* add and initialize all parameters accessable from menu */
3132  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
3133  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether detector <%s> is enabled", name);
3134  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(detector->enabled), FALSE, enabled, NULL, NULL) );
3135 
3136  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
3137  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether detector <%s> is enabled for finishing of incomplete decompositions", name);
3138  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(detector->enabledFinishing), FALSE, enabledFinishing, NULL, NULL) );
3139 
3140  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/postprocessingenabled", name);
3141  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether detector <%s> is enabled for postprocessing of finished decompositions", name);
3142  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(detector->enabledPostprocessing), FALSE, enabledPostprocessing, NULL, NULL) );
3143 
3144  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/skip", name);
3145  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether detector <%s> should be skipped if others found decompositions", name);
3146  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(detector->skip), FALSE, skip, NULL, NULL) );
3147 
3148  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/usefullrecall", name);
3149  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether detector <%s> should be called on descendants of the current partialdec", name);
3150  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(detector->usefulRecall), FALSE, usefulRecall, NULL, NULL) );
3151 
3152  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/overruleemphasis", name);
3153  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether emphasis settings for detector <%s> should be overruled by normal settings", name);
3154  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(detector->overruleemphasis), FALSE, FALSE, NULL, NULL) );
3155 
3156  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/freqcallround", name);
3157  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "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 <%s>", name);
3158  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->freqCallRound), FALSE, freqCallRound, 0, INT_MAX, NULL, NULL) );
3159 
3160  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxcallround", name);
3161  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "maximum round the detector gets called in detection loop <%s>", name);
3162  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->maxCallRound), FALSE, maxCallRound, 0, INT_MAX, NULL, NULL) );
3163 
3164  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/mincallround", name);
3165  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "minimum round the detector gets called in detection loop <%s>", name);
3166  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->minCallRound), FALSE, minCallRound, 0, INT_MAX, NULL, NULL) );
3167 
3168  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/origfreqcallround", name);
3169  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "frequency the detector gets called in detection loop,i.e., it is called in round r if and only if minCallRound <= r <= maxCallRound AND (r - minCallRound) mod freqCallRound == 0 <%s>", name);
3170  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->freqCallRoundOriginal), FALSE, freqCallRoundOriginal, 0, INT_MAX, NULL, NULL) );
3171 
3172  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/origmaxcallround", name);
3173  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "maximum round the detector gets called in detection loop <%s>", name);
3174  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->maxCallRoundOriginal), FALSE, maxCallRoundOriginal, 0, INT_MAX, NULL, NULL) );
3175 
3176  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/origmincallround", name);
3177  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "minimum round the detector gets called in detection loop <%s>", name);
3178  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->minCallRoundOriginal), FALSE, minCallRoundOriginal, 0, INT_MAX, NULL, NULL) );
3179 
3180  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/priority", name);
3181  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "priority of detector <%s>", name);
3182  SCIP_CALL( SCIPaddIntParam(scip, setstr, descstr, &(detector->priority), FALSE, priority, INT_MIN, INT_MAX, NULL, NULL) );
3183 
3184  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->detectors, (size_t)conshdlrdata->ndetectors+1) );
3185  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->priorities,(size_t) conshdlrdata->ndetectors+1) );
3186 
3187  /* add to detector array */
3188  conshdlrdata->detectors[conshdlrdata->ndetectors] = detector;
3189  conshdlrdata->ndetectors = conshdlrdata->ndetectors+1;
3190 
3191  // TODO ref replace propagatePartialdec by more appropriate name once partialdecs are introduced
3192  /* add to propagating detector array if appropriate */
3193  if( detector->propagatePartialdec != NULL )
3194  {
3195  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->propagatingdetectors, (size_t)conshdlrdata->npropagatingdetectors+1) );
3196  conshdlrdata->propagatingdetectors[conshdlrdata->npropagatingdetectors] = detector;
3197  conshdlrdata->npropagatingdetectors = conshdlrdata->npropagatingdetectors+1;
3198  }
3199 
3200  // TODO ref replace finishPartialdec by more appropriate name once partialdecs are introduced
3201  /* add to finishing detector array if appropriate */
3202  if( detector->finishPartialdec != NULL )
3203  {
3204  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->finishingdetectors, (size_t)conshdlrdata->nfinishingdetectors+1) );
3205  conshdlrdata->finishingdetectors[conshdlrdata->nfinishingdetectors] = detector;
3206  conshdlrdata->nfinishingdetectors = conshdlrdata->nfinishingdetectors+1;
3207  }
3208 
3209  // TODO ref replace postprocessPartialdec by more appropriate name once partialdecs are introduced
3210  /* add to postprocessing detector array if appropriate */
3211  if( detector->postprocessPartialdec != NULL )
3212  {
3213  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->postprocessingdetectors, (size_t)conshdlrdata->npostprocessingdetectors+1) );
3214  conshdlrdata->postprocessingdetectors[conshdlrdata->npostprocessingdetectors] = detector;
3215  conshdlrdata->npostprocessingdetectors = conshdlrdata->npostprocessingdetectors+1;
3216  }
3217 
3218  return SCIP_OKAY;
3219 }
3220 
3221 
3223  SCIP* scip,
3224  const char* name,
3225  const char* description,
3226  int priority,
3227  SCIP_Bool enabled,
3228  DEC_CLASSIFIERDATA* classifierdata,
3229  DEC_DECL_FREEVARCLASSIFIER((*freeClassifier)),
3230  DEC_DECL_VARCLASSIFY((*classify))
3231  )
3232 {
3233  DEC_VARCLASSIFIER *classifier;
3234 
3235  assert(scip != NULL);
3236  assert(name != NULL);
3237  assert(description != NULL);
3238 
3239  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3240 
3241  SCIP_CALL( SCIPallocBlockMemory(scip, &classifier) );
3242  assert(classifier != NULL);
3243 
3244  SCIPdebugMessage("Adding classifier %i: %s\n", conshdlrdata->nvarclassifiers+1, name);
3245 
3246  classifier->name = name;
3247  classifier->description = description;
3248  classifier->priority = priority;
3249  classifier->enabled = enabled;
3250  classifier->clsdata = classifierdata;
3251 
3252  classifier->freeClassifier = freeClassifier;
3253  classifier->classify = classify;
3254 
3255  char setstr[SCIP_MAXSTRLEN];
3256  char descstr[SCIP_MAXSTRLEN];
3257  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/classification/varclassifier/%s/enabled", name);
3258  (void) SCIPsnprintf(descstr, SCIP_MAXSTRLEN, "flag to indicate whether variable classifier for <%s> is enabled", description);
3259  SCIP_CALL( SCIPaddBoolParam(scip, setstr, descstr, &(classifier->enabled), FALSE, enabled, NULL, NULL) );
3260 
3261  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->varclassifiers, (size_t)conshdlrdata->nvarclassifiers+1) );
3262  SCIP_CALL( SCIPreallocMemoryArray(scip, &conshdlrdata->varclassifierpriorities,(size_t) conshdlrdata->nvarclassifiers+1) );
3263 
3264  conshdlrdata->varclassifiers[conshdlrdata->nvarclassifiers] = classifier;
3265  conshdlrdata->nvarclassifiers = conshdlrdata->nvarclassifiers+1;
3266 
3267  return SCIP_OKAY;
3268 }
3269 
3270 
3272  SCIP* scip
3273  )
3274 {
3275  int ndetectors;
3276  int i;
3277 
3278  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3279  assert(conshdlrdata != NULL);
3280 
3281  ndetectors = conshdlrdata->ndetectors;
3282 
3283  SCIPdialogMessage(scip, NULL, " detector char priority enabled description\n");
3284  SCIPdialogMessage(scip, NULL, " -------------- ---- -------- ------- -----------\n");
3285 
3286  for( i = 0; i < ndetectors; ++i )
3287  {
3288  SCIPdialogMessage(scip, NULL, " %-20s", conshdlrdata->detectors[i]->name);
3289  SCIPdialogMessage(scip, NULL, " %c", conshdlrdata->detectors[i]->decchar);
3290  SCIPdialogMessage(scip, NULL, " %8d", conshdlrdata->detectors[i]->priority);
3291  SCIPdialogMessage(scip, NULL, " %7s", conshdlrdata->detectors[i]->enabled ? "TRUE" : "FALSE");
3292  SCIPdialogMessage(scip, NULL, " %s\n", conshdlrdata->detectors[i]->description);
3293  }
3294 }
3295 
3296 
3297 SCIP_RETCODE DECwriteAllDecomps(
3298  SCIP* scip,
3299  char* directory,
3300  char* extension,
3301  SCIP_Bool original,
3302  SCIP_Bool presolved
3303  )
3304 {
3305  char outname[SCIP_MAXSTRLEN];
3306  char tempstring[SCIP_MAXSTRLEN];
3307  int i;
3308 
3309  int maxtowrite;
3310  int nwritten;
3311 
3312  assert(extension != NULL);
3313 
3314  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3315  assert(conshdlrdata != NULL);
3316 
3317  maxtowrite = -1;
3318  nwritten = 0;
3319 
3320  if( presolved && conshdlrdata->detprobdatapres != NULL && conshdlrdata->detprobdatapres->getNFinishedPartialdecs() == 0 )
3321  {
3322  SCIPwarningMessage(scip, "No decomposition available.\n");
3323  return SCIP_OKAY;
3324  }
3325 
3326  SCIPgetIntParam(scip, "visual/nmaxdecompstowrite", &maxtowrite );
3327 
3328  /* write all finished partialdecs */
3329  std::vector<PARTIALDECOMP*> partialdecs;
3330  getFinishedPartialdecs(scip, partialdecs);
3331  for( i = 0; i < (int) partialdecs.size(); i++)
3332  {
3333  PARTIALDECOMP* partialdec = partialdecs.at(i);
3334 
3335  /* get filename */
3336  GCGgetVisualizationFilename(scip, partialdec, extension, tempstring);
3337  if( directory != NULL )
3338  {
3339  (void) SCIPsnprintf(outname, SCIP_MAXSTRLEN, "%s/%s.%s", directory, tempstring, extension);
3340  }
3341  else
3342  {
3343  (void) SCIPsnprintf(outname, SCIP_MAXSTRLEN, "%s.%s", tempstring, extension);
3344  }
3345 
3346  /* mark partialdec */
3347  conshdlrdata->partialdectowrite = partialdec;
3348 
3349  /* these functions write the marked partialdec */
3350  if( partialdec->isAssignedToOrigProb() )
3351  SCIP_CALL_QUIET( SCIPwriteOrigProblem(scip, outname, extension, FALSE) );
3352  else
3353  SCIP_CALL( SCIPwriteTransProblem(scip, outname, extension, FALSE) );
3354 
3355  ++nwritten;
3356  conshdlrdata->partialdectowrite = NULL;
3357 
3358  /* stop if max is reached */
3359  if( maxtowrite != -1 && nwritten >= maxtowrite )
3360  break;
3361  }
3362 
3363  return SCIP_OKAY;
3364 }
3365 
3366 
3368  SCIP* scip,
3369  char* directory,
3370  char* extension
3371  )
3372 {
3373  char outname[SCIP_MAXSTRLEN];
3374  char tempstring[SCIP_MAXSTRLEN];
3375 
3376  assert(extension != NULL);
3377 
3378  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3379  assert(conshdlrdata != NULL);
3380 
3381  if( conshdlrdata->partialdecs->empty() )
3382  {
3383  SCIPwarningMessage(scip, "No decomposition available.\n");
3384  return SCIP_OKAY;
3385  }
3386 
3387  std::vector<PARTIALDECOMP*> selectedpartialdecs;
3388  getSelectedPartialdecs(scip, selectedpartialdecs);
3389  if( selectedpartialdecs.empty() )
3390  {
3391  SCIPwarningMessage(scip, "No decomposition selected.\n");
3392  return SCIP_OKAY;
3393  }
3394 
3395  for(auto & partialdec : selectedpartialdecs)
3396  {
3397  GCGgetVisualizationFilename(scip, partialdec, extension, tempstring);
3398  if( directory != NULL )
3399  {
3400  (void) SCIPsnprintf(outname, SCIP_MAXSTRLEN, "%s/%s.%s", directory, tempstring, extension);
3401  }
3402  else
3403  {
3404  (void) SCIPsnprintf(outname, SCIP_MAXSTRLEN, "%s.%s", tempstring, extension);
3405  }
3406 
3407  conshdlrdata->partialdectowrite = partialdec;
3408 
3409  if ( partialdec->isAssignedToOrigProb() )
3410  SCIP_CALL_QUIET( SCIPwriteOrigProblem(scip, outname, extension, FALSE) );
3411  else
3412  SCIP_CALL_QUIET( SCIPwriteTransProblem(scip, outname, extension, FALSE) );
3413 
3414  conshdlrdata->partialdectowrite = NULL;
3415  }
3416 
3417  return SCIP_OKAY;
3418 }
3419 
3420 
3422  SCIP* scip,
3423  SCIP_Bool presolved
3424  )
3425 {
3426  PARTIALDECOMP* partialdec = new PARTIALDECOMP(scip, !presolved);
3427  partialdec->setNBlocks(0);
3428  partialdec->assignOpenConssToMaster();
3429  partialdec->prepare();
3430  addPartialdec(scip, partialdec);
3431  return partialdec->getID();
3432 }
3433 
3434 
3436  SCIP* scip,
3437  SCIP_Bool origprob,
3438  int candidate
3439  )
3440 {
3441  gcg::DETPROBDATA* detprobdata;
3442  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3443  assert(conshdlrdata != NULL);
3444 
3445  detprobdata = origprob ? conshdlrdata->detprobdataorig : conshdlrdata->detprobdatapres;
3446 
3447  if( candidate > 1 )
3448  {
3449  bool alreadyIn = false;
3450  for( size_t i = 0; i < detprobdata->candidatesNBlocks.size(); ++ i )
3451  {
3452  if( detprobdata->candidatesNBlocks[i].first == candidate )
3453  {
3454  alreadyIn = true;
3455  ++detprobdata->candidatesNBlocks[i].second;
3456  break;
3457  }
3458  }
3459  if( !alreadyIn )
3460  {
3461  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "added block number candidate: %d \n", candidate );
3462  detprobdata->candidatesNBlocks.emplace_back(candidate, 1);
3463  }
3464  }
3465 }
3466 
3467 
3469  SCIP* scip,
3470  DEC_DECOMP* decomp,
3471  SCIP_Bool select
3472  )
3473 {
3474  PARTIALDECOMP* partialdec;
3475 
3476  if( decomp->presolved && SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED )
3477  {
3478  SCIPerrorMessage("Problem is not presolved yet.");
3479  return SCIP_ERROR;
3480  }
3481 
3482  SCIP_CALL( createPartialdecFromDecomp(scip, decomp, &partialdec) );
3483  SCIP_CALL( addPartialdec(scip, partialdec) );
3484  partialdec->setSelected(select);
3485 
3486  return SCIP_OKAY;
3487 }
3488 
3489 
3491  SCIP* scip,
3492  SCIP_Bool presolved
3493  )
3494 {
3495  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3496  assert(conshdlrdata != NULL);
3497 
3498  DETPROBDATA* detprobdata;
3499  // check if detection took place (this might be used in e.g. write problem)
3500  if(presolved)
3501  {
3503  resetDetprobdata(scip, false);
3504  detprobdata = conshdlrdata->detprobdatapres;
3505  }
3506  else
3507  {
3509  resetDetprobdata(scip, true);
3510  detprobdata = conshdlrdata->detprobdataorig;
3511  }
3512 
3513  assert(detprobdata != NULL);
3514 
3515  PARTIALDECOMP* matrixpartialdec;
3516 
3517  matrixpartialdec = new PARTIALDECOMP(scip, !presolved);
3518  matrixpartialdec->setNBlocks(1);
3519 
3520  for( int i = 0; i < detprobdata->getNConss(); ++i )
3521  matrixpartialdec->fixConsToBlock(i,0);
3522 
3523  for( int i = 0; i < detprobdata->getNVars(); ++i )
3524  matrixpartialdec->fixVarToBlock(i,0);
3525 
3526  matrixpartialdec->sort();
3527 
3528  detprobdata->addPartialdecToFinishedUnchecked(matrixpartialdec);
3529 
3530  return matrixpartialdec->getID();
3531 }
3532 
3533 
3535  SCIP* scip,
3536  DEC_DECOMP* decomp
3537  )
3538 {
3539  PARTIALDECOMP* partialdec;
3540 
3541  if( decomp->presolved && SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED )
3542  {
3543  SCIPerrorMessage("Problem is not presolved yet.");
3544  return SCIP_ERROR;
3545  }
3546 
3547  SCIP_CALL( createPartialdecFromDecomp(scip, decomp, &partialdec) );
3549 
3550  return SCIP_OKAY;
3551 }
3552 
3553 
3555  SCIP* scip,
3556  PARTIALDECOMP* partialdec
3557  )
3558 {
3559  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3560  bool assignedconss = false;
3561  assert(conshdlrdata != NULL);
3562  assert( partialdec != NULL );
3563 
3564  if( partialdec->shouldCompletedByConsToMaster() )
3565  {
3566  auto& openconss = partialdec->getOpenconssVec();
3567  for( auto itr = openconss.cbegin(); itr != openconss.cend(); )
3568  {
3569  itr = partialdec->fixConsToMaster(itr);
3570  assignedconss = true;
3571  }
3572  partialdec->sort();
3573  }
3574 
3575  partialdec->prepare();
3576 #ifndef NDEBUG
3577  if( partialdec->getUsergiven() == USERGIVEN::COMPLETE || partialdec->getUsergiven() == USERGIVEN::COMPLETED_CONSTOMASTER )
3578  assert( partialdec->isComplete() );
3579 #endif
3580 
3581  if( partialdec->isComplete() )
3582  {
3583  if( !assignedconss )
3584  partialdec->setUsergiven( USERGIVEN::COMPLETE );
3585  addPartialdec(scip, partialdec);
3586 
3587  /* if detprobdata for presolved problem already exist try to translate partialdec */
3588  if ( conshdlrdata->detprobdatapres != NULL && partialdec->isAssignedToOrigProb())
3589  {
3590  std::vector<PARTIALDECOMP*> partialdectotranslate;
3591  partialdectotranslate.push_back(partialdec);
3592  std::vector<PARTIALDECOMP*> newpartialdecs = conshdlrdata->detprobdatapres->translatePartialdecs(conshdlrdata->detprobdataorig, partialdectotranslate);
3593  if( !newpartialdecs.empty() )
3594  {
3595  addPartialdec(scip, newpartialdecs[0]);
3596  }
3597  }
3598  }
3599  else
3600  {
3601  partialdec->setUsergiven( USERGIVEN::PARTIAL );
3602  addPartialdec(scip, partialdec);
3603  }
3604 
3605  /* set statistics */
3606  int nvarstoblock = 0;
3607  int nconsstoblock = 0;
3608 
3609  for ( int b = 0; b < partialdec->getNBlocks(); ++b )
3610  {
3611  nvarstoblock += partialdec->getNVarsForBlock(b);
3612  nconsstoblock += partialdec->getNConssForBlock(b);
3613  }
3614 
3615  partialdec->findVarsLinkingToMaster();
3616  partialdec->findVarsLinkingToStairlinking();
3617 
3618  char const* usergiveninfo;
3619  char const* presolvedinfo;
3620 
3621  if( partialdec->getUsergiven() == USERGIVEN::PARTIAL )
3622  usergiveninfo = "partial";
3623  if( partialdec->getUsergiven() == USERGIVEN::COMPLETE )
3624  usergiveninfo = "complete";
3625  if( partialdec->getUsergiven() == USERGIVEN::COMPLETED_CONSTOMASTER )
3626  usergiveninfo = "complete";
3627  if( partialdec->isAssignedToOrigProb() )
3628  presolvedinfo = "original";
3629  else presolvedinfo = "presolved";
3630 
3631  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " added %s decomp for %s problem with %d blocks and %d masterconss, %d linkingvars, "
3632  "%d mastervars, and max white score of %s %f \n", usergiveninfo, presolvedinfo,
3633  partialdec->getNBlocks(), partialdec->getNMasterconss(),
3634  partialdec->getNLinkingvars(), partialdec->getNMastervars(), (partialdec->isComplete() ? " " : " at best "),
3635  partialdec->getScore(SCORETYPE::MAX_WHITE) );
3636 
3637  return SCIP_OKAY;
3638 }
3639 
3640 
3642  SCIP* scip,
3643  SCIP_Real time
3644  )
3645 {
3646  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3647  conshdlrdata->scoretotaltime += time;
3648  return SCIP_OKAY;
3649 }
3650 
3651 
3653  SCIP* scip,
3654  int candidate
3655  )
3656 {
3657  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3658 
3659  // make sure there is a problem
3660  if(SCIPgetStage(scip) < SCIP_STAGE_PROBLEM)
3661  {
3662  SCIPdialogMessage(scip, NULL,
3663  "Please add a problem before adding block candidates.\n");
3664  return;
3665  }
3666 
3667  conshdlrdata->userblocknrcandidates->push_back(candidate);
3668 
3669  SCIPverbMessage(scip, SCIP_VERBLEVEL_DIALOG, NULL, "added user block number candidate: %d \n", candidate );
3670 }
3671 
3672 
3674  SCIP* scip,
3675  int partialdecid,
3676  int probnr1,
3677  int probnr2,
3678  SCIP_Bool* identical
3679  )
3680 {
3681  gcg::PARTIALDECOMP* partialdec;
3682 
3683  partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
3684  assert(partialdec != NULL);
3685  assert(partialdec->isComplete());
3686 
3687  if( !partialdec->aggInfoCalculated() )
3688  {
3689  SCIPdebugMessage("calc aggregation information for partialdec!\n");
3690  // ignore limits of detection since we do this only for this specific partialdec
3691  partialdec->calcAggregationInformation(true);
3692  }
3693 
3694  if( partialdec->getRepForBlock(probnr1) == partialdec->getRepForBlock(probnr2) )
3695  *identical = TRUE;
3696  else
3697  *identical = FALSE;
3698 
3699  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, " block %d and block %d are represented by %d and %d hence they are identical=%d.\n", probnr1, probnr2, partialdec->getRepForBlock(probnr1), partialdec->getRepForBlock(probnr2), *identical );
3700 
3701  return SCIP_OKAY;
3702 }
3703 
3704 
3706  SCIP* scip,
3707  int partialdecid,
3708  SCIP_Real* score
3709  )
3710 {
3711  SCIP_Real benderareascore = 0;
3712 
3713  unsigned long nrelevantconss;
3714  unsigned long nrelevantvars;
3715  unsigned long nrelevantconss2;
3716  unsigned long nrelevantvars2;
3717  unsigned long badblockvararea;
3718  long benderborderarea;
3719  unsigned long totalarea;
3720 
3721  nrelevantconss = 0;
3722  nrelevantvars = 0;
3723  nrelevantconss2 = 0;
3724  nrelevantvars2 = 0;
3725  badblockvararea = 0;
3726 
3727  SCIP_CLOCK* clock;
3728  SCIP_CALL_ABORT( SCIPcreateClock( scip, &clock) );
3729  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
3730 
3731  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
3732 
3733  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
3734 
3735  /* calc bender area score (1 - fraction of white area in master constraints to complete area) */
3736  for( int c = 0; c < partialdec->getNMasterconss(); ++c )
3737  {
3738  bool relevant = true;
3739  int cons = partialdec->getMasterconss()[c];
3740  for( int v = 0; v < detprobdata->getNVarsForCons(cons); ++v )
3741  {
3742  int var = detprobdata->getVarsForCons(cons)[v];
3743  if ( partialdec->isVarOpenvar(var) || partialdec->isVarMastervar(var) || partialdec->isVarLinkingvar(var) )
3744  {
3745  relevant = false;
3746  break;
3747  }
3748 
3749  }
3750  if( relevant )
3751  ++nrelevantconss;
3752  }
3753 
3754  for( int b = 0; b < partialdec->getNBlocks(); ++b )
3755  {
3756  for(int v = 0; v < partialdec->getNVarsForBlock(b); ++v )
3757  {
3758  bool relevant = true;
3759  int var = partialdec->getVarsForBlock(b)[v];
3760  for( int c = 0; c < detprobdata->getNConssForVar(var); ++c )
3761  {
3762  int cons = detprobdata->getConssForVar(var)[c];
3763  if( partialdec->isConsMastercons(cons) || partialdec->isConsOpencons(cons) )
3764  {
3765  relevant = false;
3766  for( int b2 = 0; b2 < partialdec->getNBlocks(); ++b2 )
3767  {
3768  if( b2 != b )
3769  badblockvararea += partialdec->getNConssForBlock(b2);
3770  }
3771  break;
3772  }
3773  }
3774  if( relevant )
3775  ++nrelevantvars;
3776  }
3777  }
3778 
3779  for( int v = 0; v < partialdec->getNLinkingvars(); ++v )
3780  {
3781  bool relevant = true;
3782  int var = partialdec->getLinkingvars()[v];
3783  for( int c = 0; c < detprobdata->getNConssForVar(var); ++c )
3784  {
3785  int cons = detprobdata->getConssForVar(var)[c];
3786  if ( partialdec->isConsOpencons(cons) || partialdec->isConsMastercons(cons) )
3787  {
3788  relevant = false;
3789  break;
3790  }
3791 
3792  }
3793  if( relevant )
3794  ++nrelevantvars2;
3795  }
3796 
3797  for( int b = 0; b < partialdec->getNBlocks(); ++b )
3798  {
3799  for(int c = 0; c < partialdec->getNConssForBlock(b); ++c )
3800  {
3801  bool relevant = true;
3802  int cons = partialdec->getConssForBlock(b)[c];
3803  for( int v = 0; v < detprobdata->getNVarsForCons(cons); ++v )
3804  {
3805  int var = detprobdata->getVarsForCons(cons)[v];
3806  if( partialdec->isVarLinkingvar(var) || partialdec->isVarOpenvar(var) )
3807  {
3808  relevant = false;
3809  break;
3810  }
3811  }
3812  if( relevant )
3813  ++nrelevantconss2;
3814  }
3815  }
3816 
3817  benderborderarea = ( nrelevantconss * nrelevantvars ) + ( nrelevantconss2 * nrelevantvars2 ) - badblockvararea;
3818  totalarea = ( (unsigned long) partialdec->getNConss() * (unsigned long) partialdec->getNVars() );
3819  benderareascore = ( SCIP_Real) benderborderarea / totalarea;
3820 
3821  /* get block & border area score (note: these calculations have their own clock) */
3822  SCIP_Real borderareascore;
3823  SCIP_CALL_ABORT(SCIPstopClock( scip, clock) );
3824  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime( scip, clock));
3825 
3826  SCIP_Real blockareascore = calcBlockAreaScore(scip, partialdec);
3827  borderareascore = partialdec->getBorderAreaScore();
3828  if(borderareascore == -1)
3829  GCGconshdlrDecompCalcBorderAreaScore(scip, partialdecid, &borderareascore);
3830 
3831  SCIP_CALL_ABORT(SCIPresetClock( scip, clock) );
3832  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
3833 
3834  *score = blockareascore + benderareascore + borderareascore - 1.;
3835 
3836  if( *score < 0. )
3837  *score = 0.;
3838 
3839  partialdec->setBendersScore(*score);
3840 
3841  SCIP_CALL_ABORT(SCIPstopClock( scip, clock) );
3842  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime( scip, clock));
3843  SCIP_CALL_ABORT(SCIPfreeClock( scip, &clock) );
3844 
3845  return SCIP_OKAY;
3846 }
3847 
3848 
3850  SCIP* scip,
3851  int partialdecid,
3852  SCIP_Real* score
3853  )
3854 {
3855  unsigned long matrixarea;
3856  unsigned long borderarea;
3857 
3858  SCIP_CLOCK* clock;
3859  SCIP_CALL_ABORT( SCIPcreateClock( scip, &clock) );
3860  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
3861 
3862  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
3863 
3864  matrixarea = (unsigned long) partialdec->getNVars() * (unsigned long)partialdec->getNConss();
3865  borderarea = 0;
3866 
3867  borderarea += (unsigned long) ( partialdec->getNLinkingvars() + partialdec->getNTotalStairlinkingvars() ) * (unsigned long) partialdec->getNConss();
3868  borderarea += (unsigned long) partialdec->getNMasterconss() * ( (unsigned long) partialdec->getNVars() - ( partialdec->getNLinkingvars() + partialdec->getNTotalStairlinkingvars() ) ) ;
3869 
3870  *score = 1. - (matrixarea == 0 ? 0 : ( (SCIP_Real) borderarea / (SCIP_Real) matrixarea ));
3871 
3872  partialdec->setBorderAreaScore(*score);
3873 
3874  SCIP_CALL_ABORT(SCIPstopClock( scip, clock) );
3875  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime( scip, clock));
3876  SCIP_CALL_ABORT(SCIPfreeClock( scip, &clock) );
3877 
3878  return SCIP_OKAY;
3879 }
3880 
3881 
3883  SCIP* scip,
3884  SCIP_Bool transformed
3885  )
3886 {
3887  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
3888  gcg::DETPROBDATA* detprobdata = (transformed ? conshdlrdata->detprobdatapres : conshdlrdata->detprobdataorig );
3889  /* strategy: for every subset of constraint classes and variable classes calculate gcd (greatest common divisors)
3890  * of the corresponding number of constraints/variables assigned to this class */
3891 
3892  SCIP_CLOCK* nblockcandnclock;
3893  SCIPcreateClock( scip, & nblockcandnclock );
3894  SCIPstartClock( scip, nblockcandnclock );
3895 
3896  /* if distribution of classes exceeds this number it is skipped */
3897  int maximumnclasses;
3898  SCIP_Bool medianvarspercons;
3899 
3900  /* used for nvars / medianofnvars per conss */
3901  std::vector<int> nvarspercons(0);
3902  std::list<int>::iterator iter;
3903  int candidate = -1;
3904 
3905  medianvarspercons = conshdlrdata->blocknumbercandsmedianvarspercons;
3906  maximumnclasses = conshdlrdata->maxnclassesfornblockcandidates;
3907 
3908  /* firstly, iterate over all conspartitions */
3909  for( auto partition : detprobdata->conspartitioncollection )
3910  {
3911  /* check if there are too many classes in this distribution and skip it if so */
3912  if( partition->getNClasses() > maximumnclasses )
3913  {
3914  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " the current consclass distribution includes %d classes but only %d are allowed for GCGconshdlrDecompCalcCandidatesNBlocks()\n", partition->getNClasses(), maximumnclasses );
3915  continue;
3916  }
3917 
3918  /* get necessary data of current partition */
3919  std::vector<std::vector<int>> subsetsOfConstypes = partition->getAllSubsets(true, true, true );
3920  std::vector<int> nConssOfClasses = partition->getNConssOfClasses();
3921 
3922  /* start with the cardinalities of the consclasses as candidates */
3923  for( size_t i = 0; i < nConssOfClasses.size(); ++ i )
3924  {
3925  GCGconshdlrDecompAddCandidatesNBlocks( scip, detprobdata->isAssignedToOrigProb(), nConssOfClasses[i] );
3926  }
3927 
3928  /* continue with gcd of all cardinalities in this subset */
3929  for( size_t subset = 0; subset < subsetsOfConstypes.size(); ++ subset )
3930  {
3931  int greatestCD = 1;
3932 
3933  if( subsetsOfConstypes[subset].empty() || subsetsOfConstypes[subset].size() == 1 )
3934  continue;
3935 
3936  greatestCD = gcd( nConssOfClasses[subsetsOfConstypes[subset][0]], nConssOfClasses[subsetsOfConstypes[subset][1]] );
3937 
3938  for( size_t i = 2; i < subsetsOfConstypes[subset].size(); ++ i )
3939  {
3940  greatestCD = gcd( greatestCD, nConssOfClasses[subsetsOfConstypes[subset][i]] );
3941  }
3942 
3943  GCGconshdlrDecompAddCandidatesNBlocks( scip, detprobdata->isAssignedToOrigProb(), greatestCD );
3944  }
3945  }
3946 
3947  /* secondly, iterate over all varpartitions */
3948  for( auto partition : detprobdata->varpartitioncollection )
3949  {
3950  /* check if there are too many classes in this distribution and skip it if so */
3951  if( partition->getNClasses() > maximumnclasses )
3952  {
3953  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, " the current varclass distribution includes %d classes but only %d are allowed for GCGconshdlrDecompCalcCandidatesNBlocks()\n", partition->getNClasses(), maximumnclasses );
3954  continue;
3955  }
3956 
3957  /* get necessary data of current partition */
3958  std::vector<std::vector<int>> subsetsOfVartypes = partition->getAllSubsets(true, true, true, true );
3959  std::vector<int> nVarsOfClasses = partition->getNVarsOfClasses();
3960 
3961  /* start with the cardinalities of the varclasses as candidates */
3962  for( int nVarsOfClasse : nVarsOfClasses )
3963  {
3964  GCGconshdlrDecompAddCandidatesNBlocks( scip, detprobdata->isAssignedToOrigProb(), nVarsOfClasse );
3965  }
3966 
3967  /* continue with gcd of all cardinalities in this subset */
3968  for(auto& subsetsOfVartype : subsetsOfVartypes)
3969  {
3970  int greatestCD = 1;
3971 
3972  if( subsetsOfVartype.empty() || subsetsOfVartype.size() == 1 )
3973  continue;
3974 
3975  greatestCD = gcd( nVarsOfClasses[subsetsOfVartype[0]], nVarsOfClasses[subsetsOfVartype[1]] );
3976 
3977  for( size_t i = 2; i < subsetsOfVartype.size(); ++ i )
3978  {
3979  greatestCD = gcd( greatestCD, nVarsOfClasses[subsetsOfVartype[i]] );
3980  }
3981 
3982  GCGconshdlrDecompAddCandidatesNBlocks( scip, detprobdata->isAssignedToOrigProb(), greatestCD );
3983  }
3984  }
3985 
3986  /* block number candidate could be nvars / median of nvarsinconss only calculate if desired*/
3987  if( medianvarspercons )
3988  {
3989  for( int c = 0; c < detprobdata->getNConss(); ++c )
3990  {
3991  nvarspercons.push_back( detprobdata->getNVarsForCons(c) );
3992  }
3993  std::sort(nvarspercons.begin(), nvarspercons.end() );
3994  candidate = (int) detprobdata->getNVars() / nvarspercons[(int)detprobdata->getNConss()/2];
3995 
3996  GCGconshdlrDecompAddCandidatesNBlocks( scip, detprobdata->isAssignedToOrigProb(), candidate);
3997  }
3998 
3999  SCIPstopClock( scip, nblockcandnclock );
4000  detprobdata->nblockscandidatescalctime = SCIPgetClockTime( scip, nblockcandnclock );
4001  SCIPfreeClock( scip, & nblockcandnclock );
4002 }
4003 
4004 
4006  SCIP* scip,
4007  int partialdecid,
4008  SCIP_Real* score
4009  )
4010 {
4011  int i;
4012  int j;
4013  int k;
4014 
4015  unsigned long matrixarea;
4016  unsigned long borderarea;
4017  SCIP_Real borderscore; /* score of the border */
4018  SCIP_Real densityscore; /* score of block densities */
4019  SCIP_Real linkingscore; /* score related to interlinking blocks */
4020  SCIP_Real totalscore; /* accumulated score */
4021 
4022  SCIP_Real varratio;
4023  int* nzblocks;
4024  int* nlinkvarsblocks;
4025  int* nvarsblocks;
4026  SCIP_Real* blockdensities;
4027  int* blocksizes;
4028  SCIP_Real density;
4029 
4030  SCIP_Real alphaborderarea;
4031  SCIP_Real alphalinking;
4032  SCIP_Real alphadensity;
4033 
4034  SCIP_CLOCK* clock;
4035  SCIP_CALL_ABORT( SCIPcreateClock( scip, &clock) );
4036  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
4037 
4038  alphaborderarea = 0.6;
4039  alphalinking = 0.2;
4040  alphadensity = 0.2;
4041 
4042  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4043  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
4044 
4045  SCIP_CALL( SCIPallocBufferArray( scip, & nzblocks, partialdec->getNBlocks() ) );
4046  SCIP_CALL( SCIPallocBufferArray( scip, & nlinkvarsblocks, partialdec->getNBlocks() ) );
4047  SCIP_CALL( SCIPallocBufferArray( scip, & blockdensities, partialdec->getNBlocks() ) );
4048  SCIP_CALL( SCIPallocBufferArray( scip, & blocksizes, partialdec->getNBlocks() ) );
4049  SCIP_CALL( SCIPallocBufferArray( scip, & nvarsblocks, partialdec->getNBlocks() ) );
4050 
4051  /*
4052  * 3 Scores
4053  *
4054  * - Area percentage (min)
4055  * - block density (max)
4056  * - \pi_b {v_b|v_b is linking}/#vb (min)
4057  */
4058 
4059  /* calculate slave sizes, nonzeros and linkingvars */
4060  for( i = 0; i < partialdec->getNBlocks(); ++ i )
4061  {
4062  int ncurconss;
4063  int nvarsblock;
4064  SCIP_Bool *ishandled;
4065 
4066  SCIP_CALL( SCIPallocBufferArray( scip, & ishandled, partialdec->getNVars() ) );
4067  nvarsblock = 0;
4068  nzblocks[i] = 0;
4069  nlinkvarsblocks[i] = 0;
4070 
4071  for( j = 0; j < partialdec->getNVars(); ++ j )
4072  {
4073  ishandled[j] = FALSE;
4074  }
4075  ncurconss = partialdec->getNConssForBlock( i );
4076 
4077  for( j = 0; j < ncurconss; ++ j )
4078  {
4079  int cons = partialdec->getConssForBlock( i )[j];
4080  int ncurvars;
4081  ncurvars = detprobdata->getNVarsForCons( cons );
4082  for( k = 0; k < ncurvars; ++ k )
4083  {
4084  int var = detprobdata->getVarsForCons( cons )[k];
4085  int block = -3;
4086  if( partialdec->isVarBlockvarOfBlock( var, i ) )
4087  block = i + 1;
4088  else if( partialdec->isVarLinkingvar( var ) || partialdec->isVarStairlinkingvar( var ) )
4089  block = partialdec->getNBlocks() + 2;
4090  else if( partialdec->isVarMastervar( var ) )
4091  block = partialdec->getNBlocks() + 1;
4092 
4093  ++ ( nzblocks[i] );
4094 
4095  if( block == partialdec->getNBlocks() + 1 && ishandled[var] == FALSE )
4096  {
4097  ++ ( nlinkvarsblocks[i] );
4098  }
4099  ishandled[var] = TRUE;
4100  }
4101  }
4102 
4103  for( j = 0; j < partialdec->getNVars(); ++ j )
4104  {
4105  if( ishandled[j] )
4106  {
4107  ++ nvarsblock;
4108  }
4109  }
4110 
4111  blocksizes[i] = nvarsblock * ncurconss;
4112  nvarsblocks[i] = nvarsblock;
4113  if( blocksizes[i] > 0 )
4114  {
4115  blockdensities[i] = 1.0 * nzblocks[i] / blocksizes[i];
4116  }
4117  else
4118  {
4119  blockdensities[i] = 0.0;
4120  }
4121 
4122  assert( blockdensities[i] >= 0 && blockdensities[i] <= 1.0 );
4123  SCIPfreeBufferArray( scip, & ishandled );
4124  }
4125 
4126  borderarea = ((unsigned long) partialdec->getNMasterconss() * partialdec->getNVars() ) + ( ((unsigned long) partialdec->getNLinkingvars() + partialdec->getNMastervars() + partialdec->getNTotalStairlinkingvars() ) ) * ( partialdec->getNConss() - partialdec->getNMasterconss() );
4127 
4128  matrixarea = ((unsigned long) partialdec->getNVars() ) * ((unsigned long) partialdec->getNConss() );
4129 
4130  density = 1E20;
4131  varratio = 1.0;
4132  linkingscore = 1.;
4133  borderscore = 1.;
4134  densityscore = 1.;
4135 
4136  for( i = 0; i < partialdec->getNBlocks(); ++ i )
4137  {
4138  density = MIN( density, blockdensities[i] );
4139 
4140  if( ( partialdec->getNLinkingvars() + partialdec->getNMastervars() + partialdec->getNTotalStairlinkingvars() ) > 0 )
4141  {
4142  varratio *= 1.0 * nlinkvarsblocks[i] / ( partialdec->getNLinkingvars() + partialdec->getNMastervars() + partialdec->getNTotalStairlinkingvars() );
4143  }
4144  else
4145  {
4146  varratio = 0.;
4147  }
4148  }
4149  linkingscore = ( 0.5 + 0.5 * varratio );
4150 
4151  densityscore = ( 1. - density );
4152 
4153  borderscore = ( 1.0 * ( borderarea ) / matrixarea );
4154 
4155  totalscore = 1. - (alphaborderarea * ( borderscore ) + alphalinking * ( linkingscore ) + alphadensity * ( densityscore ) );
4156 
4157  if(totalscore > 1)
4158  totalscore = 1;
4159  if(totalscore < 0)
4160  totalscore = 0;
4161 
4162  *score = totalscore;
4163 
4164  partialdec->setClassicScore(*score);
4165 
4166  SCIPfreeBufferArray( scip, & nzblocks );
4167  SCIPfreeBufferArray( scip, & nlinkvarsblocks) ;
4168  SCIPfreeBufferArray( scip, & blockdensities);
4169  SCIPfreeBufferArray( scip, & blocksizes);
4170  SCIPfreeBufferArray( scip, & nvarsblocks);
4171 
4172  SCIP_CALL_ABORT(SCIPstopClock( scip, clock) );
4173  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime( scip, clock));
4174  SCIP_CALL_ABORT(SCIPfreeClock( scip, &clock) );
4175 
4176  return SCIP_OKAY;
4177 }
4178 
4179 
4181  SCIP* scip,
4182  int partialdecid,
4183  SCIP_Real* score
4184  )
4185 {
4186  unsigned long sumblockshittinglinkingvar;
4187  unsigned long sumlinkingvarshittingblock;
4188  unsigned long newheight;
4189  unsigned long newwidth;
4190  unsigned long newmasterarea;
4191  unsigned long newblockareaagg;
4192 
4193  SCIP_CLOCK* clock;
4194  SCIP_CALL_ABORT( SCIPcreateClock(scip, &clock) );
4195  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4196 
4197  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4198 
4199  std::vector<int> nlinkingvarsforblock(partialdec->getNBlocks(), 0);
4200  std::vector<int> nblocksforlinkingvar(partialdec->getNLinkingvars() + partialdec->getNTotalStairlinkingvars(), 0);
4201 
4202  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
4203 
4204  partialdec->calcAggregationInformation(false);
4205 
4206  for( int lv = 0; lv < partialdec->getNLinkingvars(); ++lv )
4207  {
4208  int linkingvarid = partialdec->getLinkingvars()[lv];
4209 
4210  for( int b = 0; b < partialdec->getNBlocks(); ++b )
4211  {
4212  for ( int blc = 0; blc < partialdec->getNConssForBlock(b); ++blc )
4213  {
4214  int blockcons = partialdec->getConssForBlock(b)[blc];
4215  if( !SCIPisZero( scip, detprobdata->getVal(blockcons, linkingvarid) ) )
4216  {
4217  /* linking var hits block */
4218  ++nlinkingvarsforblock[b];
4219  ++nblocksforlinkingvar[lv];
4220  break;
4221  }
4222  }
4223  }
4224  }
4225 
4226  for( int b = 0; b < partialdec->getNBlocks(); ++b)
4227  {
4228  for( int slv = 0; slv < partialdec->getNStairlinkingvars(b); ++slv )
4229  {
4230  ++nlinkingvarsforblock[b];
4231  ++nlinkingvarsforblock[b+1];
4232  ++nblocksforlinkingvar[partialdec->getNLinkingvars() + slv];
4233  ++nblocksforlinkingvar[partialdec->getNLinkingvars() + slv];
4234  }
4235  }
4236 
4237  sumblockshittinglinkingvar = 0;
4238  sumlinkingvarshittingblock = 0;
4239  for( int b = 0; b < partialdec->getNBlocks(); ++b )
4240  {
4241  sumlinkingvarshittingblock += nlinkingvarsforblock[b];
4242  }
4243  for( int lv = 0; lv < partialdec->getNLinkingvars(); ++lv )
4244  {
4245  sumblockshittinglinkingvar += nblocksforlinkingvar[lv];
4246  }
4247 
4248  for( int slv = 0; slv < partialdec->getNTotalStairlinkingvars(); ++slv )
4249  {
4250  sumblockshittinglinkingvar += nblocksforlinkingvar[partialdec->getNLinkingvars() + slv];
4251  }
4252 
4253  newheight = partialdec->getNConss() + sumblockshittinglinkingvar;
4254  newwidth = partialdec->getNVars() + sumlinkingvarshittingblock;
4255 
4256  newmasterarea = ( partialdec->getNMasterconss() + sumblockshittinglinkingvar) * ( partialdec->getNVars() + sumlinkingvarshittingblock );
4257  newblockareaagg = 0;
4258 
4259  for( int br = 0; br < partialdec->getNReps(); ++br )
4260  {
4261  newblockareaagg += partialdec->getNConssForBlock( partialdec->getBlocksForRep(br)[0] ) * ( partialdec->getNVarsForBlock( partialdec->getBlocksForRep(br)[0] ) + nlinkingvarsforblock[partialdec->getBlocksForRep(br)[0]] );
4262  }
4263 
4264  SCIP_Real maxforeseeingwhitescoreagg = ((SCIP_Real ) newblockareaagg + (SCIP_Real) newmasterarea) / (SCIP_Real) newwidth;
4265  maxforeseeingwhitescoreagg = maxforeseeingwhitescoreagg / (SCIP_Real) newheight ;
4266 
4267  maxforeseeingwhitescoreagg = 1. - maxforeseeingwhitescoreagg;
4268  *score = maxforeseeingwhitescoreagg;
4269 
4270  partialdec->setMaxForWhiteAggScore(*score);
4271 
4272  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4273  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4274  SCIP_CALL_ABORT(SCIPfreeClock(scip, &clock) );
4275 
4276  return SCIP_OKAY;
4277 }
4278 
4279 
4281  SCIP* scip,
4282  int partialdecid,
4283  SCIP_Real* score
4284  )
4285 {
4286  unsigned long sumblockshittinglinkingvar;
4287  unsigned long sumlinkingvarshittingblock;
4288  unsigned long newheight;
4289  unsigned long newwidth;
4290  unsigned long newmasterarea;
4291  unsigned long newblockarea;
4292 
4293  SCIP_CLOCK* clock;
4294 
4295  SCIP_CALL_ABORT( SCIPcreateClock( scip, &clock) );
4296  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
4297 
4298  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4299  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
4300 
4301  std::vector<int> blockforconss(partialdec->getNConss(), -1);
4302  std::vector<int> nlinkingvarsforblock(partialdec->getNBlocks(), 0);
4303  std::vector<int> nblocksforlinkingvar(partialdec->getNLinkingvars() + partialdec->getNTotalStairlinkingvars(), 0);
4304 
4305  /* store for each cons to which block it is assigned (or -1 if border or unassigned) */
4306  for( int b = 0; b < partialdec->getNBlocks(); ++b )
4307  {
4308  std::vector<int>& blockconss = partialdec->getConssForBlock(b);
4309  for ( int blc = 0; blc < partialdec->getNConssForBlock(b); ++blc )
4310  {
4311  int blockcons = blockconss[blc];
4312  blockforconss[blockcons] = b;
4313  }
4314  }
4315 
4316  /* iterate linking vars and corresponding conss to recognize hit blocks */
4317  for( int lv = 0; lv < partialdec->getNLinkingvars(); ++lv )
4318  {
4319  int linkingvarid = partialdec->getLinkingvars()[lv];
4320  int nhittingconss = detprobdata->getNConssForVar(linkingvarid);
4321  std::vector<int>& hittingconss = detprobdata->getConssForVar(linkingvarid);
4322 
4323  std::vector<bool> hitblock(partialdec->getNBlocks(), false);
4324 
4325  /* find out which blocks the linking var is hitting */
4326  for ( int hittingcons = 0; hittingcons < nhittingconss; ++hittingcons )
4327  {
4328  int blockforcons = blockforconss[hittingconss[hittingcons]];
4329  if( blockforcons != -1 )
4330  hitblock[blockforcons] = true;
4331  }
4332 
4333  /* count for each block and each linking var how many linking vars or blocks, respectively, they hit */
4334  for( int b = 0; b < partialdec->getNBlocks(); ++b )
4335  {
4336  if ( hitblock[b] )
4337  {
4338  /* linking var hits block, so count it */
4339  ++nlinkingvarsforblock[b];
4340  ++nblocksforlinkingvar[lv];
4341  }
4342  }
4343  }
4344 
4345  for( int b = 0; b < partialdec->getNBlocks(); ++b)
4346  {
4347  for( int slv = 0; slv < partialdec->getNStairlinkingvars(b); ++slv )
4348  {
4349  ++nlinkingvarsforblock[b];
4350  ++nlinkingvarsforblock[b+1];
4351  ++nblocksforlinkingvar[partialdec->getNLinkingvars() + slv];
4352  ++nblocksforlinkingvar[partialdec->getNLinkingvars() + slv];
4353  }
4354  }
4355 
4356  sumblockshittinglinkingvar = 0;
4357  sumlinkingvarshittingblock = 0;
4358  for( int b = 0; b < partialdec->getNBlocks(); ++b )
4359  {
4360  sumlinkingvarshittingblock += nlinkingvarsforblock[b];
4361  }
4362  for( int lv = 0; lv < partialdec->getNLinkingvars(); ++lv )
4363  {
4364  sumblockshittinglinkingvar += nblocksforlinkingvar[lv];
4365  }
4366 
4367  for( int slv = 0; slv < partialdec->getNTotalStairlinkingvars(); ++slv )
4368  {
4369  sumblockshittinglinkingvar += nblocksforlinkingvar[partialdec->getNLinkingvars() + slv];
4370  }
4371 
4372  newheight = partialdec->getNConss() + sumblockshittinglinkingvar;
4373  newwidth = partialdec->getNVars() + sumlinkingvarshittingblock;
4374 
4375  newmasterarea = ( (SCIP_Real) partialdec->getNMasterconss() + sumblockshittinglinkingvar) * ( (SCIP_Real) partialdec->getNVars() + sumlinkingvarshittingblock );
4376  newblockarea = 0;
4377 
4378  for( int b = 0; b < partialdec->getNBlocks(); ++b )
4379  {
4380  newblockarea += ((SCIP_Real) partialdec->getNConssForBlock(b) ) * ( (SCIP_Real) partialdec->getNVarsForBlock(b) + nlinkingvarsforblock[b] );
4381  }
4382 
4383  SCIP_Real maxforeseeingwhitescore = ((SCIP_Real ) newblockarea + (SCIP_Real) newmasterarea) / (SCIP_Real) newwidth;
4384  maxforeseeingwhitescore = maxforeseeingwhitescore / (SCIP_Real) newheight ;
4385 
4386  maxforeseeingwhitescore = 1. - maxforeseeingwhitescore;
4387  *score = maxforeseeingwhitescore;
4388 
4389  SCIP_CALL_ABORT(SCIPstopClock( scip, clock) );
4390  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime( scip, clock));
4391  SCIP_CALL_ABORT(SCIPfreeClock( scip, &clock) );
4392 
4393  return SCIP_OKAY;
4394 }
4395 
4396 
4398  SCIP* scip,
4399  int partialdecid,
4400  SCIP_Real* score
4401  )
4402 {
4403  SCIP_Real borderareascore = 0;
4404  SCIP_CLOCK* clock;
4405  SCIP_CALL_ABORT( SCIPcreateClock(scip, &clock) );
4406  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4407 
4408  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4409 
4410  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4411  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4412 
4413  SCIP_Real blockareascore = calcBlockAreaScore(scip, partialdec);
4414  borderareascore = partialdec->getBorderAreaScore();
4415  if(borderareascore == -1)
4416  GCGconshdlrDecompCalcBorderAreaScore(scip, partialdecid, &borderareascore);
4417 
4418  SCIP_CALL_ABORT(SCIPresetClock( scip, clock) );
4419  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4420 
4421  SCIP_Real maxwhitescore = blockareascore + borderareascore - 1.;
4422 
4423  if( maxwhitescore < 0. )
4424  maxwhitescore = 0.;
4425 
4426  *score = maxwhitescore;
4427  partialdec->setMaxWhiteScore(*score);
4428 
4429  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4430  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4431  SCIP_CALL_ABORT(SCIPfreeClock(scip, &clock) );
4432 
4433  return SCIP_OKAY;
4434 }
4435 
4436 
4438  SCIP* scip,
4439  int partialdecid,
4440  SCIP_Real* score
4441  )
4442 {
4443  SCIP_Real maxforeseeingwhitescore = 0;
4444  SCIP_CLOCK* clock;
4445 
4446  SCIP_CALL_ABORT( SCIPcreateClock(scip, &clock) );
4447  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4448 
4449  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4450 
4451  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4452  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4453 
4454  maxforeseeingwhitescore = partialdec->getMaxForWhiteScore();
4455  if(maxforeseeingwhitescore == -1)
4456  GCGconshdlrDecompCalcMaxForseeingWhiteScore(scip, partialdecid, &maxforeseeingwhitescore);
4457 
4458  SCIP_CALL_ABORT(SCIPresetClock( scip, clock) );
4459  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4460 
4461  if( partialdec->hasSetppccardMaster() && !partialdec->isTrivial() && partialdec->getNBlocks() > 1 )
4462  {
4463  *score = 0.5 * maxforeseeingwhitescore + 0.5;
4464  }
4465  else
4466  {
4467  *score = 0.5 * maxforeseeingwhitescore;
4468  }
4469 
4470  partialdec->setSetPartForWhiteScore(*score);
4471 
4472  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4473  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4474  SCIP_CALL_ABORT(SCIPfreeClock(scip, &clock) );
4475 
4476  return SCIP_OKAY;
4477 }
4478 
4479 
4481  SCIP* scip,
4482  int partialdecid,
4483  SCIP_Real* score
4484  )
4485 {
4486  SCIP_Real maxforeseeingwhitescoreagg = 0;
4487 
4488  SCIP_CLOCK* clock;
4489  SCIP_CALL_ABORT( SCIPcreateClock(scip, &clock) );
4490  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4491 
4492  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4493 
4494  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4495  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4496 
4497  maxforeseeingwhitescoreagg = partialdec->getMaxForWhiteAggScore();
4498  if(maxforeseeingwhitescoreagg == -1)
4499  GCGconshdlrDecompCalcMaxForeseeingWhiteAggScore(scip, partialdecid, &maxforeseeingwhitescoreagg);
4500 
4501  SCIP_CALL_ABORT(SCIPresetClock( scip, clock) );
4502  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
4503 
4504  if( partialdec->hasSetppccardMaster() && !partialdec->isTrivial() && partialdec->getNBlocks() > 1 )
4505  {
4506  *score = 0.5 * maxforeseeingwhitescoreagg + 0.5;
4507  }
4508  else
4509  {
4510  *score = 0.5 * maxforeseeingwhitescoreagg;
4511  }
4512 
4513  partialdec->setSetPartForWhiteAggScore(*score);
4514 
4515  SCIP_CALL_ABORT(SCIPstopClock(scip, clock) );
4516  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime(scip, clock));
4517  SCIP_CALL_ABORT(SCIPfreeClock(scip, &clock) );
4518 
4519  return SCIP_OKAY;
4520 }
4521 
4522 
4524  SCIP* scip,
4525  int partialdecid,
4526  SCIP_Real* score
4527  )
4528 {
4529  /** @todo use and introduce scip parameter limit (for a pricing problem to be considered fractional solvable) of difference optimal value of LP-Relaxation and optimal value of artificial pricing problem */
4530  /* SCIP_Real gaplimitsolved; */
4531 
4532  /** @todo use and introduce scip parameter weighted limit (for a pricing problem to be considered fractional solvable) difference optimal value of LP-Relaxation and optimal value of artificial pricing problem */
4533  /* SCIP_Real gaplimitbeneficial; */
4534 
4535  SCIP_Bool hittimelimit;
4536  SCIP_Bool errorpricing;
4537  int npricingconss = 0;
4538 
4539  SCIP_Real infinity;
4540  SCIP_Real epsilon;
4541  SCIP_Real sumepsilon;
4542  SCIP_Real feastol;
4543  SCIP_Real lpfeastol;
4544  SCIP_Real dualfeastol;
4545  SCIP_Bool enableppcuts;
4546 
4547  SCIP_Bool benefical;
4548  SCIP_Bool fast;
4549 
4550  int clocktype;
4551  SCIP_Real dualvalmethodcoef;
4552 
4553  SCIP_CLOCK* clock;
4554  SCIP_CALL_ABORT( SCIPcreateClock( scip, &clock) );
4555  SCIP_CALL_ABORT( SCIPstartClock( scip, clock) );
4556 
4557  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
4558 
4559  /* score works only on presolved */
4560  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4561  if( partialdec->isAssignedToOrigProb() )
4562  {
4563  *score = 0;
4564  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " \n Attention! Strong decomposition score is not implemented for decomps belonging to the original problem \n\n");
4565  return SCIP_OKAY;
4566  }
4567 
4568  *score = 0.;
4569 
4570  /* ***** get all relevant parameters ***** */
4571  SCIPgetRealParam(scip, "detection/score/strong_detection/coeffactororigvsrandom", &dualvalmethodcoef);
4572 
4573  /* get numerical tolerances of the original SCIP instance in order to use the same numerical tolerances in master and pricing problems */
4574  SCIP_CALL( SCIPgetRealParam(scip, "numerics/infinity", &infinity) );
4575  SCIP_CALL( SCIPgetRealParam(scip, "numerics/epsilon", &epsilon) );
4576  SCIP_CALL( SCIPgetRealParam(scip, "numerics/sumepsilon", &sumepsilon) );
4577  SCIP_CALL( SCIPgetRealParam(scip, "numerics/feastol", &feastol) );
4578  SCIP_CALL( SCIPgetRealParam(scip, "numerics/lpfeastol", &lpfeastol) );
4579  SCIP_CALL( SCIPgetRealParam(scip, "numerics/dualfeastol", &dualfeastol) );
4580 
4581  /* get clocktype of the original SCIP instance in order to use the same clocktype in master and pricing problems */
4582  SCIP_CALL( SCIPgetIntParam(scip, "timing/clocktype", &clocktype) );
4583 
4584  enableppcuts = FALSE;
4585  SCIP_CALL( SCIPgetBoolParam(scip, "sepa/basis/enableppcuts", &enableppcuts) );
4586 
4587  SCIP_Real timelimitfast = 0.1 * conshdlrdata->strongtimelimit;
4588 
4589  /* get number of pricingconss */
4590  for( int block = 0; block < partialdec->getNBlocks(); ++block )
4591  {
4592  npricingconss += partialdec->getNConssForBlock(block);
4593  }
4594 
4595  /* for every pricing problem calculate a corresponding score coeff and break if a pricing problem cannot be solved in the timelimit */
4596  for( int block = 0; block < partialdec->getNBlocks(); ++block )
4597  {
4598  SCIP* subscip;
4599  char name[SCIP_MAXSTRLEN];
4600  SCIP_HASHMAP* hashpricingvartoindex;
4601  SCIP_HASHMAP* hashorig2pricingvar;
4602  SCIP_Real score_coef;
4603  SCIP_Real weight_subproblem;
4604  std::stringstream subname;
4605 
4606  /* init all parameters */
4607  hittimelimit = FALSE;
4608  errorpricing = FALSE;
4609 
4610  subname << "temp_pp_" << block << ".lp";
4611 
4612  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "started calculate strong decomposition subproblem for block %d \n", block );
4613 
4614  std::vector<SCIP_VAR*> indextopricingvar = std::vector<SCIP_VAR*>(SCIPgetNVars(scip), NULL);
4615 
4616  SCIP_CALL( SCIPhashmapCreate(&hashpricingvartoindex, SCIPblkmem(scip), SCIPgetNVars(scip)) ); /*lint !e613*/
4617  SCIP_CALL( SCIPhashmapCreate(&hashorig2pricingvar, SCIPblkmem(scip), SCIPgetNVars(scip)) ); /*lint !e613*/
4618 
4619  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "testpricing_block_%d", block);
4620 
4621  benefical = FALSE;
4622  fast = FALSE;
4623  score_coef = 0.0;
4624  weight_subproblem = (SCIP_Real) partialdec->getNConssForBlock(block) / npricingconss;
4625 
4626  /* build subscip */
4627  SCIP_CALL( SCIPcreate(&subscip) );
4628  SCIP_CALL( SCIPincludeDefaultPlugins(subscip) );
4629  SCIP_CALL( setTestpricingProblemParameters(subscip, clocktype, infinity, epsilon, sumepsilon, feastol, lpfeastol, dualfeastol, enableppcuts, conshdlrdata->strongtimelimit) );
4630  SCIP_CALL( SCIPsetIntParam(subscip, "presolving/maxrounds", 0) );
4631  SCIP_CALL( SCIPsetIntParam(subscip, "lp/solvefreq", 1) );
4632  SCIP_CALL( SCIPcreateProb(subscip, name, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
4633 
4634  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "started calculate strong decomposition, timelimit: %f timelimitfast: %f \n", conshdlrdata->strongtimelimit, timelimitfast );
4635 
4636  /* copy variables */
4637  DETPROBDATA* detprobdata = partialdec->getDetprobdata();
4638  for( int var = 0; var < partialdec->getNVarsForBlock(block); ++var )
4639  {
4640  int varid;
4641  SCIP_VAR* origprobvar;
4642  SCIP_VAR* pricingprobvar;
4643  SCIP_Real obj;
4644 
4645  varid = partialdec->getVarsForBlock(block)[var];
4646 
4647  if ( partialdec->isAssignedToOrigProb() )
4648  origprobvar = detprobdata->getVar(varid);
4649  else
4650  origprobvar = SCIPvarGetProbvar(detprobdata->getVar(varid));
4651 
4652  /* calculate obj val from shuffled */
4653  obj = SCIPvarGetObj(origprobvar);
4654  for( int c = 0; c < detprobdata->getNConssForVar(varid); ++c )
4655  {
4656  int consid;
4657  SCIP_Real dualval;
4658 
4659  dualval = 0.;
4660 
4661  consid = detprobdata->getConssForVar(varid)[c];
4662  if ( partialdec->isConsMastercons(consid) )
4663  {
4664  if( SCIPisEQ( scip, dualvalmethodcoef, 0.0) )
4665  dualval = getDualvalRandom(scip, consid, partialdec->isAssignedToOrigProb());
4666  else if( SCIPisEQ( scip, dualvalmethodcoef, 1.0) )
4667  dualval = getDualvalOptimalLP(scip, consid, partialdec->isAssignedToOrigProb());
4668  else
4669  dualval = dualvalmethodcoef * getDualvalOptimalLP(scip, consid, partialdec->isAssignedToOrigProb()) + (1. - dualvalmethodcoef) * getDualvalRandom(scip, consid, partialdec->isAssignedToOrigProb());
4670  obj -= dualval * detprobdata->getVal(consid, varid);
4671  }
4672  }
4673 
4674  /* round variable objective coeffs to decrease numerical troubles */
4675  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pr%d_%s", block, SCIPvarGetName(origprobvar));
4676  SCIP_CALL( SCIPcreateVar(subscip, &pricingprobvar, name, SCIPvarGetLbGlobal(origprobvar),
4677  SCIPvarGetUbGlobal(origprobvar), obj, SCIPvarGetType(origprobvar),
4678  TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
4679  SCIPhashmapSetImage(hashorig2pricingvar, origprobvar, pricingprobvar);
4680  SCIPhashmapSetImage(hashpricingvartoindex, pricingprobvar, (void*) (size_t)varid);
4681  indextopricingvar[varid] = pricingprobvar;
4682  SCIP_CALL( SCIPaddVar(subscip, pricingprobvar) );
4683  }
4684 
4685  /* copy constraints */
4686  SCIP_CALL( createTestPricingprobConss(scip, subscip, partialdec, block, hashorig2pricingvar) );
4687 
4688  /* transform subscip */
4689  SCIP_CALL(SCIPtransformProb(subscip) );
4690 
4691  /* solve subscip */
4692  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "started solving subproblem for block %d \n", block );
4693  SCIP_CALL( SCIPsolve(subscip) );
4694  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "finished solving subproblem in %f seconds \n", SCIPgetSolvingTime(subscip) );
4695 
4696  if( SCIPgetStatus(subscip) != SCIP_STATUS_OPTIMAL )
4697  {
4698  if( SCIPgetStatus(subscip) == SCIP_STATUS_TIMELIMIT )
4699  hittimelimit = TRUE;
4700  else
4701  errorpricing = TRUE;
4702  }
4703 
4704  if( errorpricing || hittimelimit )
4705  {
4706  if( hittimelimit )
4707  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "Hit timelimit in pricing problem %d \n.", block);
4708  else
4709  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "Error in pricing problem %d \n.", block);
4710 
4711  *score = 0.;
4712  SCIPhashmapFree(&hashpricingvartoindex);
4713  SCIPfree(&subscip);
4714 
4715  return SCIP_OKAY;
4716  }
4717 
4718  /* get coefficient */
4719  if( !SCIPisEQ( scip, SCIPgetFirstLPLowerboundRoot(subscip), SCIPgetDualbound(subscip) ) )
4720  benefical = TRUE;
4721 
4722  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "first dual bound: %f ; dual bound end: %f \n",SCIPgetFirstLPLowerboundRoot(subscip), SCIPgetDualbound(subscip) );
4723 
4724  if( SCIPisFeasLE( scip, SCIPgetSolvingTime(subscip), timelimitfast ) )
4725  fast = TRUE;
4726 
4727  if ( fast && benefical )
4728  score_coef = DEFAULT_SCORECOEF_FASTBENEFICIAL;
4729 
4730  if ( !fast && benefical )
4732 
4733  if ( fast && !benefical )
4735 
4736  if ( !fast && !benefical )
4738 
4739  SCIPverbMessage(scip, SCIP_VERBLEVEL_HIGH, NULL, "scorecoef for subproblem %d is %f with weighting factor %f\n", block, score_coef, weight_subproblem );
4740 
4741  *score += score_coef * weight_subproblem;
4742 
4743  /* free stuff */
4744  for( int var = 0; var < partialdec->getNVarsForBlock(block); ++var )
4745  {
4746  int varid = partialdec->getVarsForBlock(block)[var];
4747  SCIPreleaseVar(subscip, &indextopricingvar[varid]);
4748  }
4749 
4750  SCIPhashmapFree(&hashpricingvartoindex);
4751 
4752  SCIPfree(&subscip);
4753  }// end for blocks
4754 
4755  partialdec->setStrongDecompScore(*score);
4756 
4757  /* add clock time */
4758  SCIP_CALL_ABORT(SCIPstopClock( scip, clock) );
4759  GCGconshdlrDecompAddScoreTime(scip, SCIPgetClockTime( scip, clock));
4760  SCIP_CALL_ABORT(SCIPfreeClock( scip, &clock) );
4761 
4762  return SCIP_OKAY;
4763 }
4764 
4765 
4767  SCIP* scip /* SCIP data structure */
4768  )
4769 {
4770  int i;
4771 
4772  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
4773  assert(conshdlrdata != NULL);
4774 
4775  /* check whether the predecessors of all finished partialdecs in both detprobdatas can be found */
4776  if( conshdlrdata->detprobdatapres != NULL)
4777  {
4778  for( i = 0; i < conshdlrdata->detprobdatapres->getNFinishedPartialdecs(); ++i )
4779  {
4780  PARTIALDECOMP* partialdec = conshdlrdata->detprobdatapres->getFinishedPartialdec( i );
4781 
4782  for( int j = 0; j < partialdec->getNAncestors(); ++j )
4783  {
4784  int id = partialdec->getAncestorID( j );
4785  if(GCGconshdlrDecompGetPartialdecFromID(scip, id) == NULL )
4786  {
4787  SCIPwarningMessage(scip, "Warning: presolved partialdec %d has an ancestor (id: %d) that is not found! \n", partialdec->getID(), id );
4788  return FALSE;
4789  }
4790  }
4791  }
4792  }
4793 
4794  if( conshdlrdata->detprobdataorig != NULL )
4795  {
4796  for( i = 0; i < conshdlrdata->detprobdataorig->getNFinishedPartialdecs(); ++i )
4797  {
4798  PARTIALDECOMP* partialdec = conshdlrdata->detprobdataorig->getFinishedPartialdec( i );
4799 
4800  for( int j = 0; j < partialdec->getNAncestors(); ++j )
4801  {
4802  int id = partialdec->getAncestorID( j );
4803  if(GCGconshdlrDecompGetPartialdecFromID(scip, id) == NULL )
4804  {
4805  SCIPwarningMessage(scip, "Warning: orig partialdec %d has an ancestor (id: %d) that is not found! \n", partialdec->getID(), id );
4806  return FALSE;
4807  }
4808  }
4809  }
4810  }
4811 
4812  return TRUE;
4813 }
4814 
4815 
4817  SCIP* scip,
4818  std::vector<std::pair<gcg::PARTIALDECOMP*, SCIP_Real> >& candidates,
4819  SCIP_Bool original,
4820  SCIP_Bool printwarnings
4821  )
4822 {
4823  std::vector<PARTIALDECOMP*>::iterator partialdeciter;
4824  std::vector<PARTIALDECOMP*>::iterator partialdeciterend;
4825 
4826  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
4827  if( conshdlrdata == NULL )
4828  {
4829  SCIPerrorMessage("Decomp constraint handler is not included, cannot manage decompositions!\n");
4830  return SCIP_ERROR;
4831  }
4832 
4833  if( (!original && conshdlrdata->detprobdatapres == NULL) || (original && conshdlrdata->detprobdataorig == NULL) )
4834  {
4835  return SCIP_OKAY;
4836  }
4837 
4838  SCIPdebugMessage("Starting decomposition candidate choosing \n");
4839 
4840  assert( GCGconshdlrDecompCheckConsistency(scip) );
4841 
4842  std::vector<PARTIALDECOMP*> selectedpartialdecs;
4843  getSelectedPartialdecs(scip, selectedpartialdecs);
4844 
4845  if( selectedpartialdecs.empty() )
4846  {
4847  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "currently no decomposition is selected, hence every known decomposition is considered: \n");
4848  if( original )
4849  {
4850  selectedpartialdecs = conshdlrdata->detprobdataorig->getFinishedPartialdecs();
4851  }
4852  else
4853  {
4854  selectedpartialdecs = conshdlrdata->detprobdatapres->getFinishedPartialdecs();
4855  }
4856  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "number of considered decompositions: %ld \n", selectedpartialdecs.size() );
4857  }
4858 
4859  partialdeciter = selectedpartialdecs.begin();
4860  partialdeciterend = selectedpartialdecs.end();
4861 
4862  /* get decomp candidates and calculate corresponding score */
4863  for( ; partialdeciter != partialdeciterend; ++partialdeciter )
4864  {
4865  PARTIALDECOMP* partialdec = *partialdeciter;
4866  if( !original && partialdec->isAssignedToOrigProb() )
4867  {
4868  partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdec->getTranslatedpartialdecid());
4869  assert(partialdec != NULL);
4870  if( !partialdec->isComplete() )
4871  {
4872  if( printwarnings )
4873  {
4874  SCIPwarningMessage(scip, "A selected decomposition (id=%d) of the orig. problem is ignored since its translation is incomplete.\n", partialdec->getID());
4875  }
4876  continue;
4877  }
4878  }
4879 
4880  assert(partialdec != NULL);
4881  if( partialdec->isComplete() )
4882  {
4883  candidates.emplace_back(partialdec, partialdec->getScore(GCGconshdlrDecompGetScoretype(scip)));
4884  }
4885  else if( printwarnings )
4886  {
4887  SCIPwarningMessage(scip, "A selected decomposition (id=%d) is ignored since it is incomplete.\n", partialdec->getID());
4888  }
4889  }
4890 
4891  /* sort decomp candidates according to score */
4892  std::sort( candidates.begin(), candidates.end(), sort_pred() );
4893 
4894  return SCIP_OKAY;
4895 }
4896 
4897 
4899  SCIP* scip,
4900  SCIP_Bool transformed
4901  )
4902 {
4903  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
4904 
4905  gcg::DETPROBDATA* detprobdata;
4906  if (transformed) {
4907  detprobdata = conshdlrdata->detprobdatapres;
4908  } else{
4909  detprobdata = conshdlrdata->detprobdataorig;
4910  }
4911 
4912  // Start clock
4913  SCIP_CLOCK* classificationclock;
4914  SCIPcreateClock( scip, & classificationclock );
4915  SCIP_CALL( SCIPstartClock( scip, classificationclock ) );
4916 
4917  // Cons classifiers
4918  for(int i = 0; i < conshdlrdata->nconsclassifiers; i++) {
4919  DEC_CONSCLASSIFIER *classifier;
4920  SCIP_Bool enabled;
4921  classifier = conshdlrdata->consclassifiers[i];
4922 
4923  char setting[SCIP_MAXSTRLEN];
4924  (void) SCIPsnprintf(setting, SCIP_MAXSTRLEN, "detection/classification/consclassifier/%s/enabled", classifier->name);
4925 
4926  SCIPgetBoolParam( scip, setting, &enabled );
4927  if ( enabled ) {
4928  classifier->classify(scip, transformed);
4929  }
4930  }
4931 
4932  // Var classifiers
4933  for(int i = 0; i < conshdlrdata->nvarclassifiers; i++) {
4934  DEC_VARCLASSIFIER *classifier;
4935  SCIP_Bool enabled;
4936  classifier = conshdlrdata->varclassifiers[i];
4937 
4938  char setting[SCIP_MAXSTRLEN];
4939  (void) SCIPsnprintf(setting, SCIP_MAXSTRLEN, "detection/classification/varclassifier/%s/enabled", classifier->name);
4940 
4941  SCIPgetBoolParam( scip, setting, &enabled );
4942  if ( enabled ) {
4943  classifier->classify(scip, transformed);
4944  }
4945  }
4946 
4947  // Reduce number of classes
4948  reduceConsclasses(scip, detprobdata);
4949  reduceVarclasses(scip, detprobdata);
4950 
4951  // Stop clock
4952  SCIP_CALL( SCIPstopClock( scip, classificationclock ) );
4953  detprobdata->classificationtime += SCIPgetClockTime( scip, classificationclock );
4954  SCIPfreeClock( scip, & classificationclock );
4955 
4956  return SCIP_OKAY;
4957 }
4958 
4959 
4961  SCIP* scip,
4962  SCIP_HASHMAP** hashorig2pricingvar,
4963  int partialdecid,
4964  int probnr1,
4965  int probnr2,
4966  SCIP* scip1,
4967  SCIP* scip2,
4968  SCIP_HASHMAP* varmap
4969  )
4970 {
4971  gcg::PARTIALDECOMP* partialdec;
4972  gcg::DETPROBDATA* currdetprobdata;
4973 
4974  int blockid1;
4975  int blockid2;
4976  int representative;
4977  int repid1;
4978  int repid2;
4979  int nblocksforrep;
4980  std::vector<int> pidtopid;
4981 
4982  repid1 = -1;
4983  repid2 = -1;
4984 
4985  partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
4986  assert(partialdec != NULL);
4987  assert(partialdec->isComplete());
4988  currdetprobdata = partialdec->getDetprobdata();
4989 
4990  if( probnr1 > probnr2 )
4991  {
4992  blockid1 = probnr2;
4993  blockid2 = probnr1;
4994  }
4995  else
4996  {
4997  blockid1 = probnr1;
4998  blockid2 = probnr2;
4999  }
5000 
5001  representative = partialdec->getRepForBlock(blockid1);
5002  assert( representative == partialdec->getRepForBlock(blockid2) );
5003  nblocksforrep = (int) partialdec->getBlocksForRep(representative).size();
5004 
5005  /* find index in representatives */
5006  for( int i = 0; i < nblocksforrep; ++i )
5007  {
5008  if( partialdec->getBlocksForRep(representative)[i] == blockid1 )
5009  repid1 = i;
5010  if( partialdec->getBlocksForRep(representative)[i] == blockid2 )
5011  {
5012  repid2 = i;
5013  break;
5014  }
5015  }
5016 
5017  /* blockid1 should be the representative */
5018  if( repid1 != 0 )
5019  {
5020  SCIPhashmapFree(&varmap);
5021  varmap = NULL;
5022  SCIPwarningMessage(scip, "blockid1 should be the representative (hence has id=0 in reptoblocksarray but in fact has %d) \n", repid1);
5023  return SCIP_OKAY;
5024  }
5025 
5026  pidtopid = partialdec->getRepVarmap(representative, repid2);
5027 
5028  for( int v = 0; v < SCIPgetNVars(scip2); ++v )
5029  {
5030  SCIP_VAR* var1;
5031  SCIP_VAR* var2;
5032  SCIP_VAR* var1orig;
5033  SCIP_VAR* var2orig;
5034  int var1origid;
5035  int var2origid;
5036  int var1originblockid;
5037  int var2originblockid;
5038 
5039  var2 = SCIPgetVars(scip2)[v];
5040  assert(var2 != NULL);
5041  var2orig = GCGpricingVarGetOriginalVar(var2);
5042  assert(var2orig!=NULL);
5043  var2origid = currdetprobdata->getIndexForVar(var2orig) ;
5044  assert(var2origid>=0);
5045  var2originblockid = partialdec->getVarProbindexForBlock(var2origid, blockid2) ;
5046  assert(var2originblockid >= 0);
5047  var1originblockid = pidtopid[var2originblockid];
5048  assert(var1originblockid>=0);
5049  var1origid = partialdec->getVarsForBlock(blockid1)[var1originblockid];
5050  assert(var1origid>=0);
5051  var1orig = currdetprobdata->getVar(var1origid) ;
5052  assert(var1orig != NULL);
5053  var1 = (SCIP_VAR*) SCIPhashmapGetImage(hashorig2pricingvar[blockid1], (void*) var1orig ) ;
5054  assert(var1 != NULL);
5055 
5056  SCIPhashmapInsert(varmap, (void*) var2, (void*) var1);
5057  }
5058 
5059  return SCIP_OKAY;
5060 }
5061 
5062 
5064  SCIP* scip
5065  )
5066 {
5067  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5068  assert(conshdlrdata != NULL);
5069 
5070  --conshdlrdata->ncallscreatedecomp;
5071 
5072  return conshdlrdata->ncallscreatedecomp;
5073 }
5074 
5075 
5077  SCIP* scip,
5078  SCIP_Bool original
5079  )
5080 {
5081  SCIP_CONSHDLRDATA *conshdlrdata = getConshdlrdata(scip);
5082 
5083  for( int i = (int) conshdlrdata->partialdecs->size() - 1; i >= 0; --i)
5084  {
5085  PARTIALDECOMP* partialdec = (*conshdlrdata->partialdecs)[i];
5086  if( partialdec->isAssignedToOrigProb() == (bool) original )
5087  {
5088  // ~PARTIALDECOMP will clean up references
5089  delete partialdec;
5090  }
5091  }
5092 }
5093 
5094 
5096  SCIP* scip,
5097  PARTIALDECOMP* partialdec
5098  )
5099 {
5100  int i = 0;
5101  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5102 
5103  assert(conshdlrdata != NULL);
5104  assert(partialdec != NULL);
5105 
5106  int id = partialdec->getID();
5107 
5108  // remove partialdec from list
5109  for(i = (int) conshdlrdata->partialdecs->size() - 1; i >= 0 ; i--)
5110  {
5111  // as registering checks for dublicates,
5112  // assumption that the partialdecs are unique in the list
5113  if(partialdec == conshdlrdata->partialdecs->at(i))
5114  {
5115  // delete item at index i
5116  conshdlrdata->partialdecs->erase(conshdlrdata->partialdecs->begin() + i);
5117  break;
5118  }
5119  }
5120 
5121  conshdlrdata->partialdecsbyid->erase(id);
5122 
5123  // remove partialdec from ancestors of all other partialdecs to avoid NULL pointers
5124  for(i = 0; i < (int) conshdlrdata->partialdecs->size(); i++)
5125  {
5126  conshdlrdata->partialdecs->at(i)->removeAncestorID(id);
5127  }
5128 }
5129 
5130 
5132  SCIP* scip
5133  )
5134 {
5135  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5136  assert(conshdlrdata != NULL);
5137 
5138  /* remove the presolved detprobdata */
5139  delete conshdlrdata->detprobdatapres;
5140  conshdlrdata->detprobdatapres = NULL;
5141 
5142  /* if parameter is set, free orig detprobdata */
5143  if( conshdlrdata->freeorig )
5144  {
5145  delete conshdlrdata->detprobdataorig;
5146  conshdlrdata->detprobdataorig = NULL;
5147  conshdlrdata->hasrunoriginal = FALSE;
5148  }
5149 }
5150 
5151 
5153  SCIP* scip,
5154  SCIP_Bool free
5155  )
5156 {
5157  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5158  assert(conshdlrdata != NULL);
5159 
5160  conshdlrdata->freeorig = free;
5161 }
5162 
5163 
5165  SCIP* scip,
5166  int index
5167  )
5168 {
5169  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5170  assert(conshdlrdata != NULL);
5171 
5172  assert(index < (int) conshdlrdata->userblocknrcandidates->size());
5173  return conshdlrdata->userblocknrcandidates->at(index);
5174 }
5175 
5176 
5178  SCIP* scip
5179  )
5180 {
5181  SCIP_Real totaltime;
5182 
5183  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5184  assert(conshdlrdata != NULL);
5185 
5186  totaltime = SCIPgetClockTime(scip, conshdlrdata->completedetectionclock );
5187 
5188  return totaltime;
5189 }
5190 
5191 
5193  SCIP* scip
5194  )
5195 {
5196  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5197  assert(conshdlrdata != NULL);
5198  int decompcounter = 0;
5199  int i;
5200 
5201  for( i = 0; i < conshdlrdata->ndecomps; ++i )
5202  {
5203  DECdecompFree(scip, &conshdlrdata->decomps[conshdlrdata->ndecomps - i - 1]);
5204  }
5205 
5206  SCIPfreeBlockMemoryArray(scip, &conshdlrdata->decomps, conshdlrdata->ndecomps);
5207 
5208  SCIP_CALL_ABORT( SCIPallocBlockMemoryArray(scip, &conshdlrdata->decomps, GCGconshdlrDecompGetNDecomps(scip) ) );
5209 
5210  conshdlrdata->ndecomps = GCGconshdlrDecompGetNDecomps(scip);
5211 
5212  sortPartialdecs(scip);
5213  for(i = 0; i < (int) conshdlrdata->partialdecs->size(); i++)
5214  {
5215  gcg::PARTIALDECOMP* partialdec = conshdlrdata->partialdecs->at(i);
5216  createDecompFromPartialdec(scip, partialdec, &conshdlrdata->decomps[decompcounter] );
5217  ++decompcounter;
5218  }
5219 
5220  return conshdlrdata->decomps;
5221 }
5222 
5223 
5225  SCIP* scip,
5226  int id
5227  )
5228 {
5229  char buffer[SCIP_MAXSTRLEN];
5230  /* get partialdec and returns its detector history */
5231  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5232  assert(partialdec != NULL);
5233  partialdec->buildDecChainString(buffer);
5234  return std::string(buffer);
5235 }
5236 
5237 
5239  SCIP* scip
5240  )
5241 {
5242  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5243  assert(conshdlrdata != NULL);
5244 
5245  return conshdlrdata->detectors;
5246 }
5247 
5248 
5250  SCIP* scip
5251  )
5252 {
5253  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5254  assert(conshdlrdata != NULL);
5255 
5257  resetDetprobdata(scip, true);
5258 
5259  return conshdlrdata->detprobdataorig;
5260 }
5261 
5262 
5264  SCIP* scip
5265  )
5266 {
5267  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5268  assert(conshdlrdata != NULL);
5269 
5271  resetDetprobdata(scip, false);
5272 
5273  return conshdlrdata->detprobdatapres;
5274 }
5275 
5276 
5278  SCIP* scip,
5279  int** idlist,
5280  int* listlength
5281  )
5282 {
5283  std::vector<PARTIALDECOMP*> partialdecs;
5284  getFinishedPartialdecs(scip, partialdecs);
5285  partialdecVecToIdArray(partialdecs, idlist, listlength);
5286 
5287  return SCIP_OKAY;
5288 }
5289 
5290 
5292  SCIP* scip,
5293  int** idlist,
5294  int* listlength
5295 )
5296 {
5297  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5298  assert( conshdlrdata != NULL );
5299  partialdecVecToIdArray(*conshdlrdata->partialdecs, idlist, listlength);
5300 
5301  return SCIP_OKAY;
5302 }
5303 
5304 
5306  SCIP* scip
5307  )
5308 {
5309  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5310  assert(conshdlrdata != NULL);
5311 
5312  return (int) conshdlrdata->userblocknrcandidates->size();
5313 }
5314 
5315 
5317  SCIP* scip,
5318  int id
5319  )
5320 {
5321  /* get partialdec and returns the number of its blocks */
5322  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5323  return partialdec->getNBlocks();
5324 }
5325 
5326 
5328  SCIP* scip
5329  )
5330 {
5331  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5332  int ndecomps;
5333 
5334  assert(conshdlrdata != NULL);
5335 
5336  ndecomps = 0;
5337 
5338  for(auto partialdec : *conshdlrdata->partialdecs)
5339  {
5340  if(partialdec->isComplete())
5341  ndecomps++;
5342  }
5343 
5344  return ndecomps;
5345 }
5346 
5347 
5349  SCIP* scip
5350  )
5351 {
5352  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5353  assert(conshdlrdata != NULL);
5354 
5355  return conshdlrdata->ndetectors;
5356 }
5357 
5358 
5360  SCIP* scip
5361  )
5362 {
5363  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5364  assert(conshdlrdata != NULL);
5365 
5366  conshdlrdata->partialdeccounter = conshdlrdata->partialdeccounter + 1;
5367 
5368  assert(GCGconshdlrDecompGetPartialdecFromID(scip, conshdlrdata->partialdeccounter) == NULL);
5369 
5370  return conshdlrdata->partialdeccounter;
5371 }
5372 
5373 
5375  SCIP* scip,
5376  int id
5377  )
5378 {
5379  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5380  assert(conshdlrdata != NULL);
5381 
5382  // look for the partialdec and check whether it is complete
5383  auto itr = conshdlrdata->partialdecsbyid->find(id);
5384  if( itr != conshdlrdata->partialdecsbyid->end() && itr->second->isComplete() )
5385  {
5386  return itr->second->getDetprobdata()->getNConss();
5387  }
5388 
5389  /* partialdec is not found hence we should not trust the isomorph information from detection */
5390  return -1;
5391 }
5392 
5393 
5395  SCIP* scip,
5396  int id
5397  )
5398 {
5399  /* get partialdec and returns the number of its linking vars */
5400  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5401  return partialdec->getNLinkingvars();
5402 }
5403 
5404 
5406  SCIP* scip,
5407  int id
5408  )
5409 {
5410  /* get partialdec and returns the number of its master conss */
5411  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5412  return partialdec->getNMasterconss();
5413 }
5414 
5415 
5417  SCIP* scip,
5418  int id
5419  )
5420 {
5421  /* get partialdec and returns the number of its master vars */
5422  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5423  return partialdec->getNMastervars();
5424 }
5425 
5426 
5428  SCIP* scip,
5429  int id
5430  )
5431 {
5432  /* get partialdec and returns the number of its open conss */
5433  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5434  return partialdec->getNOpenconss();
5435 }
5436 
5437 
5439  SCIP* scip,
5440  int id
5441  )
5442 {
5443  /* get partialdec and returns the number of its open vars */
5444  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5445  return partialdec->getNOpenvars();
5446 }
5447 
5448 
5450  SCIP* scip
5451  )
5452 {
5453  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5454  assert(conshdlrdata != NULL);
5455 
5456  if( conshdlrdata->detprobdataorig == NULL )
5457  return 0;
5458 
5459  return (int) conshdlrdata->detprobdataorig->getNFinishedPartialdecs();
5460 }
5461 
5462 
5464  SCIP* scip
5465  )
5466 {
5467  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5468  assert(conshdlrdata != NULL);
5469 
5470  if( conshdlrdata->detprobdatapres == NULL )
5471  return 0;
5472 
5473  return (int) conshdlrdata->detprobdatapres->getNFinishedPartialdecs();
5474 }
5475 
5476 
5478  SCIP* scip
5479  )
5480 {
5481  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5482  assert(conshdlrdata != NULL);
5483 
5484  if( conshdlrdata->detprobdataorig == NULL )
5485  return 0;
5486 
5487  return (int) conshdlrdata->detprobdataorig->getNOpenPartialdecs();
5488 }
5489 
5490 
5492  SCIP* scip
5493  )
5494 {
5495  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5496  assert(conshdlrdata != NULL);
5497 
5498  if( conshdlrdata->detprobdatapres == NULL )
5499  return 0;
5500 
5501  return (int) conshdlrdata->detprobdatapres->getNOpenPartialdecs();
5502 }
5503 
5504 
5506  SCIP* scip
5507  )
5508 {
5509  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5510  assert(conshdlrdata != NULL);
5511 
5512  return (int) conshdlrdata->partialdecs->size();
5513 }
5514 
5515 
5517  SCIP* scip
5518  )
5519 {
5520  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5521  assert(conshdlrdata != NULL);
5522 
5523  if( conshdlrdata->detprobdataorig == NULL )
5524  return 0;
5525 
5526  return (int) conshdlrdata->detprobdataorig->getNPartialdecs();
5527 }
5528 
5529 
5531  SCIP* scip
5532  )
5533 {
5534  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5535  assert(conshdlrdata != NULL);
5536 
5537  if( conshdlrdata->detprobdatapres == NULL )
5538  return 0;
5539 
5540  return (int) conshdlrdata->detprobdatapres->getNPartialdecs();
5541 }
5542 
5543 
5545  SCIP* scip,
5546  int id
5547  )
5548 {
5549  /* get partialdec and returns the number of its stairlinking vars */
5550  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5551  return partialdec->getNTotalStairlinkingvars();
5552 }
5553 
5554 
5555 std::vector<PARTIALDECOMP*>* GCGconshdlrDecompGetPartialdecs(
5556  SCIP* scip /**< SCIP data structure */
5557  )
5558 {
5559  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5560  assert(conshdlrdata != NULL);
5561 
5562  return conshdlrdata->partialdecs;
5563 }
5564 
5565 
5567  SCIP* scip,
5568  int partialdecid,
5570  )
5571 {
5572  PARTIALDECOMP* s;
5573 
5574  s = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
5575  pwr->partialdec = s;
5576 
5577  return SCIP_OKAY;
5578 }
5579 
5580 
5582  SCIP* scip,
5583  int id
5584  )
5585 {
5586  /* get partialdec and returns its score in respect to the current score type */
5587  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5588  return partialdec->getScore(GCGconshdlrDecompGetScoretype(scip));
5589 }
5590 
5591 
5593  SCIP* scip
5594  )
5595 {
5596  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5597  return conshdlrdata->scoretotaltime;
5598 }
5599 
5600 
5602  SCIP* scip
5603  )
5604 {
5605  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5606  assert(conshdlrdata != NULL);
5607 
5608  return static_cast<scoretype>(conshdlrdata->currscoretype);
5609 }
5610 
5611 
5613  SCIP* scip,
5614  int** idlist,
5615  int* listlength
5616  )
5617 {
5618  /* get list of selected partialdecs */
5619  std::vector<PARTIALDECOMP*> selectedpartialdecs;
5620  getSelectedPartialdecs(scip, selectedpartialdecs);
5621  /* set the length of the pointer array to the list size */
5622  *listlength = (int) selectedpartialdecs.size();
5623 
5624  /* build a pointer list of ids from the partialdec list */
5625  for(int i = 0; i < (int) selectedpartialdecs.size(); i++)
5626  {
5627  (*idlist)[i] = selectedpartialdecs[i]->getID();
5628  }
5629 
5630  return SCIP_OKAY;
5631 }
5632 
5633 
5635  SCIP* scip
5636  )
5637 {
5638  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5639  assert(conshdlrdata != NULL);
5640 
5641  ++conshdlrdata->ncallscreatedecomp;
5642 
5643  return conshdlrdata->ncallscreatedecomp;
5644 }
5645 
5646 
5648  SCIP* scip,
5649  int id
5650  )
5651 {
5652  /* get partialdec and returns whether it is presolved */
5653  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5654  return !partialdec->isAssignedToOrigProb();
5655 }
5656 
5657 
5659  SCIP* scip,
5660  int id
5661  )
5662 {
5663  /* get partialdec and returns whether it is currently selected */
5664  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, id);
5665  return partialdec->isSelected();
5666 }
5667 
5668 
5670  SCIP* scip
5671  )
5672 {
5673  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5674  assert(conshdlrdata != NULL);
5675 
5676  if(conshdlrdata->detprobdataorig == NULL)
5677  return FALSE;
5678 
5679  return TRUE;
5680 }
5681 
5682 
5684  SCIP* scip
5685  )
5686 {
5687  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5688  assert(conshdlrdata != NULL);
5689 
5690  if( conshdlrdata->detprobdataorig == NULL )
5691  return FALSE;
5692 
5693  return conshdlrdata->detprobdataorig->getNPartialdecs() > 0;
5694 }
5695 
5696 
5698  SCIP* scip
5699  )
5700 {
5701  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5702  assert(conshdlrdata != NULL);
5703 
5704  if(conshdlrdata->detprobdatapres == NULL)
5705  return FALSE;
5706 
5707  return TRUE;
5708 }
5709 
5710 
5712  SCIP* scip,
5713  FILE* file
5714  )
5715 {
5716  int i;
5717 
5718  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5719  assert(conshdlrdata != NULL);
5720 
5721  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "Detector statistics: time #decompositions #complete decompositions\n");
5722  for( i = 0; i < conshdlrdata->ndetectors; ++i )
5723  {
5724  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file,
5725  " %-17.16s: %8.2f %10d %10d\n",
5726  conshdlrdata->detectors[i]->name, conshdlrdata->detectors[i]->dectime,
5727  conshdlrdata->detectors[i]->ndecomps, conshdlrdata->detectors[i]->ncompletedecomps );
5728  }
5729  return SCIP_OKAY;
5730 }
5731 
5732 
5734  SCIP* scip,
5735  PARTIALDECOMP* partialdec
5736  )
5737 {
5738  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5739 
5740  // do not register a partialdecomp multiple times
5741  if( conshdlrdata->partialdecsbyid->find(partialdec->getID()) == conshdlrdata->partialdecsbyid->end())
5742  {
5743  conshdlrdata->partialdecs->push_back(partialdec);
5744  conshdlrdata->partialdecsbyid->emplace(partialdec->getID(), partialdec);
5745  }
5746 }
5747 
5748 
5750  SCIP* scip, /**< SCIP data structure */
5751  int partialdecid, /**< id of partialdecomp */
5752  SCIP_Bool select /**< select/unselect */
5753  )
5754 {
5755  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, partialdecid);
5756  if( partialdec )
5757  partialdec->setSelected(select);
5758  else
5759  return SCIP_INVALIDDATA;
5760  return SCIP_OKAY;
5761 }
5762 
5763 
5765  SCIP* scip,
5766  SCIP_PARAMSETTING paramsetting,
5767  SCIP_Bool quiet
5768 )
5769 {
5770  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5771  assert(conshdlrdata != NULL);
5772 
5773  switch( paramsetting )
5774  {
5775  case SCIP_PARAMSETTING_AGGRESSIVE:
5776  SCIP_CALL( setDetectionAggressive(scip, conshdlrdata, quiet) );
5777  break;
5778  case SCIP_PARAMSETTING_OFF:
5779  SCIP_CALL( setDetectionOff(scip, conshdlrdata, quiet) );
5780  break;
5781  case SCIP_PARAMSETTING_FAST:
5782  SCIP_CALL( setDetectionFast(scip, conshdlrdata, quiet) );
5783  break;
5784  case SCIP_PARAMSETTING_DEFAULT:
5785  SCIP_CALL( setDetectionDefault(scip, conshdlrdata, quiet) );
5786  break;
5787  default:
5788  SCIPerrorMessage("The given paramsetting is invalid!\n");
5789  break;
5790  }
5791 
5792  return SCIP_OKAY;
5793 }
5794 
5795 
5797  SCIP* scip,
5798  SCORETYPE sctype
5799  )
5800 {
5801  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5802  assert(conshdlrdata != NULL);
5803 
5804  conshdlrdata->currscoretype = sctype;
5805 }
5806 
5807 
5809  SCIP* scip,
5810  int n,
5811  SCIP_Bool completeGreedily
5812 )
5813 {
5814  std::vector<std::pair<PARTIALDECOMP*, SCIP_Real> > candidates;
5815  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5816  assert(conshdlrdata != NULL);
5817 
5818  if( conshdlrdata->detprobdataorig == NULL )
5819  {
5820  resetDetprobdata(scip, TRUE);
5821  resetDetprobdata(scip, FALSE);
5822  return SCIP_OKAY;
5823  }
5824 
5825  if( conshdlrdata->detprobdatapres == NULL )
5826  resetDetprobdata(scip, FALSE);
5827 
5828  if( conshdlrdata->detprobdataorig->getNOpenPartialdecs() == 0 && conshdlrdata->detprobdataorig->getNFinishedPartialdecs() == 0 )
5829  {
5830  return SCIP_OKAY;
5831  }
5832 
5833  GCGconshdlrDecompChooseCandidatesFromSelected(scip, candidates, TRUE, TRUE);
5834  if ( !candidates.empty() )
5835  {
5836  n = MIN(n, candidates.size());
5837 
5838  std::vector<PARTIALDECOMP *> origpartialdecs(n);
5839  for( int i = 0; i < n; ++i )
5840  origpartialdecs[i] = candidates[i].first;
5841 
5842  std::vector<PARTIALDECOMP *> partialdecstranslated = conshdlrdata->detprobdatapres->translatePartialdecs(
5843  conshdlrdata->detprobdataorig, origpartialdecs);
5844 
5845  if( !partialdecstranslated.empty())
5846  {
5847  PARTIALDECOMP *newpartialdec = partialdecstranslated[0];
5848  if( completeGreedily && !newpartialdec->isComplete() )
5849  newpartialdec->completeGreedily();
5850  SCIP_CALL(addPartialdec(scip, newpartialdec));
5851  }
5852  }
5853 
5854  return SCIP_OKAY;
5855 }
5856 
5857 
5859  SCIP* scip
5860  )
5861 {
5862  std::vector<PARTIALDECOMP*>::iterator partialdeciter;
5863  std::vector<PARTIALDECOMP*>::iterator partialdeciterend;
5864 
5865  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5866  assert(conshdlrdata != NULL);
5867 
5868  if( conshdlrdata->detprobdataorig == NULL )
5869  {
5870  resetDetprobdata(scip, TRUE);
5871  resetDetprobdata(scip, FALSE);
5872  return SCIP_OKAY;
5873  }
5874 
5875  if( conshdlrdata->detprobdatapres == NULL )
5876  resetDetprobdata(scip, FALSE);
5877 
5878  if( conshdlrdata->detprobdataorig->getNOpenPartialdecs() == 0 && conshdlrdata->detprobdataorig->getNFinishedPartialdecs() == 0 )
5879  {
5880  return SCIP_OKAY;
5881  }
5882 
5883  std::vector<PARTIALDECOMP*> partialdecstranslated = conshdlrdata->detprobdatapres->translatePartialdecs(conshdlrdata->detprobdataorig);
5884 
5885  partialdeciter = partialdecstranslated.begin();
5886  partialdeciterend = partialdecstranslated.end();
5887 
5888  for(; partialdeciter != partialdeciterend; ++partialdeciter )
5889  {
5890  SCIP_CALL(addPartialdec(scip, *partialdeciter) );
5891  }
5892 
5893  return SCIP_OKAY;
5894 }
5895 
5896 
5898  SCIP* scip,
5899  SCIP_Bool original
5900  )
5901 {
5902  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5903  assert(conshdlrdata != NULL);
5904 
5905  return original == TRUE ? conshdlrdata->hasrunoriginal : conshdlrdata->hasrun;
5906 }
5907 
5908 
5910  SCIP* scip
5911  )
5912 {
5913  long int startcount;
5914  SCIP_CONS** conss;
5915  SCIP_CONSHDLRDATA* conshdlrdata = getConshdlrdata(scip);
5916  assert(conshdlrdata != NULL);
5917 
5918  startcount = 1;
5919 
5920  if( conshdlrdata->consnamesalreadyrepaired )
5921  return SCIP_OKAY;
5922 
5923  unordered_map<std::string, bool> consnamemap;
5924 
5925  SCIPdebugMessage("start repair conss \n ");
5926 
5927  conss = SCIPgetConss(scip);
5928 
5929  for( int i = 0; i < (int) SCIPgetNConss(scip); ++i )
5930  {
5931  SCIP_CONS* cons = conss[i];
5932 
5933  SCIPdebugMessage( "cons name: %s\n ", SCIPconsGetName(cons));
5934 
5935  if( SCIPconsGetName(cons) == NULL || strcmp(SCIPconsGetName(cons), "") == 0 || consnamemap[SCIPconsGetName(cons)] )
5936  {
5937  if( SCIPgetStage(scip) <= SCIP_STAGE_PROBLEM )
5938  {
5939  char newconsname[SCIP_MAXSTRLEN];
5940  startcount = findGenericConsname(scip, startcount, newconsname, SCIP_MAXSTRLEN ) + 1;
5941  SCIPdebugMessage( "Change consname to %s\n", newconsname );
5942  SCIPchgConsName(scip, cons, newconsname );
5943  consnamemap[newconsname] = true;
5944  }
5945  else
5946  {
5947  if ( SCIPconsGetName(cons) == NULL )
5948  SCIPwarningMessage(scip, "Name of constraint is NULL \n");
5949  else if ( strcmp(SCIPconsGetName(cons), "") == 0 )
5950  SCIPwarningMessage(scip, "Name of constraint is not set \n");
5951  else
5952  SCIPwarningMessage(scip, "Constraint name duplicate: %s \n", SCIPconsGetName(cons) );
5953  }
5954  }
5955  else
5956  {
5957  consnamemap[SCIPconsGetName(cons)] = true;
5958  }
5959 
5960  SCIPdebugMessage( " number of elements: %d \n " , (int) consnamemap.size() );
5961  }
5962 
5963  conshdlrdata->consnamesalreadyrepaired = TRUE;
5964 
5965  return SCIP_OKAY;
5966 }
5967 
5968 
5970  SCIP* scip
5971  )
5972 {
5973  SCIP_CONSHDLR* conshdlr;
5974  SCIP_CONSHDLRDATA* conshdlrdata;
5975 
5976  /* create decomp constraint handler data */
5977  SCIP_CALL( SCIPallocMemory(scip, &conshdlrdata) );
5978  assert(conshdlrdata != NULL);
5979 
5980  /* initialize conshdlrdata */
5981  conshdlrdata->partialdecs = new std::vector<PARTIALDECOMP*>();
5982  conshdlrdata->partialdecsbyid = new std::unordered_map<int, PARTIALDECOMP*>();
5983  conshdlrdata->partialdeccounter = 0;
5984  conshdlrdata->decomps = NULL;
5985  conshdlrdata->ndecomps = 0;
5986  conshdlrdata->detectors = NULL;
5987  conshdlrdata->priorities = NULL;
5988  conshdlrdata->ndetectors = 0;
5989  conshdlrdata->propagatingdetectors = NULL;
5990  conshdlrdata->npropagatingdetectors = 0;
5991  conshdlrdata->finishingdetectors = NULL;
5992  conshdlrdata->nfinishingdetectors = 0;
5993  conshdlrdata->postprocessingdetectors = NULL;
5994  conshdlrdata->npostprocessingdetectors = 0;
5995 
5996  SCIP_CALL( SCIPcreateClock(scip, &conshdlrdata->detectorclock) );
5997  SCIP_CALL( SCIPcreateClock(scip, &conshdlrdata->completedetectionclock) );
5998 
5999  conshdlrdata->hasrun = FALSE;
6000  conshdlrdata->hasrunoriginal = FALSE;
6001  conshdlrdata->ncallscreatedecomp = 0;
6002  conshdlrdata->detprobdatapres = NULL;
6003  conshdlrdata->detprobdataorig = NULL;
6004  conshdlrdata->partialdectowrite = NULL;
6005  conshdlrdata->consnamesalreadyrepaired = FALSE;
6006  conshdlrdata->userblocknrcandidates = new std::vector<int>();
6007  conshdlrdata->freeorig = TRUE;
6008 
6009  /* classifiers */
6010  conshdlrdata->consclassifiers = NULL;
6011  conshdlrdata->nconsclassifiers = 0;
6012  conshdlrdata->consclassifierpriorities = NULL;
6013  conshdlrdata->varclassifiers = NULL;
6014  conshdlrdata->nvarclassifiers = 0;
6015  conshdlrdata->varclassifierpriorities = NULL;
6016 
6017  /* score data */
6018  conshdlrdata->scoretotaltime = 0.;
6019  conshdlrdata->dualvalsrandom = new std::vector<SCIP_Real>();
6020  conshdlrdata->dualvalsoptimaloriglp = new std::vector<SCIP_Real>();
6021  conshdlrdata->dualvalsrandomset = FALSE;
6022  conshdlrdata->dualvalsoptimaloriglpcalculated = FALSE;
6023 
6024  /* include constraint handler */
6025  SCIP_CALL( SCIPincludeConshdlrBasic(scip, &conshdlr, CONSHDLR_NAME, CONSHDLR_DESC,
6027  consEnfolpDecomp, consEnfopsDecomp, consCheckDecomp, consLockDecomp,
6028  conshdlrdata) );
6029  assert(conshdlr != FALSE);
6030 
6031  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforeDecomp) );
6032  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeDecomp) );
6033  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitDecomp) );
6034  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitDecomp) );
6035 
6036  /* add menu parameters for detection */
6037  SCIP_CALL( SCIPaddBoolParam(scip, "detection/enabled", "Enables detection", &conshdlrdata->enabled, FALSE, DEFAULT_ENABLED, NULL, NULL) );
6038 
6039  SCIP_CALL( SCIPaddBoolParam(scip, "detection/postprocess", "Enables postprocessing of complete decompositions",
6040  &conshdlrdata->postprocess, FALSE, DEFAULT_POSTPROCESS, NULL, NULL) );
6041 
6042  SCIP_CALL( SCIPaddIntParam(scip, "detection/maxrounds",
6043  "Maximum number of detection loop rounds", &conshdlrdata->maxndetectionrounds, FALSE,
6044  DEFAULT_MAXDETECTIONROUNDS, 0, INT_MAX, NULL, NULL) );
6045 
6046  SCIP_CALL( SCIPaddIntParam(scip, "detection/maxtime",
6047  "Maximum detection time in seconds", &conshdlrdata->maxdetectiontime, FALSE,
6048  DEFAULT_MAXDETECTIONTIME, 0, INT_MAX, NULL, NULL) );
6049 
6050  SCIP_CALL( SCIPaddBoolParam(scip, "detection/origprob/enabled", "Enables detection for the original problem",
6051  &conshdlrdata->enableorigdetection, FALSE, DEFAULT_ENABLEORIGDETECTION, NULL, NULL) );
6052 
6053  SCIP_CALL( SCIPaddIntParam(scip, "detection/origprob/weightinggpresolvedoriginaldecomps",
6054  "Weighting method when comparing decompositions for presolved and orig problem", &conshdlrdata->weightinggpresolvedoriginaldecomps, TRUE,
6055  NO_MODIF, 0, 3, NULL, NULL) );
6056 
6057  SCIP_CALL( SCIPaddIntParam(scip, "detection/aggregation/limitnconssperblock",
6058  "Limits the number of constraints of a block (aggregation information for block is not calculated when exceeded)",
6059  &conshdlrdata->aggregationlimitnconssperblock, FALSE,
6060  DEFAULT_AGGREGATIONLIMITNCONSSPERBLOCK, 0, INT_MAX, NULL, NULL) );
6061 
6062  SCIP_CALL( SCIPaddIntParam(scip, "detection/aggregation/limitnvarsperblock",
6063  "Limits the number of variables of a block (aggregation information for block is not calculated when exceeded)",
6064  &conshdlrdata->aggregationlimitnvarsperblock, FALSE,
6065  DEFAULT_AGGREGATIONLIMITNVARSPERBLOCK, 0, INT_MAX, NULL, NULL) );
6066 
6067  SCIP_CALL( SCIPaddBoolParam(scip, "detection/benders/onlycontsubpr", "If enabled only decomposition with only continiuous variables in the subproblems are searched",
6068  &conshdlrdata->bendersonlycontsubpr, FALSE, DEFAULT_BENDERSONLYCONTSUBPR, NULL, NULL) );
6069 
6070  SCIP_CALL( SCIPaddBoolParam(scip, "detection/benders/onlybinmaster", "If enabled only decomposition with only binary variables in the master are searched",
6071  &conshdlrdata->bendersonlybinmaster, FALSE, DEFAULT_BENDERSONLYBINMASTER, NULL, NULL) );
6072 
6073  SCIP_CALL( SCIPaddBoolParam(scip, "detection/benders/enabled", "Enables benders detection",
6074  &conshdlrdata->detectbenders, FALSE, DEFAULT_DETECTBENDERS, NULL, NULL) );
6075 
6076  /* classification */
6077  SCIP_CALL( SCIPaddBoolParam(scip, "detection/classification/enabled", "Enables classification", &conshdlrdata->classify, FALSE, DEFAULT_CLASSIFY, NULL, NULL) );
6078 
6079  SCIP_CALL( SCIPaddBoolParam(scip, "detection/classification/allowduplicates", "If enabled partition duplicates are allowed (for statistical reasons)",
6080  &conshdlrdata->allowpartitionduplicates, FALSE, DEFAULT_ALLOWPARTITIONDUPLICATES, NULL, NULL) );
6081 
6082  SCIP_CALL( SCIPaddBoolParam(scip, "detection/origprob/classificationenabled", "Enables classification for the original problem",
6083  &conshdlrdata->enableorigclassification, FALSE, DEFAULT_ENABLEORIGCLASSIFICATION, NULL, NULL) );
6084 
6085  SCIP_CALL( SCIPaddIntParam(scip, "detection/classification/maxnclassesperpartition",
6086  "Maximum number of classes per partition", &conshdlrdata->maxnclassesperpartition, FALSE,
6087  DEFAULT_MAXNCLASSES, 0, INT_MAX, NULL, NULL) );
6088 
6089  SCIP_CALL( SCIPaddIntParam(scip, "detection/classification/maxnclassesperpartitionforlargeprobs",
6090  "Maximum number of classes per partition for large problems (nconss + nvars >= 50000)", &conshdlrdata->maxnclassesperpartitionforlargeprobs, FALSE,
6091  DEFAULT_MAXNCLASSESLARGEPROBS, 0, INT_MAX, NULL, NULL) );
6092 
6093  /* block numbers */
6094  SCIP_CALL( SCIPaddIntParam(scip, "detection/blocknrcandidates/maxnclasses",
6095  "Maximum number of classes a partition can use for voting nblockcandidates", &conshdlrdata->maxnclassesfornblockcandidates, FALSE,
6096  DEFAULT_MAXNCLASSESFORNBLOCKCANDIDATES, 0, INT_MAX, NULL, NULL) );
6097 
6098  SCIP_CALL( SCIPaddBoolParam(scip, "detection/blocknrcandidates/medianvarspercons",
6099  "Enables the use of medianvarspercons calculation for block number candidates calculation ",
6100  &conshdlrdata->blocknumbercandsmedianvarspercons,
6101  FALSE, DEFAULT_BLOCKNUMBERCANDSMEDIANVARSPERCONS, NULL, NULL) );
6102 
6103  /* scores */
6104  SCIP_CALL( SCIPaddIntParam(scip, "detection/score/scoretype",
6105  "Score calculation for comparing (partial) decompositions (0: max white, 1: border area, 2: classic, 3: max foreseeing white, 4: ppc-max-white, 5: max foreseeing white with aggregation info, 6: ppc-max-white with aggregation info, 7: experimental benders score, 8: strong decomposition score)",
6106  &conshdlrdata->currscoretype, FALSE,
6107  scoretype::SETPART_FWHITE, 0, 8, NULL, NULL) );
6108 
6109  SCIP_CALL( SCIPaddRealParam(scip, "detection/score/strong_detection/timelimit",
6110  "Timelimit for strong decompositions score calculation per partialdec in seconds", &conshdlrdata->strongtimelimit, FALSE,
6111  DEFAULT_STRONGTIMELIMIT, 0., INT_MAX, NULL, NULL) );
6112 
6113  SCIP_CALL( SCIPaddIntParam(scip, "detection/score/strong_detection/dualvalrandommethod",
6114  "Method for random dual values use for strong decomposition: 1: naive, 2: expected equality exponential distributed, 3: expected overestimation exponential distributed ",
6115  &conshdlrdata->strongdetectiondualvalrandommethod, FALSE,
6116  DEFAULT_DUALVALRANDOMMETHOD, 1, 3, NULL, NULL) );
6117 
6118  SCIP_CALL( SCIPaddRealParam(scip, "detection/score/strong_detection/coeffactororigvsrandom",
6119  "Convex coefficient for orig dual val, i.e. (1-this coef) is factor for random dual value", &conshdlrdata->coeffactororigvsrandom, FALSE,
6120  DEFAULT_COEFFACTORORIGVSRANDOM, 0., 1., NULL, NULL) );
6121 
6122  return SCIP_OKAY;
6123 }
gcg::PARTIALDECOMP * partialdec
void DECdecompSetNBlocks(DEC_DECOMP *decomp, int nblocks)
Definition: decomp.c:733
void addClockTime(SCIP_Real clocktime)
adds detection time of one detector
@ FRACTION_OF_NROWS
void setFinishedByFinisher(bool finished)
sets whether this partialdec was finished by a finishing detector
#define CONSHDLR_NAME
Definition: cons_decomp.cpp:78
int getNConss()
returns the number of variables considered in the detprobdata
bool aggInfoCalculated()
Checks if the aggregation information was already calculated.
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
SCIP_Bool GCGconshdlrDecompOrigPartialdecExists(SCIP *scip)
returns whether or not an original decompositions exists in the data structures
SCIP_Bool skip
std::vector< SCIP_Real > * dualvalsoptimaloriglp
#define DEFAULT_SCORECOEF_MEDIUMNOTBENEFICIAL
static SCIP_DECL_CONSEXIT(consExitDecomp)
deinitialization method of constraint handler (called before transformed problem is freed)
#define DEC_DECL_CONSCLASSIFY(x)
@ DEC_DECTYPE_BORDERED
Definition: type_decomp.h:53
structure information for decomposition information in GCG projects
SCIP_Bool blocknumbercandsmedianvarspercons
SCIP_Bool allowpartitionduplicates
SCIP_RETCODE GCGconshdlrDecompCalcSetPartForseeingWhiteScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the setpartitioning maximum foreseeing white area score of a partialdec
gcg::DETPROBDATA * detprobdataorig
int * varclassifierpriorities
static void getFinishedPartialdecs(SCIP *scip, std::vector< PARTIALDECOMP * > &finishedpartialdecs)
gets vector of all finished partialdecs
std::vector< int > & getMastervars()
Gets array containing all master vars indices.
DEC_DETECTOR ** propagatingdetectors
SCIP_Real GCGconsGetRhs(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:108
SCIP_Real dectime
std::vector< SCIP_Real > * dualvalsrandom
void GCGconshdlrDecompAddUserCandidatesNBlocks(SCIP *scip, int candidate)
adds a candidate for block size given by the user
bool isVarStairlinkingvar(int var)
Checks whether the var is a stairlinking var.
#define DEFAULT_ALLOWPARTITIONDUPLICATES
SCIP_RETCODE DECdecompSetSubscipconss(SCIP *scip, DEC_DECOMP *decomp, SCIP_CONS ***subscipconss, int *nsubscipconss)
Definition: decomp.c:843
std::vector< int > & getVarsForBlock(int block)
Gets array containing vars of a block.
void fixVarToMaster(int var)
adds a variable to the master variables
SCIP_Real coeffactororigvsrandom
SCIP_RETCODE GCGconshdlrDecompCalcStrongDecompositionScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the strong decomposition score of a partialdec
SCIP_Bool enabledFinishing
int GCGconshdlrDecompGetNFormerDetectionConssForID(SCIP *scip, int id)
gets number of active constraints during the detection of the decomp with given id
std::string GCGconshdlrDecompGetDetectorHistoryByPartialdecId(SCIP *scip, int id)
gets detector history of partialdec with given id
SCIP_RETCODE GCGprintDecompInformation(SCIP *scip, FILE *file)
int getNOpenvars()
Gets size of vector containing variables not assigned yet.
void DECdecompSetDetectorPctVarsFromOpen(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *pctVarsFromOpen)
Definition: decomp.c:1871
enum GCG_Random_dual_methods GCG_RANDOM_DUAL_METHOD
#define CONSHDLR_EAGERFREQ
Definition: cons_decomp.cpp:82
SCIP_RETCODE GCGconshdlrDecompCalcClassicScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the classic score of a partialdec
static int gcd(int a, int b)
method to calculate the greatest common divisor
int maxnclassesfornblockcandidates
unsigned int GCGconshdlrDecompGetNOpenPartialdecsTransformed(SCIP *scip)
Gets the number of open partialdecs available for the transformed problem.
SCIP_Real * DECdecompGetDetectorPctVarsFromOpen(DEC_DECOMP *decomp)
Definition: decomp.c:1899
static SCIP_DECL_CONSFREE(consFreeDecomp)
destructor of constraint handler to free constraint handler data (called when SCIP is exiting)
static SCIP_RETCODE addPartialdec(SCIP *scip, PARTIALDECOMP *partialdec)
local method to handle store a partialdec in the correct detprobdata
std::vector< int >::const_iterator fixConsToMaster(std::vector< int >::const_iterator itr)
fixes a constraint to the master constraints
void setMaxForWhiteAggScore(SCIP_Real score)
set the maximum foreseeing white area score with respect to aggregatable blocks
SCIP_Real classificationtime
SCIP_Real GCGconsGetLhs(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:206
SCIP_Bool usefulRecall
void printPartitionInformation(FILE *file)
output method for json file writer to write partition candidate information
SCIP_RETCODE GCGconshdlrDecompPrintDetectorStatistics(SCIP *scip, FILE *file)
display statistics about detectors
float GCGconshdlrDecompGetScoreByPartialdecId(SCIP *scip, int id)
gets score of partialdec with given id
SCIP_RETCODE DECdecompSetDetectorChain(SCIP *scip, DEC_DECOMP *decomp, DEC_DETECTOR **detectors, int ndetectors)
Definition: decomp.c:1610
SCIP_Bool isAssignedToOrigProb()
returns true if the matrix structure corresponds to the presolved problem
DEC_DETECTOR ** DECdecompGetDetectorChain(DEC_DECOMP *decomp)
Definition: decomp.c:1600
scoretype
possible scores to evaluate founds decompositions
int GCGconshdlrDecompAddMatrixPartialdec(SCIP *scip, SCIP_Bool presolved)
creates a pure matrix partialdecomp (i.e. all cons/vars to one single block)
data structures for variable classifiers
unsigned int GCGconshdlrDecompGetNPartialdecsTransformed(SCIP *scip)
Gets the number of partialdecs available for the transformed problem.
void setNBlocks(int nblocks)
sets number of blocks, only increasing number allowed
void DECdecompSetVartoblock(DEC_DECOMP *decomp, SCIP_HASHMAP *vartoblock)
Definition: decomp.c:1187
DEC_CONSCLASSIFIER * DECfindConsClassifier(SCIP *scip, const char *name)
searches for the consclassifier with the given name and returns it or NULL if classifier is not found
SCIP_RETCODE GCGprintPartitionInformation(SCIP *scip, FILE *file)
int DECdecompGetNLinkingconss(DEC_DECOMP *decomp)
Definition: decomp.c:977
std::vector< int > & getOpenconssVec()
Gets a vector containing constraint ids not assigned yet as vector.
unsigned int GCGconshdlrDecompGetNFinishedPartialdecsTransformed(SCIP *scip)
Gets the number of finished partialdecs available for the transformed problem.
@ FRACTION_OF_NNONZEROS
SCIP_Real getMaxForWhiteAggScore()
gets the maximum foreseeing white area score with respect to aggregatable blocks
#define FAST_LEVENSHTEIN_MAXMATRIXHALFPERIMETER
SCIP_RETCODE GCGconshdlrDecompSelectPartialdec(SCIP *scip, int partialdecid, SCIP_Bool select)
selects/unselects a partialdecomp
SCIP_RETCODE DECwriteAllDecomps(SCIP *scip, char *directory, char *extension, SCIP_Bool original, SCIP_Bool presolved)
write out all known decompositions
@ DEC_DECTYPE_ARROWHEAD
Definition: type_decomp.h:50
SCIP_RETCODE GCGconshdlrDecompCreateVarmapForPartialdecId(SCIP *scip, SCIP_HASHMAP **hashorig2pricingvar, int partialdecid, int probnr1, int probnr2, SCIP *scip1, SCIP *scip2, SCIP_HASHMAP *varmap)
for two identical pricing problems a corresponding varmap is created
SCIP_RETCODE DECdecompSetSubscipvars(SCIP *scip, DEC_DECOMP *decomp, SCIP_VAR ***subscipvars, int *nsubscipvars)
Definition: decomp.c:755
bool isVarOpenvar(int var)
Checks whether the var is an open var.
static SCIP_RETCODE setDetectionEnabled(SCIP *scip, SCIP_Bool quiet, SCIP_Bool enabled)
sets detection/enabled setting
SCIP_Bool hasrunoriginal
SCIP_RETCODE GCGconshdlrDecompAddScoreTime(SCIP *scip, SCIP_Real time)
adds given time to total score calculation time
std::vector< SCIP_Real > & getPctConssToBlockVector()
Gets fraction of constraints assigned to a block for detectors in detectorchain.
SCIP_RETCODE GCGconshdlrDecompAddPreexistingDecomp(SCIP *scip, DEC_DECOMP *decomp)
adds a decomp that exists before the detection is called
static void reduceConsclasses(SCIP *scip, gcg::DETPROBDATA *detprobdata)
adds constraint partitions with a reduced number of classes
int getVarProbindexForBlock(int varid, int block)
Gets index in variables array of a block for a variable.
bool isVarBlockvarOfBlock(int var, int block)
Checks whether the var is assigned to the block.
void DECdecompSetConstoblock(DEC_DECOMP *decomp, SCIP_HASHMAP *constoblock)
Definition: decomp.c:1209
#define DEFAULT_AGGREGATIONLIMITNVARSPERBLOCK
SCIP_Bool postprocess
void findVarsLinkingToStairlinking()
reassigns variables classified as linking to stairlinking if appropriate
void DECsetMaxWhiteScore(SCIP *scip, DEC_DECOMP *decdecomp, SCIP_Real maxwhitescore)
Definition: decomp.c:3253
void addPctConssToBorder(SCIP_Real pct)
adds percentage of constraints assigned to border
std::vector< int > & getMasterconss()
Gets array containing all master conss indices.
SCIP_Real nblockscandidatescalctime
bool isComplete()
Gets whether this partialdec is complete, i.e. it has no more open constraints and variables.
SCIP_Bool detectbenders
SCIP_Real GCGconsGetDualsol(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:368
int GCGconshdlrDecompGetNBlockNumberCandidates(SCIP *scip)
returns the number of block candidates given by the user
SCIP_RETCODE GCGconsGetVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int nvars)
Definition: scip_misc.c:490
void GCGconshdlrDecompSetScoretype(SCIP *scip, SCORETYPE sctype)
Sets the currently used scoretype.
void fixVarToLinking(int var)
adds a variable to the linking variables
DEC_DECL_FREEDETECTOR(freeNeighborhoodmaster)
#define DEC_DECL_FREECONSCLASSIFIER(x)
unsigned int GCGconshdlrDecompGetNPartialdecs(SCIP *scip)
Gets the number of all partialdecs.
#define DEC_DECL_EXITDETECTOR(x)
Definition: type_detector.h:80
void DECdecompSetDetectorPctConssToBlock(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *pctConssToBlock)
Definition: decomp.c:1834
static SCIP_RETCODE createTestPricingprobConss(SCIP *scip, SCIP *subscip, PARTIALDECOMP *partialdec, int block, SCIP_HASHMAP *hashorig2pricingvar)
creates the pricing problem constraints
#define DEFAULT_MAXNCLASSESLARGEPROBS
Definition: cons_decomp.cpp:96
std::vector< SCIP_Real > & getPctVarsToBlockVector()
returns fraction of variables assigned to a block for detectors in detectorchain
private methods for working with decomp structures
unsigned int GCGconshdlrDecompGetNFinishedPartialdecsOrig(SCIP *scip)
Gets the number of finished partialdecs available for the original problem.
#define DEC_DECL_INITDETECTOR(x)
Definition: type_detector.h:70
SCIP_RETCODE GCGconshdlrDecompAddDecomp(SCIP *scip, DEC_DECOMP *decomp, SCIP_Bool select)
adds the given decomposition structure
#define DEFAULT_SCORECOEF_FASTBENEFICIAL
USERGIVEN getUsergiven()
Gets the USERGIVEN status of this partialdecs.
void GCGconshdlrDecompFreeOrigOnExit(SCIP *scip, SCIP_Bool free)
sets freeing of detection data of original problem during exit to true
@ DEC_DECTYPE_UNKNOWN
Definition: type_decomp.h:49
DETPROBDATA * GCGconshdlrDecompGetDetprobdataOrig(SCIP *scip)
help method to access detprobdata for unpresolved problem
int getNVarsForBlock(int block)
Gets size of the vector containing vars assigned to a block.
SCIP_Real * DECdecompGetDetectorPctConssToBorder(DEC_DECOMP *decomp)
Definition: decomp.c:1791
@ DEC_DECMODE_ORIGINAL
Definition: type_decomp.h:63
#define CONSHDLR_DESC
Definition: cons_decomp.cpp:79
#define DEFAULT_BENDERSONLYBINMASTER
SCIP_RETCODE GCGconshdlrDecompGetFinishedPartialdecsList(SCIP *scip, int **idlist, int *listlength)
Gets a list of ids of the current partialdecs that are finished.
@ MAX_FORESSEEING_WHITE
#define DEFAULT_SCORECOEF_FASTNOTBENEFICIAL
SCIP_Bool bendersonlybinmaster
DEC_CLASSIFIERDATA * DECconsClassifierGetData(DEC_CONSCLASSIFIER *classifier)
returns the data of the provided consclassifier
static SCIP_RETCODE setDetectionAggressive(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool quiet)
sets the parameters to aggressive values
#define AGGRESSIVE_LEVENSHTEIN_MAXMATRIXHALFPERIMETER
static SCIP_DECL_CONSENFOLP(consEnfolpDecomp)
SCIP_CONS ** DECdecompGetLinkingconss(DEC_DECOMP *decomp)
Definition: decomp.c:967
std::vector< int > getNNewBlocksVector()
gets number of blocks the detectors in the detectorchain added
SCIP_RETCODE DECincludeVarClassifier(SCIP *scip, const char *name, const char *description, int priority, SCIP_Bool enabled, DEC_CLASSIFIERDATA *classifierdata, DEC_DECL_FREEVARCLASSIFIER((*freeClassifier)),)
PARTIALDECOMP * partialdectowrite
void addPctVarsFromFree(SCIP_Real pct)
adds percentage of closed variables
SCIP_CLOCK * completedetectionclock
#define DEC_DECL_SETPARAMAGGRESSIVE(x)
int getNTotalStairlinkingvars()
Gets total number of stairlinking vars.
void fixVarToStairlinking(int var, int firstblock)
adds a variable to the stairlinking variables
DEC_DECL_PROPAGATEPARTIALDEC(detectorPropagatePartialdecIsomorph)
@ CLASSIC
SCIP_Real scoretotaltime
int * DECdecompGetNNewBlocks(DEC_DECOMP *decomp)
Definition: decomp.c:1970
@ SETPART_FWHITE
const char * description
SCIP_RETCODE GCGconshdlrDecompArePricingprobsIdenticalForPartialdecid(SCIP *scip, int partialdecid, int probnr1, int probnr2, SCIP_Bool *identical)
checks if two pricing problems are identical based on information from detection
std::vector< int > & getConssForVar(int varIndex)
returns the constraint indices of the coefficient matrix for a variable
void DECprintListOfDetectors(SCIP *scip)
writes out a list of all detectors
void buildDecChainString(char *buffer)
creates a detector chain short string for this partialdec, is built from detector chain
DEC_CLASSIFIERDATA * DECvarClassifierGetData(DEC_VARCLASSIFIER *classifier)
returns the data of the provided varclassifier
SCIP_Bool overruleemphasis
int GCGconshdlrDecompGetNextPartialdecID(SCIP *scip)
Gets the next partialdec id managed by cons_decomp.
SCIP_RETCODE GCGconshdlrDecompTranslateOrigPartialdecs(SCIP *scip)
translates unpresolved partialdec to a complete presolved one
#define DEFAULT_SCORECOEF_MEDIUMBENEFICIAL
PARTIALDECOMP * DECgetPartialdecToWrite(SCIP *scip, SCIP_Bool transformed)
static SCIP_RETCODE partialdecVecToIdArray(std::vector< PARTIALDECOMP * > &partialdecs, int **idlist, int *listlength)
translates a vector of PARTIALDECOMP pointers into an array of their ids
various SCIP helper methods
std::vector< PARTIALDECOMP * > * partialdecs
void setSetPartForWhiteScore(SCIP_Real score)
set the setpartitioning maximum foreseeing white area score
void setMaxWhiteScore(SCIP_Real score)
set the maximum white area score
SCIP_Real getMaxWhiteScore()
gets the maximum white area score
VarPartition * reduceClasses(int maxNumberOfClasses)
void GCGconshdlrDecompFreeDetprobdata(SCIP *scip)
Frees Detprobdata of the original and transformed/presolved problem.
SCIP_Bool presolved
Definition: struct_decomp.h:53
DEC_DETECTOR ** finishingdetectors
void setUsergiven(USERGIVEN usergiven)
sets whether this partialdec is user given
bool isConsMastercons(int cons)
Gets whether the cons is a master cons.
void DECdecompSetConsindex(DEC_DECOMP *decomp, SCIP_HASHMAP *consindex)
Definition: decomp.c:1251
static SCIP_Real calcBlockAreaScore(SCIP *scip, PARTIALDECOMP *partialdec)
gets an intermediate score value for the blocks of a partialdec
SCIP_Real DECgetRemainingTime(SCIP *scip)
returns the remaining time of scip that the decomposition may use
std::unordered_map< int, PARTIALDECOMP * > * partialdecsbyid
SCIP_Bool hasSetppccardMaster()
checks if all master constraints set partitioning, set packing, set cover, or cardinality constraints
SCIP_Real strongtimelimit
void addPartialdecToAncestor(PARTIALDECOMP *partialdec)
adds a partialdec to ancestor partialdecs
std::vector< SCIP_VAR * > getOrigVarsFixedZero()
returns pointers to all orig vars that are fixed to zero
int GCGconshdlrDecompGetNStairlinkingVarsByPartialdecId(SCIP *scip, int id)
gets number of stairlinking variables of partialdec with given id
SCIP_Real GCGconshdlrDecompGetScoreTotalTime(SCIP *scip)
gets total score computation time
std::vector< int > & getRepVarmap(int repid, int blockrepid)
Gets the represenation varmap.
int aggregationlimitnconssperblock
@ NO_MODIF
SCIP_Real GCGconshdlrDecompGetCompleteDetectionTime(SCIP *scip)
returns the total detection time
static SCIP_CONSHDLRDATA * getConshdlrdata(SCIP *scip)
local function to get the conshdlr data of the current conshdlr
#define DEFAULT_BENDERSONLYCONTSUBPR
int maxnclassesperpartitionforlargeprobs
void setDetectorFinished(DEC_DETECTOR *detector)
sets detector that finished the partialdec
DEC_CONSCLASSIFIER ** consclassifiers
SCIP_RETCODE DECdecompSetStairlinkingvars(SCIP *scip, DEC_DECOMP *decomp, SCIP_VAR ***stairlinkingvars, int *nstairlinkingvars)
Definition: decomp.c:1081
void calcStairlinkingVars()
reassigns linking vars to stairlinkingvars if possible
int * consclassifierpriorities
DEC_CLASSIFIERDATA * clsdata
int getNStairlinkingvars(int block)
Gets size of the vector containing stairlinking vars.
int getNConssForBlock(int block)
Gets size of the vector containing conss assigned to a block.
std::vector< PARTIALDECOMP * > * GCGconshdlrDecompGetPartialdecs(SCIP *scip)
gets vector of all partialdecs
unsigned int GCGconshdlrDecompGetNPartialdecsOrig(SCIP *scip)
Gets the number of partialdecs available for the original problem.
SCIP_RETCODE GCGconshdlrDecompCalcMaxForeseeingWhiteAggScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the maxforeseeingwhiteagg score of a partialdec
SCIP_VAR * GCGpricingVarGetOriginalVar(SCIP_VAR *var)
Definition: gcgvar.c:511
static SCIP_RETCODE partition(SCIP *scip, SCIP_VAR **J, int *Jsize, SCIP_Longint *priority, SCIP_VAR **F, int Fsize, SCIP_VAR **origvar, SCIP_Real *median)
SCIP_CONS * getCons(int consIndex)
returns the SCIP constraint related to a constraint index
SCIP_RETCODE GCGconshdlrDecompCalcBendersScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the benders score of a partialdec
int getNAncestors()
Gets number of ancestor partialdecs.
#define CONSHDLR_CHECKPRIORITY
Definition: cons_decomp.cpp:81
void setStrongDecompScore(SCIP_Real score)
set the strong decomposition score
SCIP_RETCODE DECdecompSetLinkingconss(SCIP *scip, DEC_DECOMP *decomp, SCIP_CONS **linkingconss, int nlinkingconss)
Definition: decomp.c:926
SCIP_Bool shouldCompletedByConsToMaster()
Checks whether this partialdec is a userpartialdec that should be completed.
SCIP_HASHMAP * DECdecompGetVartoblock(DEC_DECOMP *decomp)
Definition: decomp.c:1199
bool addPartialdecToFinished(PARTIALDECOMP *partialdec)
adds a partialdec to finished partialdecs
int DECdecompGetDetectorChainSize(DEC_DECOMP *decomp)
Definition: decomp.c:1637
void addDecChangesFromAncestor(PARTIALDECOMP *ancestor)
adds the statistical differences to an ancestor
void GCGconshdlrDecompDeregisterPartialdec(SCIP *scip, PARTIALDECOMP *partialdec)
deregisters a partialdec in the conshdlr
DEC_DETECTOR ** GCGconshdlrDecompGetDetectors(SCIP *scip)
Gets an array of all detectors.
static SCIP_DECL_CONSENFORELAX(consEnforeDecomp)
std::vector< std::pair< int, int > > candidatesNBlocks
static SCIP_Real GCGconshdlrDecompAdaptScore(SCIP *scip, SCIP_Real oldscore)
method to adapt score for orig decomps
@ FAVOUR_PRESOLVED
int GCGconshdlrDecompGetNMasterConssByPartialdecId(SCIP *scip, int id)
gets number of master constraints of partialdec with given id
DEC_DECOMP ** decomps
static SCIP_RETCODE unselectAllPartialdecs(SCIP *scip)
static PARTIALDEC_DETECTION_DATA * createPartialdecDetectionData(gcg::DETPROBDATA *detprobdata, PARTIALDECOMP *partialdec)
initializes a new detection data structure
void addPctVarsToBorder(SCIP_Real pct)
adds percentage of variables assigned to border
SCIP_Bool GCGisConsGCGCons(SCIP_CONS *cons)
Definition: misc.c:787
SCIP_RETCODE GCGconshdlrDecompCalcMaxForseeingWhiteScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the maximum foreseeing white area score of a partialdec
void addPctConssToBlock(SCIP_Real pct)
adds percentage of constraints assigned to blocks
GCG_Random_dual_methods
static SCIP_Real getDualvalRandom(SCIP *scip, int consindex, SCIP_Bool transformed)
return the a random value of the dual variable of the corresponding ; if it is not calculated yet it ...
#define DEFAULT_MAXNCLASSESFORNBLOCKCANDIDATES
Definition: cons_decomp.cpp:98
static void reduceVarclasses(SCIP *scip, gcg::DETPROBDATA *detprobdata)
adds variable partitions with a reduced number of classes
SCIP_RETCODE DECdecompSetLinkingvars(SCIP *scip, DEC_DECOMP *decomp, SCIP_VAR **linkingvars, int nlinkingvars, int nfixedlinkingvars, int nmastervars)
Definition: decomp.c:989
void DECdecompSetDetectorClockTimes(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *detectorClockTimes)
Definition: decomp.c:1671
bool operator()(const std::pair< PARTIALDECOMP *, SCIP_Real > &left, const std::pair< PARTIALDECOMP *, SCIP_Real > &right)
char DECdetectorGetChar(DEC_DETECTOR *detector)
Gets the character of the detector.
SCIP_RETCODE SCIPconshdlrDecompRepairConsNames(SCIP *scip)
DEC_DETECTORDATA * decdata
miscellaneous methods for visualizations
void completeGreedily()
assigns all open constraints and open variables
int getNVars()
return the number of variables considered in the detprobdata
DEC_DETECTORDATA * DECdetectorGetData(DEC_DETECTOR *detector)
returns the data of the provided detector
int GCGconshdlrDecompGetNOpenVarsByPartialdecId(SCIP *scip, int id)
gets number of open variables of partialdec with given id
static int findGenericConsname(SCIP *scip, int startcount, char *consname, int namelength)
finds a non duplicate constraint name of the form c_{a} with minimal natural number {a}
SCIP_Real getBorderAreaScore()
gets the border area score
int GCGconshdlrDecompGetBlockNumberCandidate(SCIP *scip, int index)
returns block number user candidate with given index
gcg::DETPROBDATA * detprobdatapres
static SCIP_RETCODE deletePartialdecDetectionData(SCIP *scip, PARTIALDEC_DETECTION_DATA *data)
delets the detection data structure
SCIP_RETCODE GCGconshdlrDecompGetPartialdecsList(SCIP *scip, int **idlist, int *listlength)
Gets a list of ids of the current partialdecs.
interface data structure for the detector calling methods
#define CONSHDLR_NEEDSCONS
Definition: cons_decomp.cpp:84
static SCIP_DECL_CONSCHECK(consCheckDecomp)
void GCGconshdlrDecompCalcCandidatesNBlocks(SCIP *scip, SCIP_Bool transformed)
calculates and adds block size candidates using constraint classifications and variable classificatio...
static SCIP_RETCODE createDecompFromPartialdec(SCIP *scip, PARTIALDECOMP *partialdec, DEC_DECOMP **newdecomp)
creates a decomposition DEC_DECOMP structure for a given partialdec
int getRepForBlock(int blockid)
Gets index of the representative block for a block, this might be blockid itself.
#define DEC_DECL_VARCLASSIFY(x)
SCIP_Bool enableorigclassification
int getIndexForCons(SCIP_CONS *cons)
returns the constraint index related to a SCIP constraint
DEC_DETECTOR ** postprocessingdetectors
int getNLinkingvars()
Gets size of the vector containing linking vars.
SCIP_Real * DECdecompGetDetectorPctVarsToBorder(DEC_DECOMP *decomp)
Definition: decomp.c:1756
#define DEFAULT_MAXDETECTIONROUNDS
Definition: cons_decomp.cpp:93
@ MAX_WHITE
bool sort()
sorts the vars and conss data structures by their indices
DEC_DECMODE GCGgetDecompositionMode(SCIP *scip)
Definition: relax_gcg.c:5123
static SCIP_Retcode detect(SCIP *scip, gcg::DETPROBDATA *detprobdata)
constructs partialdecs using the registered detectors
SCIP_VAR *** DECdecompGetStairlinkingvars(DEC_DECOMP *decomp)
Definition: decomp.c:1151
static SCIP_RETCODE calculateDualvalsOptimalOrigLP(SCIP *scip, SCIP_Bool transformed)
method to calculate and set the optimal dual values from original lp, used for strong detection score
std::vector< int > * userblocknrcandidates
int getIndexForVar(SCIP_VAR *var)
returns the variable index related to a SCIP variable
SCIP_RETCODE DECdetectStructure(SCIP *scip, SCIP_RESULT *result)
interface method to detect the structure including presolving
struct Partialdec_Detection_Data PARTIALDEC_DETECTION_DATA
Definition: type_detector.h:51
void DECdecompSetPresolved(DEC_DECOMP *decomp, SCIP_Bool presolved)
Definition: decomp.c:712
C++ interface of cons_decomp.
int getNConsPartitions()
returns number of different constraint partitions
#define DEC_DECL_SETPARAMFAST(x)
std::vector< SCIP_Real > & getPctConssFromFreeVector()
Gets fraction of constraints that are not longer open for detectors in detectorchain.
void printPartitionInformation(SCIP *givenscip, FILE *file)
prints partition information as described in
static SCIP_DECL_CONSINIT(consInitDecomp)
initialization method of constraint handler (called after problem was transformed)
SCIP_RETCODE DECdecompFree(SCIP *scip, DEC_DECOMP **decdecomp)
Definition: decomp.c:530
Provides wrapping to have Partialdecomps as parameters in C-conform function headers with C++ impleme...
#define DEC_DECL_POSTPROCESSPARTIALDEC(x)
const char * DECvarClassifierGetName(DEC_VARCLASSIFIER *classifier)
returns the name of the provided classifier
const int * getStairlinkingvars(int block)
Gets array containing stairlinking vars,.
void findVarsLinkingToMaster()
reassigns linking variables to master if appropriate
gcg::DETPROBDATA * detprobdata
static SCIP_RETCODE setDetectionFast(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool quiet)
sets the parameters to fast values
int getNReps()
Gets the number of blockrepresentatives.
void DECdecompSetNNewBlocks(SCIP *scip, DEC_DECOMP *decomp, int *nNewBlocks)
Definition: decomp.c:1944
ConsPartition * getConsPartition(int partitionIndex)
returns pointer to a constraint partition
int getNConss()
Gets the number of constraints.
int DECdecompGetNLinkingvars(DEC_DECOMP *decomp)
Definition: decomp.c:1046
int GCGconshdlrDecompIncreaseNCallsCreateDecomp(SCIP *scip)
counts up the counter for created decompositions and returns it
#define DEFAULT_ENABLEORIGDETECTION
Definition: cons_decomp.cpp:99
SCIP_Bool GCGconshdlrDecompOrigDetprobdataExists(SCIP *scip)
returns whether or not a detprobdata structure for the original problem exists
const std::vector< int > & getBlocksForRep(int repid)
get a vector of block ids that are identical to block with id repid
int freqCallRoundOriginal
data structures for constraint classifiers
SCIP_Real * DECdecompGetDetectorPctVarsToBlock(DEC_DECOMP *decomp)
Definition: decomp.c:1826
int getTranslatedpartialdecid() const
SCIP_RETCODE GCGconsGetVals(SCIP *scip, SCIP_CONS *cons, SCIP_Real *vals, int nvals)
Definition: scip_misc.c:621
void DECdecompSetDetectorPctConssFromOpen(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *pctConssFromOpen)
Definition: decomp.c:1907
std::vector< SCIP_Real > & getPctConssToBorderVector()
Gets fraction of constraints assigned to the border for detectors in detectorchain.
void setSelected(bool selected)
set the selection status of this partialdecs
DEC_DETECTOR ** detectors
SCIP_Bool GCGconshdlrDecompIsPresolvedByPartialdecId(SCIP *scip, int id)
gets whether partialdec with given id is presolved
#define DEC_DECL_FREEVARCLASSIFIER(x)
DEC_DECOMP ** GCGconshdlrDecompGetDecomps(SCIP *scip)
returns an array containing all decompositions
int minCallRoundOriginal
void addVarPartition(VarPartition *partition)
adds a variable partition if it is no duplicate of an existing variable partition
#define DEFAULT_COEFFACTORORIGVSRANDOM
Definition: cons_decomp.cpp:89
void addNNewBlocks(int nnewblocks)
adds how many new blocks were introduced
#define DEFAULT_BLOCKNUMBERCANDSMEDIANVARSPERCONS
Definition: cons_decomp.cpp:91
int getAncestorID(int ancestorindex)
gets partialdec id of given ancestor id
int DECgetNDecomps(SCIP *scip)
SCIP_Bool bendersonlycontsubpr
int GCGconshdlrDecompGetNDecomps(SCIP *scip)
gets the number of decompositions (= amount of finished partialdecs)
@ DEC_DECTYPE_STAIRCASE
Definition: type_decomp.h:51
bool checkConsistency()
Checks whether the assignments in the partialdec are consistent.
int getNDetectors()
Gets the number of detectors the partialdec is propagated by.
void DECdecompSetDetectorPctVarsToBorder(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *pctVarsToBorder)
Definition: decomp.c:1728
std::vector< PARTIALDECOMP * > & getFinishedPartialdecs()
gets all finished partialdecs
void setBorderAreaScore(SCIP_Real score)
set the border area score
void addPartialdecToFinishedUnchecked(PARTIALDECOMP *partialdec)
adds a partialdec to finished partialdecs without checking for duplicates, dev has to check this on h...
int GCGconsGetNVars(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:434
void DECdecompSetPartialdecID(DEC_DECOMP *decomp, int id)
Definition: decomp.c:1648
static SCIP_RETCODE resetDetprobdata(SCIP *scip, SCIP_Bool original)
resets/creates the detprobdata for the given problem
DEC_DETECTOR * DECfindDetector(SCIP *scip, const char *name)
searches for the detector with the given name and returns it or NULL if detector is not found
void GCGconshdlrDecompDeregisterPartialdecs(SCIP *scip, SCIP_Bool original)
deregisters partialdecs in the conshdlr
SCIP_Real postprocessingtime
static SCIP_DECL_CONSENFOPS(consEnfopsDecomp)
ConsPartition * reduceClasses(int maxNumberOfClasses)
SCIP_RETCODE GCGconshdlrDecompCalcMaxWhiteScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the maximum white area score of a partialdec
std::vector< SCIP_Real > & getDetectorClockTimes()
returns a vector of the clock times that each detector needed that was involved in this partialdec
std::vector< SCIP_VAR * > getRelevantVars()
returns pointers to all problem vars that are not fixed to 0
std::vector< int > & getConssForBlock(int block)
returns array containing constraints assigned to a block
int GCGconshdlrDecompGetNBlocksByPartialdecId(SCIP *scip, int id)
gets block number of partialdec with given id
GCG relaxator.
VarPartition * getVarPartition(int partitionIndex)
returns pointer to a variable partition with given index
#define DEC_DECL_SETPARAMDEFAULT(x)
#define DEFAULT_POSTPROCESS
Definition: cons_decomp.cpp:95
#define DEFAULT_RANDPARTIALDEC
class to manage partial decompositions
SCIP_Bool dualvalsoptimaloriglpcalculated
SCIP_RETCODE DECdecompAddRemainingConss(SCIP *scip, DEC_DECOMP *decdecomp)
Definition: decomp.c:2179
int aggregationlimitnvarsperblock
bool isVarMastervar(int var)
Checks whether the var is a master var.
int getNBlocks()
Gets the number of blocks.
void DECdecompSetDetectorPctConssToBorder(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *pctConssToBorder)
Definition: decomp.c:1764
static SCIP_RETCODE setTestpricingProblemParameters(SCIP *scip, int clocktype, SCIP_Real infinity, SCIP_Real epsilon, SCIP_Real sumepsilon, SCIP_Real feastol, SCIP_Real lpfeastol, SCIP_Real dualfeastol, SCIP_Bool enableppcuts, SCIP_Real timelimit)
sets the pricing problem parameters
static SCIP_RETCODE setDetectionDefault(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool quiet)
resets the parameters to their default value
SCIP_Bool enabledPostprocessing
struct gcg::subset subset
void setClassicScore(SCIP_Real score)
set the classic score
static void sortPartialdecs(SCIP *scip)
sorts all registered partialdecs according to score, descending
gcg::PARTIALDECOMP ** newpartialdecs
int GCGconshdlrDecompAddBasicPartialdec(SCIP *scip, SCIP_Bool presolved)
creates and adds a basic partialdecomp (all cons/vars are assigned to master)
#define DEFAULT_ENABLED
Definition: cons_decomp.cpp:86
SCIP_RETCODE GCGconshdlrDecompAddPreexisitingPartialDec(SCIP *scip, PARTIALDECOMP *partialdec)
adds a preexisting partial dec to be considered at the beginning of the detection
void fixVarToBlock(int var, int block)
adds a variable to the linking variables
SCIP_Real getScore(SCORETYPE type)
returns the score of the partialdec (depending on used scoretype)
SCIP_CLOCK * detectorclock
DEC_VARCLASSIFIER ** varclassifiers
DETPROBDATA * getDetprobdata()
Gets the corresponding detprobdata.
static SCIP_RETCODE createPartialdecFromDecomp(SCIP *scip, DEC_DECOMP *decomp, PARTIALDECOMP **newpartialdec)
creates a partialdec for a given decomposition
PARTIALDECOMP * GCGconshdlrDecompGetPartialdecFromID(SCIP *scip, int partialdecid)
local method to find a partialdec for a given id or NULL if no partialdec with such id is found
#define DEFAULT_LEVENSHTEIN_MAXMATRIXHALFPERIMETER
void assignOpenConssToMaster()
assigns open conss to master
static SCIP_DECL_CONSLOCK(consLockDecomp)
bool isVarLinkingvar(int var)
Checks whether the var is a linking var.
static SCIP_RETCODE shuffleDualvalsRandom(SCIP *scip, SCIP_Bool transformed)
method that shuffles randomly and set dual variable values, used for strong detection score
SCIP_RETCODE GCGprintCompleteDetectionTime(SCIP *givenscip, FILE *file)
@ DEC_DECTYPE_DIAGONAL
Definition: type_decomp.h:52
void setSetPartForWhiteAggScore(SCIP_Real score)
set the setpartitioning maximum foreseeing white area score with respect to aggregateable
void DECdecompSetDetector(DEC_DECOMP *decomp, DEC_DETECTOR *detector)
Definition: decomp.c:1579
std::vector< int > & getLinkingvars()
returns array containing all linking vars indices
void addPctConssFromFree(SCIP_Real pct)
adds percentage of closed constraints
int getNVarsForCons(int consIndex)
returns the number of variables for a given constraint
SCIP_RETCODE GCGprintBlockcandidateInformation(SCIP *scip, FILE *file)
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.
int GCGconshdlrDecompGetNLinkingVarsByPartialdecId(SCIP *scip, int id)
gets number of linking variables of partialdec with given id
unsigned int GCGconshdlrDecompGetNOpenPartialdecsOrig(SCIP *scip)
Gets the number of open partialdecs available for the original problem.
bool isConsOpencons(int cons)
Gets whether the cons is an open cons.
SCIP_Bool enableorigdetection
std::vector< ConsPartition * > conspartitioncollection
DETPROBDATA * GCGconshdlrDecompGetDetprobdataPresolved(SCIP *scip)
help method to access detprobdata for transformed problem
SCIP_RETCODE GCGconshdlrDecompCalcBorderAreaScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the border area score of a partialdec
bool isPropagatedBy(DEC_DETECTOR *detector)
Gets whether this partialdec was propagated by specified detector.
int DECdecompGetNBlocks(DEC_DECOMP *decomp)
Definition: decomp.c:745
int GCGconshdlrDecompGetNDetectors(SCIP *scip)
Gets the number of all detectors.
int getID()
returns the unique id of the partialdec
void addPctVarsToBlock(SCIP_Real pct)
adds percentage of variables assigned to blocks
void DECdecompSetDetectorPctVarsToBlock(SCIP *scip, DEC_DECOMP *decomp, SCIP_Real *pctVarsToBlock)
Definition: decomp.c:1799
SCIP_RETCODE DECdecompSetDetectorChainString(SCIP *scip, DEC_DECOMP *decomp, const char *detectorchainstring)
Definition: decomp.c:1705
SCIP_RETCODE DECdecompCreate(SCIP *scip, DEC_DECOMP **decdecomp)
Definition: decomp.c:471
#define DEFAULT_DUALVALRANDOMMETHOD
Definition: cons_decomp.cpp:88
void calcAggregationInformation(bool ignoreDetectionLimits)
computes if aggregation of sub problems is possible
@ GCG_RANDOM_DUAL_NAIVE
SCIP_Bool GCGconshdlrDecompIsSelectedByPartialdecId(SCIP *scip, int id)
gets whether partialdec with given id is selected
SCIP_Real * DECdecompGetDetectorClockTimes(DEC_DECOMP *decomp)
Definition: decomp.c:1696
SCIP_Bool dualvalsrandomset
#define DEFAULT_MAXNCLASSES
Definition: cons_decomp.cpp:97
const char * name
void setDetectorPropagated(DEC_DETECTOR *detector)
sets partialdec to be propagated by a detector
void GCGconshdlrDecompRegisterPartialdec(SCIP *scip, PARTIALDECOMP *partialdec)
registers a partialdec in the conshdlr
int GCGconshdlrDecompDecreaseNCallsCreateDecomp(SCIP *scip)
decreases the counter for created decompositions and returns it
class storing (potentially incomplete) decompositions
int * DECdecompGetNStairlinkingvars(DEC_DECOMP *decomp)
Definition: decomp.c:1160
SCIP_RETCODE GCGconshdlrDecompClassify(SCIP *scip, SCIP_Bool transformed)
run classification of vars and cons
SCORETYPE GCGconshdlrDecompGetScoretype(SCIP *scip)
Gets the currently selected scoretype.
int GCGconshdlrDecompGetNMasterVarsByPartialdecId(SCIP *scip, int id)
gets number of master variables of partialdec with given id
static SCIP_Real getDualvalOptimalLP(SCIP *scip, int consindex, SCIP_Bool transformed)
returns the value of the optimal lp relaxation dual value of the given constrainr rid correspondoning...
SCIP_RETCODE DECwriteSelectedDecomps(SCIP *scip, char *directory, char *extension)
writes all selected decompositions
std::vector< VarPartition * > varpartitioncollection
SCIP_Real getVal(int row, int col)
returns a coefficient from the coefficient matrix
int getNConssForVar(int varIndex)
returns the number of constraints for a given variable where the var has a nonzero entry in
std::vector< int > & getVarsForCons(int consIndex)
returns the variable indices of the coefficient matrix for a constraint
SCIP_RETCODE DECdecompCheckConsistency(SCIP *scip, DEC_DECOMP *decdecomp)
Definition: decomp.c:2267
std::vector< DEC_DETECTOR * > & getDetectorchain()
returns detector chain as vector of detector pointers
#define DEFAULT_STRONGTIMELIMIT
bool isTrivial()
Gets whether this partialdec is considered to be trivial.
bool addPartialdecToOpen(PARTIALDECOMP *partialdec)
adds a partialdec to current partialdecs (data structure for partialdecs that are goin to processed i...
SCIP_RETCODE GCGconshdlrDecompGetSelectedPartialdecs(SCIP *scip, int **idlist, int *listlength)
Gets a list of ids of all currently selected partialdecs.
SCIP_Bool consnamesalreadyrepaired
void setBendersScore(SCIP_Real score)
set the benders score
int GCGconshdlrDecompGetNOpenConssByPartialdecId(SCIP *scip, int id)
gets number of open constraints of partialdec with given id
int getNMasterconss()
Gets size of the vector containing master conss.
bool isAssignedToOrigProb()
Gets whether the partialdec is from the presolved problem.
std::vector< SCIP_Real > & getPctVarsToBorderVector()
Gets fraction of variables assigned to the border for detectors in detectorchain.
#define DEFAULT_DETECTBENDERS
void DECdecompSetVarindex(DEC_DECOMP *decomp, SCIP_HASHMAP *varindex)
Definition: decomp.c:1231
SCIP_Real * DECdecompGetDetectorPctConssToBlock(DEC_DECOMP *decomp)
Definition: decomp.c:1862
static SCIP_RETCODE setDetectionOff(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool quiet)
disables detectors
SCIP_RETCODE GCGconshdlrDecompTranslateNBestOrigPartialdecs(SCIP *scip, int n, SCIP_Bool completeGreedily)
translates n best unpresolved partialdec to a complete presolved one
const char * DECconsClassifierGetName(DEC_CONSCLASSIFIER *classifier)
returns the name of the provided classifier
SCIP_VAR * getVar(int varIndex)
returns SCIP variable related to a variable index
enum scoretype SCORETYPE
void addConsPartition(ConsPartition *partition)
adds a constraint partition if it is no duplicate of an existing constraint partition
void deleteEmptyBlocks(bool variables)
deletes empty blocks and sets nblocks accordingly
int getNMastervars()
Gets size of the vector containing master vars.
SCIP_RETCODE DECdecompSetType(DEC_DECOMP *decomp, DEC_DECTYPE type)
Definition: decomp.c:647
int weightinggpresolvedoriginaldecomps
SCIP_RETCODE DECincludeConsClassifier(SCIP *scip, const char *name, const char *description, int priority, SCIP_Bool enabled, DEC_CLASSIFIERDATA *classifierdata, DEC_DECL_FREECONSCLASSIFIER((*freeClassifier)),)
static std::vector< PARTIALDECOMP * > getSelectedPartialdecs(SCIP *scip, std::vector< PARTIALDECOMP * > &selectedpartialdecs)
gets all selected partialdecs
DEC_VARCLASSIFIER * DECfindVarClassifier(SCIP *scip, const char *name)
searches for the varclassifier with the given name and returns it or NULL if classifier is not found
class storing partialdecs and the problem matrix
SCIP_Real * DECdecompGetDetectorPctConssFromOpen(DEC_DECOMP *decomp)
Definition: decomp.c:1936
DEC_CLASSIFIERDATA * clsdata
std::vector< SCIP_Real > & getPctVarsFromFreeVector()
Gets fraction of variables that are not longer open for detectors in detectorchain.
void GCGgetVisualizationFilename(SCIP *scip, PARTIALDECOMP *partialdec, const char *extension, char *filename)
SCIP_RETCODE GCGconshdlrDecompChooseCandidatesFromSelected(SCIP *scip, std::vector< std::pair< gcg::PARTIALDECOMP *, SCIP_Real > > &candidates, SCIP_Bool original, SCIP_Bool printwarnings)
SCIP_Bool GCGdetectionTookPlace(SCIP *scip, SCIP_Bool original)
void fixConsToBlock(int cons, int block)
adds a constraint to a block
int strongdetectiondualvalrandommethod
#define DEFAULT_ENABLEORIGCLASSIFICATION
gcg::PARTIALDECOMP * workonpartialdec
std::vector< PARTIALDECOMP * > & getOpenPartialdecs()
determines all partialdecs from current (open) partialdec data structure
SCIP_Bool enabled
#define DEC_DECL_FINISHPARTIALDEC(x)
SCIP_RETCODE GCGconshdlrDecompCalcSetPartForWhiteAggScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the setpartfwhiteagg score of a partialdec
#define DEFAULT_CLASSIFY
SCIP_HASHMAP * DECdecompGetConstoblock(DEC_DECOMP *decomp)
Definition: decomp.c:1221
@ GCG_RANDOM_DUAL_EXPECTED_EQUAL
#define DEFAULT_AGGREGATIONLIMITNCONSSPERBLOCK
SCIP_Real getMaxForWhiteScore()
gets the maximum foreseeing white area score
weightinggpresolvedoriginaldecomps
int maxCallRoundOriginal
@ COMPLETED_CONSTOMASTER
SCIP_RETCODE GCGconshdlrDecompSetDetection(SCIP *scip, SCIP_PARAMSETTING paramsetting, SCIP_Bool quiet)
sets detector parameters values
SCIP_Bool GCGconshdlrDecompCheckConsistency(SCIP *scip)
check whether partialdecs are consistent
std::vector< SCIP_CONS * > getRelevantConss()
returns pointers to all constraints that are not marked as deleted or obsolete
void GCGconshdlrDecompAddCandidatesNBlocks(SCIP *scip, SCIP_Bool origprob, int candidate)
adds a candidate for block number and counts how often a candidate is added
int getNVarPartitions()
returns number of different variable partitions
#define DEFAULT_MAXDETECTIONTIME
Definition: cons_decomp.cpp:94
DEC_DECOMP * DECgetBestDecomp(SCIP *scip, SCIP_Bool printwarnings)
Gets the best known decomposition.
#define CONSHDLR_ENFOPRIORITY
Definition: cons_decomp.cpp:80
void printBlockcandidateInformation(SCIP *scip, FILE *file)
output method for json file writer to write block candidate information
SCIP_Bool GCGconshdlrDecompPresolvedDetprobdataExists(SCIP *scip)
returns whether or not a detprobdata structure for the presolved problem exists
int getNVars()
Gets number of vars.
@ GCG_RANDOM_DUAL_EXPECTED_OVERESTIMATE
SCIP_RETCODE SCIPincludeConshdlrDecomp(SCIP *scip)
creates the constraint handler for decomp and includes it in SCIP