Scippy

GCG

Branch-and-Price & Column Generation for Everyone

dec_hrcgpartition.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program */
4 /* GCG --- Generic Column Generation */
5 /* a Dantzig-Wolfe decomposition based extension */
6 /* of the branch-cut-and-price framework */
7 /* SCIP --- Solving Constraint Integer Programs */
8 /* */
9 /* Copyright (C) 2010-2021 Operations Research, RWTH Aachen University */
10 /* Zuse Institute Berlin (ZIB) */
11 /* */
12 /* This program is free software; you can redistribute it and/or */
13 /* modify it under the terms of the GNU Lesser General Public License */
14 /* as published by the Free Software Foundation; either version 3 */
15 /* of the License, or (at your option) any later version. */
16 /* */
17 /* This program is distributed in the hope that it will be useful, */
18 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
19 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
20 /* GNU Lesser General Public License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with this program; if not, write to the Free Software */
24 /* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.*/
25 /* */
26 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
27 
28 /**@file dec_hrcgpartition.cpp
29  * @ingroup DETECTORS
30  * @brief arrowhead and bordered detector via graph partitioning (uses hmetis)
31  * @author Martin Bergner
32  *
33  * Detects arrowhead (double bordered) decompositions as well as decompositions
34  * with only linking variables or linking constraints.
35  *
36  * This detector needs hmetis and works only under Linux/MacOS, it further needs the Z-shell (zsh)
37  * to enforce memory and time limits on hmetis as this is the only shell reliably doing that.
38  */
39 
40 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
41 /* #define SCIP_DEBUG */
42 #include "dec_hrcgpartition.h"
43 
44 #if !defined(_WIN32) && !defined(_WIN64)
45 #include <cassert>
46 #include <cstring>
47 #include <cerrno>
48 #include <unistd.h>
49 #include <iostream>
50 #include <vector>
51 #include <algorithm>
52 #include <queue>
53 
54 #ifdef HMETIS_HEADER
55 #include "hmetis.h"
56 #else
57 #define HMETIS_EXECUTABLE "hmetis"
58 #endif
59 
60 #include "cons_decomp.h"
61 #include "struct_decomp.h"
62 #include "pub_decomp.h"
63 #include "scip_misc.h"
64 #include "scip/pub_misc.h"
65 #include "scip/cons_linear.h"
66 #include "scip/cons_setppc.h"
67 #include "graph/matrixgraph.h"
68 #include "graph/hyperrowcolgraph.h"
69 #include "graph/graph_tclique.h"
70 #include "graph/weights.h"
71 #include "class_partialdecomp.h"
72 #include "class_detprobdata.h"
73 #include "scip/clock.h"
74 
75 
76 #include <set>
77 
79 using gcg::MatrixGraph;
80 using gcg::Weights;
81 
82 #define DEC_DETECTORNAME "hrcgpartition" /**< name of the detector */
83 #define DEC_DESC "enforces arrowhead structures using graph partitioning" /**< description of detector */
84 #define DEC_FREQCALLROUND 1 /**< frequency the detector gets called in detection loop ,ie it is called in round r if and only if minCallRound <= r <= maxCallRound AND (r - minCallRound) mod freqCallRound == 0 */
85 #define DEC_MAXCALLROUND 1 /**< last round the detector gets called */
86 #define DEC_MINCALLROUND 0 /**< first round the detector gets called */
87 #define DEC_FREQCALLROUNDORIGINAL 1 /**< frequency the detector gets called in detection loop while detecting the original problem */
88 #define DEC_MAXCALLROUNDORIGINAL 1 /**< last round the detector gets called while detecting the original problem */
89 #define DEC_MINCALLROUNDORIGINAL 0 /**< first round the detector gets called while detecting the original problem */
90 #define DEC_PRIORITY 1000 /**< priority of the detector */
91 #define DEC_DECCHAR 'a' /**< display character of detector */
92 #define DEC_ENABLED FALSE /**< should detector be called by default */
93 #define DEC_ENABLEDFINISHING FALSE /**< should the finishing be enabled */
94 #define DEC_ENABLEDPOSTPROCESSING FALSE /**< should the postprocessing be enabled */
95 #define DEC_SKIP FALSE /**< should detector be skipped if others found detections */
96 #define DEC_USEFULRECALL TRUE /**< is it useful to call this detector on a descendant of the propagated partialdec */
97 
98 
99 /* Default parameter settings */
100 #define DEFAULT_VARWEIGHT 2 /**< weight for variable nodes */
101 #define DEFAULT_VARWEIGHTBIN 3 /**< weight for binary variable nodes */
102 #define DEFAULT_VARWEIGHTINT 3 /**< weight for integer variable nodes */
103 #define DEFAULT_VARWEIGHTIMPL 3 /**< weight for implicit integer variable nodes */
104 #define DEFAULT_VARWEIGHTCONT 2 /**< weight for continous variable nodes */
105 #define DEFAULT_CONSWEIGHT 1 /**< weight for constraint hyperedges */
106 #define DEFAULT_RANDSEED 1 /**< random seed for the hmetis call */
107 #define DEFAULT_TIDY TRUE /**< whether to clean up afterwards */
108 #define DEFAULT_DUMMYNODES 0.2 /**< percentage of dummy vertices*/
109 #define DEFAULT_CONSWEIGHT_SETPPC 5 /**< weight for constraint hyperedges that are setpartitioning or covering
110  constraints */
111 #define DEFAULT_MINBLOCKS 2 /**< value for the minimum number of blocks to be considered */
112 #define DEFAULT_MAXBLOCKS 20 /**< value for the maximum number of blocks to be considered */
113 #define DEFAULT_MAXNBLOCKCANDIDATES 3 /**< number of block number candidates to be considered */
114 #define DEFAULT_ALPHA 0.0 /**< factor for standard deviation of constraint weights */
115 #define DEFAULT_BETA 0.5 /**< factor of how the weight for equality and inequality constraints is
116  distributed (keep 1/2 for the same on both) */
117 #define DEFAULT_METIS_UBFACTOR 5.0 /**< default unbalance factor given to metis on the commandline */
118 #define DEFAULT_METIS_VERBOSE FALSE /**< should metis be verbose */
119 #define DEFAULT_METISUSEPTYPE_RB TRUE /**< Should metis use the rb or kway partitioning algorithm */
120 #define DEFAULT_REALNAME FALSE /**< whether the metis name should be real or temporary */
121 #define DEFAULT_TYPE 'a' /**< type of the decomposition 'c' column hypergraph (single bordered, no
122  linking constraints), 'r' row hypergraph (single bordered, no linking
123  variables) and 'a' column-row hypergraph (arrowhead) */
124 
125 #define FAST_MAXHALFPERIMETER 25000 /**< if nrows + ncols does not exceeds this value */
126 
127 #define SET_MULTIPLEFORSIZETRANSF 12500
128 /*
129  * Data structures
130  */
131 
132 /** private detector data */
133 struct DEC_DetectorData
134 {
135 
136  /* weight parameters */
137  int varWeight; /**< weight of a variable hyperedge */
138  int varWeightBinary; /**< weight of a binary variable hyperedge */
139  int varWeightContinous; /**< weight of a continuous variable hyperedge */
140  int varWeightInteger; /**< weight of an integer variable hyperedge */
141  int varWeightImplint; /**< weight of an implicit integer variable hyperedge */
142  int consWeight; /**< weight of a constraint hyperedge */
143  int consWeightSetppc; /**< weight of a setppc constraint hyperedge */
144  SCIP_Real alpha; /**< factor for constraint coefficient value standard deviation */
145  SCIP_Real beta; /**< factor for equality od inequality constraints */
146 
147  /* general parameters */
148  SCIP_Real dummynodes; /**< percent of dummy nodes */
149  SCIP_Bool tidy; /**< whether tempory metis files should be cleaned up */
150  int maxnblockcandidates; /**< maximal number of block canddidates to test */
151  int maxblocks; /**< maximal number of blocks to test */
152  int minblocks; /**< minimal number of blocks to test */
153 
154  /* metis parameters */
155  int randomseed; /**< metis random seed */
156  SCIP_Real metisubfactor; /**< metis unbalance factor */
157  SCIP_Bool metisverbose; /**< should metis ouput be displayed */
158  SCIP_Bool metisuseptyperb; /**< flag to indicate whether metis uses kway or rb partitioning */
159  SCIP_Bool realname; /**< flag to indicate real problem name or temporary filename for metis files */
160 
161  /* various data */
162  SCIP_Bool found; /**< indicates whethere a decomposition has been found */
163  char type; /**< type of the decomposition 'c' column hypergraph (single bordered, no linking
164  constraints), 'r' row hypergraph (single bordered, no linking variables) and
165  'a' column-row hypergraph (arrowhead) */
166 };
167 
168 
169 /*
170  * Local methods
171  */
172 
173 
174 /** destructor of detector to free user data (called when GCG is exiting) */
175 static
176 DEC_DECL_FREEDETECTOR(freeHrcgpartition)
177 {
178  DEC_DETECTORDATA* detectordata;
179 
180  assert(scip != NULL);
181 
182  detectordata = DECdetectorGetData(detector);
183  assert(detectordata != NULL);
184  assert(strcmp(DECdetectorGetName(detector), DEC_DETECTORNAME) == 0);
185 
186  SCIPfreeMemory(scip, &detectordata);
187 
188  return SCIP_OKAY;
189 }
190 
191 
192 /** detector initialization method */
193 static
194 DEC_DECL_INITDETECTOR(initHrcgpartition)
195 {
196  int nconss;
197  DEC_DETECTORDATA* detectordata;
198  assert(scip != NULL);
199 
200  detectordata = DECdetectorGetData(detector);
201  assert(detectordata != NULL);
202  assert(strcmp(DECdetectorGetName(detector), DEC_DETECTORNAME) == 0);
203 
204  detectordata->found = FALSE;
205 
206  nconss = SCIPgetNConss(scip);
207  detectordata->maxblocks = MIN(nconss, detectordata->maxblocks);
208 
209 
210  return SCIP_OKAY;
211 }
212 
213 /** detector deinitialization method (called before the transformed problem is freed) */
214 static
215 DEC_DECL_EXITDETECTOR(exitHrcgpartition)
216 {
217  assert(scip != NULL);
218 
219  assert(strcmp(DECdetectorGetName(detector), DEC_DETECTORNAME) == 0);
220 
221  return SCIP_OKAY;
222 }
223 
224 /** will call hmetis via a system call */
225 static
226 SCIP_RETCODE callMetis(
227  SCIP* scip, /**< SCIP data struture */
228  DEC_DETECTORDATA* detectordata, /**< detector data data structure */
229  MatrixGraph<gcg::GraphTclique>* graph, /**< the graph of the matrix */
230  char tempfile[SCIP_MAXSTRLEN], /**< filename for the metis input file */
231  int nblocks, /**< number of blocks */
232  SCIP_RESULT* result /**< result indicating whether the detection was successful */
233  )
234 {
235  char metiscall[SCIP_MAXSTRLEN];
236  char metisout[SCIP_MAXSTRLEN];
237  SCIP_CLOCK* metisclock;
238 
239  int status;
240 
241  SCIP_Real remainingtime;
242 
243  assert(scip != NULL);
244  assert(detectordata != NULL);
245 
246  *result = SCIP_DIDNOTRUN;
247 
248 
249  remainingtime = DECgetRemainingTime(scip);
250  SCIP_CALL( SCIPcreateWallClock(scip, &metisclock) );
251 
252  if( remainingtime <= 0 )
253  {
254  return SCIP_OKAY;
255  }
256 
257  /* call metis via syscall as there is no library usable ... */
258  if( !SCIPisInfinity(scip, DECgetRemainingTime(scip)) )
259  {
260  (void) SCIPsnprintf(metiscall, SCIP_MAXSTRLEN, "zsh -c \"ulimit -t %.0f;" HMETIS_EXECUTABLE " %s %d -seed %d -ptype %s -ufactor %f %s\"",
261  remainingtime,
262  tempfile,
263  nblocks,
264  detectordata->randomseed,
265  detectordata->metisuseptyperb ? "rb" : "kway",
266  detectordata->metisubfactor,
267  detectordata->metisverbose ? "" : "> /dev/null" );
268  }
269  else
270  {
271  (void) SCIPsnprintf(metiscall, SCIP_MAXSTRLEN, "zsh -c \"" HMETIS_EXECUTABLE " %s %d -seed %d -ptype %s -ufactor %f %s\"",
272  tempfile,
273  nblocks,
274  detectordata->randomseed,
275  detectordata->metisuseptyperb ? "rb" : "kway",
276  detectordata->metisubfactor,
277  detectordata->metisverbose ? "" : "> /dev/null" );
278  }
279 
280  SCIP_CALL( SCIPstartClock(scip, metisclock) );
281  SCIPdebugMessage("Calling metis with: %s\n", metiscall);
282  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " %d", nblocks );
283  status = system( metiscall );
284 
285  SCIP_CALL( SCIPstopClock(scip, metisclock) );
286  SCIPdebugMessage("time left before metis started: %f, time metis spend %f, remainingtime: %f\n", remainingtime, SCIPgetClockTime(scip, metisclock), remainingtime-SCIPgetClockTime(scip, metisclock) );
287 
288  SCIP_CALL( SCIPfreeClock(scip, &metisclock) );
289 
290  /* check error codes */
291  if( status == -1 )
292  {
293  SCIPerrorMessage("System call did not succed: %s\n", strerror( errno ));
294  SCIPerrorMessage("Call was %s\n", metiscall);
295  }
296  else if( status != 0 )
297  {
298 
299  SCIPerrorMessage("Calling hmetis unsuccessful! See the above error message for more details.\n");
300  SCIPerrorMessage("Call was %s\n", metiscall);
301  }
302 
303  /* exit gracefully in case of errors */
304  if( status != 0 )
305  {
306  return SCIP_ERROR;
307  }
308 
309  (void) SCIPsnprintf(metisout, SCIP_MAXSTRLEN, "%s.part.%d", tempfile, nblocks);
310  SCIP_CALL( graph->readPartition(metisout) );
311 
312  /* if desired delete the temoprary metis file */
313  if( detectordata->tidy )
314  {
315  status = remove( metisout );
316  if( status == -1 )
317  {
318  SCIPerrorMessage("Could not remove metis output file: %s\n", strerror( errno ));
319  return SCIP_WRITEERROR;
320  }
321  }
322  else
323  {
324  SCIPinfoMessage(scip, NULL, "Temporary file is in: %s\n", tempfile);
325  }
326  *result = SCIP_SUCCESS;
327  return SCIP_OKAY;
328 }
329 
330 /** creates the temporary metis input file */
331 static
332 SCIP_RETCODE createMetisFile(
333  SCIP* scip, /**< SCIP data struture */
334  DEC_DETECTORDATA* detectordata, /**< detector data structure */
335  int partialdecID, /**< ID of partial decomposition to be used */
336  MatrixGraph<gcg::GraphTclique>* graph, /**< the graph of the matrix */
337  char tempfile[SCIP_MAXSTRLEN] /**< filename for the metis input file */
338  )
339 {
340  int nvertices;
341  int ndummyvertices;
342  int fd;
343  nvertices = graph->getNNonzeroes();
344  /*lint --e{524}*/
345  ndummyvertices = SCIPceil(scip, detectordata->dummynodes*nvertices);
346  graph->setDummynodes(ndummyvertices);
347 
348  if( !detectordata->realname )
349  {
350  (void) SCIPsnprintf(tempfile, SCIP_MAXSTRLEN, "gcg-%c-%d.metis.XXXXXX", DEC_DECCHAR, partialdecID );
351  }
352  else
353  {
354  (void) SCIPsnprintf(tempfile, SCIP_MAXSTRLEN, "gcg-%s-%c-%d.metis.XXXXXX", SCIPgetProbName(scip), DEC_DECCHAR, partialdecID);
355  }
356 
357  fd = mkstemp(tempfile);
358 
359  SCIP_CALL( graph->writeToFile(fd, TRUE) );
360  close(fd);
361  return SCIP_OKAY;
362 }
363 
364 /** returns, whether the hyperrolcolgraph is connected */
365 static
367  gcg::DETPROBDATA* detprobdata,
368  gcg::PARTIALDECOMP* partialdec
369  )
370 {
371  std::vector<int> queue;
372  std::vector<int> visited;
373  std::vector<bool> inqueue (detprobdata->getNVars(), false);
374  std::vector<bool> isvisited(detprobdata->getNVars(), false);
375  int start = -1;
376 
377  if(partialdec->getNOpenvars() < 2)
378  return false;
379 
380  start = partialdec->getOpenvars()[0];
381 
382  queue.push_back(start);
383  inqueue[start] = true;
384  do
385  {
386  int node = queue[0];
387  queue.erase(queue.begin());
388  inqueue[node] = false;
389  visited.push_back(node);
390  isvisited[node] = true;
391  for(int c = 0; c < detprobdata->getNConssForVar(node); ++c)
392  {
393  int cons = detprobdata->getConssForVar(node)[c];
394  if(!partialdec->isConsOpencons(cons))
395  continue;
396  for(int v = 0; v < detprobdata->getNVarsForCons(cons); ++v)
397  {
398  int var = detprobdata->getVarsForCons(cons)[v];
399  if(!partialdec->isVarOpenvar(var))
400  continue;
401  if( isvisited[var] )
402  continue;
403  if( inqueue[var] )
404  continue;
405  queue.push_back(var);
406  inqueue[var] = true;
407  }
408  }
409  } while(!queue.empty());
410 
411  if((int)visited.size() != partialdec->getNOpenvars())
412  return false;
413 
414  queue.clear();
415  visited.clear();
416  inqueue = std::vector<bool>(detprobdata->getNConss(), false);
417  isvisited = std::vector<bool>(detprobdata->getNConss(), false);
418 
419  if(partialdec->getNOpenconss() < 2)
420  return false;
421 
422  queue.push_back(partialdec->getOpenconss()[0]);
423  inqueue[partialdec->getOpenconss()[0]] = true;
424  do
425  {
426  int node = queue[0];
427  queue.erase(queue.begin());
428  inqueue[node] = false;
429  visited.push_back(node);
430  isvisited[node] = true;
431  for(int v = 0; v < detprobdata->getNVarsForCons(node); ++v)
432  {
433  int var = detprobdata->getVarsForCons(node)[v];
434  if(!partialdec->isVarOpenvar(var))
435  continue;
436  for(int c = 0; c < detprobdata->getNConssForVar(var); ++c)
437  {
438  int cons = detprobdata->getConssForVar(var)[c];
439  if(!partialdec->isConsOpencons(cons))
440  continue;
441  if( isvisited[cons] )
442  continue;
443  if( inqueue[cons] )
444  continue;
445  queue.push_back(cons);
446  inqueue[cons] = true;
447  }
448  }
449  } while( !queue.empty() );
450 
451  if( (int)visited.size() != partialdec->getNOpenconss() )
452  return false;
453  else
454  return true;
455 }
456 
457 /** detection function for partialdecs */
458 static
459 SCIP_RETCODE detection(
460  SCIP* scip, /**< SCIP data structure */
461  DEC_DETECTORDATA* detectordata, /**< detectordata of the detector */
462  Partialdec_Detection_Data* partialdecdetectiondata, /**< partialdecdetectiondata (including the detprobdata) where to store the new Partialdecs */
463  gcg::PARTIALDECOMP* partialdec, /**< partialdec to propagate */
464  bool allowopenpartialdecs, /**< whether new partialdecs should be stored in which this detector only assignes conss to master */
465  SCIP_RESULT* result /**< pointer where to store the result */
466 )
467 {
468  /* add hrgpartition presolver parameters */
469  char setstr[SCIP_MAXSTRLEN];
470  int maxnblockcandidates;
471  int k;
472  int j;
473  int s;
474  int nMaxPartialdecs;
475  gcg::PARTIALDECOMP** newpartialdecs;
476  SCIP_CLOCK* clock;
477  SCIP_CLOCK* temporaryClock;
478  std::vector<SCIP_Real> clockTimes; /* vector containing times in seconds */
479  /* Graph stuff for hmetis */
480  MatrixGraph<gcg::GraphTclique>* graph; /* the graph of the matrix */
481  char tempfile[SCIP_MAXSTRLEN]; /**< filename for the metis input file */
482 
483  SCIP_CALL_ABORT( SCIPcreateClock(scip, &clock) );
484  SCIP_CALL_ABORT( SCIPstartClock(scip, clock) );
485 
486  *result = SCIP_DIDNOTFIND;
487 
488  std::vector<int> numberOfBlocks;
489  partialdecdetectiondata->detprobdata->getSortedCandidatesNBlocks(numberOfBlocks);
490  if( numberOfBlocks.empty() )
491  numberOfBlocks.push_back(8);
492 
493  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/hrcgpartition/maxnblockcandidates");
494  SCIP_CALL( SCIPgetIntParam(scip, setstr, &maxnblockcandidates) );
495 
496  maxnblockcandidates = MIN(maxnblockcandidates, (int) numberOfBlocks.size() );
497 
498  assert(scip != NULL);
499  assert(detectordata != NULL);
500 
501  SCIPdebugMessage("Detecting structure from %s\n", DEC_DETECTORNAME);
502  nMaxPartialdecs = detectordata->maxblocks-detectordata->minblocks+1;
503 
504  /* allocate space for output data */
505  SCIP_CALL( SCIPallocMemoryArray(scip, &(newpartialdecs), 2 * nMaxPartialdecs) );
506 
507  /* build the hypergraph structure from the original problem */
508  Weights w(detectordata->varWeight, detectordata->varWeightBinary, detectordata->varWeightContinous,detectordata->varWeightInteger,detectordata->varWeightInteger,detectordata->consWeight);
509  graph = new HyperrowcolGraph<gcg::GraphTclique>(scip, w);
510  SCIP_CALL( graph->createFromPartialMatrix(partialdecdetectiondata->detprobdata, partialdec) );
511  SCIP_CALL( createMetisFile(scip, detectordata, partialdec->getID(), graph, tempfile) );
512 
513  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "Detecting Arrowhead structure:");
514  SCIP_CALL_ABORT( SCIPstopClock(scip, clock ) );
515  SCIP_CALL_ABORT( SCIPcreateClock(scip, &temporaryClock) );
516  for( j = 0, k = 0; k < maxnblockcandidates; ++k)
517  {
518  char decinfo[SCIP_MAXSTRLEN];
519  int nblocks = numberOfBlocks[k] - partialdec->getNBlocks();
520  SCIP_CALL_ABORT( SCIPstartClock(scip, temporaryClock) );
521  SCIP_RETCODE retcode;
522 
523  if( nblocks > graph->getNNonzeroes() || nblocks <= 1 )
524  {
525  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock ) );
526  SCIP_CALL_ABORT( SCIPresetClock(scip, temporaryClock ) );
527  continue;
528  }
529 
530  retcode = callMetis(scip, detectordata, graph, tempfile, nblocks, result);
531 
532  if( *result != SCIP_SUCCESS || retcode != SCIP_OKAY)
533  {
534  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock ) );
535  SCIP_CALL_ABORT( SCIPresetClock(scip, temporaryClock ) );
536  continue;
537  }
538 
539  if( allowopenpartialdecs )
540  {
541  SCIP_CALL( graph->createPartialdecFromPartition(partialdec, &newpartialdecs[j], &newpartialdecs[j+1], partialdecdetectiondata->detprobdata));
542  }
543  else
544  {
545  SCIP_CALL( graph->createPartialdecFromPartition(partialdec, &newpartialdecs[j], NULL, partialdecdetectiondata->detprobdata));
546  }
547 
548  if( newpartialdecs[j] != NULL )
549  {
550  if( !allowopenpartialdecs )
551  {
552  newpartialdecs[j]->considerImplicits();
553  newpartialdecs[j]->refineToBlocks();
554  assert(newpartialdecs[j]->getNOpenconss() == 0);
555  assert(newpartialdecs[j]->getNOpenvars() == 0);
556  }
557  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock) );
558 
559  detectordata->found = TRUE;
560  (void) SCIPsnprintf(decinfo, SCIP_MAXSTRLEN, "hrc\\_%d", numberOfBlocks[k]);
561  newpartialdecs[j]->addDetectorChainInfo(decinfo);
562 
563  if( allowopenpartialdecs )
564  {
565  clockTimes.push_back(SCIPgetClockTime(scip, temporaryClock) / 2);
566  clockTimes.push_back(SCIPgetClockTime(scip, temporaryClock) / 2);
567  newpartialdecs[j + 1]->addDetectorChainInfo(decinfo);
568  j += 2;
569  }
570  else
571  {
572  clockTimes.push_back(SCIPgetClockTime(scip, temporaryClock));
573  j++;
574  }
575  }
576  SCIP_CALL_ABORT( SCIPresetClock(scip, temporaryClock ) );
577  }
578  delete graph;
579 
580  int nnewpartialdecs = j;
581  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, " done, %d partialdecs found.\n", nnewpartialdecs);
582  SCIP_CALL( SCIPallocMemoryArray(scip, &(partialdecdetectiondata->newpartialdecs), nnewpartialdecs) );
583  partialdecdetectiondata->nnewpartialdecs = nnewpartialdecs;
584  for( s = 0; s < nnewpartialdecs; ++s )
585  {
586  partialdecdetectiondata->newpartialdecs[s] = newpartialdecs[s];
587  partialdecdetectiondata->newpartialdecs[s]->addClockTime(clockTimes[s] + SCIPgetClockTime(scip, temporaryClock) / nnewpartialdecs);
588  }
589 
590  SCIPfreeMemoryArray(scip, &newpartialdecs);
591  SCIP_CALL_ABORT( SCIPfreeClock(scip, &temporaryClock) );
592  SCIP_CALL_ABORT( SCIPfreeClock(scip, &clock) );
593 
594  if( detectordata->tidy )
595  {
596  int status = remove( tempfile );
597  if( status == -1 )
598  {
599  SCIPerrorMessage("Could not remove metis input file: %s", strerror( errno ));
600  return SCIP_WRITEERROR;
601  }
602  }
603 
604  *result = detectordata->found ? SCIP_SUCCESS: SCIP_DIDNOTFIND;
605  return SCIP_OKAY;
606 }
607 
608 #endif
609 
610 
611 static
612 DEC_DECL_PROPAGATEPARTIALDEC(propagatePartialdecHrcgpartition)
613 {
614  SCIP_CLOCK* temporaryClock;
615  gcg::PARTIALDECOMP* partialdec = partialdecdetectiondata->workonpartialdec;
616 
617  SCIP_CALL_ABORT( SCIPcreateClock(scip, &temporaryClock) );
618  SCIP_CALL_ABORT( SCIPstartClock(scip, temporaryClock) );
619 
620  partialdec->considerImplicits();
621  partialdec->refineToMaster();
622 
623  if( !connected(partialdecdetectiondata->detprobdata, partialdec) || partialdec->alreadyAssignedConssToBlocks() )
624  {
626  }
627 
628  detection(scip, DECdetectorGetData(detector), partialdecdetectiondata, partialdec, true, result);
629 
630  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock) );
631  partialdecdetectiondata->detectiontime = SCIPgetClockTime(scip, temporaryClock);
632  SCIP_CALL_ABORT(SCIPfreeClock(scip, &temporaryClock) );
633 
634  return SCIP_OKAY;
635 }
636 
637 
638 static
639 DEC_DECL_FINISHPARTIALDEC(finishPartialdecHrcgpartition)
640 {
641  SCIP_CLOCK* temporaryClock;
642  gcg::PARTIALDECOMP* partialdec = partialdecdetectiondata->workonpartialdec;
643 
644  SCIP_CALL_ABORT( SCIPcreateClock(scip, &temporaryClock) );
645  SCIP_CALL_ABORT( SCIPstartClock(scip, temporaryClock) );
646 
647  partialdec->considerImplicits();
648  partialdec->refineToBlocks();
649 
650  if( !connected(partialdecdetectiondata->detprobdata, partialdec) )
651  {
653  }
654 
655  detection(scip, DECdetectorGetData(detector), partialdecdetectiondata, partialdec, false, result);
656 
657  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock) );
658  partialdecdetectiondata->detectiontime = SCIPgetClockTime(scip, temporaryClock);
659  SCIP_CALL_ABORT(SCIPfreeClock(scip, &temporaryClock) );
660 
661  return SCIP_OKAY;
662 }
663 
664 
665 #define detectorPostprocessPartialdecHrcgpartition NULL
666 
667 
668 static
669 DEC_DECL_SETPARAMAGGRESSIVE(setParamAggressiveHrcgpartition)
670 {
671  char setstr[SCIP_MAXSTRLEN];
672  const char* name = DECdetectorGetName(detector);
673  int newval;
674  SCIP_Real modifier;
675 
676  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
677  SCIP_CALL( SCIPsetBoolParam(scip, setstr, TRUE) );
678 
679  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
680  SCIP_CALL( SCIPsetBoolParam(scip, setstr, TRUE ) );
681 
682  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxcallround", name);
683  SCIP_CALL( SCIPgetIntParam(scip, setstr, &newval) );
684  ++newval;
685  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
686  SCIPinfoMessage(scip, NULL, "After Setting %s = %d\n", setstr, newval);
687 
688 
689  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/origmaxcallround", name);
690  SCIP_CALL( SCIPgetIntParam(scip, setstr, &newval) );
691  ++newval;
692  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
693  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
694 
695  /* check if no problem is read */
696  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
697  {
698  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxnblockcandidates", name);
699  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
700  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
701  return SCIP_OKAY;
702  }
703 
704 
705  modifier = ( (SCIP_Real)SCIPgetNConss(scip) + (SCIP_Real)SCIPgetNVars(scip) ) / SET_MULTIPLEFORSIZETRANSF;
706 
707  modifier = log(modifier) / log(2);
708 
709  if (!SCIPisFeasPositive(scip, modifier) )
710  modifier = -1.;
711 
712  modifier = SCIPfloor(scip, modifier);
713  modifier += 1;
714 
715  newval = MAX( 0, DEFAULT_MAXNBLOCKCANDIDATES - modifier + 2 );
716  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxnblockcandidates", name);
717  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
718  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
719 
720  return SCIP_OKAY;
721 
722 }
723 
724 
725 static
726 DEC_DECL_SETPARAMDEFAULT(setParamDefaultHrcgpartition)
727 {
728  char setstr[SCIP_MAXSTRLEN];
729  int newval;
730  SCIP_Real modifier;
731 
732  const char* name = DECdetectorGetName(detector);
733 
734  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
735  SCIP_CALL( SCIPsetBoolParam(scip, setstr, DEC_ENABLED) );
736 
737  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
738  SCIP_CALL( SCIPsetBoolParam(scip, setstr, DEC_ENABLEDFINISHING ) );
739 
740  /* check if no problem is read */
741  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
742  {
743  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxnblockcandidates", name);
744  SCIP_CALL( SCIPsetIntParam(scip, setstr, DEFAULT_MAXNBLOCKCANDIDATES ) );
745  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, DEFAULT_MAXNBLOCKCANDIDATES);
746  return SCIP_OKAY;
747  }
748 
749 
750  modifier = ( (SCIP_Real)SCIPgetNConss(scip) + (SCIP_Real)SCIPgetNVars(scip) ) / SET_MULTIPLEFORSIZETRANSF;
751 
752  modifier = log(modifier) / log(2);
753 
754  if (!SCIPisFeasPositive(scip, modifier) )
755  modifier = -1.;
756 
757  modifier = SCIPfloor(scip, modifier);
758  modifier += 1;
759 
760  newval = MAX( 0, DEFAULT_MAXNBLOCKCANDIDATES - modifier );
761  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxnblockcandidates", name);
762  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
763  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
764 
765 
766 
767  return SCIP_OKAY;
768 
769 }
770 
771 static
772 DEC_DECL_SETPARAMFAST(setParamFastHrcgpartition)
773 {
774  char setstr[SCIP_MAXSTRLEN];
775  int newval;
776  SCIP_Real modifier;
777 
778 
779  const char* name = DECdetectorGetName(detector);
780 
781  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
782  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE) );
783 
784  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
785  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE ) );
786 
787  /* check if no problem is read */
788  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
789  {
790  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxnblockcandidates", name);
791  SCIP_CALL( SCIPsetIntParam(scip, setstr, DEFAULT_MAXNBLOCKCANDIDATES ) );
792  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, DEFAULT_MAXNBLOCKCANDIDATES);
793  return SCIP_OKAY;
794  }
795 
796  modifier = ( (SCIP_Real)SCIPgetNConss(scip) + (SCIP_Real)SCIPgetNVars(scip) ) / SET_MULTIPLEFORSIZETRANSF;
797 
798  modifier = log(modifier) / log(2);
799 
800  if (!SCIPisFeasPositive(scip, modifier) )
801  modifier = -1.;
802 
803  modifier = SCIPfloor(scip, modifier);
804  modifier += 1;
805 
806  newval = MAX( 0, DEFAULT_MAXNBLOCKCANDIDATES - modifier - 2 );
807 
808 
809  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxnblockcandidates", name);
810  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
811  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
812 
813  return SCIP_OKAY;
814 
815 }
816 
817 
818 
819 /** creates the hrcgpartition presolver and includes it in SCIP */
820 extern "C"
822  SCIP* scip /**< SCIP data structure */
823  )
824 {
825 #if !defined(_WIN32) && !defined(_WIN64)
826  DEC_DETECTORDATA *detectordata = NULL;
827  assert(scip != NULL);
828 
829  SCIP_CALL( SCIPallocMemory(scip, &detectordata) );
830  assert(detectordata != NULL);
831 
832  SCIP_CALL( DECincludeDetector(scip, DEC_DETECTORNAME, DEC_DECCHAR, DEC_DESC, DEC_FREQCALLROUND, DEC_MAXCALLROUND, DEC_MINCALLROUND, DEC_FREQCALLROUNDORIGINAL, DEC_MAXCALLROUNDORIGINAL, DEC_MINCALLROUNDORIGINAL, DEC_PRIORITY, DEC_ENABLED, DEC_ENABLEDFINISHING, DEC_ENABLEDPOSTPROCESSING, DEC_SKIP, DEC_USEFULRECALL, detectordata, freeHrcgpartition, initHrcgpartition, exitHrcgpartition, propagatePartialdecHrcgpartition, finishPartialdecHrcgpartition, detectorPostprocessPartialdecHrcgpartition, setParamAggressiveHrcgpartition, setParamDefaultHrcgpartition, setParamFastHrcgpartition) );
833 
834 
835  /* add hrcgpartition detector parameters */
836  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/maxnblockcandidates", "The maximal number of block number candidates", &detectordata->maxnblockcandidates, FALSE, DEFAULT_MAXNBLOCKCANDIDATES, 0, 1000000, NULL, NULL) );
837  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/maxblocks", "The maximal number of blocks (detector is called for all block numbers in [minblocks,maxblocks])", &detectordata->maxblocks, FALSE, DEFAULT_MAXBLOCKS, 2, 1000000, NULL, NULL) );
838  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/minblocks", "The minimal number of blocks (detector is called for all block numbers in [minblocks,maxblocks])", &detectordata->minblocks, FALSE, DEFAULT_MINBLOCKS, 2, 1000000, NULL, NULL) );
839  SCIP_CALL( SCIPaddRealParam(scip, "detection/detectors/hrcgpartition/beta", "Factor on how heavy equality (beta) and inequality constraints are measured", &detectordata->beta, FALSE, DEFAULT_BETA, 0.0, 1.0, NULL, NULL ) );
840  SCIP_CALL( SCIPaddRealParam(scip, "detection/detectors/hrcgpartition/alpha", "Factor on how heavy the standard deviation of the coefficients is measured", &detectordata->alpha, FALSE, DEFAULT_ALPHA, 0.0, 1E20, NULL, NULL ) );
841  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/varWeight", "Weight of a variable hyperedge", &detectordata->varWeight, FALSE, DEFAULT_VARWEIGHT, 0, 1000000, NULL, NULL) );
842  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/varWeightBinary", "Weight of a binary variable hyperedge", &detectordata->varWeightBinary, FALSE, DEFAULT_VARWEIGHTBIN, 0, 1000000, NULL, NULL) );
843  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/varWeightContinous", "Weight of a continuos variable hyperedge", &detectordata->varWeightContinous, FALSE, DEFAULT_VARWEIGHTCONT, 0, 1000000, NULL, NULL) );
844  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/varWeightImplint", "Weight of a implicit integer variable hyperedge", &detectordata->varWeightImplint, FALSE, DEFAULT_VARWEIGHTIMPL, 0, 1000000, NULL, NULL) );
845  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/varWeightInteger", "Weight of a integer variable hyperedge", &detectordata->varWeightInteger, FALSE, DEFAULT_VARWEIGHTINT, 0, 1000000, NULL, NULL) );
846  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/consWeight", "Weight of a constraint hyperedge", &detectordata->consWeight, FALSE, DEFAULT_CONSWEIGHT, 0, 1000000, NULL, NULL) );
847  SCIP_CALL( SCIPaddBoolParam(scip, "detection/detectors/hrcgpartition/tidy", "Whether to clean up temporary files", &detectordata->tidy, FALSE, DEFAULT_TIDY, NULL, NULL) );
848  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/randomseed", "Random seed for hmetis", &detectordata->randomseed, FALSE, DEFAULT_RANDSEED, -1, INT_MAX, NULL, NULL) );
849  SCIP_CALL( SCIPaddRealParam(scip, "detection/detectors/hrcgpartition/dummynodes", "Percentage of dummy nodes for metis", &detectordata->dummynodes, FALSE, DEFAULT_DUMMYNODES, 0.0, 1.0, NULL, NULL) );
850  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/hrcgpartition/consWeightSetppc", "Weight for constraint hyperedges that are setpartitioning or covering constraints", &detectordata->consWeightSetppc, FALSE, DEFAULT_CONSWEIGHT_SETPPC, 0, 1000000, NULL, NULL) );
851  SCIP_CALL( SCIPaddRealParam(scip, "detection/detectors/hrcgpartition/ubfactor", "Unbalance factor for metis", &detectordata->metisubfactor, FALSE, DEFAULT_METIS_UBFACTOR, 0.0, 1E20, NULL, NULL ) );
852  SCIP_CALL( SCIPaddBoolParam(scip, "detection/detectors/hrcgpartition/metisverbose", "Should the metis output be displayed", &detectordata->metisverbose, FALSE, DEFAULT_METIS_VERBOSE, NULL, NULL ) );
853  SCIP_CALL( SCIPaddBoolParam(scip, "detection/detectors/hrcgpartition/metisuseptyperb", "Should the rb or kway method be used for partitioning by metis", &detectordata->metisuseptyperb, FALSE, DEFAULT_METISUSEPTYPE_RB, NULL, NULL) );
854  SCIP_CALL( SCIPaddBoolParam(scip, "detection/detectors/hrcgpartition/realname", "Should the problem be used for metis files or a temporary name", &detectordata->realname, FALSE, DEFAULT_REALNAME, NULL, NULL) );
855 #endif
856  return SCIP_OKAY;
857 }
void addClockTime(SCIP_Real clocktime)
adds detection time of one detector
int getNConss()
returns the number of variables considered in the detprobdata
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
arrowhead and bordered detector via graph partitioning (uses hmetis)
structure information for decomposition information in GCG projects
static DEC_DECL_SETPARAMFAST(setParamFastHrcgpartition)
#define DEFAULT_VARWEIGHTINT
#define DEFAULT_METIS_VERBOSE
static DEC_DECL_PROPAGATEPARTIALDEC(propagatePartialdecHrcgpartition)
static SCIP_RETCODE callMetis(SCIP *scip, DEC_DETECTORDATA *detectordata, MatrixGraph< gcg::GraphTclique > *graph, char tempfile[SCIP_MAXSTRLEN], int nblocks, SCIP_RESULT *result)
int getNOpenvars()
Gets size of vector containing variables not assigned yet.
void addDetectorChainInfo(const char *decinfo)
add information about the detector chain
miscellaneous matrixgraph methods for structure detection
A hypergraph with row and column nodes.
#define DEFAULT_MAXNBLOCKCANDIDATES
static DEC_DECL_SETPARAMDEFAULT(setParamDefaultHrcgpartition)
#define DEFAULT_TIDY
constraint handler for structure detection
bool isVarOpenvar(int var)
Checks whether the var is an open var.
weight class for graphs
static SCIP_RETCODE createMetisFile(SCIP *scip, DEC_DETECTORDATA *detectordata, int partialdecID, MatrixGraph< gcg::GraphTclique > *graph, char tempfile[SCIP_MAXSTRLEN])
void getSortedCandidatesNBlocks(std::vector< int > &candidates)
gets the candidates for number of blocks added by the user followed by the found ones sorted in desce...
#define DEFAULT_VARWEIGHTBIN
#define DEFAULT_VARWEIGHTIMPL
static SCIP_RETCODE detection(SCIP *scip, DEC_DETECTORDATA *detectordata, Partialdec_Detection_Data *partialdecdetectiondata, gcg::PARTIALDECOMP *partialdec, bool allowopenpartialdecs, SCIP_RESULT *result)
#define DEFAULT_METIS_UBFACTOR
virtual SCIP_RETCODE writeToFile(int fd, SCIP_Bool writeweights)
Definition: matrixgraph.h:79
#define DEFAULT_BETA
#define SET_MULTIPLEFORSIZETRANSF
#define DEFAULT_VARWEIGHTCONT
#define detectorPostprocessPartialdecHrcgpartition
virtual SCIP_RETCODE createFromPartialMatrix(DETPROBDATA *detprobdata, PARTIALDECOMP *partialdec)
Definition: matrixgraph.h:146
#define HMETIS_EXECUTABLE
std::vector< int > & getConssForVar(int varIndex)
returns the constraint indices of the coefficient matrix for a variable
static DEC_DECL_FREEDETECTOR(freeHrcgpartition)
various SCIP helper methods
#define DEC_MINCALLROUND
SCIP_Bool found
Definition: dec_dbscan.cpp:90
#define DEFAULT_VARWEIGHT
SCIP_Real DECgetRemainingTime(SCIP *scip)
returns the remaining time of scip that the decomposition may use
#define DEC_MINCALLROUNDORIGINAL
void considerImplicits()
: assigns every open cons/var
void setDummynodes(int dummynodes_)
Definition: matrixgraph.h:122
#define DEC_FREQCALLROUNDORIGINAL
static DEC_DECL_FINISHPARTIALDEC(finishPartialdecHrcgpartition)
static bool connected(gcg::DETPROBDATA *detprobdata, gcg::PARTIALDECOMP *partialdec)
int getNVars()
return the number of variables considered in the detprobdata
DEC_DETECTORDATA * DECdetectorGetData(DEC_DETECTOR *detector)
returns the data of the provided detector
static DEC_DECL_EXITDETECTOR(exitHrcgpartition)
#define DEC_ENABLED
interface data structure for the detector calling methods
SCIP_RETCODE SCIPincludeDetectorHrcgpartition(SCIP *scip)
static DEC_DECL_SETPARAMAGGRESSIVE(setParamAggressiveHrcgpartition)
#define DEFAULT_MAXBLOCKS
void refineToBlocks()
refine partialdec with focus on blocks
#define DEC_DECCHAR
interface to the SCIP tclique graph library
#define DEC_DETECTORNAME
static DEC_DECL_INITDETECTOR(initHrcgpartition)
#define DEFAULT_RANDSEED
gcg::DETPROBDATA * detprobdata
const int * getOpenconss()
Gets array containing constraints not assigned yet.
void assignSmallestComponentsButOneConssAdjacency()
computes components by connectedness of conss and vars
#define DEFAULT_DUMMYNODES
virtual int getNNonzeroes() const
Definition: matrixgraph.h:152
#define DEFAULT_METISUSEPTYPE_RB
#define DEFAULT_REALNAME
#define DEC_DESC
class to manage partial decompositions
int getNBlocks()
Gets the number of blocks.
gcg::PARTIALDECOMP ** newpartialdecs
#define DEFAULT_CONSWEIGHT
virtual SCIP_RETCODE readPartition(const char *filename)
Definition: matrixgraph.h:113
#define DEC_ENABLEDFINISHING
int getNVarsForCons(int consIndex)
returns the number of variables for a given constraint
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)),)
#define DEC_USEFULRECALL
int getNOpenconss()
Gets size of vector containing constraints not assigned yet.
#define DEC_SKIP
bool isConsOpencons(int cons)
Gets whether the cons is an open cons.
#define DEFAULT_CONSWEIGHT_SETPPC
int getID()
returns the unique id of the partialdec
#define DEC_FREQCALLROUND
#define DEC_MAXCALLROUND
class storing (potentially incomplete) decompositions
bool alreadyAssignedConssToBlocks()
method to check if at least one constraint is assigned to some block
int getNConssForVar(int varIndex)
returns the number of constraints for a given variable where the var has a nonzero entry in
#define DEC_PRIORITY
std::vector< int > & getVarsForCons(int consIndex)
returns the variable indices of the coefficient matrix for a constraint
#define DEFAULT_MINBLOCKS
void refineToMaster()
refine partialdec with focus on master
const int * getOpenvars()
Gets array containing variables not assigned yet.
class storing partialdecs and the problem matrix
#define DEFAULT_ALPHA
#define DEC_MAXCALLROUNDORIGINAL
#define DEC_ENABLEDPOSTPROCESSING
virtual SCIP_RETCODE createPartialdecFromPartition(PARTIALDECOMP *oldpartialdec, PARTIALDECOMP **firstpartialdec, PARTIALDECOMP **secondpartialdec, DETPROBDATA *detprobdata)
Definition: matrixgraph.h:99
public methods for working with decomposition structures