Scippy

GCG

Branch-and-Price & Column Generation for Everyone

class_partialdecomp.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 class_partialdecomp.cpp
29  * @brief class storing incomplete decompositions
30  * @author Michael Bastubbe
31  * @author Hanna Franzen
32  *
33  */
34 
35 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36 
37 /*#define SCIP_DEBUG*/
38 
39 #include "class_partialdecomp.h"
40 #include "class_detprobdata.h"
41 #include "scip/cons_setppc.h"
42 #include "scip/scip.h"
43 #include "scip_misc.h"
44 #include "struct_detector.h"
45 #include "struct_decomp.h"
46 #include "cons_decomp.h"
47 #include "cons_decomp.hpp"
48 #include "params_visu.h"
49 #include "miscvisualization.h"
50 #include "reader_gp.h"
51 #include "bliss_automorph.hpp"
52 
53 #include <sstream>
54 #include <iostream>
55 #include <exception>
56 #include <algorithm>
57 #include <queue>
58 #include <utility>
59 #include <stdlib.h>
60 
61 #ifdef WITH_BLISS
62 #include "bliss_automorph.h"
63 #include "bliss/graph.hh"
64 #endif
65 
66 
67 /** macro to throw error if SCIP return status of the called function is not SCIP_OKAY */
68 #define SCIP_CALL_EXC( x ) do \
69  { \
70  SCIP_RETCODE _restat_; \
71  if( ( _restat_ = ( x ) ) != SCIP_OKAY ) \
72  { \
73  SCIPerrorMessage( "Error <%d> in function call\n", _restat_ ); \
74  throw std::exception(); \
75  } \
76  } \
77  while( FALSE )
78 
79 namespace gcg {
80 
81 /** array of prime numbers */
82 const int PARTIALDECOMP::primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
83  101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
84  229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349};
85 
86 /** length of primes array */
87 const int PARTIALDECOMP::nprimes = 70;
88 
89 
91  SCIP* _scip,
92  bool originalProblem
93  ) :
94  scip( _scip ), nblocks( 0 ), masterconss( 0 ),
95  mastervars( 0 ), conssforblocks( 0 ), varsforblocks( 0 ), linkingvars( 0 ), stairlinkingvars( 0 ),
96  ncoeffsforblock(std::vector<int>(0)), calculatedncoeffsforblock(FALSE), ncoeffsforblockformastercons(0),
97  varsforblocksorted(true), stairlinkingvarsforblocksorted(true),
98  conssforblocksorted(true), linkingvarssorted(true), mastervarssorted(true),
99  masterconsssorted(true), hashvalue( 0 ), hvoutdated(true), isselected( false ), isagginfoalreadytoexpensive(false), isfinishedbyfinisher( false ),
100  nrepblocks(0), reptoblocks(std::vector<std::vector<int>>(0)), blockstorep(std::vector<int>(0) ), pidtopidvarmaptofirst(std::vector<std::vector<std::vector<int> > >(0)),
101  detectorchain( 0 ), detectorclocktimes( 0 ), pctvarstoborder( 0 ),
102  pctvarstoblock( 0 ), pctvarsfromfree( 0 ), pctconsstoborder( 0 ), pctconsstoblock( 0 ), pctconssfromfree( 0 ),
103  nnewblocks( 0 ), usedpartition(0 ), classestomaster(0 ), classestolinking(0 ), listofancestorids(0 ),
104  usergiven( USERGIVEN::NOT ), maxwhitescore( -1. ), borderareascore( -1. ), classicscore( -1. ),
105  maxforeseeingwhitescore(-1.),
106  setpartfwhitescore(-1.), maxforeseeingwhitescoreagg(-1.), setpartfwhitescoreagg(-1.), bendersscore(-1.), strongdecompositionscore(-1.),
107  stemsfromorig( false ), original( originalProblem ), translatedpartialdecid( -1 )
108 {
109  // unique id
111 
112  DETPROBDATA* detprobdata = getDetprobdata();
113 
114  nvars = detprobdata->getNVars();
115  nconss = detprobdata->getNConss();
116 
117  // vector of bools are a special case, no "(n fields, default value)" constructor available
118  for(int i = 0; i < nvars; i++)
119  {
120  isvaropen.push_back(true);
121  isvarmaster.push_back(false);
122  openvars.push_back(i);
123  }
124 
125  for(int i = 0; i < nconss; i++)
126  {
127  isconsopen.push_back(true);
128  isconsmaster.push_back(false);
129  openconss.push_back(i);
130  }
131 
133 }
134 
135 
137  const PARTIALDECOMP *partialdectocopy
138  )
139 {
140  scip = ( partialdectocopy->scip );
141 
142  // unique id
144 
145  // rest is copied
146  nblocks = partialdectocopy->nblocks;
147  nvars = partialdectocopy->nvars;
148  nconss = partialdectocopy->nconss;
149  masterconss = partialdectocopy->masterconss;
150  mastervars = partialdectocopy->mastervars;
151  conssforblocks = partialdectocopy->conssforblocks;
152  varsforblocks = partialdectocopy->varsforblocks;
153  linkingvars = partialdectocopy->linkingvars;
154  stairlinkingvars = partialdectocopy->stairlinkingvars;
155  openvars = partialdectocopy->openvars;
156  openconss = partialdectocopy->openconss;
157 
158  isvaropen = partialdectocopy->isvaropen;
159  masterconsssorted = partialdectocopy->masterconsssorted;
160 
161  isconsopen = partialdectocopy->isconsopen;
162 
163  isvarmaster = partialdectocopy->isvarmaster;
164  isconsmaster = partialdectocopy->isconsmaster;
165 
166  detectorchain = partialdectocopy->detectorchain;
167  detectorchaininfo = partialdectocopy->detectorchaininfo;
168  hashvalue = partialdectocopy->hashvalue;
169  usergiven = partialdectocopy->usergiven;
170  classicscore = partialdectocopy->classicscore;
171  borderareascore = partialdectocopy->borderareascore;
172  maxwhitescore = partialdectocopy->maxwhitescore;
173  bendersscore = -1.;
174  detectorclocktimes = partialdectocopy->detectorclocktimes;
175  pctvarstoborder = partialdectocopy->pctvarstoborder;
176  pctvarstoblock = partialdectocopy->pctvarstoblock;
177  pctvarsfromfree = partialdectocopy->pctvarsfromfree;
178  pctconsstoborder = partialdectocopy->pctconsstoborder;
179  pctconsstoblock = partialdectocopy->pctconsstoblock;
180  pctconssfromfree = partialdectocopy->pctconssfromfree;
181  usedpartition = partialdectocopy->usedpartition;
182  classestomaster = partialdectocopy->classestomaster;
183  classestolinking = partialdectocopy->classestolinking;
184  isfinishedbyfinisher = partialdectocopy->isfinishedbyfinisher;
185  ncoeffsforblockformastercons = partialdectocopy->ncoeffsforblockformastercons;
186  nnewblocks = partialdectocopy->nnewblocks;
187  stemsfromorig = partialdectocopy->stemsfromorig;
188  isselected = false;
189  original = partialdectocopy->original;
190  listofancestorids = partialdectocopy->listofancestorids;
191  listofancestorids.push_back(partialdectocopy->id);
192 
193  varsforblocksorted = partialdectocopy->varsforblocksorted;
194  stairlinkingvarsforblocksorted = partialdectocopy->stairlinkingvarsforblocksorted;
195  conssforblocksorted = partialdectocopy->conssforblocksorted;
196  linkingvarssorted = partialdectocopy->linkingvarssorted;
197  mastervarssorted = partialdectocopy->mastervarssorted;
198  hvoutdated = partialdectocopy->hvoutdated;
199 
200  nrepblocks = partialdectocopy->nrepblocks;
201  reptoblocks = partialdectocopy->reptoblocks;
202  blockstorep = partialdectocopy->blockstorep;
203  pidtopidvarmaptofirst = partialdectocopy->pidtopidvarmaptofirst;
204  ncoeffsforblock = partialdectocopy->ncoeffsforblock;
205  calculatedncoeffsforblock = FALSE;
206  translatedpartialdecid = partialdectocopy->getTranslatedpartialdecid();
207 
208  maxforeseeingwhitescore = -1.;
209  maxforeseeingwhitescoreagg = -1.;
210  setpartfwhitescore = -1.;
211  setpartfwhitescoreagg = -1.;
212  strongdecompositionscore = -1;
213 
214  isagginfoalreadytoexpensive = partialdectocopy->isagginfoalreadytoexpensive;
215 
217 }
218 
219 
221 {
223 }
224 
225 
226 /** @brief checks whether two arrays of SCIP_Real's are identical
227  * @returns true iff the given arrays are identical */
228 static
230  SCIP* scip, /**< SCIP data structure */
231  SCIP_Real* array1, /**< first array */
232  int array1length, /**< length of first array */
233  SCIP_Real* array2, /**< second array */
234  int array2length /**< length of second array */
235  )
236 {
237  int i;
238 
239  if( array1length != array2length )
240  return FALSE;
241 
242  if( array1length == 0 )
243  return TRUE;
244 
245  assert(array1 != NULL);
246  assert(array2 != NULL);
247 
248  for( i = 0; i < array1length; i++ )
249  {
250  if( !SCIPisEQ(scip, array1[i], array2[i]) )
251  return FALSE;
252  }
253 
254  return TRUE;
255 }
256 
257 
258 /** Checks whether the second value of a is lower than the second value of b
259  * @returns true iff the second value of a is lower than the second value of b */
260 static
262  std::pair<int, int> const & a,
263  std::pair<int, int> const & b
264  )
265 {
266  return ( a.second < b.second );
267 }
268 
269 
271 {
272  std::vector<int> vector = std::vector<int>( 0 );
273 
274  assert( (int) conssforblocks.size() == nblocks );
275  assert( (int) varsforblocks.size() == nblocks );
276  assert( (int) stairlinkingvars.size() == nblocks );
277 
278  conssforblocks.push_back( vector );
279  varsforblocks.push_back( vector );
280  stairlinkingvars.push_back( vector );
281  nblocks ++;
282  return nblocks - 1;
283 }
284 
285 
287  SCIP_Real clocktime
288  )
289 {
290  detectorclocktimes.push_back( clocktime );
291 }
292 
293 
295  PARTIALDECOMP* ancestor
296  )
297 {
298  /* add number of new blocks */
299  assert( ancestor != NULL );
300 
301  nnewblocks.push_back( getNBlocks() - ancestor->getNBlocks() );
302  pctconssfromfree.push_back( getNConss() != 0 ? ( ancestor->getNOpenconss() - getNOpenconss() ) / (SCIP_Real) getNConss() : 0. );
303  pctvarsfromfree.push_back( getNVars() != 0 ? ( ancestor->getNOpenvars() - getNOpenvars() ) / (SCIP_Real) getNVars() : 0. );
304  pctconsstoblock.push_back( getNConss() != 0 ?
305  ( - getNOpenconss() - getNMasterconss() + ancestor->getNOpenconss() + ancestor->getNMasterconss() ) / getNConss() : 0. );
306  pctvarstoblock.push_back( getNVars() != 0 ? ( - getNOpenvars() - getNMastervars() - getNLinkingvars() - getNTotalStairlinkingvars() + ancestor->getNOpenvars()
307  + ancestor->getNMastervars() + ancestor->getNLinkingvars() + ancestor->getNTotalStairlinkingvars() ) / getNVars() : 0. );
308  pctconsstoborder.push_back( getNConss() != 0 ? ( getNMasterconss() - ancestor->getNMasterconss() ) / (SCIP_Real) getNConss() : 0. );
309  pctvarstoborder.push_back( getNVars() != 0 ? ( getNMastervars() + getNLinkingvars() + getNTotalStairlinkingvars() - ancestor->getNMastervars()
310  - ancestor->getNLinkingvars() - ancestor->getNTotalStairlinkingvars() ) / (SCIP_Real) getNVars() : 0. );
311  listofancestorids.push_back( ancestor->getID() );
312 }
313 
314 
316  const char* decinfo
317  )
318 {
319  std::stringstream help;
320  help << decinfo;
321  detectorchaininfo.push_back( help.str() );
322 }
323 
324 
325 void PARTIALDECOMP::addEmptyPartitionStatistics()
326 {
327  std::vector<int> emptyVector( 0 );
328  usedpartition.push_back(NULL );
329  classestomaster.push_back( emptyVector );
330  classestolinking.push_back( emptyVector );
331 }
332 
333 
335  int newblocks
336  )
337  {
338  nnewblocks.push_back( newblocks );
339  }
340 
341 
343  SCIP_Real pct
344  )
345  {
346  pctconssfromfree.push_back( pct );
347  }
348 
349 
351  SCIP_Real pct
352  )
353  {
354  pctconsstoblock.push_back( pct );
355  }
356 
357 
359  SCIP_Real pct
360  )
361  {
362  pctconsstoborder.push_back( pct );
363  }
364 
365 
367  SCIP_Real pct
368  )
369  {
370  pctvarsfromfree.push_back( pct );
371  }
372 
373 
375  SCIP_Real pct
376  )
377  {
378  pctvarstoblock.push_back( pct );
379  }
380 
381 
383  SCIP_Real pct
384  )
385  {
386  pctvarstoborder.push_back( pct );
387  }
388 
389 
391 {
392  for( int b = 0; b < this->nblocks; ++ b )
393  if( conssforblocks[b].size() != 0 )
394  return true;
395  return false;
396 }
397 
398 
400  SCIP_HASHMAP* constoblock,
401  int givenNBlocks
402  )
403 {
404  int cons;
405  std::vector<int> del;
406 
407  for( int i = 0; i < getNOpenconss(); ++ i )
408  {
409  cons = openconss[i];
410  if( ! SCIPhashmapExists( constoblock, (void*) (size_t) cons ) )
411  continue;
412  if( (int) (size_t) SCIPhashmapGetImage( constoblock, (void*) (size_t) cons ) - 1 == givenNBlocks )
413  {
414  setConsToMaster( cons );
415  del.push_back(cons);
416  }
417  }
418 
419  /* remove assigned conss from list of open conss */
420  for(auto c : del)
421  deleteOpencons(c);
422 
423  sort();
424  assert( checkConsistency() );
425  return SCIP_OKAY;
426 }
427 
428 
430  )
431 {
432  std::vector<int> blocksOfOpenvar;
433  bool assigned = false;
434  int var;
435  int cons;
436  std::vector<int> del;
437 
438  DETPROBDATA* detprobdata = this->getDetprobdata();
439 
440  /* look for blocks in which the var appears */
441  for( int i = 0; i < getNOpenvars(); ++ i )
442  {
443  blocksOfOpenvar.clear();
444  var = openvars.at(i);
445  for( int b = 0; b < nblocks; ++ b )
446  {
447  for( int c = 0; c < getNConssForBlock( b ); ++ c )
448  {
449  cons = conssforblocks.at(b).at(c);
450  if( detprobdata->getVal( cons, var ) != 0 )
451  {
452  blocksOfOpenvar.push_back( b );
453  break;
454  }
455  }
456  }
457  /* assign all vars included in two consecutive blocks to stairlinking */
458  if( blocksOfOpenvar.size() == 2 && blocksOfOpenvar.at(0) + 1 == blocksOfOpenvar.at(1) )
459  {
460  setVarToStairlinking(var, blocksOfOpenvar.at(0), blocksOfOpenvar.at(1));
461  del.push_back(var);
462  assigned = true;
463  }
464  }
465 
466  /* remove assigned vars from open vars list */
467  for(auto v : del)
468  deleteOpenvar(v);
469 
470  sort();
471 
472  return assigned;
473 }
474 
475 
476 bool PARTIALDECOMP::assignHittingOpenconss(
477  )
478 {
479  int cons;
480  int var;
481  int block;
482  bool stairlinking; /* true if the cons includes stairlinkingvars */
483  bool assigned = false; /* true if open conss get assigned in this function */
484  std::vector<int>::iterator it;
485  std::vector<int> blocksOfStairlinkingvars; /* first block of the stairlinkingvars which can be found in the conss */
486  std::vector<int> blocksOfVars; /* blocks of the vars which can be found in the conss */
487  std::vector<int> blocks; /* cons can be assigned to the blocks stored in this vector */
488  std::vector<int> eraseBlock;
489  std::vector<int> del;
490 
491  DETPROBDATA* detprobdata = this->getDetprobdata();
492 
493  for( size_t c = 0; c < openconss.size(); ++ c )
494  {
495  cons = openconss[c];
496  stairlinking = false;
497 
498  blocksOfVars.clear();
499  blocks.clear();
500  blocksOfStairlinkingvars.clear();
501  eraseBlock.clear();
502 
503  /* fill out blocksOfStairlinkingvars and blocksOfBlockvars */
504  for( int b = 0; b < nblocks; ++ b )
505  {
506  for( int v = 0; v < detprobdata->getNVarsForCons( cons ); ++ v )
507  {
508  var = detprobdata->getVarsForCons( cons )[v];
509  if( isVarBlockvarOfBlock( var, b ) )
510  {
511  blocksOfVars.push_back( b );
512  break;
513  }
514  }
515  }
516 
517  for( int b = 0; b < nblocks; ++ b )
518  {
519  for( int v = 0; v < detprobdata->getNVarsForCons( cons ); ++ v )
520  {
521  int var2 = detprobdata->getVarsForCons(cons)[v];
522  std::vector<int>::iterator lb = lower_bound( stairlinkingvars[b].begin(), stairlinkingvars[b].end(), var2 );
523  if( lb != stairlinkingvars[b].end() && *lb == var2 )
524  {
525  stairlinking = true;
526  blocksOfStairlinkingvars.push_back( b );
527  break;
528  }
529  }
530  }
531 
532  /* fill out blocks */
533  if( stairlinking && blocksOfVars.size() < 2 )
534  {
535  if( blocksOfVars.size() == 0 )
536  {
537  blocks.push_back( blocksOfStairlinkingvars[0] );
538  blocks.push_back( blocksOfStairlinkingvars[0] + 1 );
539  for( size_t i = 1; i < blocksOfStairlinkingvars.size(); ++ i )
540  {
541  for( it = blocks.begin(); it != blocks.end(); ++ it )
542  {
543  if( * it != blocksOfStairlinkingvars[i] && * it != blocksOfStairlinkingvars[i] + 1 )
544  eraseBlock.push_back( * it );
545  }
546  for( size_t j = 0; j < eraseBlock.size(); ++ j )
547  {
548  it = find( blocks.begin(), blocks.end(), eraseBlock[j] );
549  assert( it != blocks.end() );
550  blocks.erase( it );
551  }
552  }
553  }
554  else
555  {
556  blocks.push_back( blocksOfVars[0] );
557  for( size_t i = 0; i < blocksOfStairlinkingvars.size(); ++ i )
558  {
559  if( blocks[0] != blocksOfStairlinkingvars[i] && blocks[0] != blocksOfStairlinkingvars[i] + 1 )
560  {
561  blocks.clear();
562  break;
563  }
564  }
565  }
566  }
567 
568  if( blocksOfVars.size() > 1 )
569  {
570  setConsToMaster( cons );
571  del.push_back(cons);
572  assigned = true;
573  }
574  else if( ! stairlinking && blocksOfVars.size() == 1 )
575  {
576  setConsToBlock( cons, blocksOfVars[0] );
577  del.push_back(cons);
578  assigned = true;
579  }
580  else if( stairlinking && blocks.size() == 0 )
581  {
582  setConsToMaster( cons );
583  del.push_back(cons);
584  assigned = true;
585  }
586  else if( stairlinking && blocks.size() == 1 )
587  {
588  setConsToBlock( cons, blocks[0] );
589  del.push_back(cons);
590  assigned = true;
591  }
592  else if( stairlinking && blocks.size() > 1 )
593  {
594  block = blocks[0];
595  for( size_t i = 1; i < blocks.size(); ++ i )
596  {
597  if( getNConssForBlock( i ) < getNConssForBlock( block ) )
598  block = i;
599  }
600  setConsToBlock( cons, block );
601  del.push_back(cons);
602  assigned = true;
603  }
604  }
605 
606  /* remove assigned conss from list of open conss */
607  if( assigned )
608  {
609  for(auto c : del)
610  deleteOpencons(c);
611  sort();
612  }
613 
614  return assigned;
615 }
616 
617 
618 bool PARTIALDECOMP::assignHittingOpenvars(
619  )
620 {
621  int cons;
622  int var;
623  std::vector<int> blocksOfOpenvar;
624  bool found;
625  bool assigned = false;
626  std::vector<int> del;
627 
628  DETPROBDATA* detprobdata = this->getDetprobdata();
629 
630  /* set vars to linking, if they can be found in more than one block;
631  * set vars to block if they can be found in only one block */
632  for( size_t i = 0; i < openvars.size(); ++ i )
633  {
634  blocksOfOpenvar.clear();
635  var = openvars.at(i);
636  assert( var >= 0 && var < nvars );
637  for( int b = 0; b < nblocks; ++ b )
638  {
639  found = false;
640  for( int c = 0; c < getNConssForBlock( b ) && ! found; ++ c )
641  {
642  cons = conssforblocks[b][c];
643  for( int v = 0; v < detprobdata->getNVarsForCons( cons ) && ! found; ++ v )
644  {
645  if( detprobdata->getVarsForCons( cons )[v] == var )
646  {
647  blocksOfOpenvar.push_back( b );
648  found = true;
649  }
650  }
651  }
652  }
653  if( blocksOfOpenvar.size() == 1 )
654  {
655  setVarToBlock( var, blocksOfOpenvar.at(0) );
656  del.push_back(var);
657  assigned = true;
658  }
659  else if( blocksOfOpenvar.size() > 1 )
660  {
661  setVarToLinking(var);
662  del.push_back( var );
663  assigned = true;
664  }
665  }
666 
667  /* remove the stored vars from open vars list */
668  if( assigned )
669  {
670  for(auto v : del)
671  deleteOpenvar(v);
672 
673  sort();
674  }
675 
676  return assigned;
677 }
678 
679 
681  )
682 {
683  for( auto cons : openconss )
684  {
685  setConsToMaster(cons);
686  isconsopen[cons] = false;
687  }
688  openconss.clear();
689 }
690 
691 
692 void PARTIALDECOMP::assignOpenPartialHittingConsToMaster(
693  )
694 {
695  int cons;
696  int var;
697  std::vector<int> blocksOfBlockvars; /* blocks with blockvars which can be found in the cons */
698  std::vector<int> blocksOfOpenvar; /* blocks in which the open var can be found */
699  bool master;
700  bool hitsOpenVar;
701  std::vector<bool> isblockhit;
702  std::vector<int> del;
703 
704  DETPROBDATA* detprobdata = this->getDetprobdata();
705 
706  /* set openconss with more than two blockvars to master */
707  for( size_t c = 0; c < openconss.size(); ++ c )
708  {
709  isblockhit= std::vector<bool>(getNBlocks(), false );
710  blocksOfBlockvars.clear();
711  master = false;
712  hitsOpenVar = false;
713  cons = openconss[c];
714 
715  for( int v = 0; v < detprobdata->getNVarsForCons( cons ) && ! master; ++ v )
716  {
717  var = detprobdata->getVarsForCons( cons )[v];
718 
719  if( isVarOpenvar( var ) )
720  {
721  hitsOpenVar = true;
722  continue;
723  }
724 
725  if( isVarMastervar( var ) )
726  {
727  master = true;
728  setConsToMaster( cons );
729  del.push_back(cons);
730  continue;
731  }
732 
733  for( int b = 0; b < nblocks; ++ b )
734  {
735  if( isblockhit[b] )
736  continue;
737 
738  if( isVarBlockvarOfBlock( var, b ) )
739  {
740  blocksOfBlockvars.push_back( b );
741  isblockhit[b] = true;
742  break;
743  }
744  }
745  }
746  if( blocksOfBlockvars.size() == 1 && hitsOpenVar )
747  {
748  setConsToMaster( cons );
749  del.push_back(cons);
750  }
751  }
752 
753  /* remove assigned conss from list of open conss */
754  for(auto c : del)
755  deleteOpencons(c);
756  sort();
757 }
758 
759 
760 void PARTIALDECOMP::assignOpenPartialHittingToMaster(
761  )
762 {
763  assignOpenPartialHittingConsToMaster( );
764  assignOpenPartialHittingVarsToMaster( );
765 }
766 
767 
768 void PARTIALDECOMP::assignOpenPartialHittingVarsToMaster(
769  )
770 {
771  int cons;
772  int var;
773  std::vector<int> blocksOfBlockvars; /* blocks with blockvars which can be found in the cons */
774  std::vector<int> blocksOfOpenvar; /* blocks in which the open var can be found */
775  bool hitsOpenCons;
776  std::vector<bool> isblockhit;
777  SCIP_Bool benders;
778  std::vector<int> del;
779 
780  DETPROBDATA* detprobdata = this->getDetprobdata();
781 
782  SCIPgetBoolParam(scip, "detection/benders/enabled", &benders);
783 
784  /* set open var to linking if it can be found in one block and open constraint */
785  for( size_t i = 0; i < openvars.size(); ++ i )
786  {
787  isblockhit= std::vector<bool>(getNBlocks(), false );
788  blocksOfOpenvar.clear();
789  var = openvars[i];
790  hitsOpenCons = false;
791 
792  for( int c = 0; c < detprobdata->getNConssForVar( var ); ++ c )
793  {
794  cons = detprobdata->getConssForVar( var )[c];
795 
796  if( benders && isConsMastercons( cons ) )
797  {
798  continue;
799  }
800 
801  if( isConsOpencons( cons ) )
802  {
803  hitsOpenCons = true;
804  continue;
805  }
806  for( int b = 0; b < nblocks; ++ b )
807  {
808  if ( isblockhit[b] )
809  continue;
810 
811  if( isConsBlockconsOfBlock( cons, b ) )
812  {
813  blocksOfOpenvar.push_back( b );
814  isblockhit[b] = true;
815  break;
816  }
817  }
818  }
819 
820  if( blocksOfOpenvar.size() == 1 && hitsOpenCons )
821  {
822  setVarToLinking(var);
823  del.push_back( var );
824  }
825  }
826 
827  /* revome assigned vars from list of open vars */
828  for(auto v : del)
829  deleteOpenvar(v);
830 
831  sort();
832 }
833 
834 
836  SCIP_HASHMAP* constoblock,
837  int additionalNBlocks
838 )
839 {
840  int oldNBlocks = nblocks;
841  int consblock;
842  int cons;
843  std::vector<int> del;
844 
845  assert( additionalNBlocks >= 0 );
846 
847  for( int b = 0; b < additionalNBlocks; ++ b )
848  addBlock();
849 
850  for( int i = 0; i < getNOpenconss(); ++ i )
851  {
852  cons = openconss[i];
853 
854  if( ! SCIPhashmapExists( constoblock, (void*) (size_t) cons ) )
855  continue;
856  consblock = oldNBlocks + ( (int) (size_t) SCIPhashmapGetImage( constoblock, (void*) (size_t) cons ) - 1 );
857  assert( consblock >= oldNBlocks && consblock <= nblocks );
858  if( consblock == nblocks )
859  {
860  setConsToMaster( cons );
861  del.push_back(cons);
862  }
863  else
864  {
865  setConsToBlock( cons, consblock );
866  del.push_back(cons);
867  }
868  }
869 
870  /* remove assigned conss from list of open conss */
871  for(auto c : del)
872  deleteOpencons(c);
873 
874  deleteEmptyBlocks(false);
875  sort();
876  assert( checkConsistency( ) );
877  return SCIP_OKAY;
878 }
879 
880 
882  std::vector<int> constoblock,
883  int additionalNBlocks
884  )
885 {
886  int oldNBlocks = nblocks;
887  int consblock;
888  int cons;
889  std::vector<int> del;
890 
891  assert( additionalNBlocks >= 0 );
892 
893  for( int b = 0; b < additionalNBlocks; ++ b )
894  addBlock();
895 
896  for( int i = 0; i < getNOpenconss(); ++ i )
897  {
898  cons = openconss[i];
899 
900  if( constoblock[cons] == - 1 )
901  continue;
902 
903  consblock = oldNBlocks + ( constoblock[cons] - 1 );
904  assert( consblock >= oldNBlocks && consblock <= nblocks );
905  if( consblock == nblocks )
906  {
907  setConsToMaster( cons );
908  del.push_back(cons);
909  }
910  else
911  {
912  setConsToBlock( cons, consblock );
913  del.push_back(cons);
914  }
915  }
916 
917  /* remove assigned conss from list of open conss */
918  for(auto c : del)
919  deleteOpencons(c);
920 
921  deleteEmptyBlocks(false);
922  sort();
923  assert( checkConsistency( ) );
924  return SCIP_OKAY;
925 }
926 
927 
929 {
930  /* tools to check if the openvars can still be found in a constraint yet */
931  std::vector<int> varinblocks(nvars, -1); /* stores, in which block the variable can be found */
932 
933  /* tools to update openvars */
934  std::vector<int> oldOpenconss;
935  std::vector<int> openvarsToDelete;
936  gcg::DETPROBDATA* detprobdata = getDetprobdata();
937 
938  if( getNLinkingvars() != 0 )
939  {
940  complete();
941  return;
942  }
943 
944  if ( !detprobdata->isConssAdjInitialized() )
945  detprobdata->createConssAdjacency();
946 
947  std::vector<bool> isConsOpen(nconss, false);
948  std::vector<bool> isConsVisited(nconss, false);
949 
950  std::vector<std::vector<int>> conssfornewblocks;
951  std::vector<std::vector<int>> varsfornewblocks;
952 
953  int newblocks;
954  int largestcomponent;
955  int sizelargestcomponent;
956 
957  newblocks = 0;
958  largestcomponent = -1;
959  sizelargestcomponent = 0;
960 
961  std::queue<int> helpqueue;
962  std::vector<int> neighborConss;
963 
964  assert( (int) conssforblocks.size() == getNBlocks() );
965  assert( (int)varsforblocks.size() == getNBlocks() );
966  assert( (int)stairlinkingvars.size() == getNBlocks() );
967 
968  if( getNBlocks() < 0 )
969  setNBlocks(0);
970 
971  /* do breadth first search to find connected conss */
972  auto constoconsider = getOpenconssVec();
973  while( !constoconsider.empty() )
974  {
975  std::vector<int> newconss;
976  std::vector<int> newvars;
977 
978  assert( helpqueue.empty() );
979  helpqueue.push(constoconsider[0]);
980  neighborConss.clear();
981  neighborConss.push_back(constoconsider[0]);
982  isConsVisited[constoconsider[0]] = true;
983 
984  while( !helpqueue.empty() )
985  {
986  int nodeCons = helpqueue.front();
987  assert( isConsOpencons(nodeCons) );
988  helpqueue.pop();
989  for( int cons : detprobdata->getConssForCons(nodeCons) )
990  {
991  if( isConsVisited[cons] || isConsMastercons(cons) || !isConsOpen[cons] )
992  continue;
993 
994  assert( isConsOpencons(cons) );
995  isConsVisited[cons] = true;
996  neighborConss.push_back(cons);
997  helpqueue.push(cons);
998  }
999  }
1000 
1001  /* assign found conss and vars to a new block */
1002  ++newblocks;
1003  for( int cons : neighborConss )
1004  {
1005  std::vector<int>::iterator consiter = std::lower_bound(constoconsider.begin(), constoconsider.end(), cons);
1006  assert(consiter != constoconsider.end() );
1007  constoconsider.erase(consiter);
1008  assert( isConsOpencons(cons) );
1009  newconss.push_back(cons);
1010 
1011  for( int var : detprobdata->getVarsForCons(cons) )
1012  {
1013  if( isVarLinkingvar(var) || varinblocks[var] != -1 )
1014  continue;
1015 
1016  assert( !isVarMastervar(var) );
1017  newvars.push_back(var);
1018  varinblocks[var] = newblocks;
1019  }
1020  }
1021  conssfornewblocks.push_back(newconss);
1022  varsfornewblocks.push_back(newvars);
1023  }
1024 
1025  for( int i = 0; i < newblocks; ++i )
1026  {
1027  if( (int)conssfornewblocks[i].size() > sizelargestcomponent )
1028  {
1029  sizelargestcomponent = (int)conssfornewblocks[i].size();
1030  largestcomponent = i;
1031  }
1032  }
1033 
1034  if( newblocks > 1 )
1035  {
1036  int oldnblocks = getNBlocks();;
1037  bool largestdone = false;
1038 
1039  setNBlocks(newblocks - 1 + getNBlocks());
1040 
1041  for( int i = 0; i < newblocks; ++i)
1042  {
1043  if( i == largestcomponent )
1044  {
1045  largestdone = true;
1046  continue;
1047  }
1048  for( int c = 0; c < (int) conssfornewblocks[i].size() ; ++c)
1049  {
1050  fixConsToBlock(conssfornewblocks[i][c], oldnblocks + i - (largestdone ? 1 : 0) );
1051  }
1052 
1053  for( int v = 0; v < (int) varsfornewblocks[i].size() ; ++v )
1054  {
1055  fixVarToBlock(varsfornewblocks[i][v], oldnblocks + i - (largestdone ? 1 : 0) );
1056  }
1057  }
1058  prepare();
1059  }
1060 
1061  assert( checkConsistency() );
1062 }
1063 
1064 
1065 SCIP_Bool PARTIALDECOMP::isAgginfoTooExpensive()
1066 {
1067 
1068  int limitfornconss;
1069  int limitfornvars;
1070 
1071  if( isagginfoalreadytoexpensive )
1072  return TRUE;
1073 
1074  SCIPgetIntParam(scip, "detection/aggregation/limitnconssperblock", &limitfornconss);
1075  SCIPgetIntParam(scip, "detection/aggregation/limitnvarsperblock", &limitfornvars);
1076 
1077  /* check if calculating aggregation information is too expensive */
1078  for( int b1 = 0; b1 < getNBlocks() ; ++b1 )
1079  {
1080  for( int b2 = b1+1; b2 < getNBlocks(); ++b2 )
1081  {
1082  if( getNVarsForBlock(b1) != getNVarsForBlock(b2) )
1083  continue;
1084 
1085  if( getNConssForBlock(b1) != getNConssForBlock(b2) )
1086  continue;
1087 
1088  SCIPdebugMessage("Checking if agg info is too expensive for blocks %d and %d, nconss: %d, nvars: %d . \n", b1, b2, getNConssForBlock(b2), getNVarsForBlock(b2) );
1089  if( getNConssForBlock(b2) >= limitfornconss || getNVarsForBlock(b2) >= limitfornvars )
1090  {
1091  SCIPdebugMessage("Calculating agg info is too expensive, nconss: %d, nvars: %d . \n", getNConssForBlock(b2), getNVarsForBlock(b2) );
1092  isagginfoalreadytoexpensive = true;
1093  return TRUE;
1094  }
1095  }
1096 
1097  }
1098 
1099  /* check if there are too many master coeffs */
1100  SCIPdebugMessage("Calculated: agg info is NOT too expensive.\n");
1101  return FALSE;
1102 }
1103 
1104 
1106  bool ignoreDetectionLimits
1107  )
1108 {
1109 #ifdef WITH_BLISS
1110  SCIP_Bool tooexpensive;
1111  SCIP_Bool usebliss;
1112  int searchnodelimit;
1113  int generatorlimit;
1114 #endif
1115  SCIP_Bool aggisnotactive;
1116  SCIP_Bool discretization;
1117  SCIP_Bool aggregation;
1118 
1119  int nreps = 1;
1120 
1121  if( aggInfoCalculated() )
1122  return;
1123 
1124  if( !isComplete() )
1125  return;
1126 
1127 #ifdef WITH_BLISS
1128  if(
1129 #ifdef BLISS_PATCH_PRESENT
1130  !ignoreDetectionLimits &&
1131 #endif
1132  isAgginfoTooExpensive()
1133  )
1134  tooexpensive = TRUE;
1135  else
1136  tooexpensive = FALSE;
1137  SCIPgetBoolParam(scip, "relaxing/gcg/bliss/enabled", &usebliss);
1138  SCIPgetIntParam(scip, "relaxing/gcg/bliss/searchnodelimit", &searchnodelimit);
1139  SCIPgetIntParam(scip, "relaxing/gcg/bliss/generatorlimit", &generatorlimit);
1140 #endif
1141 
1142  SCIPgetBoolParam(scip, "relaxing/gcg/aggregation", &aggregation);
1143  SCIPgetBoolParam(scip, "relaxing/gcg/discretization", &discretization);
1144 
1145  if( discretization && aggregation )
1146  aggisnotactive = FALSE;
1147  else
1148  aggisnotactive = TRUE;
1149 
1150  std::vector<std::vector<int>> identblocksforblock( getNBlocks(), std::vector<int>(0) );
1151 
1152  blockstorep = std::vector<int>(getNBlocks(), -1);
1153 
1154  for( int b1 = 0; b1 < getNBlocks() ; ++b1 )
1155  {
1156  std::vector<int> currrep = std::vector<int>(0);
1157  std::vector< std::vector<int> > currrepvarmapforthisrep =std::vector<std::vector<int>>(0);
1158  std::vector<int> identityvec = std::vector<int>(0);
1159 
1160 
1161  if( !identblocksforblock[b1].empty() )
1162  continue;
1163 
1164  for( int i = 0; i < getNVarsForBlock(b1); ++i )
1165  identityvec.push_back(i);
1166 
1167  currrep.push_back(b1);
1168  currrepvarmapforthisrep.push_back(identityvec);
1169 
1170 
1171  for( int b2 = b1+1; b2 < getNBlocks(); ++b2 )
1172  {
1173  SCIP_Bool identical;
1174  SCIP_Bool notidentical;
1175  std::vector<int> varmap;
1176  SCIP_HASHMAP* varmap2;
1177 
1178  notidentical = FALSE;
1179  identical = FALSE;
1180 
1181  if( !identblocksforblock[b2].empty() )
1182  continue;
1183 
1184  if( aggisnotactive )
1185  continue;
1186 
1187 
1188  SCIP_CALL_ABORT( SCIPhashmapCreate( &varmap2,
1189  SCIPblkmem(scip),
1190  5 * getNVarsForBlock(b1)+1) ); /* +1 to deal with empty subproblems */
1191 
1192  SCIPdebugMessage("Check identity for block %d and block %d!\n", b1, b2);
1193 
1194  checkIdenticalBlocksTrivial( b1, b2, &notidentical);
1195 
1196  if( !notidentical )
1197  {
1198  checkIdenticalBlocksBrute( b1, b2, varmap, varmap2, &identical);
1199 
1200 #ifdef WITH_BLISS
1201  if( usebliss && !tooexpensive && !identical )
1202  checkIdenticalBlocksBliss(b1, b2, varmap, varmap2, &identical,
1203  searchnodelimit >= 0 ? searchnodelimit : 0u, generatorlimit >= 0 ? generatorlimit : 0u);
1204 #endif
1205  }
1206  else
1207  identical = FALSE;
1208 
1209  if( identical )
1210  {
1211  SCIPdebugMessage("Block %d is identical to block %d!\n", b1, b2);
1212  identblocksforblock[b1].push_back(b2);
1213  identblocksforblock[b2].push_back(b1);
1214  currrep.push_back(b2);
1215  /* handle varmap */
1216  currrepvarmapforthisrep.push_back(varmap);
1217 
1218  }
1219  else
1220  {
1221  SCIPdebugMessage("Block %d is not identical to block %d!\n", b1, b2);
1222  }
1223  SCIPhashmapFree(&varmap2);
1224  }
1225 
1226  reptoblocks.push_back( currrep );
1227  pidtopidvarmaptofirst.push_back(currrepvarmapforthisrep);
1228  for( size_t i = 0; i < currrep.size(); ++i )
1229  blockstorep[currrep[i]] = nreps-1;
1230  ++nreps;
1231 
1232  }
1233  nrepblocks = nreps-1;
1234 }
1235 
1236 
1237 void PARTIALDECOMP::calcHashvalue()
1238 {
1239  if( !hvoutdated )
1240  return;
1241 
1242  std::vector<std::pair<int, int>> blockorder = std::vector < std::pair<int, int> > ( 0 );
1243  unsigned long hashval = 0;
1244  unsigned long borderval = 0;
1245 
1246  sort();
1247 
1248  /* find sorting for blocks (non decreasing according smallest row index) */
1249  for( int i = 0; i < this->nblocks; ++ i )
1250  {
1251  if( !this->conssforblocks[i].empty() )
1252  blockorder.emplace_back( i, this->conssforblocks[i][0] );
1253  else
1254  {
1255  assert( this->varsforblocks[i].size() > 0 );
1256  blockorder.emplace_back( i, this->getNConss() + this->varsforblocks[i][0] );
1257  }
1258  }
1259 
1260  std::sort( blockorder.begin(), blockorder.end(), compare_blocks );
1261 
1262  for( int i = 0; i < nblocks; ++ i )
1263  {
1264  unsigned long blockval = 0;
1265  int blockid = blockorder[i].first;
1266 
1267  for( size_t tau = 0; tau < conssforblocks[blockid].size(); ++ tau )
1268  {
1269  blockval += ( 2 * conssforblocks[blockid][tau] + 1 ) * (unsigned long) pow( 2, tau % 16 );
1270  }
1271 
1272  hashval += primes[i % ( nprimes - 1 )] * blockval;
1273  }
1274 
1275  for( size_t tau = 0; tau < masterconss.size(); ++ tau )
1276  {
1277  borderval += ( 2 * masterconss[tau] + 1 ) * (unsigned long) pow( 2, tau % 16 );
1278  }
1279 
1280  hashval += primes[nblocks % nprimes] * borderval;
1281  hashval += primes[( nblocks + 1 ) % nprimes] * openvars.size();
1282 
1283  hashvalue = hashval;
1284  hvoutdated = false;
1285 }
1286 
1287 
1288 void PARTIALDECOMP::calcNCoeffsForBlocks()
1289 {
1290  if( calculatedncoeffsforblock )
1291  return;
1292 
1293  ncoeffsforblock = std::vector<int>(getNBlocks(), 0);
1294  int counter;
1295  DETPROBDATA* detprobdata = this->getDetprobdata();
1296 
1297  for( int b = 0; b < getNBlocks(); ++b )
1298  {
1299  counter = 0;
1300  for( int blco = 0; blco < getNConssForBlock(b); ++blco )
1301  {
1302  int consid = getConssForBlock(b)[blco];
1303  for( int cva = 0; cva < detprobdata->getNVarsForCons(consid) ;++cva )
1304  if( isVarBlockvarOfBlock(detprobdata->getVarsForCons(consid)[cva], b ) )
1305  ++counter;
1306  }
1307  ncoeffsforblock[b] = counter;
1308  }
1309 
1310  counter = 0;
1311  for( int mco = 0; mco < getNMasterconss(); ++mco )
1312  {
1313  int consid = getMasterconss()[mco];
1314  counter += detprobdata->getNVarsForCons(consid);
1315  }
1316  ncoeffsformaster = counter;
1317 
1318  calculatedncoeffsforblock = TRUE;
1319 }
1320 
1321 
1323  )
1324 {
1325  assert( getNTotalStairlinkingvars() == 0 );
1326 
1327  /* data structure containing pairs of varindices and blocknumbers */
1328  std::vector< std::pair< int, std::vector< int > > > blocksOfVars = findLinkingVarsPotentiallyStairlinking( );
1329 
1330  /* if there are no vars that are potentially stairlinking, return without further calculations */
1331  if( blocksOfVars.size() == 0 )
1332  return;
1333 
1334  GraphGCG* g = new GraphGCG( getNBlocks(), true );
1335 
1336  /* create block graph: every block is represented by a node and two nodes are adjacent if there exists a
1337  * var that potentially links these blocks, the edge weight is the number of such variables */
1338  for( int i = 0; i < (int) blocksOfVars.size(); ++i )
1339  {
1340  assert( blocksOfVars[i].second.size() == 2 );
1341  int v = blocksOfVars[i].second[0];
1342  int w = blocksOfVars[i].second[1];
1343 
1344  if ( g->isEdge( v, w ) )
1345  {
1346  g->setEdge( v, w, g->getEdgeWeight( v, w ) + 1 );
1347  }
1348  else
1349  {
1350  g->setEdge( v, w, 1 );
1351  }
1352  }
1353 
1354  bool isstaircase = true; /* maintains information whether staircase structure is still possible */
1355  std::vector< int > sources( 0 ); /* all nodes with degree one */
1356  std::vector< bool > marks( getNBlocks() ); /* a node is marked if its degree is zero or it is reachable from a source */
1357 
1358  /* firstly, check whether every node has an degree of at most 2 */
1359  for( int b = 0; b < getNBlocks(); ++b )
1360  {
1361  if( g->getNNeighbors( b ) > 2 )
1362  {
1363  isstaircase = false;
1364  break;
1365  }
1366  else if( g->getNNeighbors( b ) == 1 )
1367  {
1368  sources.push_back( b );
1369  }
1370  else if ( g->getNNeighbors( b ) == 0 )
1371  {
1372  marks[b] = true;
1373  }
1374  }
1375 
1376  /* secondly, check whether there exists a circle in the graph by moving along all paths starting from a source */
1377  for( int s = 0; s < (int) sources.size() && isstaircase; ++s )
1378  {
1379  int curBlock = sources[s];
1380  if( marks[curBlock] )
1381  continue;
1382 
1383  marks[curBlock] = true;
1384 
1385  /* check whether there is an unmarked neighbor
1386  * if there is none, a circle is detected */
1387  do
1388  {
1389  std::vector< int > neighbors = g->getNeighbors( curBlock );
1390  if( !marks[neighbors[0]] )
1391  {
1392  marks[neighbors[0]] = true;
1393  curBlock = neighbors[0];
1394  }
1395  else if ( !marks[neighbors[1]] )
1396  {
1397  marks[neighbors[1]] = true;
1398  curBlock = neighbors[1];
1399  }
1400  else
1401  {
1402  isstaircase = false;
1403  break;
1404  }
1405  }
1406  while( g->getNNeighbors( curBlock ) != 1 );
1407  }
1408 
1409  /* thirdly, check whether all nodes with neighbors are reachable from a source,
1410  * since there is a circle if this is not the case */
1411  for( int b = 0; b < getNBlocks() && isstaircase; ++b )
1412  {
1413  if( !marks[b] )
1414  {
1415  isstaircase = false;
1416  break;
1417  }
1418  }
1419 
1420  if( isstaircase )
1421  {
1422  changeBlockOrderStaircase( g );
1423  }
1424  else
1425  {
1426  return;
1427  }
1428 
1430 
1431  assert( checkConsistency( ) );
1432 }
1433 
1434 
1435 void PARTIALDECOMP::changeBlockOrderStaircase(
1436  GraphGCG* g
1437  )
1438 {
1439  int blockcounter = 0; /* counts current new block to assign an old one to */
1440  std::vector< int > blockmapping( getNBlocks() ); /* stores new block order */
1441  for( int b = 0; b < getNBlocks(); ++b )
1442  blockmapping[b] = -1;
1443 
1444  for( int b = 0; b < getNBlocks(); ++b )
1445  {
1446  if( g->getNNeighbors( b ) == 0 )
1447  {
1448  /* if block does not have a neighbor, just assign it to current blockindex */
1449  assert( blockmapping[b] == -1 );
1450  blockmapping[b] = blockcounter;
1451  ++blockcounter;
1452  }
1453  else if( blockmapping[b] == -1 && g->getNNeighbors( b ) == 1 )
1454  {
1455  /* if the block is the source of an yet unconsidered path, assign whole path to ascending new block ids */
1456  int curBlock = b;
1457  blockmapping[b] = blockcounter;
1458  ++blockcounter;
1459 
1460  do
1461  {
1462  std::vector< int > neighbors = g->getNeighbors( curBlock );
1463 
1464  if( blockmapping[neighbors[0]] == -1 )
1465  {
1466  blockmapping[neighbors[0]] = blockcounter;
1467  curBlock = neighbors[0];
1468  }
1469  else if ( blockmapping[neighbors[1]] == -1 )
1470  {
1471  blockmapping[neighbors[1]] = blockcounter;
1472  curBlock = neighbors[1];
1473  }
1474  else
1475  {
1476  assert( false );
1477  }
1478  ++blockcounter;
1479  }
1480  while( g->getNNeighbors( curBlock ) != 1 );
1481  }
1482  }
1483 
1484  changeBlockOrder( blockmapping );
1485 }
1486 
1487 
1488 void PARTIALDECOMP::changeBlockOrder(
1489  std::vector<int> oldToNewBlockIndex
1490  )
1491 {
1492  assert((int ) oldToNewBlockIndex.size() == getNBlocks() );
1493  assert( getNTotalStairlinkingvars() == 0 );
1494 
1495  std::vector< std::vector< int > > newconssforblocks( getNBlocks() );
1496  std::vector< std::vector< int > > newvarsforblocks( getNBlocks() );
1497 
1498  for( int b = 0; b < getNBlocks(); ++b )
1499  {
1500  assert( 0 <= oldToNewBlockIndex[b] && oldToNewBlockIndex[b] < getNBlocks() );
1501 
1502  newconssforblocks[oldToNewBlockIndex[b]] = conssforblocks[b];
1503  newvarsforblocks[oldToNewBlockIndex[b]] = varsforblocks[b];
1504  }
1505 
1506  conssforblocks = newconssforblocks;
1507  varsforblocks = newvarsforblocks;
1508 }
1509 
1510 
1512 {
1513  for( size_t i = 0; i < openconss.size(); ++ i )
1514  {
1515  bool consfound = false;
1516  for( size_t k = 0; k < masterconss.size(); ++ k )
1517  {
1518  if( openconss[i] == masterconss[k] )
1519  {
1520  consfound = true;
1521  break;
1522  }
1523  }
1524  for( int b = 0; b < nblocks && ! consfound; ++ b )
1525  {
1526  for( size_t k = 0; k < conssforblocks[b].size(); ++ k )
1527  {
1528  if( openconss[i] == conssforblocks[b][k] )
1529  {
1530  consfound = true;
1531  break;
1532  }
1533  }
1534  }
1535  if( ! consfound )
1536  {
1537  return false;
1538  }
1539  }
1540  openconss.clear();
1541  isconsopen = std::vector<bool>(nconss, false);
1542  return true;
1543 }
1544 
1545 
1547  )
1548 {
1549  std::vector<bool> openvarsBool( nvars, true );
1550  std::vector<int> stairlinkingvarsvec( 0 );
1551  std::vector<int>::const_iterator varIter = linkingvars.begin();
1552  std::vector<int>::const_iterator varIterEnd = linkingvars.end();
1553 
1554  int value;
1555 
1556  /* check if nblocks is set appropriately */
1557  if( nblocks != (int) conssforblocks.size() )
1558  {
1559  SCIPwarningMessage(scip, "In (partialdec %d) nblocks %d and size of conssforblocks %ld are not identical! \n" , id, nblocks, conssforblocks.size() );
1560  assert( false );
1561  return false;
1562  }
1563 
1564  if( nblocks != (int) varsforblocks.size() )
1565  {
1566  SCIPwarningMessage(scip, "In (partialdec %d) nblocks %d and size of varsforblocks %ld are not identical! \n" , id, nblocks, varsforblocks.size() );
1567  assert( false );
1568  return false;
1569  }
1570 
1571  /* check for empty (row- and col-wise) blocks */
1572  for( int b = 0; b < nblocks; ++ b )
1573  {
1574  if( conssforblocks[b].empty() && varsforblocks[b].empty() )
1575  {
1576  SCIPwarningMessage(scip, "In (partialdec %d) block %d is empty! \n" , id, b );
1577  assert( false );
1578  return false;
1579  }
1580  }
1581 
1582  /* check variables (every variable is assigned at most once) */
1583  for( ; varIter != varIterEnd; ++ varIter )
1584  {
1585  if( ! openvarsBool[ * varIter] )
1586  {
1587  SCIPwarningMessage(scip, "In (partialdec %d) linking variable with index %d is already assigned! \n" , id, * varIter );
1588 
1589  assert( false );
1590  return false;
1591  }
1592  openvarsBool[ * varIter] = false;
1593  }
1594 
1595  for( int b = 0; b < nblocks; ++ b )
1596  {
1597  varIterEnd = varsforblocks[b].end();
1598  for( varIter = varsforblocks[b].begin(); varIter != varIterEnd; ++ varIter )
1599  {
1600  if( ! openvarsBool[ * varIter] )
1601  {
1602  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is already assigned but also assigned to block %d! \n" , id, * varIter, b );
1603  assert( false );
1604  return false;
1605  }
1606  openvarsBool[ * varIter] = false;
1607  }
1608  }
1609 
1610  varIterEnd = mastervars.end();
1611  for( varIter = mastervars.begin(); varIter != varIterEnd; ++ varIter )
1612  {
1613  if( ! openvarsBool[ * varIter] )
1614  {
1615  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is already assigned but also assigned to master! \n" , id, * varIter);
1616  assert( false );
1617  return false;
1618  }
1619  openvarsBool[ * varIter] = false;
1620  }
1621 
1622  for( int b = 0; b < nblocks; ++ b )
1623  {
1624  varIter = stairlinkingvars[b].begin();
1625  varIterEnd = stairlinkingvars[b].end();
1626  for( ; varIter != varIterEnd; ++ varIter )
1627  {
1628  if( ! openvarsBool[ * varIter] )
1629  {
1630  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is already assigned but also assigned to stairlinking block %d! \n" , id, * varIter, b );
1631  assert( false );
1632  return false;
1633  }
1634  openvarsBool[ * varIter] = false;
1635  }
1636  if( ( b == nblocks - 1 ) && ( (int) stairlinkingvars[b].size() != 0 ) )
1637  {
1638  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is is as assigned as stairlinking var of last block! \n" , id, * varIter );
1639  assert( false );
1640  return false;
1641  }
1642  }
1643 
1644  /* check if all not assigned variables are open vars */
1645  for( int v = 0; v < nvars; ++ v )
1646  {
1647  if( openvarsBool[v] && !isVarOpenvar(v) )
1648  {
1649  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is not assigned and not an open var! \n" , id, v );
1650  assert( false );
1651  return false;
1652  }
1653  }
1654 
1655  /* check if all open vars are not assigned */
1656  for( size_t i = 0; i < openvars.size(); ++ i )
1657  {
1658  if( !openvarsBool[openvars[i]] )
1659  {
1660  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is an open var but assigned! \n" , id, openvars[i] );
1661  assert( false );
1662  return false;
1663  }
1664  }
1665 
1666  for( size_t i = 0; i < openvarsBool.size(); ++ i )
1667  {
1668  if( openvarsBool[i] != isvaropen[i] )
1669  {
1670  SCIPwarningMessage(scip, "In (partialdec %d) variable with index %d is causes asynchronity with isvaropen array ! \n" , id, openvars[i] );
1671  assert( false );
1672  return false;
1673 
1674  }
1675  }
1676 
1677  /* check constraints (every constraint is assigned at most once) */
1678  std::vector<bool> openconssBool( nconss, true );
1679  std::vector<int> openconssVec( 0 );
1680  std::vector<int>::const_iterator consIter = masterconss.begin();
1681  std::vector<int>::const_iterator consIterEnd = masterconss.end();
1682 
1683  for( ; consIter != consIterEnd; ++ consIter )
1684  {
1685  if( ! openconssBool[ * consIter] )
1686  {
1687  SCIPwarningMessage(scip, "In (partialdec %d) constraint with index %d is at least two times assigned as a master constraint! \n" , id, * consIter );
1688  assert( false );
1689  return false;
1690  }
1691  openconssBool[ * consIter] = false;
1692  }
1693 
1694  for( int b = 0; b < nblocks; ++ b )
1695  {
1696  consIterEnd = conssforblocks[b].end();
1697  for( consIter = conssforblocks[b].begin(); consIter != consIterEnd; ++ consIter )
1698  {
1699  if( ! openconssBool[ * consIter] )
1700  {
1701  SCIPwarningMessage(scip, "In (partialdec %d) constraint with index %d is already assigned but also assigned to block %d! \n" , id, * consIter, b );
1702  assert( false );
1703  return false;
1704  }
1705  openconssBool[ * consIter] = false;
1706  }
1707  }
1708 
1709  /* check if all not assigned constraints are open cons */
1710  for( int v = 0; v < nconss; ++ v )
1711  {
1712  if( openconssBool[v] && !isConsOpencons(v) )
1713  {
1714  SCIPwarningMessage(scip, "In (partialdec %d) constraint with index %d is not assigned and not an open cons! \n" , id, v );
1715  assert( false );
1716  return false;
1717  }
1718  }
1719 
1720  /* check if all open conss are not assigned */
1721  for( size_t i = 0; i < openconss.size(); ++ i )
1722  {
1723  if( !openconssBool[openconss[i]] )
1724  {
1725  SCIPwarningMessage(scip, "In (partialdec %d) constraint with index %d is an open cons but assigned! \n" , id, openconss[i] );
1726  assert( false );
1727  return false;
1728  }
1729  }
1730 
1731  /* check if the partialdec is sorted */
1732  for( int b = 0; b < nblocks; ++ b )
1733  {
1734  value = - 1;
1735  for( int v = 0; v < getNVarsForBlock( b ); ++ v )
1736  {
1737  if( value >= getVarsForBlock(b)[v] )
1738  {
1739  SCIPwarningMessage(scip, "In (partialdec %d) variables of block %d are not sorted! \n" , id, b );
1740  assert( false );
1741  return false;
1742  }
1743  value = getVarsForBlock( b )[v];
1744  }
1745  }
1746  for( int b = 0; b < nblocks; ++ b )
1747  {
1748  value = - 1;
1749  for( int v = 0; v < getNStairlinkingvars( b ); ++ v )
1750  {
1751  if( value >= getStairlinkingvars(b)[v] )
1752  {
1753  SCIPwarningMessage(scip, "In (partialdec %d) stairlinking variables of block %d are not sorted! \n" , id, b );
1754  assert( false );
1755  return false;
1756  }
1757  value = getStairlinkingvars( b )[v];
1758  }
1759  }
1760  value = - 1;
1761  for( int v = 0; v < getNLinkingvars(); ++ v )
1762  {
1763  if( value >= getLinkingvars()[v] )
1764  {
1765  SCIPwarningMessage(scip, "In (partialdec %d) linking variables are not sorted! \n" , id );
1766  assert( false );
1767  return false;
1768  }
1769  value = getLinkingvars()[v];
1770  }
1771  value = - 1;
1772  for( int v = 0; v < getNMastervars(); ++ v )
1773  {
1774  if( value >= getMastervars()[v] )
1775  {
1776  SCIPwarningMessage(scip, "In (partialdec %d) master variables are not sorted! \n" , id );
1777  assert( false );
1778  return false;
1779  }
1780  value = getMastervars()[v];
1781  }
1782  for( int b = 0; b < nblocks; ++ b )
1783  {
1784  value = - 1;
1785  for( int v = 0; v < getNConssForBlock(b); ++ v )
1786  {
1787  if( value >= getConssForBlock(b)[v] )
1788  {
1789  SCIPwarningMessage(scip, "In (partialdec %d) constraints of block %d are not sorted! \n" , id, b );
1790  assert( false );
1791  return false;
1792  }
1793  value = getConssForBlock(b)[v];
1794  }
1795  }
1796  value = - 1;
1797  for( int v = 0; v < getNMasterconss(); ++ v )
1798  {
1799  if( value >= getMasterconss()[v] )
1800  {
1801  SCIPwarningMessage(scip, "In (partialdec %d) master constraints are not sorted! \n" , id);
1802  assert( false );
1803  return false;
1804  }
1805  value = getMasterconss()[v];
1806  }
1807 
1808  DETPROBDATA* detprobdata = this->getDetprobdata();
1809  /* check if variables hitting a cons are either in the cons's block or border or still open */
1810  for( int b = 0; b < nblocks; ++ b )
1811  {
1812  for( int c = 0; c < getNConssForBlock( b ); ++ c )
1813  {
1814  for( int v = 0; v < detprobdata->getNVarsForCons( getConssForBlock( b )[c] ); ++ v )
1815  {
1816  int varid = detprobdata->getVarsForCons( getConssForBlock( b )[c] )[v];
1817 
1818  if( !(isVarBlockvarOfBlock(varid, b) || isVarLinkingvar(varid) || isVarStairlinkingvarOfBlock(varid, b)
1819  || isVarOpenvar(varid)) )
1820  {
1821  SCIP_Bool partofblock;
1822 
1823  partofblock = FALSE;
1824 
1825  SCIPwarningMessage(scip,
1826  "This should only happen during translation of (partial) decompositions from orginal to transformed problem, and means that translation has failed for this particaluar partial decomposition. Variable %d is not part of block %d or linking or open as constraint %d suggests! \n ", varid, b,
1827  getConssForBlock(b)[c]);
1828 
1829  for( int b2 = 0; b2 < getNBlocks(); ++b2 )
1830  {
1831  if ( isVarBlockvarOfBlock(varid, b2) )
1832  {
1833  partofblock = TRUE;
1834  SCIPwarningMessage(scip,
1835  "instead Variable %d is part of block %d \n ", varid, b2);
1836  break;
1837  }
1838  }
1839 
1840  if( !partofblock )
1841  {
1842  if( isvarmaster[varid] )
1843  SCIPwarningMessage(scip, "instead Variable %d is part of master \n ", varid);
1844  else
1845  SCIPwarningMessage(scip, "in fact Variable %d is completely unassigned \n ", varid);
1846  }
1847  assert(false);
1848  return false;
1849  }
1850  }
1851  }
1852  }
1853 
1854  if( getDetectorchain().size() != getDetectorchainInfo().size() )
1855  {
1856  assert(false);
1857  return false;
1858  }
1859 
1860  if( getNDetectors() != pctvarstoblock.size() || getNDetectors() != pctvarstoborder.size()
1861  || getNDetectors() != pctvarsfromfree.size() || getNDetectors() != pctconsstoblock.size()
1862  || getNDetectors() != pctconsstoborder.size() || getNDetectors() != pctconssfromfree.size() )
1863  {
1864  assert(false);
1865  return false;
1866  }
1867 
1868  return true;
1869 }
1870 
1871 
1872 #ifdef WITH_BLISS
1873 void PARTIALDECOMP::checkIdenticalBlocksBliss(
1874  int b1,
1875  int b2,
1876  std::vector<int>& varmap,
1877  SCIP_HASHMAP* varmap2,
1878  SCIP_Bool* identical,
1879  unsigned int searchnodelimit,
1880  unsigned int generatorlimit
1881  )
1882 {
1883  *identical = FALSE;
1884  SCIP_HASHMAP* consmap;
1885  SCIP_Result result;
1886 
1887  varmap = std::vector<int>(getNVarsForBlock(b1), -1);
1888 
1889  SCIP_CALL_ABORT( SCIPhashmapCreate(&consmap,
1890  SCIPblkmem(scip ),
1891  getNConssForBlock(b1)+1) ); /* +1 to deal with empty subproblems */
1892 
1893 
1894  SCIPdebugMessage("obvious test fails, start building graph \n");
1895 
1896  cmpGraphPair(scip, this, b1, b2, &result, varmap2, consmap, searchnodelimit, generatorlimit);
1897  if( result == SCIP_SUCCESS )
1898  {
1899  *identical = TRUE;
1900  /** TODO translate varmaps */
1901  for( int var2idinblock = 0; var2idinblock < getNVarsForBlock(b2) ; ++var2idinblock )
1902  {
1903  SCIP_VAR* var2;
1904  SCIP_VAR* var1;
1905  int var1idinblock;
1906  int var1id;
1907  auto detprobdata = this->getDetprobdata();
1908 
1909  var2 = detprobdata->getVar(getVarsForBlock(b2)[var2idinblock]);
1910  var1 = (SCIP_VAR*) SCIPhashmapGetImage(varmap2, (void*) var2);
1911  var1id = detprobdata->getIndexForVar(var1);
1912  var1idinblock = getVarProbindexForBlock(var1id, b1);
1913  varmap[var2idinblock] = var1idinblock;
1914  }
1915 
1916  }
1917  else
1918  *identical = FALSE;
1919 
1920  SCIPhashmapFree(&consmap);
1921 
1922  return;
1923 
1924 }
1925 #endif
1926 
1927 
1928 void PARTIALDECOMP::checkIdenticalBlocksBrute(
1929  int b1,
1930  int b2,
1931  std::vector<int>& varmap,
1932  SCIP_HASHMAP* varmap2,
1933  SCIP_Bool* identical
1934  )
1935 {
1936 
1937 
1938  *identical = FALSE;
1939  SCIPdebugMessage("check block %d and block %d for identity...\n", b1, b2);
1940  varmap = std::vector<int>(getNVars(), -1);
1941  DETPROBDATA* detprobdata = this->getDetprobdata();
1942 
1943  /* check variables */
1944  for( int i = 0; i < getNVarsForBlock(b1); ++i )
1945  {
1946  SCIP_VAR* var1;
1947  SCIP_VAR* var2;
1948 
1949  var1 = detprobdata->getVar(getVarsForBlock(b1)[i]);
1950  var2 = detprobdata->getVar(getVarsForBlock(b2)[i]);
1951 
1952  if( !SCIPisEQ(scip, SCIPvarGetObj(var1), SCIPvarGetObj(var2) ) )
1953  {
1954  SCIPdebugMessage("--> obj differs for var %s and var %s!\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
1955  return;
1956  }
1957  if( !SCIPisEQ(scip, SCIPvarGetLbGlobal(var1), SCIPvarGetLbGlobal(var2) ) )
1958  {
1959  SCIPdebugMessage("--> lb differs for var %s and var %s!\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
1960  return;
1961  }
1962  if( !SCIPisEQ(scip, SCIPvarGetUbGlobal(var1), SCIPvarGetUbGlobal(var2) ) )
1963  {
1964  SCIPdebugMessage("--> ub differs for var %s and var %s!\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
1965  return;
1966  }
1967  if( SCIPvarGetType(var1) != SCIPvarGetType(var2) )
1968  {
1969  SCIPdebugMessage("--> type differs for var %s and var %s!\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
1970  return;
1971  }
1972 
1973  for( int mc = 0; mc < getNMasterconss(); ++mc )
1974  {
1975 
1976  if( !SCIPisEQ(scip, detprobdata->getVal(getMasterconss()[mc], getVarsForBlock(b1)[i]), detprobdata->getVal(getMasterconss()[mc], getVarsForBlock(b2)[i]) ))
1977  {
1978  SCIPdebugMessage("--> master coefficients differ for var %s (%f) and var %s (%f) !\n", SCIPvarGetName(
1979  detprobdata->getVar(getVarsForBlock(b1)[i]) ), detprobdata->getVal(getMasterconss()[mc], getVarsForBlock(b1)[i]), SCIPvarGetName(
1980  detprobdata->getVar(getVarsForBlock(b2)[i])), detprobdata->getVal(getMasterconss()[mc], getVarsForBlock(b2)[i]) );
1981  return;
1982  }
1983  }
1984 
1985  /* variables seem to be identical so far */
1986  varmap[getVarsForBlock(b2)[i]] = getVarsForBlock(b1)[i];
1987  }
1988 
1989  for( int i = 0; i < getNConssForBlock(b1); ++i )
1990  {
1991  int cons1id;
1992  int cons2id;
1993  SCIP_CONS* cons1;
1994  SCIP_CONS* cons2;
1995  SCIP_Real* vals1;
1996  SCIP_Real* vals2;
1997  int nvals1;
1998  int nvals2;
1999 
2000  cons1id = getConssForBlock(b1)[i];
2001  cons2id = getConssForBlock(b2)[i];
2002 
2003  cons1 = detprobdata->getCons(cons1id);
2004  cons2 = detprobdata->getCons(cons2id);
2005 
2006  if( detprobdata->getNVarsForCons(cons1id) != detprobdata->getNVarsForCons(cons2id) )
2007  {
2008  SCIPdebugMessage("--> nvars differs for cons %s and cons %s!\n", SCIPconsGetName(cons1), SCIPconsGetName(cons2));
2009  return;
2010  }
2011 
2012  if( !SCIPisEQ(scip, GCGconsGetLhs(scip, cons1), GCGconsGetLhs(scip, cons2) ) )
2013  {
2014  SCIPdebugMessage("--> lhs differs for cons %s and cons %s!\n", SCIPconsGetName(cons1), SCIPconsGetName(cons2));
2015  return;
2016  }
2017 
2018  if( !SCIPisEQ(scip, GCGconsGetRhs(scip, cons1), GCGconsGetRhs(scip, cons2) ) )
2019  {
2020  SCIPdebugMessage("--> rhs differs for cons %s and cons %s!\n", SCIPconsGetName(cons1), SCIPconsGetName(cons2));
2021  return;
2022  }
2023 
2024  nvals1 = GCGconsGetNVars(scip, cons1);
2025  nvals2 = GCGconsGetNVars(scip, cons2);
2026  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &vals1, nvals1) );
2027  SCIP_CALL_ABORT( SCIPallocBufferArray(scip, &vals2, nvals2) );
2028  GCGconsGetVals(scip, cons1, vals1, nvals1);
2029  GCGconsGetVals(scip, cons2, vals2, nvals2);
2030 
2031  if( !realArraysAreEqual(scip, vals1, nvals1, vals2, nvals2) )
2032  {
2033  SCIPdebugMessage("--> coefs differ for cons %s and cons %s!\n", SCIPconsGetName(cons1), SCIPconsGetName(cons2));
2034  SCIPfreeBufferArray(scip, &vals1);
2035  SCIPfreeBufferArray(scip, &vals2);
2036  return;
2037  }
2038 
2039  for( int v = 0; v < detprobdata->getNVarsForCons(cons1id) ; ++v )
2040  {
2041  if( varmap[detprobdata->getVarsForCons(cons2id)[v]] != detprobdata->getVarsForCons(cons1id)[v])
2042  {
2043  SCIPfreeBufferArray(scip, &vals1);
2044  SCIPfreeBufferArray(scip, &vals2);
2045  SCIPdebugMessage("--> vars differ for cons %s and cons %s!\n", SCIPconsGetName(cons1), SCIPconsGetName(cons2));
2046  return;
2047  }
2048  }
2049 
2050  SCIPfreeBufferArray(scip, &vals1);
2051  SCIPfreeBufferArray(scip, &vals2);
2052  }
2053 
2054  varmap = std::vector<int>(getNVarsForBlock(b1), -1);
2055  for( int i = 0; i < getNVarsForBlock(b1); ++i )
2056  varmap[i] = i;
2057 
2058  *identical = TRUE;
2059  return;
2060 }
2061 
2062 void PARTIALDECOMP::calcNCoeffsForBlockForMastercons()
2063 {
2064  ncoeffsforblockformastercons = std::vector<std::vector<int>>(getNBlocks());
2065  DETPROBDATA* detprobdata = this->getDetprobdata();
2066 
2067  for( int b = 0; b < getNBlocks(); ++b )
2068  ncoeffsforblockformastercons[b] = std::vector<int>(getNMasterconss(), 0);
2069 
2070  for( int mc = 0; mc < getNMasterconss(); ++mc )
2071  {
2072  int cons = getMasterconss()[mc];
2073  for ( int vmc = 0; vmc < detprobdata->getNVarsForCons(cons); ++vmc )
2074  {
2075  int var = detprobdata->getVarsForCons(cons)[vmc];
2076  for( int b = 0; b < getNBlocks(); ++b )
2077  {
2078  if( isVarBlockvarOfBlock(var, b) )
2079  ++ncoeffsforblockformastercons[b][mc];
2080  }
2081  }
2082  }
2083  return;
2084 }
2085 
2086 
2087 void PARTIALDECOMP::checkIdenticalBlocksTrivial(
2088  int b1,
2089  int b2,
2090  SCIP_Bool* notidentical)
2091 {
2092  if( getNConssForBlock(b1) != getNConssForBlock(b2) )
2093  {
2094  SCIPdebugMessage("--> number of constraints differs!\n");
2095  *notidentical = TRUE;
2096  }
2097  else if( getNVarsForBlock(b1) != getNVarsForBlock(b2) )
2098  {
2099  SCIPdebugMessage("--> number of variables differs!\n");
2100  *notidentical = TRUE;
2101  }
2102  else if( getNCoeffsForBlock(b1) != getNCoeffsForBlock( b2) )
2103  {
2104  SCIPdebugMessage("--> number of nonzero coeffs differs!\n");
2105  *notidentical = TRUE;
2106  }
2107  else
2108  {
2109  if( ncoeffsforblockformastercons.size() == 0 )
2110  calcNCoeffsForBlockForMastercons();
2111 
2112  for( int mc = 0; mc < getNMasterconss(); ++mc )
2113  {
2114  if ( ncoeffsforblockformastercons[b1][mc] != ncoeffsforblockformastercons[b2][mc] )
2115  {
2116  SCIPdebugMessage("--> number of nonzero coeffs in %d-th master cons differs!\n", mc);
2117  *notidentical = TRUE;
2118  break;
2119  }
2120  }
2121  }
2122 }
2123 
2124 
2126 {
2127  size_t nopenconss = openconss.size();
2128  size_t nopenvars = openvars.size();
2129  size_t i = 0;
2130 
2131  refineToBlocks();
2132 
2133  // assign the open components to the master (without removing them to avoid screwing with the vector indices)
2134  for(auto cons : openconss)
2135  setConsToMaster(cons);
2136  // remove them from the open lists
2137  openconss.clear();
2138  for(i = 0; i < nopenconss; i++)
2139  {
2140  isconsopen[i] = false;
2141  }
2142 
2143  for(auto var: openvars)
2144  setVarToMaster(var);
2145 
2146  openvars.clear();
2147  for(i = 0; i < nopenvars; i++)
2148  {
2149  isvaropen[i] = false;
2150  }
2151 
2152  // consider implicits, calc hash, and check whether the partialdec is still consistent
2153  prepare();
2154 }
2155 
2156 
2158 {
2159  /* tools to update openvars */
2160  std::vector<int> openvarsToDelete;
2161  std::vector<int> oldOpenconss;
2162 
2163  std::vector<bool> isConsVisited( nconss, false );
2164  std::vector<bool> isVarVisited( nvars, false );
2165 
2166  std::queue<int> helpqueue;
2167  std::vector<int> neighborConss;
2168  std::vector<int> neighborVars;
2169 
2170  assert( (int) conssforblocks.size() == getNBlocks() );
2171  assert( (int) varsforblocks.size() == getNBlocks() );
2172  assert( (int) stairlinkingvars.size() == getNBlocks() );
2173 
2174  refineToMaster();
2175 
2176  if( getNBlocks() < 0 )
2177  {
2178  setNBlocks(0);
2179  }
2180 
2181  gcg::DETPROBDATA* detprobdata = getDetprobdata();
2182 
2183  /* do breadth first search to find connected conss and vars */
2184  while( !openconss.empty() )
2185  {
2186  int newBlockNr;
2187 
2188  assert( helpqueue.empty() );
2189  helpqueue.push(openconss[0]);
2190  neighborConss.clear();
2191  neighborConss.push_back(openconss[0]);
2192  isConsVisited[openconss[0]] = true;
2193  neighborVars.clear();
2194 
2195  while( !helpqueue.empty() )
2196  {
2197  int nodeCons = helpqueue.front();
2198  assert( isConsOpencons(nodeCons) );
2199  helpqueue.pop();
2200  for( int var : detprobdata->getVarsForCons(nodeCons) )
2201  {
2202  assert( isVarOpenvar(var) || isVarLinkingvar(var) );
2203 
2204  if( isVarVisited[var] || isVarLinkingvar(var) )
2205  continue;
2206 
2207  for( int cons : detprobdata->getConssForVar(var) )
2208  {
2209  if( !isConsOpencons(cons) || isConsVisited[cons] )
2210  {
2211  continue;
2212  }
2213  assert( isConsOpencons(cons) );
2214  isConsVisited[cons] = true;
2215  neighborConss.push_back(cons);
2216  helpqueue.push(cons);
2217  }
2218  isVarVisited[var] = true;
2219  neighborVars.push_back(var);
2220  }
2221  }
2222 
2223  /* assign found conss and vars to a new block */
2224  newBlockNr = getNBlocks() + 1;
2225  setNBlocks(newBlockNr);
2226  for( int cons : neighborConss )
2227  {
2228  setConsToBlock(cons, newBlockNr - 1);
2229  if( isConsOpencons(cons) )
2230  deleteOpencons(cons);
2231  }
2232  for( int var : neighborVars )
2233  {
2234  setVarToBlock(var, newBlockNr - 1);
2235  if( isVarOpenvar(var) )
2236  deleteOpenvar(var);
2237  }
2238  }
2239 
2240  /* assign left open vars to block 0, if it exists, and to master, otherwise */
2241  for( int var : openvars )
2242  {
2243  if( getNBlocks() != 0 )
2244  setVarToBlock(var, 0);
2245  else
2246  setVarToMaster(var);
2247  openvarsToDelete.push_back(var);
2248  }
2249 
2250  for( int var : openvarsToDelete )
2251  {
2252  if( isVarOpenvar(var) )
2253  deleteOpenvar(var);
2254  }
2255 
2256  assert( getNOpenconss() == 0 );
2257  assert( getNOpenvars() == 0 );
2258 
2259  prepare();
2260 
2261  assert( checkConsistency() );
2262 }
2263 
2264 
2265 /**
2266 * @brief assigns all open constraints and open variables
2267 *
2268 * strategy: assigns all conss and vars to the same block if they are connected
2269 * a cons and a var are adjacent if the var appears in the cons
2270 * \note this relies on the consadjacency structure of the detprobdata
2271 * hence it cannot be applied in presence of linking variables
2272 */
2274 {
2275  /* tools to check if the openvars can still be found in a constraint yet */
2276  std::vector<int> varinblocks(nvars, -1); /* stores in which block the variable can be found */
2277 
2278  /* tools to update openvars */
2279  std::vector<int> oldOpenconss;
2280  std::vector<int> openvarsToDelete;
2281 
2282  // note: this should not happen
2283  if( getNLinkingvars() != 0 )
2285 
2286  std::vector<bool> isConsVisited(nconss, false);
2287 
2288  std::queue<int> helpqueue;
2289  std::vector<int> neighborConss;
2290 
2291  assert( (int) conssforblocks.size() == getNBlocks() );
2292  assert( (int) varsforblocks.size() == getNBlocks() );
2293  assert( (int) stairlinkingvars.size() == getNBlocks() );
2294 
2295  refineToMaster();
2296 
2297  assert( checkConsistency() );
2298  gcg::DETPROBDATA* detprobdata = getDetprobdata();
2299 
2300  if( getNBlocks() < 0 )
2301  {
2302  setNBlocks(0);
2303  }
2304 
2305  /* do breadth first search to find connected conss */
2306  while( !openconss.empty() )
2307  {
2308  int newBlockNr;
2309 
2310  assert( helpqueue.empty() );
2311  helpqueue.push(openconss[0]);
2312  neighborConss.clear();
2313  neighborConss.push_back(openconss[0]);
2314  isConsVisited[openconss[0]] = true;
2315 
2316  while( !helpqueue.empty() )
2317  {
2318  int nodeCons = helpqueue.front();
2319  assert( isConsOpencons(nodeCons) );
2320  helpqueue.pop();
2321  for( int cons : detprobdata->getConssForCons(nodeCons) )
2322  {
2323  if( isConsVisited[cons] || isConsMastercons(cons) || !isConsOpencons(cons) )
2324  continue;
2325 
2326  assert( isConsOpencons(cons) );
2327  isConsVisited[cons] = true;
2328  neighborConss.push_back(cons);
2329  helpqueue.push(cons);
2330  }
2331  }
2332 
2333  /* assign found conss and vars to a new block */
2334  newBlockNr = getNBlocks() + 1;
2335  setNBlocks( newBlockNr );
2336  for( int cons : neighborConss )
2337  {
2338  setConsToBlock(cons, newBlockNr - 1);
2339  if(isConsOpencons(cons))
2340  deleteOpencons(cons);
2341 
2342  for( int var : detprobdata->getVarsForCons(cons) )
2343  {
2344 
2345  if( isVarLinkingvar(var) || varinblocks[var] != -1 )
2346  continue;
2347 
2348  assert( !isVarMastervar(var) );
2349  setVarToBlock(var, newBlockNr - 1);
2350  varinblocks[var] = newBlockNr - 1;
2351  if( isVarOpenvar(var) )
2352  deleteOpenvar(var);
2353  }
2354  }
2355  }
2356 
2357  /* assign left open vars to block 0, if it exists, and to master, otherwise */
2358  for( int var : openvars )
2359  {
2360  if( getNBlocks() != 0 )
2361  setVarToBlock(var, 0);
2362  else
2363  setVarToMaster(var);
2364  openvarsToDelete.push_back(var);
2365  }
2366 
2367  for( int var : openvarsToDelete )
2368  {
2369  if( isVarOpenvar(var) )
2370  deleteOpenvar(var);
2371  }
2372 
2373  assert( getNOpenconss() == 0 );
2374  assert( getNOpenvars() == 0 );
2375 
2376  prepare();
2377 
2378  assert( checkConsistency() );
2379 }
2380 
2381 
2383  )
2384 {
2385  bool checkvar;
2386  bool isvarinblock;
2387  bool notassigned;
2388  DETPROBDATA* detprobdata = getDetprobdata();
2389 
2390  /* tools to check if the openvars can still be found in a constraint yet*/
2391  std::vector<int> varinblocks; /* stores in which block the variable can be found */
2392 
2393  if( getNBlocks() == 0 && getNOpenconss() > 0 )
2394  {
2395  int block = addBlock();
2396  fixConsToBlock( openconss[0], block );
2397  }
2398 
2399  std::vector<int> del;
2400 
2401  /* check if the openvars can already be found in a constraint */
2402  for( int i = 0; i < getNOpenvars(); ++ i )
2403  {
2404  varinblocks.clear();
2405 
2406  /* test if the variable can be found in blocks */
2407  for( int b = 0; b < getNBlocks(); ++ b )
2408  {
2409  isvarinblock = false;
2410  std::vector<int>& conssforblock = getConssForBlock(b);
2411  for( int k = 0; k < getNConssForBlock(b) && !isvarinblock; ++ k )
2412  {
2413  for( int l = 0; l < detprobdata->getNVarsForCons( conssforblock[k] ); ++ l )
2414  {
2415  if( openvars[i] == detprobdata->getVarsForCons( conssforblock[k] )[l] )
2416  {
2417  varinblocks.push_back( b );
2418  isvarinblock = true;
2419  break;
2420  }
2421  }
2422  }
2423  }
2424  if( varinblocks.size() == 1 ) /* if the variable can be found in one block set the variable to a variable of the block*/
2425  {
2426  setVarToBlock(openvars[i], varinblocks[0]);
2427  del.push_back(openvars[i]);
2428  continue; /* the variable doesn't need to be checked any more */
2429  }
2430  else if( varinblocks.size() == 2 ) /* if the variable can be found in two blocks check if it is a linking var or a stairlinking var*/
2431  {
2432  if( varinblocks[0] + 1 == varinblocks[1] )
2433  {
2434  setVarToStairlinking(openvars[i], varinblocks[0], varinblocks[1]);
2435  del.push_back(openvars[i]);
2436  continue; /* the variable doesn't need to be checked any more */
2437  }
2438  else
2439  {
2440  setVarToLinking(openvars[i]);
2441  del.push_back(openvars[i]);
2442  continue; /* the variable doesn't need to be checked any more */
2443  }
2444  }
2445  else if( varinblocks.size() > 2 ) /* if the variable can be found in more than two blocks it is a linking var */
2446  {
2447  setVarToLinking(openvars[i]);
2448  del.push_back(openvars[i]);
2449  continue; /* the variable doesn't need to be checked any more */
2450  }
2451 
2452  checkvar = true;
2453 
2454  /* if the variable can be found in an open constraint it is still an open var */
2455  for( int j = 0; j < getNOpenconss(); ++ j )
2456  {
2457  checkvar = true;
2458  for( int k = 0; k < detprobdata->getNVarsForCons( j ); ++ k )
2459  {
2460  if( openvars[i] == detprobdata->getVarsForCons( j )[k] )
2461  {
2462  checkvar = false;
2463  break;
2464  }
2465  }
2466  if( ! checkvar )
2467  {
2468  break;
2469  }
2470  }
2471 
2472  /* test if the variable can be found in a master constraint yet */
2473  for( int k = 0; k < detprobdata->getNConssForVar( openvars[i] ) && checkvar; ++ k )
2474  {
2475  if( isConsMastercons(detprobdata->getConssForVar(openvars[i])[k]) )
2476  {
2477  setVarToMaster(openvars[i]);
2478  del.push_back(openvars[i]);
2479  checkvar = false; /* the variable does'nt need to be checked any more */
2480  break;
2481  }
2482  }
2483  }
2484 
2485  /* remove assigned vars from list of open vars */
2486  for(auto v : del)
2487  deleteOpenvar(v);
2488 
2489  del.clear();
2490  sort();
2491 
2492  std::vector<int> delconss;
2493 
2494  /* assign open conss greedily */
2495  for( int i = 0; i < getNOpenconss(); ++ i )
2496  {
2497  std::vector<int> vecOpenvarsOfBlock; /* stores the open vars of the blocks */
2498  bool consGotBlockcons = false; /* if the constraint can be assigned to a block */
2499 
2500  /* check if the constraint can be assigned to a block */
2501  for( int j = 0; j < getNBlocks(); ++ j )
2502  {
2503  /* check if all vars of the constraint are a block var of the current block, an open var, a linkingvar or a mastervar*/
2504  consGotBlockcons = true;
2505  for( int k = 0; k < detprobdata->getNVarsForCons( openconss[i] ); ++ k )
2506  {
2507  if( isVarBlockvarOfBlock( detprobdata->getVarsForCons( openconss[i] )[k], j )
2508  || isVarOpenvar( detprobdata->getVarsForCons( openconss[i] )[k] )
2509  || isVarLinkingvar( detprobdata->getVarsForCons( openconss[i] )[k] )
2510  || isVarStairlinkingvarOfBlock( detprobdata->getVarsForCons( openconss[i] )[k], j )
2511  || ( j != 0 && isVarStairlinkingvarOfBlock( detprobdata->getVarsForCons( openconss[i] )[k], j - 1 ) ) )
2512  {
2513  if( isVarOpenvar( detprobdata->getVarsForCons( openconss[i] )[k] ) )
2514  {
2515  vecOpenvarsOfBlock.push_back( detprobdata->getVarsForCons( openconss[i] )[k] );
2516  }
2517  }
2518  else
2519  {
2520  vecOpenvarsOfBlock.clear(); /* the open vars don't get vars of the block */
2521  consGotBlockcons = false; /* the constraint can't be constraint of the block, check the next block */
2522  break;
2523  }
2524  }
2525  if( consGotBlockcons ) /* the constraint can be assigned to the current block */
2526  {
2527  setConsToBlock( openconss[i], j );
2528  delconss.push_back(openconss[i]);
2529  for( size_t k = 0; k < vecOpenvarsOfBlock.size(); ++ k ) /* the openvars in the constraint get block vars */
2530  {
2531  setVarToBlock( vecOpenvarsOfBlock[k], j );
2532  deleteOpenvar( vecOpenvarsOfBlock[k] );
2533  }
2534  vecOpenvarsOfBlock.clear();
2535 
2536  break;
2537  }
2538  }
2539 
2540  if( !consGotBlockcons ) /* the constraint can not be assigned to a block, set it to master */
2541  {
2542  setConsToMaster( openconss[i] );
2543  delconss.push_back(openconss[i]);
2544  }
2545  }
2546 
2547  /* remove assigned conss from list of open conss */
2548  for(auto c : delconss)
2549  deleteOpencons(c);
2550 
2551  sort();
2552 
2553  /* assign open vars greedily */
2554  for( int i = 0; i < getNOpenvars(); ++ i )
2555  {
2556  notassigned = true;
2557  for( int j = 0; j < getNMasterconss() && notassigned; ++ j )
2558  {
2559  for( int k = 0; k < detprobdata->getNVarsForCons(masterconss[j]); ++ k )
2560  {
2561  if( openvars[i] == detprobdata->getVarsForCons(masterconss[j])[k] )
2562  {
2563  setVarToMaster(openvars[i]);
2564  del.push_back(openvars[i]);
2565  notassigned = false;
2566  break;
2567  }
2568  }
2569  }
2570  }
2571 
2572  /* remove assigned vars from list of open vars */
2573  for(auto v : del)
2574  deleteOpenvar(v);
2575 
2576  sort();
2577 
2578  /* check if the open conss are all assigned */
2579  assert( checkAllConssAssigned() );
2580 
2581  /* check if the open vars are all assigned */
2582  assert( getNOpenvars() == 0 );
2583 
2584  assert( checkConsistency() );
2585 }
2586 
2587 
2589  int consid
2590  )
2591 {
2592  std::vector<int>::iterator todelete = lower_bound( masterconss.begin(), masterconss.end(), consid );
2593  masterconss.erase(todelete);
2594 }
2595 
2596 
2597 bool PARTIALDECOMP::consPartitionUsed(
2598  int detectorchainindex
2599  )
2600 {
2601  assert( 0 <= detectorchainindex && detectorchainindex < (int) usedpartition.size() );
2602 
2603  return (usedpartition[detectorchainindex] != NULL )
2604  && (dynamic_cast<ConsPartition*>( usedpartition[detectorchainindex] ) != NULL );
2605 }
2606 
2607 
2609  )
2610 {
2611  int cons;
2612  int var;
2613  std::vector<int> blocksOfBlockvars; /* blocks with blockvars which can be found in the cons */
2614  std::vector<int> blocksOfOpenvar; /* blocks in which the open var can be found */
2615  bool master;
2616  bool hitsOpenVar;
2617  bool hitsOpenCons;
2618  SCIP_Bool benders;
2619  std::vector<int> del;
2620  std::vector<int> delconss;
2621 
2622  DETPROBDATA* detprobdata = this->getDetprobdata();
2623 
2624  SCIPgetBoolParam(scip, "detection/benders/enabled", &benders);
2625 
2626  sort();
2627 
2628  /* set openconss with more than two blockvars to master */
2629  for( size_t c = 0; c < openconss.size(); ++ c )
2630  {
2631  std::vector<bool> hitsblock = std::vector<bool>(nblocks, false);
2632  blocksOfBlockvars.clear();
2633  master = false;
2634  hitsOpenVar = false;
2635  cons = openconss[c];
2636 
2637  for( int v = 0; v < detprobdata->getNVarsForCons( cons ) && ! master; ++ v )
2638  {
2639  var = detprobdata->getVarsForCons( cons )[v];
2640 
2641  if( isVarMastervar( var ) )
2642  {
2643  master = true;
2644  fixConsToMaster( cons );
2645  continue;
2646  }
2647 
2648  if( isVarOpenvar( var ) )
2649  {
2650  hitsOpenVar = true;
2651  if( !benders )
2652  continue;
2653  }
2654 
2655  for( int b = 0; b < nblocks && ! master; ++ b )
2656  {
2657  if( isVarBlockvarOfBlock( var, b ) && !hitsblock[b] )
2658  {
2659  hitsblock[b] = true;
2660  blocksOfBlockvars.push_back( b );
2661  break;
2662  }
2663  }
2664  }
2665 
2666  if ( benders && blocksOfBlockvars.size() == 1 && !master )
2667  {
2668  setConsToBlock( cons, blocksOfBlockvars[0] );
2669  delconss.push_back(cons);
2670  }
2671 
2672  if( !benders && blocksOfBlockvars.size() > 1 )
2673  {
2674  setConsToMaster( cons );
2675  delconss.push_back(cons);
2676  }
2677 
2678  /* also assign open constraints that only have vars assigned to one single block and no open vars*/
2679  if( blocksOfBlockvars.size() == 1 && ! hitsOpenVar && ! master && ! benders )
2680  {
2681  setConsToBlock( cons, blocksOfBlockvars[0] );
2682  delconss.push_back(cons);
2683  }
2684  }
2685 
2686  /* remove assigned conss from list of open conss */
2687  for(auto c : delconss)
2688  deleteOpencons(c);
2689 
2690  sort();
2691 
2692  /* set open var to linking, if it can be found in more than one block
2693  * or set it to a block if it has only constraints in that block and no open constraints
2694  * or set it to master if it only hits master constraints */
2695  for( size_t i = 0; i < openvars.size(); ++ i )
2696  {
2697  std::vector<bool> hitsblock = std::vector<bool>(nblocks, false);
2698  bool hitsmasterconss = false;
2699  bool hitonlymasterconss = true;
2700  bool hitonlyblockconss = true;
2701  blocksOfOpenvar.clear();
2702  var = openvars[i];
2703  hitsOpenCons = false;
2704 
2705 
2706  for( int c = 0; c < detprobdata->getNConssForVar( var ); ++ c )
2707  {
2708  cons = detprobdata->getConssForVar( var )[c];
2709  if ( isConsMastercons(cons) )
2710  {
2711  hitsmasterconss = true;
2712  hitonlyblockconss = false;
2713  continue;
2714  }
2715 
2716  if( isConsOpencons( cons ) )
2717  {
2718  hitsOpenCons = true;
2719  hitonlyblockconss = false;
2720  hitonlymasterconss = false;
2721  continue;
2722  }
2723  }
2724  for( int b = 0; b < nblocks; ++ b )
2725  {
2726  for( int c = 0; c < detprobdata->getNConssForVar( var ); ++ c )
2727  {
2728  cons = detprobdata->getConssForVar( var )[c];
2729  if( isConsBlockconsOfBlock( cons, b ) && !hitsblock[b] )
2730  {
2731  hitsblock[b] = true;
2732  hitonlymasterconss = false;
2733  blocksOfOpenvar.push_back( b );
2734  break;
2735  }
2736  }
2737  }
2738 
2739  if( blocksOfOpenvar.size() > 1 )
2740  {
2741  setVarToLinking( var );
2742  del.push_back(var);
2743  continue;
2744  }
2745 
2746  if( benders && blocksOfOpenvar.size() == 1 && hitsmasterconss )
2747  {
2748  setVarToLinking( var );
2749  del.push_back(var);
2750  }
2751 
2752  if( benders && hitonlyblockconss && blocksOfOpenvar.size() > 0 )
2753  {
2754  setVarToBlock( var, blocksOfOpenvar[0] );
2755  del.push_back(var);
2756  }
2757 
2758  if( benders && hitonlymasterconss)
2759  {
2760  setVarToMaster( var);
2761  del.push_back(var);
2762  }
2763 
2764  if( !benders && blocksOfOpenvar.size() == 1 && ! hitsOpenCons )
2765  {
2766  setVarToBlock( var, blocksOfOpenvar[0] );
2767  del.push_back(var);
2768  }
2769 
2770  if( !benders && blocksOfOpenvar.size() == 0 && ! hitsOpenCons )
2771  {
2772  setVarToMaster( var );
2773  del.push_back(var);
2774  }
2775  }
2776 
2777  /* remove assigned vars from list of open vars */
2778  for(auto v : del)
2779  deleteOpenvar(v);
2780  sort();
2781 }
2782 
2783 
2785  const PARTIALDECOMP* otherpartialdec
2786  )
2787 {
2788  usedpartition = otherpartialdec->usedpartition;
2789  classestomaster = otherpartialdec->classestomaster;
2790  classestolinking = otherpartialdec->classestolinking;
2791 }
2792 
2793 
2795  bool variables /* if TRUE a block is only considered to be empty if it contains neither constraints or variables */
2796  )
2797 {
2798  bool emptyBlocks = true;
2799  SCIP_Bool benders = FALSE;
2800  int block = - 1;
2801  int b;
2802 
2803  assert( (int) conssforblocks.size() == nblocks );
2804  assert( (int) varsforblocks.size() == nblocks );
2805  assert( (int) stairlinkingvars.size() == nblocks );
2806 
2807  SCIPgetBoolParam(scip, "detection/benders/enabled", &benders);
2808 
2809  while( emptyBlocks )
2810  {
2811  emptyBlocks = false;
2812  for( b = nblocks - 1; b >= 0; --b )
2813  {
2814  if( conssforblocks[b].empty() && ( variables ? varsforblocks[b].empty() : true) )
2815  {
2816  emptyBlocks = true;
2817  block = b;
2818  break;
2819  }
2820  if( benders && ( conssforblocks[b].empty() || varsforblocks[b].empty()) )
2821  {
2822  emptyBlocks = true;
2823  block = b;
2824  break;
2825  }
2826 
2827  }
2828  if( emptyBlocks )
2829  {
2830  nblocks--;
2831 
2832  stairlinkingvars.erase(stairlinkingvars.begin() + block);
2833 
2834  for( int j : conssforblocks[block] )
2835  {
2836  masterconss.push_back(j);
2837  isconsmaster[j] = true;
2838  }
2839  std::sort(masterconss.begin(), masterconss.end());
2840  conssforblocks.erase(conssforblocks.begin() + block);
2841 
2842  for( int j : varsforblocks[block] )
2843  {
2844  mastervars.push_back(j);
2845  isvarmaster[j] = true;
2846  }
2847  varsforblocks.erase(varsforblocks.begin() + block);
2848  std::sort( mastervars.begin(), mastervars.end() );
2849 
2850  //set stairlinkingvars of the previous block to block vars
2851  if( block != 0 && !stairlinkingvars[block - 1].empty() )
2852  {
2853  for( int j : stairlinkingvars[block - 1] )
2854  {
2855  fixVarToBlock(j, block - 1);
2856  }
2857  stairlinkingvars[block - 1].clear();
2858  sort();
2859  }
2860  }
2861  }
2862 }
2863 
2864 
2866  int opencons
2867  )
2868 {
2869  assert( opencons >= 0 && opencons < nconss );
2870  std::vector<int>::iterator it;
2871  it = lower_bound( openconss.begin(), openconss.end(), opencons );
2872  assert( it != openconss.end() && *it == opencons );
2873  openconss.erase(it);
2874  isconsopen[opencons] = false;
2875 }
2876 
2877 
2878 std::vector<int>::const_iterator PARTIALDECOMP::deleteOpencons(
2879  std::vector<int>::const_iterator itr
2880  )
2881 {
2882  isconsopen[*itr] = false;
2883  return openconss.erase(itr);
2884 }
2885 
2886 
2888  int openvar
2889  )
2890 {
2891  assert( openvar >= 0 && openvar < nvars );
2892  std::vector<int>::iterator it;
2893  it = lower_bound( openvars.begin(), openvars.end(), openvar );
2894  assert( it != openvars.end() && *it == openvar );
2895  openvars.erase( it );
2896  isvaropen[openvar] = false;
2897 }
2898 
2899 
2900 std::vector<int>::const_iterator PARTIALDECOMP::deleteOpenvar(
2901  std::vector<int>::const_iterator itr
2902  )
2903 {
2904  assert( itr != openvars.cend() );
2905 
2906  isvaropen[*itr] = false;
2907  return openvars.erase(itr);
2908 }
2909 
2910 
2911 void PARTIALDECOMP::displayAggregationInformation()
2912 {
2913  if( !aggInfoCalculated() )
2914  {
2915  SCIPinfoMessage(scip, NULL, " Aggregation information is not calculated yet \n ");
2916  }
2917  else
2918  {
2919  SCIPinfoMessage(scip, NULL, " number of representative blocks: %d \n", nrepblocks);
2920  for( int i = 0; i < nrepblocks; ++i )
2921  {
2922  SCIPinfoMessage(scip, NULL, "representative block %d : ", i);
2923 
2924  for( size_t b = 0; b < reptoblocks[i].size(); ++b )
2925  SCIPinfoMessage(scip, NULL, "%d ", reptoblocks[i][b] );
2926 
2927  SCIPinfoMessage(scip, NULL, "\n");
2928  }
2929  }
2930 }
2931 
2932 
2934  int detailLevel
2935  )
2936 {
2937  assert( 0 <= detailLevel );
2938  DETPROBDATA* detprobdata = this->getDetprobdata();
2939 
2940  std::cout << std::endl;
2941 
2942  /* general information */
2943  std::cout << "-- General information --" << std::endl;
2944  std::cout << " ID: " << id << std::endl;
2945  std::cout << " Hashvalue: " << hashvalue << std::endl;
2946  std::cout << " Score: " << classicscore << std::endl;
2947  if( getNOpenconss() + getNOpenconss() > 0 )
2948  std::cout << " Maxwhitescore >= " << maxwhitescore << std::endl;
2949  else
2950  std::cout << " Max white score: " << maxwhitescore << std::endl;
2951  if( getNOpenconss() + getNOpenconss() == 0 )
2952  std::cout << " Max-foreseeing-white-score: " << maxforeseeingwhitescore << std::endl;
2953  if( getNOpenconss() + getNOpenconss() == 0 )
2954  std::cout << " Max-foreseeing-white-aggregated-score: " << maxforeseeingwhitescoreagg << std::endl;
2955  if( getNOpenconss() + getNOpenconss() == 0 )
2956  std::cout << " PPC-max-foreseeing-white-score: " << setpartfwhitescore << std::endl;
2957 
2958  if( getNOpenconss() + getNOpenconss() == 0 )
2959  std::cout << " PPC-max-foreseeing-white-aggregated-score: " << setpartfwhitescoreagg << std::endl;
2960 
2961  if( getNOpenconss() + getNOpenconss() == 0 )
2962  std::cout << " Bendersscore: " << bendersscore << std::endl;
2963 
2964  if( getNOpenconss() + getNOpenconss() == 0 )
2965  std::cout << " borderareascore: " << borderareascore << std::endl;
2966 
2967  std::cout << " HassetppMaster: " << hasSetppMaster() << std::endl;
2968  std::cout << " HassetppcMaster: " << hasSetppcMaster() << std::endl;
2969  std::cout << " HassetppccardMaster: " << hasSetppccardMaster() << std::endl;
2970  std::cout << " PARTIALDECOMP is for the " << (original ? "original" : "presolved" ) << " problem and "
2971  << ( usergiven ? "usergiven" : "not usergiven" ) << "." << std::endl;
2972  std::cout << " Number of constraints: " << getNConss() << std::endl;
2973  std::cout << " Number of variables: " << getNVars() << std::endl;
2974 
2975  displayAggregationInformation();
2976  std::cout << std::endl;
2977 
2978  /* detection information */
2979  std::cout << "-- Detection and detectors --" << std::endl;
2980  std::cout << " PARTIALDECOMP stems from the " << ( stemsfromorig ? "original" : "presolved" ) << " problem." << std::endl;
2981 
2982  /* ancestor partialdecs' ids */
2983  std::cout << " IDs of ancestor partialdecs: ";
2984  if( !listofancestorids.empty() )
2985  std::cout << listofancestorids[0];
2986  for( int i = 1; i < (int) listofancestorids.size(); ++i )
2987  std::cout << ", " << listofancestorids[i];
2988  std::cout << std::endl;
2989 
2990  /* detector chain information */
2991  std::cout << " " << getNDetectors() << " detector" << ( getNDetectors() > 1 ? "s" : "" ) << " worked on this partialdec:";
2992  if( getNDetectors() != 0 )
2993  {
2994  std::string detectorrepres;
2995 
2996  if( detectorchain[0] == NULL )
2997  detectorrepres = "user";
2998  else
2999  {
3000  /* potentially add finisher label */
3001  detectorrepres = (
3002  getNDetectors() != 1 || !isfinishedbyfinisher ? DECdetectorGetName(detectorchain[0]) :
3003  "(finish) " + std::string(DECdetectorGetName(detectorchain[0])));
3004  }
3005 
3006  if( detailLevel > 0 )
3007  {
3008  std::cout << std::endl << " 1.: " << detectorrepres << std::endl;
3009  std::cout << getDetectorStatistics( 0 );
3010  std::cout << getDetectorPartitionInfo(0, detailLevel > 1 && (!stemsfromorig || original));
3011  }
3012  else
3013  {
3014  std::cout << " " << detectorrepres;
3015  }
3016 
3017  for( int d = 1; d < getNDetectors(); ++d )
3018  {
3019  /* potentially add finisher label */
3020  detectorrepres = (
3021  getNDetectors() != d + 1 || !isfinishedbyfinisher ? DECdetectorGetName(detectorchain[d]) :
3022  "(finish) " + std::string(DECdetectorGetName(detectorchain[d])));
3023 
3024 
3025  if( detailLevel > 0 )
3026  {
3027  std::cout << " " << ( d + 1 ) << ".: " << detectorrepres << std::endl;
3028  std::cout << getDetectorStatistics( d );
3029  std::cout << getDetectorPartitionInfo(d, detailLevel > 1 && (!stemsfromorig || original));
3030  }
3031  else
3032  {
3033  std::cout << ", " << detectorrepres;
3034  }
3035  }
3036 
3037  if( detailLevel <= 0 )
3038  {
3039  std::cout << std::endl;
3040  }
3041  }
3042 
3043  std::cout << std::endl;
3044 
3045  /* variable information */
3046  std::cout << "-- Border and unassigned --" << std::endl;
3047  std::cout << " Linkingvariables";
3048  if( detailLevel > 1 )
3049  {
3050  std::cout << " (" << getNLinkingvars() << ")";
3051  if( getNLinkingvars() > 0 )
3052  std::cout << ": " << SCIPvarGetName(detprobdata->getVar(getLinkingvars()[0]));
3053  for( int v = 1; v < getNLinkingvars(); ++v )
3054  {
3055  std::cout << ", " << SCIPvarGetName(detprobdata->getVar(getLinkingvars()[v]));
3056  }
3057  std::cout << std::endl;
3058  }
3059  else
3060  {
3061  std::cout << ": " << getNLinkingvars() << std::endl;
3062  }
3063  std::cout << " Masterconstraints";
3064  if( detailLevel > 1 )
3065  {
3066  std::cout << " (" << getNMasterconss() << ")";
3067  if( getNMasterconss() > 0 )
3068  std::cout << ": " << SCIPconsGetName(detprobdata->getCons(getMasterconss()[0]));
3069  for( int c = 1; c < getNMasterconss(); ++c )
3070  {
3071  std::cout << ", " << SCIPconsGetName(detprobdata->getCons(getMasterconss()[c]));
3072  }
3073  std::cout << std::endl;
3074  }
3075  else
3076  {
3077  std::cout << ": " << getNMasterconss() << std::endl;
3078  }
3079  std::cout << " Mastervariables";
3080  if( detailLevel > 1 )
3081  {
3082  std::cout << " (" << getNMastervars() << ")";
3083  if( getNMastervars() > 0 )
3084  std::cout << ": " << SCIPvarGetName(detprobdata->getVar(getMastervars()[0]));
3085  for( int v = 1; v < getNMastervars(); ++v )
3086  {
3087  std::cout << ", " << SCIPvarGetName(detprobdata->getVar(getMastervars()[v]));
3088  }
3089  std::cout << std::endl;
3090  }
3091  else
3092  {
3093  std::cout << ": " << getNMastervars() << std::endl;
3094  }
3095  std::cout << " Open constraints";
3096  if( detailLevel > 1 )
3097  {
3098  std::cout << " (" << getNOpenconss() << ")";
3099  if( getNOpenconss() > 0 )
3100  std::cout << ": " << SCIPconsGetName(detprobdata->getCons(getOpenconss()[0]));
3101  for( int c = 1; c < getNOpenconss(); ++c )
3102  {
3103  std::cout << ", " << SCIPconsGetName(detprobdata->getCons(getOpenconss()[c]));
3104  }
3105  std::cout << std::endl;
3106  }
3107  else
3108  {
3109  std::cout << ": " << getNOpenconss() << std::endl;
3110  }
3111  std::cout << " Open variables";
3112  if( detailLevel > 1 )
3113  {
3114  std::cout << " (" << getNOpenvars() << ")";
3115  if( getNOpenvars() > 0 )
3116  std::cout << ": " << SCIPvarGetName(detprobdata->getVar(getOpenvars()[0]));
3117  for( int v = 1; v < getNOpenvars(); ++v )
3118  {
3119  std::cout << ", " << SCIPvarGetName(detprobdata->getVar(getOpenvars()[v]));
3120  }
3121  std::cout << std::endl;
3122  }
3123  else
3124  {
3125  std::cout << ": " << getNOpenvars() << std::endl;
3126  }
3127 
3128  std::cout << std::endl;
3129 
3130  /* block information */
3131  std::cout << "-- Blocks --" << std::endl;
3132  std::cout << " Number of blocks: " << nblocks << std::endl;
3133 
3134  if( detailLevel > 0 )
3135  {
3136  for( int b = 0; b < nblocks; ++b )
3137  {
3138  std::cout << " Block " << b << ":" << std::endl;
3139 
3140  std::cout << " Constraints";
3141  if( detailLevel > 1 )
3142  {
3143  std::cout << " (" << getNConssForBlock(b) << ")";
3144  if( getNConssForBlock(b) > 0 )
3145  std::cout << ": " << SCIPconsGetName(detprobdata->getCons(getConssForBlock(b)[0]));
3146  for( int c = 1; c < getNConssForBlock(b); ++c )
3147  {
3148  std::cout << ", " << SCIPconsGetName(detprobdata->getCons(getConssForBlock(b)[c]));
3149  }
3150  std::cout << std::endl;
3151  }
3152  else
3153  {
3154  std::cout << ": " << getNConssForBlock(b) << std::endl;
3155  }
3156 
3157  std::cout << " Variables";
3158  if( detailLevel > 1 )
3159  {
3160  std::cout << " (" << getNVarsForBlock(b) << ")";
3161  if( getNVarsForBlock(b) > 0 )
3162  std::cout << ": " << SCIPvarGetName(detprobdata->getVar(getVarsForBlock(b)[0]));
3163  for( int v = 1; v < getNVarsForBlock(b); ++v )
3164  {
3165  std::cout << ", " << SCIPvarGetName(detprobdata->getVar(getVarsForBlock(b)[v]));
3166  }
3167  std::cout << std::endl;
3168  }
3169  else
3170  {
3171  std::cout << ": " << getNVarsForBlock(b) << std::endl;
3172  }
3173 
3174  std::cout << " Stairlinkingvariables";
3175  if( detailLevel > 1 )
3176  {
3177  std::cout << " (" << getNStairlinkingvars(b) << ")";
3178  if( getNStairlinkingvars(b) > 0 )
3179  std::cout << ": " << SCIPvarGetName(detprobdata->getVar(getStairlinkingvars(b)[0]));
3180  for( int v = 1; v < getNStairlinkingvars(b); ++v )
3181  {
3182  std::cout << ", " << SCIPvarGetName(detprobdata->getVar(getStairlinkingvars(b)[v]));
3183  }
3184  std::cout << std::endl;
3185  }
3186  else
3187  {
3188  std::cout << ": " << getNStairlinkingvars(b) << std::endl;
3189  }
3190  }
3191  }
3192 
3193  std::cout << std::endl;
3194 }
3195 
3196 
3198 )
3199 {
3200  SCIP_Bool hassetpartmaster;
3201  SCIP_Bool verbose;
3202  hassetpartmaster = TRUE;
3203  verbose = FALSE;
3204 
3206  return FALSE;
3207 
3208  DETPROBDATA* detprobdata = this->getDetprobdata();
3209 
3210  for( int l = 0; l < getNMasterconss(); ++l )
3211  {
3212  int consid = getMasterconss()[l];
3213  if( !detprobdata->isConsSetppc(consid) && !detprobdata->isConsCardinalityCons(consid) )
3214  {
3215  hassetpartmaster = FALSE;
3216  if( verbose )
3217  std::cout << " cons with name " << SCIPconsGetName(detprobdata->getCons(consid)) << " is no setppccard constraint." << std::endl;
3218  break;
3219  }
3220  }
3221 
3222  return hassetpartmaster;
3223 }
3224 
3225 
3227 )
3228 {
3229  SCIP_Bool hassetpartmaster;
3230  hassetpartmaster = TRUE;
3231 
3233  return FALSE;
3234 
3235  DETPROBDATA* detprobdata = this->getDetprobdata();
3236 
3237  for( int l = 0; l < getNMasterconss(); ++l )
3238  {
3239  int consid = getMasterconss()[l];
3240  if( !detprobdata->isConsSetppc(consid) )
3241  {
3242  hassetpartmaster = FALSE;
3243  break;
3244  }
3245  }
3246  return hassetpartmaster;
3247 }
3248 
3249 
3251 )
3252 {
3253  SCIP_Bool hassetpartmaster;
3254  hassetpartmaster = TRUE;
3255 
3257  return FALSE;
3258 
3259  DETPROBDATA* detprobdata = this->getDetprobdata();
3260 
3261  for( int l = 0; l < getNMasterconss(); ++l )
3262  {
3263  int consid = getMasterconss()[l];
3264  if( !detprobdata->isConsSetpp(consid) )
3265  {
3266  hassetpartmaster = FALSE;
3267  break;
3268  }
3269  }
3270  return hassetpartmaster;
3271 }
3272 
3273 
3275  SCIP_HASHMAP* constoblock,
3276  int givenNBlocks
3277  )
3278 {
3279  assert( givenNBlocks >= 0 );
3280  assert( nblocks == 0 );
3281  assert( (int) conssforblocks.size() == nblocks );
3282  assert( (int) varsforblocks.size() == nblocks );
3283  assert( (int) stairlinkingvars.size() == nblocks );
3284  assert( ! alreadyAssignedConssToBlocks() );
3285  nblocks = givenNBlocks;
3286  DETPROBDATA* detprobdata = this->getDetprobdata();
3287  nvars = detprobdata->getNVars();
3288  nconss = detprobdata->getNConss();
3289  int consnum;
3290  int consblock;
3291 
3292  for( int i = 0; i < nconss; ++ i )
3293  {
3294  consnum = i;
3295  consblock = ( (int) (size_t) SCIPhashmapGetImage( constoblock, (void*) (size_t) i ) ) - 1;
3296  assert( consblock >= 0 && consblock <= nblocks );
3297  if( consblock == nblocks )
3298  {
3299  setConsToMaster( consnum );
3300  deleteOpencons( consnum );
3301  }
3302  }
3303 
3304  nblocks = 0;
3305  sort();
3306 
3307  assert( checkConsistency() );
3308 
3309  return SCIP_OKAY;
3310 }
3311 
3312 
3314  SCIP_HASHMAP* constoblock,
3315  int givenNBlocks
3316  )
3317 {
3318  assert( givenNBlocks >= 0 );
3319  assert( nblocks == 0 );
3320  assert( (int) conssforblocks.size() == nblocks );
3321  assert( (int) varsforblocks.size() == nblocks );
3322  assert( (int) stairlinkingvars.size() == nblocks );
3323  assert( ! alreadyAssignedConssToBlocks() );
3324  nblocks = givenNBlocks;
3325  DETPROBDATA* detprobdata = this->getDetprobdata();
3326  nvars = detprobdata->getNVars();
3327  nconss = detprobdata->getNConss();
3328  int consnum;
3329  int consblock;
3330  int varnum;
3331  bool varInBlock;
3332  std::vector<int> varinblocks = std::vector<int>( 0 );
3333  std::vector<int> emptyVector = std::vector<int>( 0 );
3334 
3335  for( int c = 0; c < nconss; ++ c )
3336  {
3337  SCIPverbMessage(scip, SCIP_VERBLEVEL_FULL, NULL, "%d\n", c);
3338  assert( SCIPhashmapExists( constoblock, (void*) (size_t) c ) );
3339  assert( (int) (size_t) SCIPhashmapGetImage( constoblock, (void*) (size_t) c ) - 1 <= nblocks );
3340  assert( (int) (size_t) SCIPhashmapGetImage( constoblock, (void*) (size_t) c ) - 1 >= 0 );
3341  }
3342 
3343  for( int b = (int) conssforblocks.size(); b < nblocks; b ++ )
3344  conssforblocks.push_back( emptyVector );
3345 
3346  for( int b = (int) varsforblocks.size(); b < nblocks; b ++ )
3347  varsforblocks.push_back( emptyVector );
3348 
3349  for( int b = (int) stairlinkingvars.size(); b < nblocks; b ++ )
3350  stairlinkingvars.push_back( emptyVector );
3351 
3352  for( int i = 0; i < nconss; ++ i )
3353  {
3354  consnum = i;
3355  consblock = ( (int) (size_t) SCIPhashmapGetImage( constoblock, (void*) (size_t) i ) ) - 1;
3356  assert( consblock >= 0 && consblock <= nblocks );
3357  if( consblock == nblocks )
3358  setConsToMaster( consnum );
3359  else
3360  setConsToBlock( consnum, consblock );
3361  }
3362 
3363  for( int i = 0; i < nvars; ++ i )
3364  {
3365  varinblocks.clear();
3366  varnum = i;
3367 
3368  /* test if the variable can be found in blocks */
3369  for( int b = 0; b < nblocks; ++ b )
3370  {
3371  varInBlock = false;
3372  for( size_t k = 0; k < conssforblocks[b].size() && ! varInBlock; ++ k )
3373  {
3374  for( int l = 0; l < detprobdata->getNVarsForCons( conssforblocks[b][k] ) && ! varInBlock; ++ l )
3375  {
3376  if( varnum == ( detprobdata->getVarsForCons( conssforblocks[b][k] ) )[l] )
3377  {
3378  varinblocks.push_back( b );
3379  varInBlock = true;
3380  }
3381  }
3382  }
3383  }
3384  if( varinblocks.size() == 1 ) /* if the var can be found in one block set the var to block var */
3385  setVarToBlock( varnum, varinblocks[0] );
3386  else if( varinblocks.size() == 2 ) /* if the variable can be found in two blocks check if it is a linking var or a stairlinking var*/
3387  {
3388  if( varinblocks[0] + 1 == varinblocks[1] )
3389  setVarToStairlinking( varnum, varinblocks[0], varinblocks[1] );
3390  else
3391  setVarToLinking( varnum );
3392  }
3393  else if( varinblocks.size() > 2 ) /* if the variable can be found in more than two blocks it is a linking var */
3394  setVarToLinking( varnum );
3395  else
3396  assert( varinblocks.size() == 0 );
3397  setVarToMaster( varnum );
3398  }
3399  sort();
3400  openvars = std::vector<int>( 0 );
3401  openconss = std::vector<int>( 0 );
3402  isvaropen = std::vector<bool>(nvars, false);
3403  isconsopen = std::vector<bool>(nconss, false);
3404 
3405  deleteEmptyBlocks(false);
3406  sort();
3407  assert( checkConsistency( ) );
3408 
3409  return SCIP_OKAY;
3410 }
3411 
3412 
3414  )
3415 {
3416  int i;
3417  int j;
3418  bool isMasterVar;
3419  std::vector<int> foundMasterVarIndices;
3420  std::vector<int>& lvars = getLinkingvars();
3421 
3422  DETPROBDATA* detprobdata = this->getDetprobdata();
3423 
3424  // sort Master constraints for binary search
3425  sort();
3426 
3427  for( i = 0; i < getNLinkingvars(); ++ i )
3428  {
3429  isMasterVar = true;
3430  std::vector<int>& varcons = detprobdata->getConssForVar( lvars[i] );
3431  for( j = 0; j < detprobdata->getNConssForVar( lvars[i] ); ++ j )
3432  {
3433  if( ! isconsmaster[varcons[j]] )
3434  {
3435  isMasterVar = false;
3436  break;
3437  }
3438  }
3439 
3440  if( isMasterVar )
3441  {
3442  foundMasterVarIndices.push_back( i );
3443  }
3444  }
3445 
3446  for( auto it = foundMasterVarIndices.rbegin(); it != foundMasterVarIndices.rend(); ++ it )
3447  {
3448  mastervars.push_back( lvars[ * it] );
3449  mastervarssorted = false;
3450  hvoutdated = true;
3451  isvarmaster[lvars[ * it]] = true;
3452  linkingvars.erase( linkingvars.begin() + * it );
3453  }
3454 }
3455 
3456 
3458  )
3459 {
3460  int i;
3461  int j;
3462  int k;
3463 
3464  int consblock;
3465  int block1 = - 1;
3466  int block2 = - 1;
3467 
3468  std::vector<int>& lvars = getLinkingvars();
3469 
3470  std::vector<int> foundMasterVarIndices;
3471  DETPROBDATA* detprobdata = this->getDetprobdata();
3472 
3473  sort();
3474 
3475  for( i = 0; i < getNLinkingvars(); ++ i )
3476  {
3477  block1 = - 1;
3478  block2 = - 1;
3479  std::vector<int>& varcons = detprobdata->getConssForVar( lvars[i] );
3480  for( j = 0; j < detprobdata->getNConssForVar( lvars[i] ); ++ j )
3481  {
3482  consblock = - 1;
3483  for( k = 0; k < nblocks; ++ k )
3484  {
3485  if( std::binary_search( conssforblocks[k].begin(), conssforblocks[k].end(), varcons[j] ) )
3486  {
3487  consblock = k;
3488  break;
3489  }
3490  }
3491 
3492  if( consblock == - 1 )
3493  {
3494  block1 = - 1;
3495  block2 = - 1;
3496  break;
3497  }
3498  else if( block1 == consblock || block2 == consblock )
3499  {
3500  continue;
3501  }
3502  else if( block1 == - 1 )
3503  {
3504  block1 = consblock;
3505  continue;
3506  }
3507  else if( block2 == - 1 )
3508  {
3509  block2 = consblock;
3510  continue;
3511  }
3512  else
3513  {
3514  block1 = - 1;
3515  block2 = - 1;
3516  break;
3517  }
3518  }
3519 
3520  if( block1 != - 1 && block2 != - 1 && ( block1 == block2 + 1 || block1 + 1 == block2 ) )
3521  {
3522 
3523  setVarToStairlinking( lvars[i], block1, block2 );
3524  foundMasterVarIndices.push_back( i );
3525  }
3526  }
3527 
3528  for( auto it = foundMasterVarIndices.rbegin(); it != foundMasterVarIndices.rend(); ++ it )
3529  {
3530  linkingvars.erase( linkingvars.begin() + * it );
3531  }
3532 }
3533 
3534 
3535 std::vector< std::pair< int, std::vector< int > > > PARTIALDECOMP::findLinkingVarsPotentiallyStairlinking(
3536  )
3537 {
3538  std::vector< std::pair< int, std::vector< int > > > blocksOfVars( 0 );
3539  int blockcounter;
3540  DETPROBDATA* detprobdata = this->getDetprobdata();
3541 
3542  /* if there is at least one linking variable, then the blocks of vars must be created. */
3543  if( getNLinkingvars() > 0 )
3544  {
3545  std::vector<int>& lvars = getLinkingvars();
3546  sort();
3547 
3548  /* check every linking var */
3549  for ( int v = 0; v < getNLinkingvars(); ++v )
3550  {
3551  std::vector< int > blocksOfVar( 0 );
3552  blockcounter = 0;
3553 
3554  std::vector<int>& varcons = detprobdata->getConssForVar( lvars[v] );
3555 
3556  /* find all blocks that are hit by this linking var */
3557  for ( int c = 0; c < detprobdata->getNConssForVar( lvars[v] ) && blockcounter <= 2; ++c )
3558  {
3559  for ( int b = 0; b < nblocks && blockcounter <= 2; ++b )
3560  {
3561  if ( std::binary_search( conssforblocks[b].begin(),
3562  conssforblocks[b].end(), varcons[c] ) )
3563  {
3564  /* if the hit block is new, add it to blockOfVar vector */
3565  if ( std::find( blocksOfVar.begin(), blocksOfVar.end(), b ) == blocksOfVar.end() )
3566  {
3567  ++blockcounter;
3568  blocksOfVar.push_back( b );
3569  }
3570  }
3571  }
3572  }
3573 
3574  /* if the var hits exactly two blocks, it is potentially stairlinking */
3575  if ( blockcounter == 2 )
3576  {
3577  std::pair< int, std::vector< int > > pair( v, blocksOfVar );
3578  blocksOfVars.push_back( pair );
3579  }
3580  }
3581  }
3582 
3583  return blocksOfVars;
3584 }
3585 
3586 
3588  int ancestorindex
3589  )
3590 {
3591  assert( 0 <= ancestorindex && ancestorindex < (int) listofancestorids.size() );
3592 
3593  return listofancestorids[ancestorindex];
3594 }
3595 
3596 
3598 {
3599  return listofancestorids;
3600 }
3601 
3602 const std::vector<int> & PARTIALDECOMP::getBlocksForRep(int repid)
3603 {
3604  return reptoblocks[repid];
3605 }
3606 
3607 
3609  std::vector<int>& newlist
3610  )
3611 {
3612  listofancestorids = newlist;
3613 }
3614 
3615 
3617  int ancestor
3618  )
3619 {
3620  assert( 0 <= ancestor );
3621  listofancestorids.push_back(ancestor);
3622 }
3623 
3624 
3626  int ancestorid
3627  )
3628 {
3629  int i;
3630  std::vector<int> indices;
3631  // look for id (including duplicates)
3632  for(i = 0; i < (int) listofancestorids.size(); i++)
3633  {
3634  // add indices, descending
3635  if(listofancestorids.at(i) == ancestorid)
3636  {
3637  indices.insert(indices.begin(), i);
3638  }
3639  }
3640  // as indices are descending this is consistent
3641  for(auto index : indices)
3642  listofancestorids.erase(listofancestorids.begin() + index);
3643 }
3644 
3645 
3647  int detectorchainindex
3648  )
3649 {
3650  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorclocktimes.size() );
3651 
3652  return detectorclocktimes[ detectorchainindex ];
3653 }
3654 
3655 
3656 std::vector<SCIP_Real>& PARTIALDECOMP::getDetectorClockTimes()
3657 {
3658  return detectorclocktimes;
3659 }
3660 
3661 
3662 void PARTIALDECOMP::getConsPartitionData(
3663  int detectorchainindex,
3665  std::vector<int>& consclassesmaster
3666  )
3667 {
3668  assert(consPartitionUsed(detectorchainindex) );
3669 
3670  *partition = dynamic_cast<ConsPartition*>( usedpartition[detectorchainindex] );
3671  consclassesmaster = classestomaster[detectorchainindex];
3672 }
3673 
3674 
3676  std::vector<SCIP_Real>& newvector)
3677 {
3678  detectorclocktimes = newvector;
3679 }
3680 
3681 
3682 bool PARTIALDECOMP::varPartitionUsed(
3683  int detectorchainindex
3684  )
3685 {
3686  assert( 0 <= detectorchainindex && detectorchainindex < (int) usedpartition.size() );
3687 
3688  return (usedpartition[detectorchainindex] != NULL )
3689  && (dynamic_cast<VarPartition*>( usedpartition[detectorchainindex] ) != NULL );
3690 }
3691 
3692 
3694  int block
3695  )
3696 {
3697  assert( block >= 0 && block < nblocks );
3698  return conssforblocks[block];
3699 }
3700 
3701 
3702 std::vector<DEC_DETECTOR*>& PARTIALDECOMP::getDetectorchain()
3703 {
3704  return detectorchain;
3705 }
3706 
3707 
3708 std::string PARTIALDECOMP::getDetectorStatistics(
3709  int detectorchainindex
3710  )
3711 {
3712  std::stringstream output;
3713 
3714  if( (int) getDetectorClockTimes().size() > detectorchainindex )
3715  output << " Detection time: " << getDetectorClockTime( detectorchainindex ) << std::endl;
3716  if( (int) getPctConssFromFreeVector().size() > detectorchainindex )
3717  output << " % newly assigned constraints: " << getPctConssFromFree( detectorchainindex ) << std::endl;
3718  if( (int) getPctConssToBorderVector().size() > detectorchainindex )
3719  output << " % constraints the detector assigned to border: " << getPctConssToBorder( detectorchainindex ) << std::endl;
3720  if( (int) getPctConssToBlockVector().size() > detectorchainindex )
3721  output << " % constraints the detector assigned to blocks: " << getPctConssToBlock( detectorchainindex ) << std::endl;
3722  if( (int) getPctVarsFromFreeVector().size() > detectorchainindex )
3723  output << " % newly assigned variables: " << getPctVarsFromFree( detectorchainindex ) << std::endl;
3724  if( (int) getPctVarsToBorderVector().size() > detectorchainindex )
3725  output << " % variables the detector assigned to border: " << getPctVarsToBorder( detectorchainindex ) << std::endl;
3726  if( (int) getPctVarsToBlockVector().size() > detectorchainindex )
3727  output << " % variables the detector assigned to blocks: " << getPctVarsToBlock( detectorchainindex ) << std::endl;
3728  if( (int) getNNewBlocksVector().size() > detectorchainindex )
3729  output << " New blocks: " << getNNewBlocks( detectorchainindex ) << std::endl;
3730 
3731  return output.str();
3732 }
3733 
3734 
3735 std::string PARTIALDECOMP::getDetectorPartitionInfo(
3736  int detectorchainindex,
3737  bool displayConssVars
3738  )
3739 {
3740  std::stringstream output;
3741  DETPROBDATA* detprobdata = this->getDetprobdata();
3742 
3743  if( consPartitionUsed(detectorchainindex) )
3744  {
3746  std::vector<int> constomaster;
3747 
3748  getConsPartitionData(detectorchainindex, &partition, constomaster);
3749 
3750  output << " Used conspartition: " << partition->getName() << std::endl;
3751  output << " Pushed to master:";
3752 
3753  if( !constomaster.empty() )
3754  {
3755  if( displayConssVars )
3756  {
3757  output << std::endl << " " << partition->getClassName(constomaster[0] ) << " ("
3758  << partition->getClassDescription(constomaster[0] ) << "): ";
3759  bool first = true;
3760  for( int c = 0; c < partition->getNConss(); ++c )
3761  {
3762  if( partition->getClassOfCons(c ) == constomaster[0] )
3763  {
3764  if( first )
3765  {
3766  output << SCIPconsGetName(detprobdata->getCons(c));
3767  first = false;
3768  }
3769  else
3770  {
3771  output << ", " << SCIPconsGetName(detprobdata->getCons(c));
3772  }
3773  }
3774  }
3775  output << std::endl;
3776  }
3777  else
3778  {
3779  output << " " << partition->getClassName(constomaster[0] );
3780  }
3781  }
3782 
3783  for( size_t i = 1; i < constomaster.size(); ++i )
3784  {
3785  if( displayConssVars )
3786  {
3787  output << " " << partition->getClassName(constomaster[i] ) << " ("
3788  << partition->getClassDescription(constomaster[i] ) << "): ";
3789  bool first = true;
3790  for( int c = 0; c < partition->getNConss(); ++c )
3791  {
3792  if( partition->getClassOfCons(c ) == constomaster[i] )
3793  {
3794  if( first )
3795  {
3796  output << SCIPconsGetName(detprobdata->getCons(c));
3797  first = false;
3798  }
3799  else
3800  {
3801  output << ", " << SCIPconsGetName(detprobdata->getCons(c));
3802  }
3803  }
3804  }
3805  output << std::endl;
3806  }
3807  else
3808  {
3809  output << ", " << partition->getClassName(constomaster[i] );
3810  }
3811  }
3812 
3813  if ( !displayConssVars || constomaster.empty() )
3814  {
3815  output << std::endl;
3816  }
3817  }
3818 
3819  if( varPartitionUsed(detectorchainindex) )
3820  {
3822  std::vector<int> vartolinking;
3823  std::vector<int> vartomaster;
3824 
3825  getVarPartitionData(detectorchainindex, &partition, vartolinking, vartomaster);
3826 
3827  output << " Used varpartition: " << partition->getName() << std::endl;
3828  output << " Pushed to linking:";
3829 
3830  if( !vartolinking.empty() )
3831  {
3832  if( displayConssVars )
3833  {
3834  output << std::endl << " " << partition->getClassName(vartolinking[0] ) << " ("
3835  << partition->getClassDescription(vartolinking[0] ) << "): ";
3836  bool first = true;
3837  for( int v = 0; v < partition->getNVars(); ++v )
3838  {
3839  if( partition->getClassOfVar(v ) == vartolinking[0] )
3840  {
3841  if( first )
3842  {
3843  output << SCIPvarGetName(detprobdata->getVar(v));
3844  first = false;
3845  }
3846  else
3847  {
3848  output << ", " << SCIPvarGetName(detprobdata->getVar(v));
3849  }
3850  }
3851  }
3852  output << std::endl;
3853  }
3854  else
3855  {
3856  output << " " << partition->getClassName(vartolinking[0] );
3857  }
3858  }
3859 
3860  for( size_t i = 1; i < vartolinking.size(); ++i )
3861  {
3862  if( displayConssVars )
3863  {
3864  output << " " << partition->getClassName(vartolinking[i] ) << " ("
3865  << partition->getClassDescription(vartolinking[i] ) << "): ";
3866  bool first = true;
3867  for( int v = 0; v < partition->getNVars(); ++v )
3868  {
3869  if( partition->getClassOfVar(v ) == vartolinking[i] )
3870  {
3871  if( first )
3872  {
3873  output << SCIPvarGetName(detprobdata->getVar(v));
3874  first = false;
3875  }
3876  else
3877  {
3878  output << ", " << SCIPvarGetName(detprobdata->getVar(v));
3879  }
3880  }
3881  }
3882  output << std::endl;
3883  }
3884  else
3885  {
3886  output << ", " << partition->getClassName(vartolinking[i] );
3887  }
3888  }
3889 
3890  if ( !displayConssVars || vartolinking.empty() )
3891  {
3892  output << std::endl;
3893  }
3894 
3895  output << " Pushed to master:";
3896 
3897  if( !vartomaster.empty() )
3898  {
3899  if( displayConssVars )
3900  {
3901  output << std::endl << " " << partition->getClassName(vartomaster[0] ) << " ("
3902  << partition->getClassDescription(vartomaster[0] ) << "): ";
3903  bool first = true;
3904  for( int v = 0; v < partition->getNVars(); ++v )
3905  {
3906  if( partition->getClassOfVar(v ) == vartomaster[0] )
3907  {
3908  if( first )
3909  {
3910  output << SCIPvarGetName(detprobdata->getVar(v));
3911  first = false;
3912  }
3913  else
3914  {
3915  output << ", " << SCIPvarGetName(detprobdata->getVar(v));
3916  }
3917  }
3918  }
3919  output << std::endl;
3920  }
3921  else
3922  {
3923  output << " " << partition->getClassName(vartomaster[0] );
3924  }
3925  }
3926 
3927  for( size_t i = 1; i < vartomaster.size(); ++i )
3928  {
3929  if( displayConssVars )
3930  {
3931  output << " " << partition->getClassName(vartomaster[i] ) << " ("
3932  << partition->getClassDescription(vartomaster[i] ) << "): ";
3933  bool first = true;
3934  for( int v = 0; v < partition->getNVars(); ++v )
3935  {
3936  if( partition->getClassOfVar(v ) == vartolinking[i] )
3937  {
3938  if( first )
3939  {
3940  output << SCIPvarGetName(detprobdata->getVar(v));
3941  first = false;
3942  }
3943  else
3944  {
3945  output << ", " << SCIPvarGetName(detprobdata->getVar(v));
3946  }
3947  }
3948  }
3949  output << std::endl;
3950  }
3951  else
3952  {
3953  output << ", " << partition->getClassName(vartomaster[i] );
3954  }
3955  }
3956 
3957  if ( !displayConssVars || vartomaster.empty() )
3958  {
3959  output << std::endl;
3960  }
3961  }
3962 
3963  return output.str();
3964 }
3965 
3966 
3968 {
3969  return isfinishedbyfinisher;
3970 }
3971 
3972 
3974 {
3975  calcHashvalue();
3976  return hashvalue;
3977 }
3978 
3979 
3981 {
3982  return id;
3983 }
3984 
3985 
3987 {
3988  return linkingvars;
3989 }
3990 
3991 
3993 {
3994  return masterconss;
3995 }
3996 
3997 
3998 std::vector<int>& PARTIALDECOMP::getMastervars()
3999 {
4000  return mastervars;
4001 }
4002 
4003 
4005  int blockid
4006  ){
4007 
4008  if( !calculatedncoeffsforblock )
4009  calcNCoeffsForBlocks();
4010 
4011  return ncoeffsforblock[blockid];
4012 }
4013 
4014 
4016  ){
4017 
4018  if( !calculatedncoeffsforblock )
4019  calcNCoeffsForBlocks();
4020 
4021  return ncoeffsformaster;
4022 }
4023 
4024 
4026  SCORETYPE type
4027 )
4028 {
4029  /* if there are indicator constraints in the master we want to reject this decomposition */
4030  for( int mc = 0; mc < getNMasterconss(); ++mc )
4031  {
4032  SCIP_CONS* cons;
4033  cons = getDetprobdata()->getCons(getMasterconss()[mc]);
4034  if( GCGconsGetType(scip, cons) == consType::indicator )
4035  return 0.;
4036  }
4037 
4038  if( type == scoretype::MAX_WHITE )
4039  {
4040  if( maxwhitescore == -1. )
4041  GCGconshdlrDecompCalcMaxWhiteScore(scip, this->id, &maxwhitescore);
4042  return maxwhitescore;
4043  }
4044  else if( type == scoretype::CLASSIC )
4045  {
4046  if ( classicscore == -1. )
4047  GCGconshdlrDecompCalcClassicScore(scip, this->id, &classicscore);
4048  return classicscore;
4049  }
4050  else if( type == scoretype::BORDER_AREA )
4051  {
4052  if( borderareascore == -1. )
4053  GCGconshdlrDecompCalcBorderAreaScore(scip, this->id, &borderareascore);
4054  return borderareascore;
4055  }
4056  else if( type == scoretype::MAX_FORESSEEING_WHITE )
4057  {
4058  if( maxforeseeingwhitescore == -1. )
4059  GCGconshdlrDecompCalcMaxForseeingWhiteScore(scip, this->id, &maxforeseeingwhitescore);
4060  return maxforeseeingwhitescore;
4061  }
4062  else if( type == scoretype::MAX_FORESEEING_AGG_WHITE )
4063  {
4064  if( maxforeseeingwhitescoreagg == -1. )
4065  GCGconshdlrDecompCalcMaxForeseeingWhiteAggScore(scip, this->id, &maxforeseeingwhitescoreagg);
4066  return maxforeseeingwhitescoreagg;
4067  }
4068  else if( type == scoretype::SETPART_FWHITE )
4069  {
4070  if( setpartfwhitescore == -1. )
4071  GCGconshdlrDecompCalcSetPartForseeingWhiteScore(scip, this->id, &setpartfwhitescore);
4072  return setpartfwhitescore;
4073  }
4074  else if( type == scoretype::SETPART_AGG_FWHITE )
4075  {
4076  if( setpartfwhitescoreagg == -1. )
4077  GCGconshdlrDecompCalcSetPartForWhiteAggScore(scip, this->id, &setpartfwhitescoreagg);
4078  return setpartfwhitescoreagg;
4079  }
4080  else if( type == scoretype::BENDERS )
4081  {
4082  if( bendersscore == -1. )
4083  GCGconshdlrDecompCalcBendersScore(scip, this->id, &bendersscore);
4084  return bendersscore;
4085  }
4086  else if( type == scoretype::STRONG_DECOMP )
4087  {
4088  if( strongdecompositionscore == -1. )
4089  GCGconshdlrDecompCalcStrongDecompositionScore(scip, this->id, &strongdecompositionscore);
4090  return strongdecompositionscore;
4091  }
4092 
4093  return 0;
4094 }
4095 
4096 
4098 {
4099  return usergiven;
4100 }
4101 
4102 
4104 {
4105  return listofancestorids.size();
4106 }
4107 
4108 
4110 {
4111  return nblocks;
4112 }
4113 
4114 
4116 {
4117  return nconss;
4118 }
4119 
4120 
4122  int block
4123  )
4124 {
4125  assert( block >= 0 && block < nblocks );
4126  return (int) conssforblocks[block].size();
4127 }
4128 
4129 
4130 std::vector<std::string>& PARTIALDECOMP::getDetectorchainInfo()
4131 {
4132  return detectorchaininfo;
4133 }
4134 
4135 
4137 {
4138  return (int) detectorchain.size();
4139 }
4140 
4141 
4142 int PARTIALDECOMP::getNUsedPartitions()
4143 {
4144  return (int) usedpartition.size();
4145 }
4146 
4147 
4149 {
4150  return (int) linkingvars.size();
4151 }
4152 
4153 
4155  int detectorchainindex
4156  )
4157 {
4158  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4159 
4160  return nnewblocks[detectorchainindex];
4161 }
4162 
4163 
4165 {
4166  return nnewblocks;
4167 }
4168 
4169 
4171 {
4172  return (int) masterconss.size();
4173 }
4174 
4175 
4177 {
4178  return (int) mastervars.size();
4179 }
4180 
4181 
4183 {
4184  int nstairlinkingvars = 0;
4185  for( int b = 0; b < getNBlocks(); ++ b )
4186  nstairlinkingvars += getNStairlinkingvars( b );
4187 
4188  return nstairlinkingvars;
4189 }
4190 
4191 
4193 {
4194  return (int) openconss.size();
4195 }
4196 
4197 
4199 {
4200  return (int) openvars.size();
4201 }
4202 
4203 
4205 
4206  return nrepblocks;
4207 }
4208 
4209 
4211  int block
4212  )
4213 {
4214  assert( block >= 0 && block < nblocks );
4215  assert( (int) stairlinkingvars.size() > block );
4216  return (int) stairlinkingvars[block].size();
4217 }
4218 
4219 
4221 {
4222  return nvars;
4223 }
4224 
4225 
4227  int block
4228  )
4229 {
4230  assert( block >= 0 && block < nblocks );
4231  return (int) varsforblocks[block].size();
4232 }
4233 
4234 
4236 {
4237  int count = 0;
4238  for( auto& block : varsforblocks )
4239  {
4240  count += (int) block.size();
4241  }
4242 
4243  return count;
4244 }
4245 
4246 
4248 {
4249  return openconss.data();
4250 }
4251 
4252 
4254 {
4255  return openconss;
4256 }
4257 
4258 
4260 {
4261  return openvars.data();
4262 }
4263 
4264 
4266 {
4267  return openvars;
4268 }
4269 
4270 
4272  int detectorchainindex
4273  )
4274 {
4275  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4276 
4277  return pctvarstoborder[detectorchainindex];
4278 }
4279 
4280 
4282 {
4283  return pctvarstoborder;
4284 }
4285 
4286 
4288  std::vector<SCIP_Real>& newvector
4289  )
4290 {
4291  pctvarstoborder = newvector;
4292 }
4293 
4294 
4296  int detectorchainindex
4297  )
4298 {
4299  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4300 
4301  return pctvarstoblock[detectorchainindex];
4302 }
4303 
4304 
4306 {
4307  return pctvarstoblock;
4308 }
4309 
4310 
4311 
4313  std::vector<SCIP_Real>& newvector
4314 )
4315 {
4316  pctvarstoblock = newvector;
4317 }
4318 
4319 
4321  int detectorchainindex
4322  )
4323 {
4324  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4325 
4326  return pctvarsfromfree[detectorchainindex];
4327 }
4328 
4329 
4331 {
4332  return pctvarsfromfree;
4333 }
4334 
4335 
4337  std::vector<SCIP_Real>& newvector
4338  )
4339 {
4340  pctvarsfromfree = newvector;
4341 }
4342 
4343 
4345  int detectorchainindex
4346  )
4347 {
4348  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4349 
4350  return pctconsstoborder[detectorchainindex];
4351 }
4352 
4353 
4355 {
4356  return pctconsstoborder;
4357 }
4358 
4359 
4361  std::vector<SCIP_Real>& newvector
4362  )
4363 {
4364  pctconsstoborder = newvector;
4365 }
4366 
4367 
4369  int detectorchainindex
4370  )
4371 {
4372  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4373 
4374  return pctconsstoblock[detectorchainindex];
4375 }
4376 
4377 
4379 {
4380  return pctconsstoblock;
4381 }
4382 
4383 
4385  std::vector<SCIP_Real>& newvector
4386  )
4387 {
4388  pctconsstoblock = newvector;
4389 }
4390 
4391 
4393  int detectorchainindex
4394  )
4395 {
4396  assert( 0 <= detectorchainindex && detectorchainindex < (int) detectorchain.size() );
4397 
4398  return pctconssfromfree[detectorchainindex];
4399 }
4400 
4401 
4403 {
4404  return pctconssfromfree;
4405 }
4406 
4407 
4409  int blockid
4410  )
4411 {
4412  return blockstorep[blockid];
4413 }
4414 
4416  int repid,
4417  int blockrepid
4418  )
4419 {
4420  return pidtopidvarmaptofirst[repid][blockrepid];
4421 }
4422 
4423 
4425 {
4426  DETPROBDATA* detprobdata;
4427  if( original )
4428  detprobdata = GCGconshdlrDecompGetDetprobdataOrig(scip);
4429  else
4430  detprobdata = GCGconshdlrDecompGetDetprobdataPresolved(scip);
4431 
4432  assert(detprobdata != NULL);
4433 
4434  return detprobdata;
4435 }
4436 
4437 
4439  std::vector<SCIP_Real>& newvector
4440  )
4441 {
4442  pctconssfromfree = newvector;
4443 }
4444 
4445 
4447  int block
4448  )
4449 {
4450  assert( block >= 0 && block < nblocks );
4451  return stairlinkingvars[block].data();
4452 }
4453 
4454 
4455 void PARTIALDECOMP::getVarPartitionData(
4456  int detectorchainindex,
4458  std::vector<int>& varclasseslinking,
4459  std::vector<int>& varclassesmaster
4460  )
4461 {
4462  assert(varPartitionUsed(detectorchainindex) );
4463 
4464  *partition = dynamic_cast<VarPartition*>( usedpartition[detectorchainindex] );
4465  varclasseslinking = classestolinking[detectorchainindex];
4466  varclassesmaster = classestomaster[detectorchainindex];
4467 }
4468 
4469 
4471  int block
4472  )
4473 {
4474  assert( block >= 0 && block < nblocks );
4475  return varsforblocks[block];
4476 }
4477 
4478 
4480  int varid,
4481  int block
4482  )
4483 {
4484  std::vector<int>::iterator lb = lower_bound( varsforblocks[block].begin(), varsforblocks[block].end(), varid );
4485 
4486  if( lb != varsforblocks[block].end() )
4487  return (int) ( lb - varsforblocks[block].begin() );
4488  else
4489  return -1;
4490 
4491 }
4492 
4493 
4495 {
4496  return ( 0 == getNOpenconss() && 0 == getNOpenvars() );
4497 }
4498 
4499 
4500 bool PARTIALDECOMP::isConsBlockconsOfBlock(
4501  int cons,
4502  int block
4503  )
4504 {
4505  assert( cons >= 0 && cons < nconss );
4506  assert( block >= 0 && block < nblocks );
4507  std::vector<int>::iterator lb = lower_bound( conssforblocks[block].begin(), conssforblocks[block].end(), cons );
4508  if( lb != conssforblocks[block].end() && *lb == cons )
4509  return true;
4510  else
4511  return false;
4512 }
4513 
4514 
4516  int cons
4517  )
4518 {
4519  assert( cons >= 0 && cons < nconss );
4520  return isconsmaster[cons];
4521 }
4522 
4523 
4525  int cons
4526  )
4527 {
4528  assert( cons >= 0 && cons < nconss );
4529  return isconsopen[cons];
4530 }
4531 
4532 
4534 {
4535  return original;
4536 }
4537 
4538 
4540  PARTIALDECOMP* otherpartialdec,
4541  SCIP_Bool* isequal,
4542  bool sortpartialdecs
4543  )
4544 {
4545  if( sortpartialdecs )
4546  {
4547  sort();
4548  otherpartialdec->sort();
4549  }
4550 
4551  * isequal = isEqual( otherpartialdec );
4552 
4553  return SCIP_OKAY;
4554 }
4555 
4556 
4558  PARTIALDECOMP* other
4559  )
4560 {
4561  if( getNMasterconss() != other->getNMasterconss() || getNMastervars() != other->getNMastervars()
4562  || getNBlocks() != other->getNBlocks() || getNLinkingvars() != other->getNLinkingvars() )
4563  return false;
4564 
4565  std::vector<std::pair<int, int>> blockorderthis;
4566  std::vector<std::pair<int, int>> blockorderother;
4567 
4568  /* find sorting for blocks (non decreasing according smallest row index) */
4569  for( int i = 0; i < this->nblocks; ++ i )
4570  {
4571  blockorderthis.emplace_back(i, conssforblocks[i][0]);
4572  blockorderother.emplace_back(i, other->conssforblocks[i][0]);
4573  }
4574 
4575  std::sort(blockorderthis.begin(), blockorderthis.end(), compare_blocks);
4576  std::sort(blockorderother.begin(), blockorderother.end(), compare_blocks);
4577 
4578  /* compares the number of stairlinking vars */
4579  for( int b = 0; b < getNBlocks(); ++ b )
4580  {
4581  int blockthis = blockorderthis[b].first;
4582  int blockother = blockorderother[b].first;
4583 
4584  if( getNStairlinkingvars(blockthis) != other->getNStairlinkingvars(blockother) )
4585  return false;
4586  }
4587 
4588  /* compares the number of constraints and variables in the blocks*/
4589  for( int b = 0; b < getNBlocks(); ++ b )
4590  {
4591  int blockthis = blockorderthis[b].first;
4592  int blockother = blockorderother[b].first;
4593 
4594  if( ( getNVarsForBlock( blockthis ) != other->getNVarsForBlock(blockother) )
4595  || ( getNConssForBlock( blockthis ) != other->getNConssForBlock(blockother) ) )
4596  return false;
4597  }
4598 
4599  /* compares the master cons */
4600  for( int j = 0; j < getNMasterconss(); ++ j )
4601  {
4602  if( getMasterconss()[j] != other->getMasterconss()[j] )
4603  return false;
4604  }
4605 
4606  /* compares the master vars */
4607  for( int j = 0; j < getNMastervars(); ++ j )
4608  {
4609  if( getMastervars()[j] != other->getMastervars()[j] )
4610  return false;
4611  }
4612 
4613  /* compares the constrains and variables in the blocks */
4614  for( int b = 0; b < getNBlocks(); ++ b )
4615  {
4616  int blockthis = blockorderthis[b].first;
4617  int blockother = blockorderother[b].first;
4618 
4619  for( int j = 0; j < getNConssForBlock( blockthis ); ++ j )
4620  {
4621  if( getConssForBlock( blockthis )[j] != other->getConssForBlock(blockother)[j] )
4622  return false;
4623  }
4624 
4625  for( int j = 0; j < getNVarsForBlock( blockthis ); ++ j )
4626  {
4627  if( getVarsForBlock(blockthis)[j] != other->getVarsForBlock(blockother)[j] )
4628  return false;
4629  }
4630 
4631  for( int j = 0; j < getNStairlinkingvars( blockthis ); ++ j )
4632  {
4633  if( getStairlinkingvars(blockthis)[j] != other->getStairlinkingvars(blockother)[j] )
4634  return false;
4635  }
4636  }
4637 
4638  /* compares the linking vars */
4639  for( int j = 0; j < getNLinkingvars(); ++ j )
4640  {
4641  if( getLinkingvars()[j] != other->getLinkingvars()[j] )
4642  return false;
4643  }
4644 
4645  return true;
4646 }
4647 
4648 
4650  DEC_DETECTOR* detector
4651  )
4652 {
4653  std::vector<DEC_DETECTOR*>::const_iterator iter = std::find(detectorchain.begin(), detectorchain.end(), detector);
4654 
4655  return iter != detectorchain.end();
4656 }
4657 
4658 
4660 {
4661  if( getNBlocks() == 1 && (SCIP_Real) getNConssForBlock( 0 ) >= 0.95 * getNConss() )
4662  return true;
4663 
4664  if( getNConss() == getNMasterconss() )
4665  return true;
4666 
4667  if( getNConss() == getNOpenconss() && getNVars() == getNOpenvars() )
4668  return true;
4669 
4670  if( getNVars() == getNMastervars() + getNLinkingvars() )
4671  return true;
4672 
4673  return false;
4674 }
4675 
4676 
4678 {
4679  return isselected;
4680 }
4681 
4682 
4684  int var,
4685  int block
4686  )
4687 {
4688  assert( var >= 0 && var < nvars );
4689  assert( block >= 0 && block < nconss );
4690 
4691  std::vector<int>::iterator lb = lower_bound(varsforblocks[block].begin(), varsforblocks[block].end(), var);
4692  if( lb != varsforblocks[block].end() && *lb == var )
4693  return true;
4694  else
4695  return false;
4696 }
4697 
4698 
4700  int var
4701  )
4702 {
4703  assert( var >= 0 && var < nvars );
4704  return isvarmaster[var];
4705 }
4706 
4707 
4709  int var
4710  )
4711 {
4712  assert( var >= 0 && var < nvars );
4713  std::vector<int>::iterator lb = lower_bound(linkingvars.begin(), linkingvars.end(), var);
4714  if( lb != linkingvars.end() && *lb == var )
4715  return true;
4716  else
4717  return false;
4718 }
4719 
4720 
4722  int var
4723  )
4724 {
4725  assert( var >= 0 && var < nvars );
4726  return isvaropen[var];
4727 }
4728 
4729 
4731  int var
4732  )
4733 {
4734  for( int b = 0; b < nblocks; ++ b )
4735  {
4736  std::vector<int>::iterator lb = lower_bound(stairlinkingvars[b].begin(), stairlinkingvars[b].end(), var);
4737  if( lb != stairlinkingvars[b].end() && *lb == var )
4738  return true;
4739  }
4740  return false;
4741 }
4742 
4743 
4745  int var,
4746  int block
4747  )
4748 {
4749  assert( var >= 0 && var < nvars );
4750  assert( block >= 0 && block < nblocks );
4751  std::vector<int>::iterator lb = lower_bound(stairlinkingvars[block].begin(), stairlinkingvars[block].end(), var);
4752  if( lb != stairlinkingvars[block].end() && *lb == var )
4753  return true;
4754  else
4755  {
4756  if( block == 0 )
4757  return false;
4758  else
4759  {
4760  lb = lower_bound(stairlinkingvars[block - 1].begin(), stairlinkingvars[block - 1].end(), var);
4761  return ( lb != stairlinkingvars[block-1].end() && *lb == var );
4762  }
4763  }
4764 }
4765 
4766 
4768  SCIP* givenscip,
4769  FILE* file
4770  )
4771 {
4772 
4773  int nusedpartitions = (int) getNUsedPartitions();
4774  int nconspartitions = 0;
4775  int nvarpartitions = 0;
4776 
4777  for( int i = 0; i < nusedpartitions; ++i)
4778  {
4779  if( usedpartition[i] == NULL )
4780  continue;
4781 
4782  if( dynamic_cast<ConsPartition*>( usedpartition[i] ) != NULL )
4783  {
4784  /* partition is cons partition */
4785  ++nconspartitions;
4786  }
4787  else
4788  {
4789  /* partition is var partition */
4790  ++nvarpartitions;
4791  }
4792  }
4793 
4794  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", nconspartitions);
4795 
4796  for( int i = 0; i < nusedpartitions; ++i)
4797  {
4798  if( dynamic_cast<ConsPartition*>( usedpartition[i] ) != NULL )
4799  {
4800  /* partition is cons partition */
4801  int nmasterclasses = (int) classestomaster[i].size();
4802  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%s\n", usedpartition[i]->getName());
4803  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", nmasterclasses);
4804  for ( int mclass = 0; mclass < (int) classestomaster[i].size(); ++mclass )
4805  {
4806  int classid = classestomaster[i][mclass];
4807  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%s\n", usedpartition[i]->getClassName(classid));
4808  }
4809  }
4810  }
4811 
4812  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", nvarpartitions);
4813 
4814  for( int i = 0; i < nusedpartitions; ++i)
4815  {
4816  if( dynamic_cast<VarPartition*>( usedpartition[i] ) != NULL )
4817  {
4818  /* partition is var partition */
4819  int nmasterclasses = (int) classestomaster[i].size();
4820  int nlinkingclasses = (int) classestolinking[i].size();
4821  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%s\n", usedpartition[i]->getName());
4822  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", nmasterclasses);
4823  for ( int mclass = 0; mclass < (int) classestomaster[i].size(); ++mclass )
4824  {
4825  int classid = classestomaster[i][mclass];
4826  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%s : %s\n", usedpartition[i]->getClassName(classid), usedpartition[i]->getClassDescription(classid));
4827  }
4828 
4829  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%d\n", nlinkingclasses );
4830  for ( int linkingclass = 0; linkingclass < nlinkingclasses; ++linkingclass )
4831  {
4832  int classid = classestolinking[i][linkingclass];
4833  SCIPmessageFPrintInfo(SCIPgetMessagehdlr(scip), file, "%s : %s\n", usedpartition[i]->getClassName(classid), usedpartition[i]->getClassDescription(classid));
4834  }
4835 
4836  }
4837  }
4838 }
4839 
4840 
4842  )
4843 {
4844  bool success = true;
4845 
4846  while( success )
4847  success = assignHittingOpenconss() || assignHittingOpenvars();
4848  sort();
4849 }
4850 
4851 
4853  )
4854 {
4856  assignOpenPartialHittingToMaster();
4857 }
4858 
4859 
4861  int detectorchainindex,
4863  std::vector<int>& consclassesmaster
4864  )
4865 {
4866  assert( 0 <= detectorchainindex );
4867 
4868  if( detectorchainindex >= (int) usedpartition.size() )
4869  {
4870  usedpartition.resize(detectorchainindex + 1);
4871  classestomaster.resize(detectorchainindex + 1);
4872  }
4873 
4874  usedpartition[detectorchainindex] = partition;
4875  classestomaster[detectorchainindex] = consclassesmaster;
4876 }
4877 
4878 
4880  int consToBlock,
4881  int block
4882  )
4883 {
4884  assert( consToBlock >= 0 && consToBlock < nconss );
4885  assert( block >= 0 && block < nblocks );
4886  assert( (int) conssforblocks.size() > block );
4887 
4888  conssforblocks[block].push_back( consToBlock );
4889  conssforblocksorted = false;
4890  hvoutdated = true;
4891 }
4892 
4893 
4895  int cons,
4896  int block
4897  )
4898 {
4899  assert( cons >= 0 && cons < nconss );
4900  assert( isconsopen[cons] );
4901 
4902  if( block >= nblocks )
4903  setNBlocks(block+1);
4904  assert( block >= 0 && block < nblocks );
4905 
4906  setConsToBlock(cons, block);
4907  deleteOpencons(cons);
4908 }
4909 
4911  SCIP_CONS* cons, /**< pointer of the constraint */
4912  int block /**< block index (counting from 0) */
4913  )
4914 {
4915  int consindex = getDetprobdata()->getIndexForCons(cons);
4916 
4917  if( consindex >= 0 )
4918  {
4919  fixConsToBlock(consindex, block);
4920  return true;
4921  }
4922  return false;
4923 }
4924 
4925 
4927  int consToMaster
4928  )
4929 {
4930  assert( consToMaster >= 0 && consToMaster < nconss );
4931  masterconss.push_back( consToMaster );
4932  isconsmaster[consToMaster] = true;
4933  masterconsssorted = false;
4934  hvoutdated = true;
4935 }
4936 
4937 
4938 std::vector<int>::const_iterator PARTIALDECOMP::fixConsToMaster(
4939  std::vector<int>::const_iterator itr
4940  )
4941 {
4942  assert(itr != openconss.cend());
4943  assert(isconsopen[*itr]);
4944  setConsToMaster(*itr);
4945  return deleteOpencons(itr);
4946 }
4947 
4948 
4950  int cons
4951  )
4952 {
4953  assert( cons >= 0 && cons < nconss );
4954  assert(isconsopen[cons]);
4955 
4956  setConsToMaster(cons);
4957  deleteOpencons(cons);
4958 }
4959 
4961  SCIP_CONS* cons /**< pointer of cons to fix as master cons */
4962  )
4963 {
4964  int consindex = getDetprobdata()->getIndexForCons(cons);
4965  if( consindex >= 0 )
4966  {
4967  fixConsToMaster(consindex);
4968  return true;
4969  }
4970  return false;
4971 }
4972 
4973 
4975  std::vector<DEC_DETECTOR*>& givenDetectorChain
4976  )
4977 {
4978  detectorchain = givenDetectorChain;
4979 }
4980 
4981 
4983  DEC_DETECTOR* detectorID
4984  )
4985 {
4986  detectorchain.push_back(detectorID);
4987  addEmptyPartitionStatistics();
4988 }
4989 
4990 
4992  DEC_DETECTOR* detectorID
4993  )
4994 {
4995  isfinishedbyfinisher = true;
4996  detectorchain.push_back(detectorID);
4997  addEmptyPartitionStatistics();
4998 }
4999 
5000 
5002  DEC_DETECTOR* detectorID
5003  )
5004 {
5005  isfinishedbyfinisherorig = true;
5006 }
5007 
5008 
5010  bool finished
5011  )
5012 {
5013  isfinishedbyfinisher = finished;
5014 }
5015 
5016 
5018  bool finished
5019  )
5020 {
5021  isfinishedbyfinisherorig = finished;
5022 }
5023 
5024 
5026  int newNBlocks
5027  )
5028 {
5029  assert( newNBlocks >= nblocks );
5030 
5031  assert( (int) conssforblocks.size() == nblocks );
5032  assert( (int) varsforblocks.size() == nblocks );
5033  assert( (int) stairlinkingvars.size() == nblocks );
5034  /* increase number of blocks in conssforblocks and varsforblocks */
5035 
5036  for( int b = nblocks; b < newNBlocks; ++ b )
5037  {
5038  conssforblocks.emplace_back(0);
5039  varsforblocks.emplace_back(0);
5040  stairlinkingvars.emplace_back(0);
5041  }
5042 
5043  nblocks = newNBlocks;
5044 }
5045 
5046 
5048  bool selected
5049  )
5050 {
5051  isselected = selected;
5052 }
5053 
5054 
5056  bool fromorig
5057  )
5058 {
5059  stemsfromorig = fromorig;
5060 }
5061 
5062 
5064  USERGIVEN givenusergiven
5065  )
5066 {
5067  usergiven = givenusergiven;
5068 }
5069 
5070 
5072  int detectorchainindex,
5074  std::vector<int>& varclasseslinking,
5075  std::vector<int>& varclassesmaster
5076  )
5077 {
5078  assert( 0 <= detectorchainindex );
5079 
5080  if( detectorchainindex >= (int) usedpartition.size() )
5081  {
5082  usedpartition.resize(detectorchainindex + 1);
5083  classestomaster.resize(detectorchainindex + 1);
5084  classestolinking.resize(detectorchainindex + 1);
5085  }
5086 
5087 
5088  usedpartition[detectorchainindex] = partition;
5089  classestolinking[detectorchainindex] = varclasseslinking;
5090  classestomaster[detectorchainindex] = varclassesmaster;
5091 }
5092 
5093 
5095  int varToBlock,
5096  int block
5097  )
5098 {
5099  assert( varToBlock >= 0 && varToBlock < nvars );
5100  assert( block >= 0 && block < nblocks );
5101  assert( (int) varsforblocks.size() > block );
5102 
5103  varsforblocks[block].push_back(varToBlock);
5104  varsforblocksorted = false;
5105  hvoutdated = true;
5106 }
5107 
5108 
5110  int var,
5111  int block
5112  )
5113 {
5114  assert( var >= 0 && var < nvars );
5115  assert( isvaropen[var] );
5116  assert( block >= 0 && block < nblocks );
5117 
5118  if( isVarLinkingvar(var) )
5119  return;
5120 
5121  setVarToBlock(var, block);
5122  deleteOpenvar(var);
5123 }
5124 
5125 
5126 std::vector<int>::const_iterator PARTIALDECOMP::fixVarToBlock(
5127  std::vector<int>::const_iterator itr,
5128  int block
5129 )
5130 {
5131  assert( itr != openvars.cend() );
5132  assert( isvaropen[*itr] );
5133  assert( block >= 0 && block < nblocks );
5134 
5135  if( isVarLinkingvar(*itr) )
5136  return ++itr;
5137 
5138  setVarToBlock(*itr, block);
5139  return deleteOpenvar(itr);
5140 }
5141 
5142 
5144  int varToLinking
5145  )
5146 {
5147  assert( varToLinking >= 0 && varToLinking < nvars );
5148  linkingvars.push_back( varToLinking );
5149  linkingvarssorted = false;
5150  hvoutdated = true;
5151 }
5152 
5153 
5155  int var
5156  )
5157 {
5158  assert( var >= 0 && var < nvars );
5159  assert( isvaropen[var]);
5160 
5161  setVarToLinking(var);
5162  deleteOpenvar(var);
5163 
5164  // delete this var in blocks
5165  for(auto block : varsforblocks)
5166  {
5167  for(auto iter = block.begin(); iter != block.end(); iter++)
5168  {
5169  if((*iter) == var)
5170  block.erase(iter);
5171  }
5172  }
5173 }
5174 
5175 
5176 std::vector<int>::const_iterator PARTIALDECOMP::fixVarToLinking(
5177  std::vector<int>::const_iterator itr
5178 )
5179 {
5180  assert( itr != openvars.cend() );
5181  assert( isvaropen[*itr] );
5182 
5183  setVarToLinking(*itr);
5184 
5185  // delete this var in blocks
5186  for(auto block : varsforblocks)
5187  {
5188  for(auto iter = block.begin(); iter != block.end(); iter++)
5189  {
5190  if((*iter) == *itr)
5191  block.erase(iter);
5192  }
5193  }
5194  return deleteOpenvar(itr);;
5195 }
5196 
5197 
5199  int varToMaster
5200  )
5201 {
5202  assert( varToMaster >= 0 && varToMaster < nvars );
5203  mastervars.push_back( varToMaster );
5204  isvarmaster[varToMaster] = true;
5205  mastervarssorted = false;
5206  hvoutdated = true;
5207 }
5208 
5209 
5211  int var
5212  )
5213 {
5214  assert( var >= 0 && var < nvars );
5215  assert( isvaropen[var]);
5216 
5217  setVarToMaster(var);
5218  deleteOpenvar(var);
5219 }
5220 
5221 
5222 std::vector<int>::const_iterator PARTIALDECOMP::fixVarToMaster(
5223  std::vector<int>::const_iterator itr
5224 )
5225 {
5226  assert( itr != openvars.cend() );
5227  assert( isvaropen[*itr] );
5228 
5229  setVarToMaster(*itr);
5230  return deleteOpenvar(itr);
5231 }
5232 
5233 
5235  int varToStairlinking,
5236  int block1,
5237  int block2
5238  )
5239 {
5240  assert( varToStairlinking >= 0 && varToStairlinking < nvars );
5241  assert( block1 >= 0 && block1 <= nblocks );
5242  assert( block2 >= 0 && block2 <= nblocks );
5243  assert( ( block1 + 1 == block2 ) || ( block2 + 1 == block1 ) );
5244 
5245  if( block1 > block2 )
5246  stairlinkingvars[block2].push_back( varToStairlinking );
5247  else
5248  stairlinkingvars[block1].push_back( varToStairlinking );
5249 
5250  stairlinkingvarsforblocksorted = false;
5251  hvoutdated = true;
5252 }
5253 
5254 
5256  int var,
5257  int firstblock
5258  )
5259 {
5260  assert( isvaropen[var]);
5261  assert( var >= 0 && var < nvars );
5262  assert( firstblock >= 0 && firstblock < ( nblocks - 1 ) );
5263 
5264  setVarToStairlinking(var, firstblock, firstblock + 1);
5265  deleteOpenvar(var);
5266 }
5267 
5268 
5269 std::vector<int>::const_iterator PARTIALDECOMP::fixVarToStairlinking(
5270  std::vector<int>::const_iterator itr,
5271  int firstblock
5272 )
5273 {
5274  assert( isvaropen[*itr]);
5275  assert( itr != openvars.cend() );
5276  assert( firstblock >= 0 && firstblock < ( nblocks - 1 ) );
5277 
5278  setVarToStairlinking(*itr, firstblock, firstblock + 1);
5279  return openvars.erase(itr);
5280 }
5281 
5282 
5284  const char* consname, /**< name of the constraint */
5285  int blockid /**< block index (counting from 0) */
5286  )
5287 {
5288  int consindex = getDetprobdata()->getIndexForCons(consname);
5289 
5290  if( consindex >= 0 )
5291  {
5292  fixConsToBlock(consindex, blockid);
5293  return true;
5294  }
5295  return false;
5296 }
5297 
5298 
5300  const char* varname,
5301  int blockid
5302  )
5303 {
5304  int varindex = getDetprobdata()->getIndexForVar(varname);
5305 
5306  if( varindex >= 0 )
5307  {
5308  if( blockid >= nblocks )
5309  nblocks = blockid + 1;
5310  fixVarToBlock(varindex, blockid);
5311  return true;
5312  }
5313  return false;
5314 }
5315 
5316 
5318  const char* consname /**< name of cons to fix as master cons */
5319  )
5320 {
5321  int consindex = getDetprobdata()->getIndexForCons(consname);
5322  if( consindex >= 0 )
5323  {
5324  fixConsToMaster(consindex);
5325  return true;
5326  }
5327  return false;
5328 }
5329 
5330 
5332  const char* varname
5333  )
5334 {
5335  int varindex = getDetprobdata()->getIndexForVar(varname);
5336  if( varindex >= 0 )
5337  {
5338  fixVarToMaster(varindex);
5339  return true;
5340  }
5341  return false;
5342 }
5343 
5344 
5346  const char* varname /**< name of the variable */
5347  )
5348 {
5349  int varindex = getDetprobdata()->getIndexForVar(varname);
5350  if( varindex >= 0 )
5351  {
5352  fixVarToLinking(varindex);
5353  return true;
5354  }
5355  return false;
5356 }
5357 
5358 
5360 {
5361  int returnvalue;
5362 
5363  /* get names for gp file and output file */
5364  char filename[SCIP_MAXSTRLEN];
5365  char outname[SCIP_MAXSTRLEN];
5366  GCGgetVisualizationFilename(scip, this, ".gp", filename);
5367  GCGgetVisualizationFilename(scip, this, ".pdf", outname);
5368 
5369  this->generateVisualization(filename, outname);
5370 
5371  /* open outputfile */
5372  char command[SCIP_MAXSTRLEN];
5373  /* command: e.g. evince "outname" && rm "filename" */
5374  strcpy(command, GCGVisuGetPdfReader(scip));
5375  strcat(command, " \"");
5376  strcat(command, outname);
5377  strcat(command, "\" && rm \"");
5378  strcat(command, filename);
5379  strcat(command, "\"");
5380 #ifdef SCIP_DEBUG
5381  SCIPinfoMessage(scip, NULL, "%s\n", command);
5382 #endif
5383  returnvalue = system(command);
5384  if( returnvalue == -1 )
5385  SCIPwarningMessage(scip, "Unable to open gnuplot file\n");
5386  SCIPinfoMessage(scip, NULL, "Please note that the generated pdf file was not deleted automatically! \n");
5387 }
5388 
5390  char* filename,
5391  char* outname,
5392  GP_OUTPUT_FORMAT outputformat
5393  )
5394 {
5395  this->writeVisualizationFile(filename, outname, outputformat);
5396 
5397  int returnvalue;
5398 
5399  /* compile gp file */
5400  char command[SCIP_MAXSTRLEN];
5401  /* command: gnuplot "filename" */
5402  strcpy(command, "gnuplot \"");
5403  strcat(command, filename);
5404  strcat(command, "\"");
5405 #ifdef SCIP_DEBUG
5406  SCIPinfoMessage(scip, NULL, "%s\n", command);
5407 #endif
5408  returnvalue = system(command);
5409  if( returnvalue == -1 )
5410  {
5411  SCIPwarningMessage(scip, "Unable to write gnuplot file\n");
5412  return;
5413  }
5414 }
5415 
5417  char* filename,
5418  char* outname,
5419  GP_OUTPUT_FORMAT outputformat
5420  )
5421 {
5422  /* generate gp file */
5423  GCGwriteGpVisualizationFormat( scip, filename, outname, getID(), outputformat );
5424 }
5425 
5426 
5428 {
5429  /* get names for gp file and output file */
5430  char filename[SCIP_MAXSTRLEN];
5431  char outname[SCIP_MAXSTRLEN];
5432  GCGgetVisualizationFilename(scip, this, ".gp", filename);
5433  GCGgetVisualizationFilename(scip, this, ".pdf", outname);
5434 
5435  /* generate gp file */
5436  GCGwriteGpVisualization( scip, filename, outname, getID() );
5437 }
5438 
5440 {
5441  return usergiven == USERGIVEN::COMPLETED_CONSTOMASTER;
5442 }
5443 
5444 
5446 {
5447  if( varsforblocksorted && stairlinkingvarsforblocksorted && conssforblocksorted && linkingvarssorted
5448  && mastervarssorted && masterconsssorted )
5449  {
5450  return false;
5451  }
5452 
5453  for( int b = 0; b < nblocks; ++ b )
5454  {
5455  if( !varsforblocksorted )
5456  std::sort( varsforblocks[b].begin(), varsforblocks[b].end() );
5457  if( !stairlinkingvarsforblocksorted )
5458  std::sort( stairlinkingvars[b].begin(), stairlinkingvars[b].end() );
5459  if( !conssforblocksorted )
5460  std::sort( conssforblocks[b].begin(), conssforblocks[b].end() );
5461  }
5462  if( !linkingvarssorted )
5463  std::sort( linkingvars.begin(), linkingvars.end() );
5464  if( !mastervarssorted )
5465  std::sort( mastervars.begin(), mastervars.end() );
5466  if( !masterconsssorted )
5467  std::sort( masterconss.begin(), masterconss.end() );
5468 
5469  varsforblocksorted = true;
5470  stairlinkingvarsforblocksorted = true;
5471  conssforblocksorted = true;
5472  linkingvarssorted = true;
5473  mastervarssorted = true;
5474  masterconsssorted = true;
5475 
5476  return true;
5477 }
5478 
5479 
5481  char* buffer
5482  )
5483 {
5484  /* set detector chain info string */
5485  SCIPsnprintf( buffer, SCIP_MAXSTRLEN, "" );
5486  if( this->usergiven == USERGIVEN::PARTIAL || this->usergiven == USERGIVEN::COMPLETE
5487  || this->usergiven == USERGIVEN::COMPLETED_CONSTOMASTER || this->getDetectorchain().empty() )
5488  {
5489  char str1[2] = "\0"; /* gives {\0, \0} */
5490  str1[0] = 'U';
5491  (void) strncat( buffer, str1, 1 );
5492  }
5493 
5494  for( int d = 0; d < this->getNDetectors(); ++ d )
5495  {
5496  if( d == 0 && this->getDetectorchain()[d] == NULL )
5497  continue;
5498  char str[2] = "\0"; /* gives {\0, \0} */
5499  str[0] = DECdetectorGetChar( this->getDetectorchain()[d] );
5500  (void) strncat( buffer, str, 1 );
5501  }
5502 }
5503 
5504 
5506 {
5507  return classicscore;
5508 }
5509 
5511  SCIP_Real score
5512  )
5513 {
5514  classicscore = score;
5515 }
5516 
5517 
5519 {
5520  return borderareascore;
5521 }
5522 
5524  SCIP_Real score
5525  )
5526 {
5527  borderareascore = score;
5528 }
5529 
5530 
5532 {
5534 }
5535 
5537  SCIP_Real score
5538  )
5539 {
5540  maxwhitescore = score;
5541 }
5542 
5543 
5545 {
5547 }
5548 
5550  SCIP_Real score
5551  )
5552 {
5553  maxforeseeingwhitescore = score;
5554 }
5555 
5556 
5558 {
5559  return setpartfwhitescore;
5560 }
5561 
5563  SCIP_Real score
5564  )
5565 {
5566  setpartfwhitescore = score;
5567 }
5568 
5569 
5571 {
5572  return maxforeseeingwhitescoreagg;
5573 }
5574 
5576  SCIP_Real score
5577  )
5578 {
5579  maxforeseeingwhitescoreagg = score;
5580 }
5581 
5582 
5584 {
5585  return setpartfwhitescoreagg;
5586 }
5587 
5589  SCIP_Real score
5590  )
5591 {
5592  setpartfwhitescoreagg = score;
5593 }
5594 
5596 {
5597  return bendersscore;
5598 }
5599 
5601  SCIP_Real score
5602  )
5603 {
5604  bendersscore = score;
5605 }
5606 
5607 
5609 {
5610  return strongdecompositionscore;
5611 }
5612 
5614  SCIP_Real score
5615  )
5616 {
5617  strongdecompositionscore = score;
5618 }
5619 
5620 
5622 {
5624  deleteEmptyBlocks(true);
5625  calcHashvalue();
5626 }
5627 
5628 
5629 std::vector<std::vector<int>>& PARTIALDECOMP::getConssForBlocks()
5630 {
5631  return conssforblocks;
5632 }
5633 
5635 {
5636  return getNBlocks() == 0 || getNReps() > 0;
5637 }
5638 
5640 {
5641  return translatedpartialdecid;
5642 }
5643 
5645  int decid
5646  )
5647 {
5648  PARTIALDECOMP::translatedpartialdecid = decid;
5649 }
5650 
5651 } /* namespace gcg */
void addClockTime(SCIP_Real clocktime)
adds detection time of one detector
void removeAncestorID(int ancestorid)
void setFinishedByFinisher(bool finished)
sets whether this partialdec was finished by a finishing detector
bool isConsSetppc(int consindexd)
is cons with specified index partitioning packing, or covering constraint?
int getNConss()
returns the number of variables considered in the detprobdata
bool aggInfoCalculated()
Checks if the aggregation information was already calculated.
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
SCIP_Real getClassicScore()
gets the classic score
SCIP_Bool hasSetppMaster()
checks iff all master constraints set partitioning, or set packing constraints
@ MAX_FORESEEING_AGG_WHITE
structure information for decomposition information in GCG projects
SCIP_RETCODE GCGconshdlrDecompCalcSetPartForseeingWhiteScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the setpartitioning maximum foreseeing white area score of a partialdec
std::vector< int > & getMastervars()
Gets array containing all master vars indices.
SCIP_Real GCGconsGetRhs(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:108
bool isVarStairlinkingvar(int var)
Checks whether the var is a stairlinking var.
std::vector< int > & getVarsForBlock(int block)
Gets array containing vars of a block.
void fixVarToMaster(int var)
adds a variable to the master variables
SCIP_RETCODE GCGconshdlrDecompCalcStrongDecompositionScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the strong decomposition score of a partialdec
void setVarToStairlinking(int varToStairLinking, int block1, int block2)
adds a variable to the stairlinking variables, does not delete this var from list of open vars
int getNOpenvars()
Gets size of vector containing variables not assigned yet.
const char * GCGVisuGetPdfReader(SCIP *scip)
Definition: params_visu.c:609
std::vector< int > & getOpenvarsVec()
void copyPartitionStatistics(const PARTIALDECOMP *otherpartialdec)
copies the given partialdec's partition statistics
SCIP_RETCODE GCGconshdlrDecompCalcClassicScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the classic score of a partialdec
SCIP_Real getBendersScore()
gets the benders score
std::vector< int >::const_iterator fixConsToMaster(std::vector< int >::const_iterator itr)
fixes a constraint to the master constraints
void setMaxForWhiteAggScore(SCIP_Real score)
set the maximum foreseeing white area score with respect to aggregatable blocks
std::vector< int > & getConssForCons(int consIndex)
return array of constraint indices that have a common variable with the given constraint
SCIP_Real GCGconsGetLhs(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:206
void addDetectorChainInfo(const char *decinfo)
add information about the detector chain
void setAncestorList(std::vector< int > &newlist)
USERGIVEN
enumeration to display if a decomposition was given by the user and if so, how it was processed after...
SCIP_Real getPctVarsFromFree(int detectorchainindex)
Gets fraction of variables that are not longer open for a detector.
SCIP_Real getPctConssFromFree(int detectorchainindex)
Gets fraction of constraints that are not longer open for a detector.
void setNBlocks(int nblocks)
sets number of blocks, only increasing number allowed
void setFinishedByFinisherOrig(bool finished)
sets whether this partialdec was finished by a finishing detector in the original problem
std::vector< int > & getOpenconssVec()
Gets a vector containing constraint ids not assigned yet as vector.
bool checkAllConssAssigned()
checks if all conss are assigned
void setVarToMaster(int varToMaster)
adds a variable to the master variables, does not delete this var from list of open vars
SCIP_Real getMaxForWhiteAggScore()
gets the maximum foreseeing white area score with respect to aggregatable blocks
void displayInfo(int detailLevel)
displays the relevant information of the partialdec
void writeVisualizationFile(char *filename, char *outname, GP_OUTPUT_FORMAT outputformat=GP_OUTPUT_FORMAT_PDF)
writes a gp visualization of the partialdec to a file
constraint handler for structure detection
bool isVarOpenvar(int var)
Checks whether the var is an open var.
virtual double getEdgeWeight(int node_i, int node_j)
Definition: graph_gcg.cpp:704
@ BENDERS
std::vector< SCIP_Real > & getPctConssToBlockVector()
Gets fraction of constraints assigned to a block for detectors in detectorchain.
virtual int getNNeighbors(int node)
Definition: graph_gcg.cpp:448
void setPctVarsToBlockVector(std::vector< SCIP_Real > &newvector)
set statistical vector of fractions of variables assigned to a block per involved detector
int getVarProbindexForBlock(int varid, int block)
Gets index in variables array of a block for a variable.
bool isVarBlockvarOfBlock(int var, int block)
Checks whether the var is assigned to the block.
void setVarToLinking(int varToLinking)
adds a variable to the linking variables, does not delete this var from list of open vars
void findVarsLinkingToStairlinking()
reassigns variables classified as linking to stairlinking if appropriate
void addPctConssToBorder(SCIP_Real pct)
adds percentage of constraints assigned to border
std::vector< int > & getMasterconss()
Gets array containing all master conss indices.
@ indicator
Definition: scip_misc.h:49
bool isComplete()
Gets whether this partialdec is complete, i.e. it has no more open constraints and variables.
void fixVarToLinking(int var)
adds a variable to the linking variables
void setTranslatedpartialdecid(int decid)
void setDetectorClockTimes(std::vector< SCIP_Real > &newvector)
set statistical vector of the times that the detectors needed for detecting per involved detector
std::vector< SCIP_Real > & getPctVarsToBlockVector()
returns fraction of variables assigned to a block for detectors in detectorchain
USERGIVEN getUsergiven()
Gets the USERGIVEN status of this partialdecs.
DETPROBDATA * GCGconshdlrDecompGetDetprobdataOrig(SCIP *scip)
help method to access detprobdata for unpresolved problem
int getNVarsForBlock(int block)
Gets size of the vector containing vars assigned to a block.
void setDetectorchain(std::vector< DEC_DETECTOR * > &givenDetectorChain)
sets the detectorchain with the given vector of detector pointers
SCIP_RETCODE filloutBorderFromConstoblock(SCIP_HASHMAP *constoblock, int givenNBlocks)
every constraint is either assigned to master or open
@ MAX_FORESSEEING_WHITE
void showVisualization()
generates and opens a gp visualization of the partialdec
bool getFinishedByFinisher()
returns true iff this partialdec was finished by finishPartialdec() method of a detector
std::vector< int > getNNewBlocksVector()
gets number of blocks the detectors in the detectorchain added
void setMaxForWhiteScore(SCIP_Real score)
set the maximum foreseeing white area score
void complete()
assigns all open constraints and open variables trivially
bool fixVarToMasterByName(const char *varname)
assigns a variable with given name as master
data structures for detectors
void addPctVarsFromFree(SCIP_Real pct)
adds percentage of closed variables
SCIP_Real getSetPartForWhiteScore()
gets the setpartitioning maximum foreseeing white area score
int getNTotalStairlinkingvars()
Gets total number of stairlinking vars.
void fixVarToStairlinking(int var, int firstblock)
adds a variable to the stairlinking variables
void deleteOpencons(int opencons)
deletes a cons from list of open conss
@ CLASSIC
static SCIP_Bool realArraysAreEqual(SCIP *scip, SCIP_Real *array1, int array1length, SCIP_Real *array2, int array2length)
checks whether two arrays of SCIP_Real's are identical
void completeByConnected()
assigns all open constraints and open variables
@ SETPART_FWHITE
std::vector< int > & getConssForVar(int varIndex)
returns the constraint indices of the coefficient matrix for a variable
void buildDecChainString(char *buffer)
creates a detector chain short string for this partialdec, is built from detector chain
void addAncestorID(int ancestor)
int GCGconshdlrDecompGetNextPartialdecID(SCIP *scip)
Gets the next partialdec id managed by cons_decomp.
various SCIP helper methods
bool fixVarToLinkingByName(const char *varname)
assigns a variable by name to the linking variables
void setSetPartForWhiteScore(SCIP_Real score)
set the setpartitioning maximum foreseeing white area score
void setMaxWhiteScore(SCIP_Real score)
set the maximum white area score
SCIP_Real getMaxWhiteScore()
gets the maximum white area score
void setUsergiven(USERGIVEN usergiven)
sets whether this partialdec is user given
bool isConsMastercons(int cons)
Gets whether the cons is a master cons.
SCIP_Bool hasSetppccardMaster()
checks if all master constraints set partitioning, set packing, set cover, or cardinality constraints
std::vector< int > & getRepVarmap(int repid, int blockrepid)
Gets the represenation varmap.
void setDetectorFinished(DEC_DETECTOR *detector)
sets detector that finished the partialdec
void considerImplicits()
: assigns every open cons/var
void calcStairlinkingVars()
reassigns linking vars to stairlinkingvars if possible
int getNStairlinkingvars(int block)
Gets size of the vector containing stairlinking vars.
int getNConssForBlock(int block)
Gets size of the vector containing conss assigned to a block.
SCIP_RETCODE GCGconshdlrDecompCalcMaxForeseeingWhiteAggScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the maxforeseeingwhiteagg score of a partialdec
static SCIP_RETCODE partition(SCIP *scip, SCIP_VAR **J, int *Jsize, SCIP_Longint *priority, SCIP_VAR **F, int Fsize, SCIP_VAR **origvar, SCIP_Real *median)
SCIP_CONS * getCons(int consIndex)
returns the SCIP constraint related to a constraint index
void deleteOpenvar(int openvar)
deletes a var from the list of open vars
SCIP_RETCODE GCGconshdlrDecompCalcBendersScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the benders score of a partialdec
int getNAncestors()
Gets number of ancestor partialdecs.
SCIP_Bool hasSetppcMaster()
checks iff all master constraints set partitioning, set packing, or set cover constraints
void setStrongDecompScore(SCIP_Real score)
set the strong decomposition score
SCIP_Bool shouldCompletedByConsToMaster()
Checks whether this partialdec is a userpartialdec that should be completed.
SCIP_Real getPctConssToBorder(int detectorchainindex)
Gets fraction of constraints assigned to the border for a detector.
void addDecChangesFromAncestor(PARTIALDECOMP *ancestor)
adds the statistical differences to an ancestor
void GCGconshdlrDecompDeregisterPartialdec(SCIP *scip, PARTIALDECOMP *partialdec)
deregisters a partialdec in the conshdlr
void exportVisualization()
generates a gp visualization of the partialdec without compilation or opening
void setConsToBlock(int consToBlock, int block)
adds a constraint to a block, does not delete this cons from list of open conss
void setPctVarsToBorderVector(std::vector< SCIP_Real > &newvector)
set statistical vector of fraction of variables assigned to the border per involved detector
SCIP_RETCODE filloutPartialdecFromConstoblock(SCIP_HASHMAP *constoblock, int givenNBlocks)
assigns all conss to master or a block
void addPctVarsToBorder(SCIP_Real pct)
adds percentage of variables assigned to border
SCIP_RETCODE GCGconshdlrDecompCalcMaxForseeingWhiteScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the maximum foreseeing white area score of a partialdec
void addPctConssToBlock(SCIP_Real pct)
adds percentage of constraints assigned to blocks
SCIP_Real getPctConssToBlock(int detectorchainindex)
Gets fraction of constraints assigned to a block for a detector.
char DECdetectorGetChar(DEC_DETECTOR *detector)
Gets the character of the detector.
bool isVarStairlinkingvarOfBlock(int var, int block)
Checks whether the var is a stairlinkingvar of a specified block.
automorphism recognition (C++ interface)
SCIP_Real getSetPartForWhiteAggScore()
gets the setpartitioning maximum foreseeing white area score with respect to aggregateable
miscellaneous methods for visualizations
void completeGreedily()
assigns all open constraints and open variables
int getNVars()
return the number of variables considered in the detprobdata
SCIP_Real getBorderAreaScore()
gets the border area score
SCIP_RETCODE assignBorderFromConstoblock(SCIP_HASHMAP *constoblock, int givenNBlocks)
assigns open conss to master
void setStemsFromOrig(bool fromorig)
sets whether this partialdec stems from an orig problem partialdec
int getRepForBlock(int blockid)
Gets index of the representative block for a block, this might be blockid itself.
int getIndexForCons(SCIP_CONS *cons)
returns the constraint index related to a SCIP constraint
int getNLinkingvars()
Gets size of the vector containing linking vars.
bool assignCurrentStairlinking()
assigns open vars to stairlinking if appropriate
void setConsPartitionStatistics(int detectorchainindex, ConsPartition *partition, std::vector< int > &consclassesmaster)
registers statistics for a used conspartition
void setPctConssToBorderVector(std::vector< SCIP_Real > &newvector)
set statistical vector of fractions of constraints assigned to the border per involved detector
@ MAX_WHITE
bool sort()
sorts the vars and conss data structures by their indices
int getIndexForVar(SCIP_VAR *var)
returns the variable index related to a SCIP variable
SCIP_RETCODE GCGwriteGpVisualizationFormat(SCIP *scip, char *filename, char *outputname, int partialdecid, GP_OUTPUT_FORMAT outputformat)
Definition: reader_gp.cpp:449
void setPctConssFromFreeVector(std::vector< SCIP_Real > &newvector)
set statistical vector of fractions of constraints that are not longer open per involved detector
C++ interface of cons_decomp.
void refineToBlocks()
refine partialdec with focus on blocks
SCIP_Real getStrongDecompScore()
gets the strong decomposition score
std::vector< SCIP_Real > & getPctConssFromFreeVector()
Gets fraction of constraints that are not longer open for detectors in detectorchain.
void setConsToMaster(int consToMaster)
adds a constraint to the master constraints, does not delete this cons from list of open conss
void printPartitionInformation(SCIP *givenscip, FILE *file)
prints partition information as described in
const int * getStairlinkingvars(int block)
Gets array containing stairlinking vars,.
void findVarsLinkingToMaster()
reassigns linking variables to master if appropriate
void createConssAdjacency()
create the constraint adjacency datastructure that is used (if created) for some methods to faster ac...
int getNReps()
Gets the number of blockrepresentatives.
SCIP_Real getPctVarsToBorder(int detectorchainindex)
Gets fraction of variables assigned to the border for a detector.
const int * getOpenconss()
Gets array containing constraints not assigned yet.
SCIP_RETCODE GCGwriteGpVisualization(SCIP *scip, char *filename, char *outputname, int partialdecid)
Definition: reader_gp.cpp:483
int getNConss()
Gets the number of constraints.
void assignSmallestComponentsButOneConssAdjacency()
computes components by connectedness of conss and vars
consType GCGconsGetType(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:51
const std::vector< int > & getBlocksForRep(int repid)
get a vector of block ids that are identical to block with id repid
int getNNewBlocks(int detectorchainindex)
Gets number of blocks a detector added.
unsigned long getHashValue()
returns the calculated hash value of this partialdec
virtual std::vector< int > getNeighbors(int node)
Definition: graph_gcg.cpp:475
int getTranslatedpartialdecid() const
SCIP_RETCODE GCGconsGetVals(SCIP *scip, SCIP_CONS *cons, SCIP_Real *vals, int nvals)
Definition: scip_misc.c:621
std::vector< SCIP_Real > & getPctConssToBorderVector()
Gets fraction of constraints assigned to the border for detectors in detectorchain.
void setSelected(bool selected)
set the selection status of this partialdecs
void addNNewBlocks(int nnewblocks)
adds how many new blocks were introduced
int getAncestorID(int ancestorindex)
gets partialdec id of given ancestor id
bool isConsCardinalityCons(int consindexd)
returns whether a constraint is a cardinality constraint, i.e. of the
bool checkConsistency()
Checks whether the assignments in the partialdec are consistent.
int getNDetectors()
Gets the number of detectors the partialdec is propagated by.
int addBlock()
adds a block
void setBorderAreaScore(SCIP_Real score)
set the border area score
bool isConsSetpp(int consindexd)
is cons with specified indec partitioning, or packing covering constraint?
std::vector< std::string > & getDetectorchainInfo()
Gets the detectorchain info vector.
int getNCoeffsForBlock(int blockid)
Gets the number of nonzero coeffs in a certain block.
void setPctConssToBlockVector(std::vector< SCIP_Real > &newvector)
set statistical vector of fractions of constraints set to blocks per involved detector
int GCGconsGetNVars(SCIP *scip, SCIP_CONS *cons)
Definition: scip_misc.c:434
PARTIALDECOMP(SCIP *scip, bool originalProblem)
Standard constructor, creates empty partialdec with unique id.
automorphism recognition of SCIPs
enum GPOutputFormat GP_OUTPUT_FORMAT
Definition: reader_gp.h:57
SCIP_RETCODE GCGconshdlrDecompCalcMaxWhiteScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the maximum white area score of a partialdec
std::vector< SCIP_Real > & getDetectorClockTimes()
returns a vector of the clock times that each detector needed that was involved in this partialdec
std::vector< int > & getConssForBlock(int block)
returns array containing constraints assigned to a block
int getNVarsForBlocks()
Gets overall number of vars assigned to a block.
bool fixConsToMasterByName(const char *consname)
assgins a constraint by name as master
class to manage partial decompositions
bool isVarMastervar(int var)
Checks whether the var is a master var.
int getNBlocks()
Gets the number of blocks.
void setClassicScore(SCIP_Real score)
set the classic score
void fixVarToBlock(int var, int block)
adds a variable to the linking variables
SCIP_Real getScore(SCORETYPE type)
returns the score of the partialdec (depending on used scoretype)
void setVarToBlock(int varToBlock, int block)
adds a variable to the linking variables, does not delete this var from list of open vars
DETPROBDATA * getDetprobdata()
Gets the corresponding detprobdata.
void removeMastercons(int consid)
removes the given cons from master
SCIP_RETCODE assignPartialdecFromConstoblockVector(std::vector< int > constoblock, int additionalNBlocks)
assigns conss structure according to given vector
void assignOpenConssToMaster()
assigns open conss to master
bool isVarLinkingvar(int var)
Checks whether the var is a linking var.
void setVarPartitionStatistics(int detectorchainindex, VarPartition *partition, std::vector< int > &varclasseslinking, std::vector< int > &varclassesmaster)
registers statistics for a used varpartition
void setSetPartForWhiteAggScore(SCIP_Real score)
set the setpartitioning maximum foreseeing white area score with respect to aggregateable
virtual SCIP_RETCODE setEdge(int node_i, int node_j, double weight)
Definition: graph_gcg.cpp:657
std::vector< int > & getLinkingvars()
returns array containing all linking vars indices
void addPctConssFromFree(SCIP_Real pct)
adds percentage of closed constraints
int getNVarsForCons(int consIndex)
returns the number of variables for a given constraint
bool fixVarToBlockByName(const char *varname, int blockid)
assigns a variable by name to a block
SCIP_Bool isConssAdjInitialized()
determines whether or not the constraint-constraint adjacency data structure is initilized
int getNOpenconss()
Gets size of vector containing constraints not assigned yet.
SCIP_RETCODE assignPartialdecFromConstoblock(SCIP_HASHMAP *constoblock, int additionalNBlocks)
assigns conss structure according to given hashmap
bool isConsOpencons(int cons)
Gets whether the cons is an open cons.
DETPROBDATA * GCGconshdlrDecompGetDetprobdataPresolved(SCIP *scip)
help method to access detprobdata for transformed problem
SCIP_RETCODE isEqual(PARTIALDECOMP *otherpartialdec, SCIP_Bool *isequal, bool sortpartialdecs)
method to check whether this partialdec is equal to a given other partialdec (
SCIP_RETCODE GCGconshdlrDecompCalcBorderAreaScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the border area score of a partialdec
static bool compare_blocks(std::pair< int, int > const &a, std::pair< int, int > const &b)
bool isPropagatedBy(DEC_DETECTOR *detector)
Gets whether this partialdec was propagated by specified detector.
int getID()
returns the unique id of the partialdec
void addPctVarsToBlock(SCIP_Real pct)
adds percentage of variables assigned to blocks
void setPctVarsFromFreeVector(std::vector< SCIP_Real > &newvector)
set statistical vector of variables that are not longer open per involved detector
void calcAggregationInformation(bool ignoreDetectionLimits)
computes if aggregation of sub problems is possible
@ BORDER_AREA
bool fixConsToBlockByName(const char *consname, int blockid)
assigns a constraint by name to a block
void setDetectorPropagated(DEC_DETECTOR *detector)
sets partialdec to be propagated by a detector
SCIP_Real getPctVarsToBlock(int detectorchainindex)
Gets fraction of variables assigned to a block for a detector.
void GCGconshdlrDecompRegisterPartialdec(SCIP *scip, PARTIALDECOMP *partialdec)
registers a partialdec in the conshdlr
class storing (potentially incomplete) decompositions
std::vector< int > & getAncestorList()
get ancestor ids as vector
GP file reader writing decompositions to gnuplot files.
SCIP_Real getVal(int row, int col)
returns a coefficient from the coefficient matrix
SCIP_RETCODE cmpGraphPair(SCIP *origscip, SCIP *scip1, SCIP *scip2, int prob1, int prob2, SCIP_RESULT *result, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, unsigned int searchnodelimit, unsigned int generatorlimit)
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
std::vector< int > & getVarsForCons(int consIndex)
returns the variable indices of the coefficient matrix for a constraint
std::vector< DEC_DETECTOR * > & getDetectorchain()
returns detector chain as vector of detector pointers
bool isTrivial()
Gets whether this partialdec is considered to be trivial.
void setBendersScore(SCIP_Real score)
set the benders score
int getNMasterconss()
Gets size of the vector containing master conss.
bool isAssignedToOrigProb()
Gets whether the partialdec is from the presolved problem.
std::vector< SCIP_Real > & getPctVarsToBorderVector()
Gets fraction of variables assigned to the border for detectors in detectorchain.
void refineToMaster()
refine partialdec with focus on master
SCIP_Real getDetectorClockTime(int detectorchainindex)
returns the time that the detector related to the given detectorchainindex needed for detecting
const int * getOpenvars()
Gets array containing variables not assigned yet.
void setDetectorFinishedOrig(DEC_DETECTOR *detectorID)
sets detector that finished the partialdec in the original problem
SCIP_VAR * getVar(int varIndex)
returns SCIP variable related to a variable index
@ SETPART_AGG_FWHITE
enum scoretype SCORETYPE
void deleteEmptyBlocks(bool variables)
deletes empty blocks and sets nblocks accordingly
int getNMastervars()
Gets size of the vector containing master vars.
class storing partialdecs and the problem matrix
virtual SCIP_Bool isEdge(int node_i, int node_j)
Definition: graph_gcg.cpp:430
std::vector< SCIP_Real > & getPctVarsFromFreeVector()
Gets fraction of variables that are not longer open for detectors in detectorchain.
void GCGgetVisualizationFilename(SCIP *scip, PARTIALDECOMP *partialdec, const char *extension, char *filename)
void fixConsToBlock(int cons, int block)
adds a constraint to a block
void completeByConnectedConssAdjacency()
assigns all open constraints and open variables
SCIP_RETCODE GCGconshdlrDecompCalcSetPartForWhiteAggScore(SCIP *scip, int partialdecid, SCIP_Real *score)
calculates the setpartfwhiteagg score of a partialdec
SCIP_Real getMaxForWhiteScore()
gets the maximum foreseeing white area score
void generateVisualization(char *filename, char *outname, GP_OUTPUT_FORMAT outputformat=GP_OUTPUT_FORMAT_PDF)
generates a visualization of the partialdec using gnuplot
@ STRONG_DECOMP
@ COMPLETED_CONSTOMASTER
std::vector< std::vector< int > > & getConssForBlocks()
int getNVars()
Gets number of vars.