Scippy

GCG

Branch-and-Price & Column Generation for Everyone

dec_isomorph.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_isomorph.cpp
29  * @ingroup DETECTORS
30  * @brief detector for pricing problems that can be aggregated (uses bliss)
31  * @author Martin Bergner
32  * @author Daniel Peters
33  * @author Jonas Witt
34  * @author Michael Bastubbe
35  *
36  * @note requires package to be installed: BLISS, requires flag to be set: `BLISS=true`
37  *
38  * This detector finds subproblems that can be aggregated thus reducing the symmetry of the problem using color preserving
39  * automorphisms and bliss.
40  */
41 
42 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43 /* #define SCIP_DEBUG */
44 
45 #include "dec_isomorph.h"
46 #include "pub_decomp.h"
47 #include "cons_decomp.h"
48 #include "scip_misc.h"
49 #include "gcg.h"
50 #include "class_partialdecomp.h"
51 #include "class_detprobdata.h"
52 #include "scip/clock.h"
53 
54 #include "bliss/graph.hh"
55 #include "pub_gcgvar.h"
56 #include <cstring>
57 #include <cassert>
58 #include <algorithm>
59 #include <iostream>
60 
61 #include "pub_bliss.h"
62 
63 /* constraint handler properties */
64 #define DEC_DETECTORNAME "isomorph" /**< name of detector */
65 #define DEC_DESC "detector for pricing problems suitable for aggregation" /**< description of detector */
66 #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 */
67 #define DEC_MAXCALLROUND 0 /**< last round the detector gets called */
68 #define DEC_MINCALLROUND 0 /**< first round the detector gets called */
69 #define DEC_FREQCALLROUNDORIGINAL 1 /**< frequency the detector gets called in detection loop while detecting the original problem */
70 #define DEC_MAXCALLROUNDORIGINAL 0 /**< last round the detector gets called while detecting the original problem */
71 #define DEC_MINCALLROUNDORIGINAL 0 /**< first round the detector gets called while detecting the original problem */
72 #define DEC_PRIORITY 100 /**< priority of the constraint handler for separation */
73 #define DEC_DECCHAR 'I' /**< display character of detector */
74 
75 #define DEC_ENABLED FALSE /**< should the detection be enabled */
76 #define DEC_ENABLEDFINISHING FALSE /**< should the finishing be enabled */
77 #define DEC_ENABLEDPOSTPROCESSING FALSE /**< should the postprocessing be enabled */
78 #define DEC_SKIP TRUE /**< should the detector be skipped if others found decompositions */
79 #define DEC_USEFULRECALL FALSE /**< is it useful to call this detector on a descendant of the propagated partialdec */
80 
81 #define DEFAULT_MAXDECOMPSEXACT 6 /**< default maximum number of decompositions */
82 #define DEFAULT_MAXDECOMPSEXTEND 4 /**< default maximum number of decompositions */
83 
84 #define SET_MULTIPLEFORSIZETRANSF 12500
85 
86 /*
87  * Data structures
88  */
89 
90 /** detector data */
91 struct DEC_DetectorData
92 {
93  SCIP_RESULT result; /**< result pointer to indicate success or failure */
94  int maxdecompsexact; /**< maximum number of decompositions for exact emthod */
95  int maxdecompsextend; /**< maximum number of decompositions for extend method*/
96 };
97 
98 typedef struct struct_hook AUT_HOOK;
99 
100 /** saves information of the permutation */
102 {
103  SCIP_Bool aut; /**< true if there is an automorphism */
104  unsigned int n; /**< number of permutations */
105  SCIP* scip; /**< scip to search for automorphisms */
106  int* conssperm; /**< permutations of conss*/
107  gcg::PARTIALDECOMP* partialdec; /**< partialdec to propagate */
108  gcg::DETPROBDATA* detprobdata; /**< detection process information and data */
109 
110  /** constructor for the hook struct*/
111  struct_hook(SCIP_Bool aut, /**< true if there is an automorphism */
112  unsigned int n, /**< number of permutations */
113  SCIP* scip /**< scip to search for automorphisms */
114  );
115 
116  /** constructor for the hook struct with a partialdec */
117  struct_hook(SCIP_Bool aut, /**< true if there is an automorphism */
118  unsigned int n, /**< number of permutations */
119  SCIP* scip, /**< scip to search for automorphisms */
120  gcg::PARTIALDECOMP* partialdec, /**< partial decomposition */
121  gcg::DETPROBDATA* detprobdata /**< detection process information and data */
122  );
123 
124  ~struct_hook();
125  /** getter for the bool aut */
126  SCIP_Bool getBool();
127 
128  /** setter for the bool aut */
129  void setBool(SCIP_Bool aut);
130 
131  /** getter for the SCIP */
132  SCIP* getScip();
133 
134  /** getter for the partialdec */
136 
137  /** getter for the detprobdata */
139 };
140 
142 {
143  return this->scip;
144 }
145 
147 {
148  return this->partialdec;
149 }
150 
152 {
153  return this->detprobdata;
154 }
155 
157 {
158  return aut;
159 }
160 
161 void struct_hook::setBool( SCIP_Bool aut_ )
162 {
163  aut = aut_;
164 }
165 
166 
167 
168 
169 /** method to calculate the greatest common divisor */
170 static
171 int gcd(int a, int b) {
172  return b == 0 ? a : gcd(b, a % b);
173 }
174 
175 /** constructor of the hook struct */
177  SCIP_Bool aut_, /**< true if there is an automorphism */
178  unsigned int n_, /**< number of permutations */
179  SCIP* scip_ /**< array of scips to search for automorphisms */
180  ) : conssperm(NULL)
181 {
182  aut = aut_;
183  n = n_;
184  scip = scip_;
185  SCIP_CALL_ABORT( SCIPallocMemoryArray(scip, &conssperm, SCIPgetNConss(scip)) ); /*lint !e666*/
186  partialdec = NULL;
187  detprobdata = NULL;
188 }
189 
190 /** constructor of the hook struct */
192  SCIP_Bool aut_, /**< true if there is an automorphism */
193  unsigned int n_, /**< number of permutations */
194  SCIP* scip_, /**< array of scips to search for automorphisms */
195  gcg::PARTIALDECOMP* partialdec_, /**< partialdec to propagate */
196  gcg::DETPROBDATA* detprobdata_ /**< detection process information and data */
197  ) : conssperm(NULL)
198 {
199  aut = aut_;
200  n = n_;
201  scip = scip_;
202  SCIP_CALL_ABORT( SCIPallocMemoryArray(scip, &conssperm, detprobdata_->getNConss() ) ); /*lint !e666*/
203  partialdec = partialdec_;
204  detprobdata = detprobdata_;
205 }
206 
208 { /*lint -esym(1540,struct_hook::conssperm) */
209  if( conssperm != NULL )
210  SCIPfreeMemoryArrayNull(scip, &conssperm);
211  conssperm = NULL;
212  scip = NULL;
213 }
214 /** hook function to save the permutation of the graph */
215 static
216 void fhook(
217  void* user_param, /**< data structure to save hashmaps with permutation */
218  unsigned int N, /**< number of permutations */
219  const unsigned int* aut /**< array of permutations */
220  )
221 { /*lint -e715*/
222  int i;
223  int nconss;
224  SCIP_CONS** conss;
225  AUT_HOOK* hook = (AUT_HOOK*) user_param;
226  int auti;
227  int ind;
228 
229  nconss = SCIPgetNConss(hook->getScip());
230  assert(nconss == SCIPgetNConss(hook->getScip()));
231  conss = SCIPgetConss(hook->getScip());
232 
233  for( i = 0; i < nconss; i++ )
234  {
235  assert(aut[i] < INT_MAX);
236  if( (size_t) i != aut[i])
237  {
238  auti = (int) aut[i];
239 
240  SCIPdebugMessage("%d <%s> <-> %d <%s>\n", i, SCIPconsGetName(conss[i]), auti, SCIPconsGetName(conss[auti]));
241 
242  ind = MIN(i, auti);
243 
244  if( hook->conssperm[i] != -1)
245  ind = MIN(ind, hook->conssperm[i]);
246  if( hook->conssperm[auti] != -1 )
247  ind = MIN(ind, hook->conssperm[auti]);
248 
249  hook->conssperm[i] = ind;
250  hook->conssperm[auti] = ind;
251  hook->setBool(TRUE);
252  }
253  }
254 }
255 
256 /** hook function to save the permutation of the graph */
257 static
259  void* user_param, /**< data structure to save hashmaps with permutation */
260  unsigned int N, /**< number of permutations */
261  const unsigned int* aut /**< array of permutations */
262  )
263 { /*lint -e715*/
264  int i;
265  int nconss;
266  AUT_HOOK* hook = (AUT_HOOK*) user_param;
267  int auti;
268  int ind;
269  gcg::PARTIALDECOMP* partialdec;
270  gcg::DETPROBDATA* detprobdata;
271 
272  partialdec = hook->getPartialdec();
273  detprobdata = hook->getDetprobdata() ;
274  assert(partialdec != NULL);
275  assert(detprobdata != NULL);
276  nconss = partialdec->getNOpenconss();
277 
278  for( i = 0; i < nconss; i++ )
279  {
280  SCIP_CONS* cons = detprobdata->getCons(partialdec->getOpenconss()[i]);
281  assert(aut[i] < INT_MAX);
282  if( (size_t) i != aut[i])
283  {
284  auti = (int) aut[i];
285 
286  SCIPdebugMessage("%d <%s> <-> %d <%s>\n", i, SCIPconsGetName(cons), auti,
287  SCIPconsGetName(detprobdata->getCons(partialdec->getOpenconss()[auti])));
288 
289  ind = MIN(i, auti);
290 
291  if( hook->conssperm[i] != -1)
292  ind = MIN(ind, hook->conssperm[i]);
293  if( hook->conssperm[auti] != -1 )
294  ind = MIN(ind, hook->conssperm[auti]);
295 
296  hook->conssperm[i] = ind;
297  hook->conssperm[auti] = ind;
298  hook->setBool(TRUE);
299  }
300  }
301 }
302 
303 static
304 SCIP_RETCODE allocMemory(
305  SCIP* scip, /**< SCIP data structure */
306  AUT_COLOR* colorinfo, /**< struct to save intermediate information */
307  int nconss, /**< number of constraints */
308  int nvars /**< number of variables */
309  )
310 {
311  SCIP_CALL( SCIPallocMemoryArray(scip, &colorinfo->ptrarraycoefs, nvars) );
312  SCIP_CALL( SCIPallocMemoryArray(scip, &colorinfo->ptrarrayvars, nvars) );
313  SCIP_CALL( SCIPallocMemoryArray(scip, &colorinfo->ptrarrayconss, nconss) );
314  colorinfo->alloccoefsarray = nvars;
315  return SCIP_OKAY;
316 }
317 
318 /** destructor for colorinfo */
319 static
321  SCIP* scip, /**< SCIP data structure */
322  AUT_COLOR* colorinfo /**< struct to save intermediate information */
323 )
324 {
325  int i;
326 
327  for( i = 0; i < colorinfo->lenvarsarray; i++ )
328  {
329  AUT_VAR* svar = (AUT_VAR*) colorinfo->ptrarrayvars[i];
330  delete svar;
331  }
332  for( i = 0; i < colorinfo->lenconssarray; i++ )
333  {
334  AUT_CONS* scons = (AUT_CONS*) colorinfo->ptrarrayconss[i];
335  delete scons;
336  }
337  for( i = 0; i < colorinfo->lencoefsarray; i++ )
338  {
339  AUT_COEF* scoef = (AUT_COEF*) colorinfo->ptrarraycoefs[i];
340  delete scoef;
341  }
342 
343  SCIPfreeMemoryArray(scip, &colorinfo->ptrarraycoefs);
344  SCIPfreeMemoryArray(scip, &colorinfo->ptrarrayconss);
345  SCIPfreeMemoryArray(scip, &colorinfo->ptrarrayvars);
346 }
347 
348 /** set up a help structure for graph creation */
349 static
350 SCIP_RETCODE setupArrays(
351  SCIP* scip, /**< SCIP to compare */
352  AUT_COLOR* colorinfo, /**< data structure to save intermediate data */
353  SCIP_RESULT* result /**< result pointer to indicate success or failure */
354  )
355 { /*lint -esym(593,scoef) */
356  int i;
357  int j;
358  int nconss;
359  int nvars;
360  SCIP_CONS** conss;
361  SCIP_VAR** vars;
362  AUT_COEF* scoef;
363  AUT_CONS* scons;
364  SCIP_Bool added;
365  SCIP_Bool onlysign;
366 
367  //allocate max n of coefarray, varsarray, and boundsarray in scip
368  nconss = SCIPgetNConss(scip);
369  nvars = SCIPgetNVars(scip);
370  SCIP_CALL( allocMemory(scip, colorinfo, nconss, nvars) );
371 
372  conss = SCIPgetConss(scip);
373  vars = SCIPgetVars(scip);
374 
375  onlysign = colorinfo->getOnlySign();
376 
377  //save the properties of variables in a struct array and in a sorted pointer array
378  for( i = 0; i < nvars; i++ )
379  {
380  AUT_VAR* svar = new AUT_VAR(scip, vars[i]);
381  //add to pointer array iff it doesn't exist
382  SCIP_CALL( colorinfo->insert(svar, &added) );
383  SCIPdebugMessage("%s color %d %d\n", SCIPvarGetName(vars[i]), colorinfo->get(*svar), colorinfo->color);
384  //otherwise free allocated memory
385  if( !added )
386  delete svar;
387  }
388 
389  //save the properties of constraints in a struct array and in a sorted pointer array
390  for( i = 0; i < nconss && *result == SCIP_SUCCESS; i++ )
391  {
392  SCIP_Real* curvals = NULL;
393  SCIP_VAR** curvars = NULL;
394 
395  int ncurvars = GCGconsGetNVars(scip, conss[i]);
396  if( ncurvars == 0 )
397  continue;
398  scons = new AUT_CONS(scip, conss[i]);
399  //add to pointer array iff it doesn't exist
400  SCIPdebugMessage("nconss %d %d\n", nconss, *result);
401  SCIP_CALL( colorinfo->insert(scons, &added) );
402  SCIPdebugMessage("%s color %d %d\n", SCIPconsGetName(conss[i]), colorinfo->get(*scons), colorinfo->color);
403  //otherwise free allocated memory
404  if( !added )
405  delete scons;
406 
407  SCIP_CALL( SCIPallocMemoryArray(scip, &curvars, ncurvars) );
408  SCIP_CALL( SCIPallocMemoryArray(scip, &curvals, ncurvars) );
409 
410  SCIP_CALL( GCGconsGetVars(scip, conss[i], curvars, ncurvars) );
411  SCIP_CALL( GCGconsGetVals(scip, conss[i], curvals, ncurvars) );
412 
413  //save the properties of variables of the constraints in a struct array and in a sorted pointer array
414  for( j = 0; j < ncurvars; j++ )
415  {
416  SCIP_Real constant;
417  added = FALSE;
418 
419  if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED)
420  SCIPgetProbvarSum(scip, &(curvars[j]), &(curvals[j]), &constant);
421 
422  if( !onlysign )
423  {
424  scoef = new AUT_COEF(scip, curvals[j]);
425  }
426  else
427  {
428  if( SCIPisPositive(scip, curvals[j]) )
429  scoef = new AUT_COEF(scip, 1.0);
430  else if( SCIPisNegative(scip, curvals[j]) )
431  scoef = new AUT_COEF(scip, -1.0);
432  else
433  scoef = new AUT_COEF(scip, 0.0);
434  }
435 
436  //test, whether the coefficient is not zero
437  if( !SCIPisZero(scip, scoef->getVal()) )
438  {
439  //add to pointer array iff it doesn't exist
440  SCIP_CALL( colorinfo->insert(scoef, &added) );
441  SCIPdebugMessage("%f color %d %d\n", scoef->getVal(), colorinfo->get(*scoef), colorinfo->color);
442  }
443  //otherwise free allocated memory
444  if( !added )
445  delete scoef;
446 
447  }
448  SCIPfreeMemoryArray(scip, &curvars);
449  SCIPfreeMemoryArray(scip, &curvals);
450 }
451  return SCIP_OKAY;
452 }
453 
454 /** set up a help structure for graph creation (for partialdecs) */
455 static
456 SCIP_RETCODE setupArrays(
457  SCIP* scip, /**< SCIP to compare */
458  AUT_COLOR* colorinfo, /**< data structure to save intermediate data */
459  SCIP_RESULT* result, /**< result pointer to indicate success or failure */
460  gcg::PARTIALDECOMP* partialdec, /**< partialdec to set up help structure for */
461  gcg::DETPROBDATA* detprobdata /**< detection process information and data */
462  )
463 { /*lint -esym(593,scoef) */
464  int i;
465  int j;
466  int nconss;
467  int nvars;
468  AUT_COEF* scoef;
469  AUT_CONS* scons;
470  SCIP_Bool added;
471  SCIP_Bool onlysign;
472 
473  //allocate max n of coefarray, varsarray, and boundsarray in scip
474  nconss = partialdec->getNOpenconss();
475  nvars = partialdec->getNVars();
476  SCIP_CALL( allocMemory(scip, colorinfo, nconss, nvars) );
477 
478  onlysign = colorinfo->getOnlySign();
479 
480  //save the properties of variables in a struct array and in a sorted pointer array
481  for( i = 0; i < nvars; i++ )
482  {
483  SCIP_VAR* var = detprobdata->getVar(i);
484  AUT_VAR* svar = new AUT_VAR(scip, var);
485  //add to pointer array iff it doesn't exist
486  SCIP_CALL( colorinfo->insert(svar, &added) );
487  SCIPdebugMessage("%s color %d %d\n", SCIPvarGetName(var), colorinfo->get(*svar), colorinfo->color);
488  //otherwise free allocated memory
489  if( !added )
490  delete svar;
491  }
492 
493  //save the properties of constraints in a struct array and in a sorted pointer array
494  for( i = 0; i < nconss && *result == SCIP_SUCCESS; i++ )
495  {
496  int consindex = partialdec->getOpenconss()[i];
497  SCIP_CONS* cons = detprobdata->getCons(consindex);
498 
499  int ncurvars = detprobdata->getNVarsForCons(consindex);
500  if( ncurvars == 0 )
501  continue;
502 
503  scons = new AUT_CONS(scip, cons);
504  //add to pointer array iff it doesn't exist
505  SCIPdebugMessage("nconss %d %d\n", nconss, *result);
506  SCIP_CALL( colorinfo->insert(scons, &added) );
507  SCIPdebugMessage("%s color %d %d\n", SCIPconsGetName(cons), colorinfo->get(*scons), colorinfo->color);
508  //otherwise free allocated memory
509  if( !added )
510  delete scons;
511 
512  //save the properties of variables of the constraints in a struct array and in a sorted pointer array
513  for( j = 0; j < ncurvars; j++ )
514  {
515  added = FALSE;
516 
517  if( !onlysign )
518  {
519  scoef = new AUT_COEF(scip, detprobdata->getValsForCons(consindex)[j]);
520  }
521  else
522  {
523  if( SCIPisPositive(scip, detprobdata->getValsForCons(consindex)[j]) )
524  scoef = new AUT_COEF(scip, 1.0);
525  else if( SCIPisNegative(scip, detprobdata->getValsForCons(consindex)[j]) )
526  scoef = new AUT_COEF(scip, -1.0);
527  else
528  scoef = new AUT_COEF(scip, 0.0);
529  }
530 
531  //test, whether the coefficient is not zero
532  if( !SCIPisZero(scip, scoef->getVal()) )
533  {
534  //add to pointer array iff it doesn't exist
535  SCIP_CALL( colorinfo->insert(scoef, &added) );
536  SCIPdebugMessage("%f color %d %d\n", scoef->getVal(), colorinfo->get(*scoef), colorinfo->color);
537  }
538  //otherwise free allocated memory
539  if( !added )
540  delete scoef;
541 
542  }
543  }
544  return SCIP_OKAY;
545 }
546 
547 /** create a graph out of an array of scips */
548 static
549 SCIP_RETCODE createGraph(
550  SCIP* scip, /**< SCIP to compare */
551  AUT_COLOR colorinfo, /**< data structure to save intermediate data */
552  bliss::Graph* graph, /**< graph needed for discovering isomorphism */
553  SCIP_RESULT* result /**< result pointer to indicate success or failure */
554  )
555 {
556  int i;
557  int j;
558  int z;
559  int nvars;
560  int nconss;
561  int ncurvars;
562  int curvar;
563  int color;
564  SCIP_CONS** conss;
565  SCIP_VAR** vars;
566  SCIP_VAR** curvars = NULL;
567  SCIP_Real* curvals = NULL;
568  unsigned int nnodes;
569  SCIP_Bool onlysign;
570 
571  nnodes = 0;
572  //building the graph out of the arrays
573  bliss::Graph* h = graph;
574  nconss = SCIPgetNConss(scip);
575  nvars = SCIPgetNVars(scip);
576  conss = SCIPgetConss(scip);
577  vars = SCIPgetVars(scip);
578  z = 0;
579  onlysign = colorinfo.getOnlySign();
580 
581  //add a node for every constraint
582  for( i = 0; i < nconss && *result == SCIP_SUCCESS; i++ )
583  {
584  ncurvars = GCGconsGetNVars(scip, conss[i]);
585 
586  AUT_CONS scons(scip, conss[i]);
587  color = colorinfo.get(scons);
588 
589  if( color == -1 )
590  {
591  *result = SCIP_DIDNOTFIND;
592  break;
593  }
594 
595  assert(color >= 0);
596  (void)h->add_vertex((unsigned int) color);
597  nnodes++;
598  }
599  //add a node for every variable
600  for( i = 0; i < nvars && *result == SCIP_SUCCESS; i++ )
601  {
602  AUT_VAR svar(scip, vars[i]);
603  color = colorinfo.get(svar);
604 
605  if( color == -1 )
606  {
607  *result = SCIP_DIDNOTFIND;
608  break;
609  }
610  (void) h->add_vertex((unsigned int) (colorinfo.getLenCons() + color));
611  nnodes++;
612  }
613  //connecting the nodes with an additional node in the middle
614  //it is necessary, since only nodes have colors
615  for( i = 0; i < nconss && *result == SCIP_SUCCESS; i++ )
616  {
617  AUT_CONS scons(scip, conss[i]);
618  ncurvars = GCGconsGetNVars(scip, conss[i]);
619  if( ncurvars == 0 )
620  continue;
621  SCIP_CALL( SCIPallocMemoryArray(scip, &curvars, ncurvars) );
622  SCIP_CALL( GCGconsGetVars(scip, conss[i], curvars, ncurvars) );
623  SCIP_CALL( SCIPallocMemoryArray(scip, &curvals, ncurvars) );
624  SCIP_CALL( GCGconsGetVals(scip, conss[i], curvals, ncurvars) );
625 
626  for( j = 0; j < ncurvars; j++ )
627  {
628  SCIP_Real constant;
629 
630  if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED)
631  SCIPgetProbvarSum(scip, &(curvars[j]), &(curvals[j]), &constant);
632 
633  SCIP_Real val;
634 
635  if( !onlysign )
636  {
637  val = curvals[j];
638  }
639  else
640  {
641  if( SCIPisPositive(scip, curvals[j]) )
642  val = 1.0;
643  else if( SCIPisNegative(scip, curvals[j]) )
644  val = -1.0;
645  else
646  val = 0.0;
647  }
648 
649  AUT_COEF scoef(scip, val);
650  AUT_VAR svar(scip, curvars[j]);
651 
652  color = colorinfo.get(scoef);
653 
654  if( color == -1 )
655  {
656  *result = SCIP_DIDNOTFIND;
657 
658  break;
659  }
660  curvar = SCIPvarGetProbindex(curvars[j]);
661  (void) h->add_vertex((unsigned int) (colorinfo.getLenCons() + colorinfo.getLenVar() + color)); /*lint !e864 */
662  nnodes++;
663  h->add_edge((unsigned int)i, (unsigned int) (nconss + nvars + z));
664  h->add_edge((unsigned int) (nconss + nvars + z), (unsigned int) (nconss + curvar));
665  SCIPdebugMessage(
666  "nz: c <%s> (id: %d, colour: %d) -> nz (id: %d) (value: %f, colour: %d) -> var <%s> (id: %d, colour: %d) \n",
667  SCIPconsGetName(conss[i]), i, colorinfo.get(scons),
668  nconss + nvars + z, scoef.getVal(),
669  color + colorinfo.getLenCons() + colorinfo.getLenVar(), /*lint !e864 */
670  SCIPvarGetName(curvars[j]), nconss + curvar,
671  colorinfo.get(svar) + colorinfo.getLenCons()); /*lint !e864 */
672  z++;
673 
674  }
675 
676  SCIPfreeMemoryArray(scip, &curvals);
677  SCIPfreeMemoryArray(scip, &curvars);
678 
679  }
680  SCIPdebugMessage("Iteration 1: nnodes = %ud, Cons = %d, Vars = %d\n", nnodes, colorinfo.getLenCons(), colorinfo.getLenVar()); /*lint !e864 */
681  assert(*result == SCIP_SUCCESS && nnodes == h->get_nof_vertices());
682 
683  //free all allocated memory
684  freeMemory(scip, &colorinfo);
685  return SCIP_OKAY;
686 }
687 
688 /** create a graph out of an array of scips (for partialdecs) */
689 static
690 SCIP_RETCODE createGraph(
691  SCIP* scip, /**< SCIP to compare */
692  AUT_COLOR colorinfo, /**< data structure to save intermediate data */
693  bliss::Graph* graph, /**< graph needed for discovering isomorphism */
694  SCIP_RESULT* result, /**< result pointer to indicate success or failure */
695  gcg::PARTIALDECOMP* partialdec, /**< partialdec to create graph for */
696  gcg::DETPROBDATA* detprobdata /**< detection process information and data */
697  )
698 {
699  int i;
700  int j;
701  int z;
702  int nvars;
703  int nconss;
704  int ncurvars;
705  int curvar;
706  int color;
707  unsigned int nnodes;
708  SCIP_Bool onlysign;
709  nnodes = 0;
710  //building the graph out of the arrays
711  bliss::Graph* h = graph;
712  nconss = partialdec->getNOpenconss();
713  nvars = partialdec->getNVars();
714  z = 0;
715  onlysign = colorinfo.getOnlySign();
716 
717  //add a node for every constraint
718  for( i = 0; i < nconss && *result == SCIP_SUCCESS; i++ )
719  {
720  ncurvars = detprobdata->getNVarsForCons(partialdec->getOpenconss()[i]);
721  SCIP_CONS* cons = detprobdata->getCons(partialdec->getOpenconss()[i]);
722 
723  AUT_CONS scons(scip, cons);
724  color = colorinfo.get(scons);
725 
726  if( color == -1 )
727  {
728  *result = SCIP_DIDNOTFIND;
729  break;
730  }
731 
732  assert(color >= 0);
733  (void)h->add_vertex((unsigned int) color);
734  nnodes++;
735  }
736  //add a node for every variable
737  for( i = 0; i < nvars && *result == SCIP_SUCCESS; i++ )
738  {
739  SCIP_VAR* var = detprobdata->getVar(i);
740  AUT_VAR svar(scip, var);
741  color = colorinfo.get(svar);
742 
743  if( color == -1 )
744  {
745  *result = SCIP_DIDNOTFIND;
746  break;
747  }
748  (void) h->add_vertex((unsigned int) (colorinfo.getLenCons() + color));
749  nnodes++;
750  }
751  //connecting the nodes with an additional node in the middle
752  //it is necessary, since only nodes have colors
753  for( i = 0; i < nconss && *result == SCIP_SUCCESS; i++ )
754  {
755  int consindex = partialdec->getOpenconss()[i];
756  SCIP_CONS* cons = detprobdata->getCons(consindex);
757  AUT_CONS scons(scip, cons);
758  ncurvars = detprobdata->getNVarsForCons(partialdec->getOpenconss()[i]);
759  if( ncurvars == 0 )
760  continue;
761 
762  for( j = 0; j < ncurvars; j++ )
763  {
764  int varindex = detprobdata->getVarsForCons(consindex)[j];
765  SCIP_VAR* var = detprobdata->getVar(varindex);
766 
767 
768 // if( SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED)
769 // SCIPgetProbvarSum(scip, &(curvars[j]), &(curvals[j]), &constant);
770 
771  SCIP_Real val;
772 
773  if( !onlysign )
774  {
775  val = detprobdata->getValsForCons(consindex)[j];
776  }
777  else
778  {
779  if( SCIPisPositive(scip, detprobdata->getValsForCons(consindex)[j]) )
780  val = 1.0;
781  else if( SCIPisNegative(scip, detprobdata->getValsForCons(consindex)[j]) )
782  val = -1.0;
783  else
784  val = 0.0;
785  }
786  *result = SCIP_SUCCESS;
787 
788  AUT_COEF scoef(scip, val);
789  AUT_VAR svar(scip, var);
790 
791  color = colorinfo.get(scoef);
792 
793  if( color == -1 )
794  {
795  *result = SCIP_DIDNOTFIND;
796  break;
797  }
798 
799  curvar = SCIPvarGetProbindex(var);
800  (void) h->add_vertex((unsigned int) (colorinfo.getLenCons() + colorinfo.getLenVar() + color)); /*lint !e864 */
801  nnodes++;
802  h->add_edge((unsigned int)i, (unsigned int) (nconss + nvars + z));
803  h->add_edge((unsigned int) (nconss + nvars + z), (unsigned int) (nconss + curvar));
804  SCIPdebugMessage(
805  "nz: c <%s> (id: %d, colour: %d) -> nz (id: %d) (value: %f, colour: %d) -> var <%s> (id: %d, colour: %d) \n",
806  SCIPconsGetName(cons), i, colorinfo.get(scons),
807  nconss + nvars + z, scoef.getVal(),
808  color + colorinfo.getLenCons() + colorinfo.getLenVar(), /*lint !e864 */
809  SCIPvarGetName(var), nconss + curvar,
810  colorinfo.get(svar) + colorinfo.getLenCons()); /*lint !e864 */
811  z++;
812 
813  }
814 
815 
816  }
817  SCIPdebugMessage("Iteration 1: nnodes = %ud, Cons = %d, Vars = %d\n", nnodes, colorinfo.getLenCons(), colorinfo.getLenVar()); /*lint !e864 */
818  assert(*result == SCIP_SUCCESS && nnodes == h->get_nof_vertices());
819 
820  //free all allocated memory
821  freeMemory(scip, &colorinfo);
822  return SCIP_OKAY;
823 }
824 
825 
826 /** creates a partialdec with provided constraints in the master
827  * The function will put the remaining constraints in one or more pricing problems
828  * depending on whether the subproblems decompose with no variables in common.
829  */
831  SCIP* scip, /**< SCIP data structure */
832  gcg::PARTIALDECOMP** newPartialdec, /**< partialdec data structure */
833  int* masterconss, /**< constraints to be put in the master */
834  int nmasterconss, /**< number of constraints in the master */
835  gcg::PARTIALDECOMP* partialdec, /**< partialdec to propagate */
836  gcg::DETPROBDATA* detprobdata, /**< detection process information and data */
837  SCIP_Bool exact /** does this partialdec stems from exact graph construction ( or was onlysign = TRUE ) was used */
838  )
839 {
840 
841 
842  char decinfo[SCIP_MAXSTRLEN];
843  int nconss;
844  int nvars;
845  int nblocks;
846  int* blockrepresentative;
847  int nextblock = 1;
848  SCIP_Bool* consismaster;
849  int i, j;
850  int* vartoblock;
851  int ncurvars;
852 
853  std::vector<int> constoblock( detprobdata->getNConss(), -1);
854  std::vector<int> newconstoblock( detprobdata->getNConss(), -1);
855 
856  assert(scip != NULL);
857  assert(nmasterconss == 0 || masterconss != NULL);
858  assert(SCIPgetStage(scip) >= SCIP_STAGE_TRANSFORMED);
859 
860  nconss = partialdec->getNOpenconss();
861  nvars = partialdec->getNVars();
862 
863  assert( nmasterconss <= nconss );
864 
865  nblocks = nconss-nmasterconss+1;
866  assert(nblocks > 0);
867 
868  SCIP_CALL( SCIPallocMemoryArray(scip, &blockrepresentative, nblocks) );
869  SCIP_CALL( SCIPallocMemoryArray(scip, &consismaster, nconss) );
870  SCIP_CALL( SCIPallocMemoryArray(scip, &vartoblock, nvars) );
871 
872  for( i = 0; i < nmasterconss; ++i )
873  {
874  constoblock[masterconss[i]] = nblocks+1;
875  }
876 
877  for( i = 0; i < nconss; ++i )
878  {
879  consismaster[i] = ( constoblock[partialdec->getOpenconss()[i]] != -1 );
880  }
881 
882  for( i = 0; i < nvars; ++i )
883  {
884  vartoblock[i] = -1;
885  }
886 
887  for( i = 0; i < nblocks; ++i )
888  {
889  blockrepresentative[i] = -1;
890  }
891 
892  /* assign constraints to representatives */
893 
894  /* go through the all constraints */
895  for( i = 0; i < nconss; ++i )
896  {
897  int consblock;
898  int cons = partialdec->getOpenconss()[i];
899 
900  if( consismaster[i] )
901  continue;
902 
903  /* get variables of constraint; ignore empty constraints */
904  ncurvars = detprobdata->getNVarsForCons(partialdec->getOpenconss()[i]);
905  assert(ncurvars >= 0);
906 
907  assert( constoblock[cons] == -1 );
908 
909  /* if there are no variables, put it in the first block, otherwise put it in the next block */
910  if( ncurvars == 0 )
911  consblock = -1;
912  else
913  consblock = nextblock;
914 
915  /* go through all variables */
916  for( j = 0; j < ncurvars; ++j )
917  {
918  int var;
919  int varblock;
920  var = detprobdata->getVarsForCons(cons)[j];
921 
922  assert(var >= 0);
923 
924  /** @todo what about deleted variables? */
925  /* get block of variable */
926  varblock = vartoblock[var];
927 
928  /* if variable is already assigned to a block, assign constraint to that block */
929  if( varblock > -1 && varblock != consblock )
930  {
931  consblock = MIN(consblock, blockrepresentative[varblock]);
932  SCIPdebugPrintf("still in block %d.\n", varblock);
933  }
934  else if( varblock == -1 )
935  {
936  /* if variable is free, assign it to the new block for this constraint */
937  varblock = consblock;
938  assert(varblock > 0);
939  assert(varblock <= nextblock);
940  vartoblock[var] = varblock;
941  SCIPdebugPrintf("new in block %d.\n", varblock);
942  }
943  else
944  {
945  assert((varblock > 0) && (consblock == varblock));
946  SCIPdebugPrintf("no change.\n");
947  }
948 
949  SCIPdebugPrintf("VARINDEX: %d (%d)\n", var, vartoblock[var]);
950  }
951 
952  /* if the constraint belongs to a new block, mark it as such */
953  if( consblock == nextblock )
954  {
955  assert(consblock > 0);
956  blockrepresentative[consblock] = consblock;
957  assert(blockrepresentative[consblock] > 0);
958  assert(blockrepresentative[consblock] <= nextblock);
959  ++(nextblock);
960  }
961 
962  SCIPdebugMessage("Cons %s will be in block %d (next %d)\n", SCIPconsGetName(detprobdata->getCons(cons)), consblock, nextblock);
963 
964  for( j = 0; j < ncurvars; ++j )
965  {
966  int var;
967  int oldblock;
968  var = detprobdata->getVarsForCons(cons)[j];
969 
970  oldblock = vartoblock[var];
971  assert((oldblock > 0) && (oldblock <= nextblock));
972 
973  SCIPdebugMessage("\tVar %s ", SCIPvarGetName(detprobdata->getVar(var)));
974  if( oldblock != consblock )
975  {
976  SCIPdebugPrintf("reset from %d to block %d.\n", oldblock, consblock);
977  vartoblock[var] = consblock;
978  SCIPdebugPrintf("VARINDEX: %d (%d)\n", var, consblock);
979 
980  if( (blockrepresentative[oldblock] != -1) && (blockrepresentative[oldblock] > blockrepresentative[consblock]) )
981  {
982  int oldrepr;
983  oldrepr = blockrepresentative[oldblock];
984  SCIPdebugMessage("\t\tBlock representative from block %d changed from %d to %d.\n", oldblock, blockrepresentative[oldblock], consblock);
985  assert(consblock > 0);
986  blockrepresentative[oldblock] = consblock;
987  if( (oldrepr != consblock) && (oldrepr != oldblock) )
988  {
989  blockrepresentative[oldrepr] = consblock;
990  SCIPdebugMessage("\t\tBlock representative from block %d changed from %d to %d.\n", oldrepr, blockrepresentative[oldrepr], consblock);
991  }
992  }
993  }
994  else
995  {
996  SCIPdebugPrintf("will not be changed from %d to %d.\n", oldblock, consblock);
997  }
998  }
999  assert(consblock >= 1 || consblock == -1);
1000  assert(consblock <= nextblock);
1001 
1002  /* store the constraint block */
1003  if( consblock != -1 )
1004  {
1005  SCIPdebugMessage("cons %s in block %d\n", SCIPconsGetName(detprobdata->getCons(cons)), consblock);
1006  constoblock[cons] = consblock;
1007  }
1008  else
1009  {
1010  SCIPdebugMessage("ignoring %s\n", SCIPconsGetName(detprobdata->getCons(cons)));
1011  }
1012  }
1013 
1014  /* postprocess blockrepresentatives */
1015 
1016  int tempblock = 1;
1017  int maxblock = nextblock;
1018 
1019  assert(maxblock >= 1);
1020  assert(blockrepresentative != NULL );
1021  //SCIPdebugPrintf("Blocks: ");
1022 
1023  for( i = 1; i < maxblock; ++i )
1024  {
1025  /* forward replace the representatives */
1026  assert(blockrepresentative[i] >= 0);
1027  assert(blockrepresentative[i] < maxblock);
1028  if( blockrepresentative[i] != i )
1029  blockrepresentative[i] = blockrepresentative[blockrepresentative[i]];
1030  else
1031  {
1032  blockrepresentative[i] = tempblock;
1033  ++tempblock;
1034  }
1035  /* It is crucial that this condition holds */
1036  assert(blockrepresentative[i] <= i);
1037  // SCIPdebugPrintf("%d ", blockrepresentative[i]);
1038  }
1039 // SCIPdebugPrintf("\n");
1040 
1041  /* convert temporary data to detectordata */
1042 
1043  /* fillout Constoblock */
1044  /* convert temporary data to detectordata */
1045  for( i = 0; i < nconss; ++i )
1046  {
1047  int consblock;
1048 
1049  int cons = partialdec->getOpenconss()[i];
1050 
1051  if( consismaster[i] )
1052  {
1053  /* notation is misleading: masterconss are only potential master constraints */
1054  /* SCIP_CALL( SCIPhashmapInsert(newconstoblock, (void*) (size_t) cons, (void*) (size_t) (nblocks+1)) ); */
1055  continue;
1056  }
1057 
1058  if( constoblock[cons] == -1)
1059  continue;
1060 
1061  consblock = constoblock[cons]; /*lint !e507*/
1062  assert(consblock > 0);
1063  consblock = blockrepresentative[consblock];
1064  assert(consblock <= nblocks);
1065  newconstoblock[cons] = consblock;
1066  SCIPdebugMessage("%d %s\n", consblock, SCIPconsGetName(detprobdata->getCons(cons)));
1067  }
1068  (*newPartialdec) = new gcg::PARTIALDECOMP(partialdec);
1069  SCIP_CALL( (*newPartialdec)->assignPartialdecFromConstoblockVector(newconstoblock, nblocks) );
1070 
1071  (*newPartialdec)->considerImplicits();
1072  (*newPartialdec)->refineToBlocks();
1073 
1074  if( exact )
1075  (void) SCIPsnprintf(decinfo, SCIP_MAXSTRLEN, "isomorph\\_exact");
1076  else
1077  (void) SCIPsnprintf(decinfo, SCIP_MAXSTRLEN, "isomorph\\_extended" );
1078  (*newPartialdec)->addDetectorChainInfo(decinfo);
1079 
1080 
1081 
1082  //(*newPartialdec)->showScatterPlot(detprobdata);
1083 
1084  SCIPfreeMemoryArray(scip, &vartoblock);
1085  SCIPfreeMemoryArray(scip, &consismaster);
1086  SCIPfreeMemoryArray(scip, &blockrepresentative);
1087 
1088  return SCIP_OKAY;
1089 }
1090 
1091 /** destructor of detector to free user data (called when GCG is exiting) */
1092 static
1093 DEC_DECL_FREEDETECTOR(detectorFreeIsomorph)
1094 { /*lint --e{715}*/
1095  DEC_DETECTORDATA *detectordata;
1096 
1097  assert(scip != NULL);
1098  assert(detector != NULL);
1099 
1100  assert(strcmp(DECdetectorGetName(detector), DEC_DETECTORNAME) == 0);
1101 
1102  detectordata = DECdetectorGetData(detector);
1103  assert(detectordata != NULL);
1104 
1105  SCIPfreeMemory(scip, &detectordata);
1106 
1107  return SCIP_OKAY;
1108 }
1109 
1110 /** detector initialization method (called after problem was transformed) */
1111 static
1112 DEC_DECL_INITDETECTOR(detectorInitIsomorph)
1113 { /*lint --e{715}*/
1114  DEC_DETECTORDATA *detectordata;
1115 
1116  assert(scip != NULL);
1117  assert(detector != NULL);
1118 
1119  assert(strcmp(DECdetectorGetName(detector), DEC_DETECTORNAME) == 0);
1120 
1121  detectordata = DECdetectorGetData(detector);
1122  assert(detectordata != NULL);
1123 
1124  detectordata->result = SCIP_SUCCESS;
1125 
1126  return SCIP_OKAY;
1127 }
1128 
1129 /** renumbers the permutations from 0 to n-1 and returns the number of permutations
1130  * @return the number of permutations
1131  */
1133  int* permutation, /**< the permutation */
1134  int permsize /**< size of the permutation */
1135 )
1136 {
1137  // renumbering from 0 to number of permutations
1138  int nperms = -1;
1139 
1140  for( int i = 0; i < permsize; i++ )
1141  {
1142  SCIPdebugMessage("%d: %d -> ", i, permutation[i]);
1143  if( permutation[i] == -1 )
1144  {
1145  SCIPdebugPrintf("%d\n", permutation[i]);
1146  continue;
1147  }
1148 
1149  if( permutation[i] > nperms && permutation[permutation[i]] > nperms )
1150  {
1151  nperms++;
1152  permutation[i] = nperms;
1153  }
1154  else
1155  {
1156  permutation[i] = permutation[permutation[i]];
1157  }
1158  SCIPdebugPrintf("%d\n", permutation[i]);
1159  }
1160 
1161  return nperms+1;
1162 }
1163 
1164 /** collapses the permutation, if possible */
1166  int* permutation, /**< the permutation */
1167  int permsize /**< size of the permutation */
1168 )
1169 {
1170  int tmp = 0;
1171  // assign to a permutation circle only one number
1172  for( int i = 0; i < permsize; i++ )
1173  {
1174  if( permutation[i] != -1 && permutation[i] != i )
1175  {
1176  tmp = permutation[i];
1177  permutation[i] = permutation[tmp];
1178  }
1179  SCIPdebugMessage("%d %d\n",i, permutation[i]);
1180 
1181  }
1182 }
1183 
1184 /** method to enumerate all subsets */
1185 static
1186 std::vector< std::vector<int> > getAllSubsets(std::vector<int> set)
1187 {
1188  std::vector< std::vector<int> > subset;
1189  std::vector<int> empty;
1190  subset.push_back( empty );
1191 
1192  for ( size_t i = 0; i < set.size(); ++i )
1193  {
1194  std::vector< std::vector<int> > subsetTemp = subset;
1195 
1196  for (size_t j = 0; j < subsetTemp.size(); ++j)
1197  subsetTemp[j].push_back( set[i] );
1198 
1199  for (size_t j = 0; j < subsetTemp.size(); ++j)
1200  subset.push_back( subsetTemp[j] );
1201  }
1202  return subset;
1203 }
1204 
1205 /** reorder such that the best permutation is represented by 0, the second best by 1, etc. */
1206 SCIP_RETCODE reorderPermutations(
1207  SCIP* scip, /**< SCIP data structure */
1208  gcg::DETPROBDATA* detprobdata, /**< detection process information and data */
1209  int* permutation, /**< the permutation */
1210  int permsize, /**< size of the permutation */
1211  int nperms /**< number of permutations */
1212 )
1213 {
1214  int i;
1215  int* count;
1216  int* order;
1217  int* invorder;
1218 
1219  assert(scip != NULL);
1220  assert(permutation != NULL);
1221  assert(permsize > 0);
1222  assert(nperms > 0);
1223 
1224  SCIP_CALL( SCIPallocMemoryArray(scip, &count, nperms) );
1225  SCIP_CALL( SCIPallocMemoryArray(scip, &order, nperms) );
1226  SCIP_CALL( SCIPallocMemoryArray(scip, &invorder, nperms) );
1227  BMSclearMemoryArray(count, nperms);
1228  BMSclearMemoryArray(order, nperms);
1229  BMSclearMemoryArray(invorder, nperms);
1230 
1231  /* initialize order array that will give a mapping from new to old representatives */
1232  for( i = 0; i < nperms; ++i )
1233  {
1234  order[i] = i;
1235  }
1236 
1237  /* count sizes of orbits */
1238  for( i = 0; i < permsize; ++i )
1239  {
1240  if( permutation[i] >= 0 )
1241  {
1242  count[permutation[i]] += 1;
1243 
1244  SCIPdebugMessage("permutation[i] = %d; count %d\n", permutation[i], count[permutation[i]]);
1245  }
1246  }
1247 
1248  /* sort count and order array */
1249  SCIPsortDownIntInt(count, order, nperms);
1250 
1251 #ifdef SCIP_DEBUG
1252 
1253  for( i = 0; i < nperms; ++i )
1254  {
1255  SCIPdebugMessage("count[%d] = %d, order[%d] = %d\n", i, count[i], i, order[i]);
1256  }
1257 #endif
1258 
1259  /* compute invorder array that gives a mapping from old to new representatives */
1260  for( i = 0; i < nperms; ++i )
1261  {
1262  invorder[order[i]] = i;
1263  SCIPdebugMessage("invorder[%d] = %d\n", order[i], invorder[order[i]]);
1264  }
1265 
1266  SCIPdebugMessage("Best permutation with orbit of size %d, best %d\n", count[0], order[0]);
1267 
1268  /* update representatives of constraints */
1269  for( i = 0; i < permsize; ++i )
1270  {
1271  if( permutation[i] >= 0 )
1272  permutation[i] = invorder[permutation[i]];
1273  }
1274 
1275 
1276  std::vector<int> orbitsizes(0);
1277 
1278  /* compute invorder array that gives a mapping from old to new representatives */
1279  for( i = 0; i < nperms; ++i )
1280  {
1281  int orbitsize;
1282  orbitsize = count[i];
1283 
1284  /* find orbitsize or not */
1285  std::vector<int>::const_iterator orbitsizesIter = orbitsizes.begin();
1286  for(; orbitsizesIter != orbitsizes.end(); ++orbitsizesIter)
1287  {
1288  if(*orbitsizesIter == orbitsize)
1289  break;
1290  }
1291 
1292  if( orbitsizesIter == orbitsizes.end() )
1293  {
1294  GCGconshdlrDecompAddCandidatesNBlocks(scip, detprobdata->isAssignedToOrigProb(), orbitsize);
1295 
1296  orbitsizes.push_back(orbitsize);
1297  }
1298  }
1299  std::vector< std::vector<int> > subsetsOfOrbitsizes = getAllSubsets(orbitsizes);
1300 
1301  for(size_t subset = 0; subset < subsetsOfOrbitsizes.size(); ++subset)
1302  {
1303  int greatestCD = 1;
1304 
1305  if(subsetsOfOrbitsizes[subset].size() == 0 || subsetsOfOrbitsizes[subset].size() == 1)
1306  continue;
1307 
1308  greatestCD = gcd(subsetsOfOrbitsizes[subset][0], subsetsOfOrbitsizes[subset][1] );
1309 
1310  for( size_t j = 2; j < subsetsOfOrbitsizes[subset].size() ; ++j)
1311  {
1312  greatestCD = gcd( greatestCD, subsetsOfOrbitsizes[subset][j] );
1313  }
1314 
1315  GCGconshdlrDecompAddCandidatesNBlocks(scip, detprobdata->isAssignedToOrigProb(), greatestCD);
1316  }
1317 
1318 
1319  SCIPfreeMemoryArray(scip, &count);
1320  SCIPfreeMemoryArray(scip, &order);
1321  SCIPfreeMemoryArray(scip, &invorder);
1322 
1323  return SCIP_OKAY;
1324 }
1325 
1326 
1327 /** detection function of isomorph detector for partialdecs */
1328 static
1329 SCIP_RETCODE detectIsomorph(
1330  SCIP* scip, /**< SCIP data structure */
1331  PARTIALDEC_DETECTION_DATA* detectiondata, /**< detection data */
1332  DEC_DETECTORDATA* detectordata, /**< detector data structure */
1333  SCIP_RESULT* result, /**< pointer to store result */
1334  SCIP_Bool onlysign, /**< use only sign of coefficients instead of coefficients? */
1335  int maxdecomps /**< maximum number of new decompositions */
1336  )
1337 {
1338  SCIP_CLOCK* temporaryClock;
1339  SCIP_CALL_ABORT( SCIPcreateClock(scip, &temporaryClock) );
1340  SCIP_CALL_ABORT( SCIPstartClock(scip, temporaryClock) );
1341 
1342  bliss::Graph graph;
1343  bliss::Stats bstats;
1344  AUT_HOOK *ptrhook;
1345  AUT_COLOR *colorinfo;
1346  gcg::PARTIALDECOMP* partialdec = detectiondata->workonpartialdec;
1347  gcg::DETPROBDATA* detprobdata = detectiondata->detprobdata;
1348 
1349  int nconss = partialdec->getNOpenconss();
1350  int i;
1351 
1352  detectordata->result = SCIP_SUCCESS;
1353 
1354  colorinfo = new AUT_COLOR();
1355 
1356  colorinfo->setOnlySign(onlysign);
1357 
1358 
1359  if( !onlysign )
1360  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "Detecting aggregatable structure: ");
1361  else
1362  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "Detecting almost aggregatable structure: ");
1363 
1364  SCIP_CALL( setupArrays(scip, colorinfo, &detectordata->result, partialdec, detprobdata) );
1365  SCIP_CALL( createGraph(scip, *colorinfo, &graph, &detectordata->result, partialdec, detprobdata) );
1366 
1367  ptrhook = new AUT_HOOK(FALSE, graph.get_nof_vertices(), scip, partialdec, detprobdata);
1368  for( i = 0; i < nconss; i++ )
1369  {
1370  ptrhook->conssperm[i] = -1;
1371  }
1372 
1373  graph.find_automorphisms(bstats, fhookForPartialdecs, ptrhook);
1374 
1375  if( !ptrhook->getBool() )
1376  detectordata->result = SCIP_DIDNOTFIND;
1377 
1378  if( detectordata->result == SCIP_SUCCESS )
1379  {
1380  int nperms;
1381  int nmasterconss;
1382  int* masterconss = NULL;
1383  int p;
1384 
1385  // assign to a permutation circle only one number
1386  collapsePermutation(ptrhook->conssperm, nconss);
1387  // renumbering from 0 to number of permutations
1388  nperms = renumberPermutations(ptrhook->conssperm, nconss);
1389 
1390  // reorder decomposition (corresponding to orbit size)
1391  SCIP_CALL( reorderPermutations(scip, detprobdata, ptrhook->conssperm, nconss, nperms) );
1392 
1393  SCIP_CALL( SCIPreallocMemoryArray(scip, &(detectiondata->newpartialdecs), detectiondata->nnewpartialdecs + MIN(maxdecomps, nperms)) ); /*lint !e506*/
1394 
1395  int pos = detectiondata->nnewpartialdecs;
1396 
1397  for( p = 0; p < nperms && pos < maxdecomps; ++p )
1398  {
1399  SCIP_CALL( SCIPallocMemoryArray(scip, &masterconss, nconss) );
1400 
1401  SCIPdebugMessage("masterconss of partialdec %d:\n", p);
1402 
1403  nmasterconss = 0;
1404  for( i = 0; i < nconss; i++ )
1405  {
1406  if( p != ptrhook->conssperm[i] )
1407  {
1408  masterconss[nmasterconss] = partialdec->getOpenconss()[i];
1409  SCIPdebugMessage("%s\n", SCIPconsGetName(detprobdata->getCons(masterconss[nmasterconss])));
1410  nmasterconss++;
1411  }
1412  }
1413  SCIPdebugMessage("%d\n", nmasterconss);
1414 
1415  if( nmasterconss < nconss )
1416  {
1417  SCIP_Bool isduplicate;
1418  int q;
1419 
1420  SCIP_CALL( createPartialdecFromMasterconss(scip, &(detectiondata->newpartialdecs[pos]), masterconss, nmasterconss, partialdec, detprobdata, !onlysign) );
1421 
1422  isduplicate = FALSE;
1423  for( q = 0; q < pos && !isduplicate; ++q )
1424  {
1425  SCIP_CALL( detectiondata->newpartialdecs[pos]->isEqual(detectiondata->newpartialdecs[q], &isduplicate, TRUE) );
1426  }
1427 
1428  if( isduplicate )
1429  {
1430  delete detectiondata->newpartialdecs[pos];
1431  }
1432  else
1433  {
1434  ++pos;
1435  }
1436 
1437  SCIPfreeMemoryArray(scip, &masterconss);
1438  }
1439 
1440  else
1441  {
1442  SCIPfreeMemoryArray(scip, &masterconss);
1443  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock ) );
1444  continue;
1445  }
1446  }
1447  detectiondata->nnewpartialdecs = pos;
1448 
1449  if( detectiondata->nnewpartialdecs > 0 )
1450  {
1451  SCIP_CALL( SCIPreallocMemoryArray(scip, &(detectiondata->newpartialdecs), detectiondata->nnewpartialdecs) );
1452  }
1453 
1454  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "found %d (new) decompositions.\n", detectiondata->nnewpartialdecs);
1455  }
1456  else
1457  {
1458  SCIPverbMessage(scip, SCIP_VERBLEVEL_NORMAL, NULL, "not found.\n");
1459  }
1460 
1461  delete colorinfo;
1462  delete ptrhook;
1463 
1464  SCIP_CALL_ABORT( SCIPstopClock(scip, temporaryClock ) );
1465 
1466  if( detectiondata->nnewpartialdecs == 0 )
1467  {
1468  SCIPfreeMemoryArrayNull(scip, &(detectiondata->newpartialdecs));
1469  }
1470 
1471  detectiondata->detectiontime = SCIPgetClockTime(scip, temporaryClock);
1472  for( i = 0; i < detectiondata->nnewpartialdecs; ++i )
1473  {
1474  detectiondata->newpartialdecs[i]->addClockTime(detectiondata->detectiontime / detectiondata->nnewpartialdecs);
1475  }
1476 
1477  *result = detectordata->result;
1478 
1479  SCIP_CALL_ABORT(SCIPfreeClock(scip, &temporaryClock) );
1480 
1481  return SCIP_OKAY;
1482 }
1483 
1484 
1485 DEC_DECL_PROPAGATEPARTIALDEC(detectorPropagatePartialdecIsomorph)
1486 {
1487  *result = SCIP_DIDNOTFIND;
1488  DEC_DETECTORDATA* detectordata = DECdetectorGetData(detector);
1489  gcg::PARTIALDECOMP* partialdec = partialdecdetectiondata->workonpartialdec ;
1490 
1491  partialdecdetectiondata->nnewpartialdecs = 0;
1492  partialdecdetectiondata->newpartialdecs = NULL;
1493 
1494  if(partialdec->getNBlocks() != 0 || partialdec->getNOpenvars() != partialdec->getNVars())
1495  {
1496  *result = SCIP_SUCCESS;
1497  return SCIP_OKAY;
1498  }
1499 
1500  if( detectordata->maxdecompsextend > 0 )
1501  SCIP_CALL( detectIsomorph(scip, partialdecdetectiondata, detectordata, result, TRUE, detectordata->maxdecompsextend) );
1502 
1503  if( detectordata->maxdecompsexact > 0 )
1504  SCIP_CALL( detectIsomorph(scip, partialdecdetectiondata, detectordata, result, FALSE, detectordata->maxdecompsexact) );
1505 
1506  for( int i = 0; i < partialdecdetectiondata->nnewpartialdecs; ++i )
1507  {
1508  partialdecdetectiondata->newpartialdecs[i]->refineToMaster();
1509  }
1510 
1511  return SCIP_OKAY;
1512 }
1513 #define detectorExitIsomorph NULL
1514 
1515 #define detectorFinishPartialdecIsomorph NULL
1516 
1517 #define detectorPostprocessPartialdecIsomorph NULL
1518 
1519 static
1520 DEC_DECL_SETPARAMAGGRESSIVE(setParamAggressiveIsomorph)
1521 {
1522  char setstr[SCIP_MAXSTRLEN];
1523  const char* name = DECdetectorGetName(detector);
1524  int newval;
1525  SCIP_Real modifier;
1526 
1527  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
1528  SCIP_CALL( SCIPsetBoolParam(scip, setstr, TRUE) );
1529 
1530  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
1531  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE ) );
1532 
1533  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxcallround", name);
1534  SCIP_CALL( SCIPgetIntParam(scip, setstr, &newval) );
1535  ++newval;
1536  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1537  SCIPinfoMessage(scip, NULL, "After Setting %s = %d\n", setstr, newval);
1538 
1539 
1540  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/origmaxcallround", name);
1541  SCIP_CALL( SCIPgetIntParam(scip, setstr, &newval) );
1542  ++newval;
1543  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1544  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1545 
1546  /* check if no problem is read */
1547  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
1548  {
1549  newval = MAX( 0, DEFAULT_MAXDECOMPSEXACT );
1550  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsexact", name);
1551  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1552  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1553 
1554  newval = MAX( 0, DEFAULT_MAXDECOMPSEXTEND );
1555  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsextend", name);
1556  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1557  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1558  return SCIP_OKAY;
1559  }
1560 
1561  modifier = ( (SCIP_Real)SCIPgetNConss(scip) + (SCIP_Real)SCIPgetNVars(scip) ) / SET_MULTIPLEFORSIZETRANSF;
1562 
1563  modifier = log(modifier) / log(2);
1564 
1565  if (!SCIPisFeasPositive(scip, modifier) )
1566  modifier = -1.;
1567 
1568  modifier = SCIPfloor(scip, modifier);
1569  modifier += 0;
1570 
1571  newval = MAX( 0, DEFAULT_MAXDECOMPSEXACT - modifier );
1572  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsexact", name);
1573  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1574  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1575 
1576  newval = MAX( 0, DEFAULT_MAXDECOMPSEXTEND - modifier );
1577  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsextend", name);
1578  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1579  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1580 
1581  return SCIP_OKAY;
1582 }
1583 
1584 
1585 static
1586 DEC_DECL_SETPARAMDEFAULT(setParamDefaultIsomorph)
1587 {
1588  char setstr[SCIP_MAXSTRLEN];
1589  int newval;
1590  SCIP_Real modifier;
1591 
1592  const char* name = DECdetectorGetName(detector);
1593 
1594  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
1595  SCIP_CALL( SCIPsetBoolParam(scip, setstr, DEC_ENABLED) );
1596 
1597  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
1598  SCIP_CALL( SCIPsetBoolParam(scip, setstr, DEC_ENABLEDFINISHING ) );
1599 
1600 
1601  /* check if no problem is read */
1602  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
1603  {
1604  newval = MAX( 0, DEFAULT_MAXDECOMPSEXACT );
1605  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsexact", name);
1606  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1607  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1608 
1609  newval = MAX( 0, DEFAULT_MAXDECOMPSEXTEND );
1610  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsextend", name);
1611  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1612  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1613  return SCIP_OKAY;
1614  }
1615 
1616 
1617  modifier = ( (SCIP_Real)SCIPgetNConss(scip) + (SCIP_Real)SCIPgetNVars(scip) ) / SET_MULTIPLEFORSIZETRANSF;
1618 
1619  modifier = log(modifier) / log(2);
1620 
1621  if (!SCIPisFeasPositive(scip, modifier) )
1622  modifier = -1.;
1623 
1624  modifier = SCIPfloor(scip, modifier);
1625  modifier += 2;
1626 
1627  newval = MAX( 0, DEFAULT_MAXDECOMPSEXACT - modifier );
1628  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsexact", name);
1629  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1630  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1631 
1632  newval = MAX( 0, DEFAULT_MAXDECOMPSEXTEND - modifier );
1633  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsextend", name);
1634  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1635  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1636 
1637  return SCIP_OKAY;
1638 }
1639 
1640 static
1641 DEC_DECL_SETPARAMFAST(setParamFastIsomorph)
1642 {
1643  char setstr[SCIP_MAXSTRLEN];
1644  int newval;
1645 
1646  const char* name = DECdetectorGetName(detector);
1647 
1648  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/enabled", name);
1649  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE) );
1650 
1651  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/finishingenabled", name);
1652  SCIP_CALL( SCIPsetBoolParam(scip, setstr, FALSE ) );
1653 
1654  /* check if no problem is read */
1655  if( SCIPgetStage(scip) < SCIP_STAGE_PROBLEM )
1656  {
1657  newval = MAX( 0, DEFAULT_MAXDECOMPSEXACT );
1658  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsexact", name);
1659  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1660  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1661 
1662  newval = MAX( 0, DEFAULT_MAXDECOMPSEXTEND );
1663  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsextend", name);
1664  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1665  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1666  return SCIP_OKAY;
1667  }
1668 
1669 
1670 
1671  newval = ( (SCIP_Real)SCIPgetNConss(scip) + (SCIP_Real)SCIPgetNVars(scip) > SET_MULTIPLEFORSIZETRANSF) ? 0 : 1;
1672  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsexact", name);
1673  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1674  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1675 
1676  newval = 0;
1677  (void) SCIPsnprintf(setstr, SCIP_MAXSTRLEN, "detection/detectors/%s/maxdecompsextend", name);
1678  SCIP_CALL( SCIPsetIntParam(scip, setstr, newval ) );
1679  SCIPinfoMessage(scip, NULL, "%s = %d\n", setstr, newval);
1680 
1681  return SCIP_OKAY;
1682 
1683 }
1684 
1685 
1686 /*
1687  * detector specific interface methods
1688  */
1689 
1690 
1691 /** creates the handler for isomorph subproblems and includes it in SCIP */
1692 extern "C"
1694  SCIP* scip /**< SCIP data structure */
1695  )
1696 {
1697  DEC_DETECTORDATA* detectordata;
1698 
1699  detectordata = NULL;
1700 
1701  SCIP_CALL( SCIPallocMemory(scip, &detectordata) );
1702  assert(detectordata != NULL);
1703 
1704 
1705 
1707  detectordata, detectorFreeIsomorph, detectorInitIsomorph, detectorExitIsomorph, detectorPropagatePartialdecIsomorph, detectorFinishPartialdecIsomorph, detectorPostprocessPartialdecIsomorph, setParamAggressiveIsomorph, setParamDefaultIsomorph, setParamFastIsomorph) );
1708 
1709  /* add isomorph constraint handler parameters */
1710  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/isomorph/maxdecompsexact",
1711  "Maximum number of solutions/decompositions with exact detection", &detectordata->maxdecompsexact, FALSE,
1712  DEFAULT_MAXDECOMPSEXACT, 0, INT_MAX, NULL, NULL) );
1713 
1714  SCIP_CALL( SCIPaddIntParam(scip, "detection/detectors/isomorph/maxdecompsextend",
1715  "Maximum number of solutions/decompositions with extended detection", &detectordata->maxdecompsextend, FALSE,
1716  DEFAULT_MAXDECOMPSEXTEND, 0, INT_MAX, NULL, NULL) );
1717 
1718  return SCIP_OKAY;
1719 }
#define DEC_DESC
void addClockTime(SCIP_Real clocktime)
adds detection time of one detector
static int gcd(int a, int b)
int getNConss()
returns the number of variables considered in the detprobdata
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
static void fhook(void *user_param, unsigned int N, const unsigned int *aut)
static DEC_DECL_FREEDETECTOR(detectorFreeIsomorph)
GCG interface methods.
int getNOpenvars()
Gets size of vector containing variables not assigned yet.
#define DEC_ENABLEDFINISHING
SCIP_RETCODE SCIPincludeDetectorIsomorphism(SCIP *scip)
static SCIP_RETCODE detectIsomorph(SCIP *scip, PARTIALDEC_DETECTION_DATA *detectiondata, DEC_DETECTORDATA *detectordata, SCIP_RESULT *result, SCIP_Bool onlysign, int maxdecomps)
SCIP_Bool isAssignedToOrigProb()
returns true if the matrix structure corresponds to the presolved problem
static DEC_DECL_SETPARAMDEFAULT(setParamDefaultIsomorph)
SCIP * getScip()
SCIP_Bool getBool()
static void freeMemory(SCIP *scip, AUT_COLOR *colorinfo)
constraint handler for structure detection
struct struct_cons AUT_CONS
Definition: pub_bliss.h:50
#define DEC_FREQCALLROUNDORIGINAL
SCIP_RETCODE GCGconsGetVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int nvars)
Definition: scip_misc.c:490
#define DEC_PRIORITY
gcg::PARTIALDECOMP * partialdec
#define detectorFinishPartialdecIsomorph
#define DEFAULT_MAXDECOMPSEXTEND
#define DEC_USEFULRECALL
DEC_DECL_PROPAGATEPARTIALDEC(detectorPropagatePartialdecIsomorph)
unsigned int n
various SCIP helper methods
struct struct_colorinformation AUT_COLOR
Definition: pub_bliss.h:53
#define DEC_ENABLEDPOSTPROCESSING
struct struct_hook AUT_HOOK
#define detectorExitIsomorph
#define detectorPostprocessPartialdecIsomorph
SCIP_CONS * getCons(int consIndex)
returns the SCIP constraint related to a constraint index
void collapsePermutation(int *permutation, int permsize)
std::vector< SCIP_Real > & getValsForCons(int consIndex)
returns the nonzero coefficients of the coefficient matrix for a constraint
DEC_DETECTORDATA * DECdetectorGetData(DEC_DETECTOR *detector)
returns the data of the provided detector
gcg::DETPROBDATA * detprobdata
interface data structure for the detector calling methods
static DEC_DECL_INITDETECTOR(detectorInitIsomorph)
#define DEC_MINCALLROUND
#define DEC_FREQCALLROUND
gcg::DETPROBDATA * getDetprobdata()
gcg::DETPROBDATA * detprobdata
struct struct_coef AUT_COEF
Definition: pub_bliss.h:52
const int * getOpenconss()
Gets array containing constraints not assigned yet.
SCIP_RETCODE GCGconsGetVals(SCIP *scip, SCIP_CONS *cons, SCIP_Real *vals, int nvals)
Definition: scip_misc.c:621
#define DEC_DETECTORNAME
void setBool(SCIP_Bool aut)
int GCGconsGetNVars(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:434
detector for pricing problems that can be aggregated (uses bliss)
SCIP_RESULT result
Definition: dec_dbscan.cpp:89
int renumberPermutations(int *permutation, int permsize)
#define DEFAULT_MAXDECOMPSEXACT
#define DEC_DECCHAR
static SCIP_RETCODE setupArrays(SCIP *scip, AUT_COLOR *colorinfo, SCIP_RESULT *result)
class to manage partial decompositions
int getNBlocks()
Gets the number of blocks.
#define DEC_ENABLED
struct gcg::subset subset
gcg::PARTIALDECOMP ** newpartialdecs
static SCIP_RETCODE createGraph(SCIP *scip, AUT_COLOR colorinfo, bliss::Graph *graph, SCIP_RESULT *result)
gcg::PARTIALDECOMP * getPartialdec()
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_MAXCALLROUNDORIGINAL
helper functions for automorphism detection
int getNOpenconss()
Gets size of vector containing constraints not assigned yet.
SCIP_RETCODE isEqual(PARTIALDECOMP *otherpartialdec, SCIP_Bool *isequal, bool sortpartialdecs)
method to check whether this partialdec is equal to a given other partialdec (
static DEC_DECL_SETPARAMFAST(setParamFastIsomorph)
#define DEC_MINCALLROUNDORIGINAL
static void fhookForPartialdecs(void *user_param, unsigned int N, const unsigned int *aut)
static DEC_DECL_SETPARAMAGGRESSIVE(setParamAggressiveIsomorph)
SCIP_RETCODE reorderPermutations(SCIP *scip, gcg::DETPROBDATA *detprobdata, int *permutation, int permsize, int nperms)
struct struct_var AUT_VAR
Definition: pub_bliss.h:51
class storing (potentially incomplete) decompositions
#define SET_MULTIPLEFORSIZETRANSF
public methods for GCG variables
#define DEC_MAXCALLROUND
std::vector< int > & getVarsForCons(int consIndex)
returns the variable indices of the coefficient matrix for a constraint
static SCIP_RETCODE allocMemory(SCIP *scip, AUT_COLOR *colorinfo, int nconss, int nvars)
SCIP_VAR * getVar(int varIndex)
returns SCIP variable related to a variable index
static std::vector< std::vector< int > > getAllSubsets(std::vector< int > set)
SCIP_RETCODE createPartialdecFromMasterconss(SCIP *scip, gcg::PARTIALDECOMP **newPartialdec, int *masterconss, int nmasterconss, gcg::PARTIALDECOMP *partialdec, gcg::DETPROBDATA *detprobdata, SCIP_Bool exact)
class storing partialdecs and the problem matrix
gcg::PARTIALDECOMP * workonpartialdec
struct_hook(SCIP_Bool aut, unsigned int n, SCIP *scip)
SCIP_Bool aut
void GCGconshdlrDecompAddCandidatesNBlocks(SCIP *scip, SCIP_Bool origprob, int candidate)
adds a candidate for block number and counts how often a candidate is added
#define DEC_SKIP
public methods for working with decomposition structures
int getNVars()
Gets number of vars.