Scippy

GCG

Branch-and-Price & Column Generation for Everyone

rowgraph_weighted_def.h
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 rowgraph_weighted_def.h
29  * @brief A row graph where each row is a node and rows are adjacent if they share a variable.
30  * The edges are weighted according to specified similarity measure.
31  * @author Igor Pesic
32  */
33 
34 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
35 // #define SCIP_DEBUG
36 
37 #ifndef GCG_ROWGRAPH_WEIGHTED_DEF_H_
38 #define GCG_ROWGRAPH_WEIGHTED_DEF_H_
39 
40 #include "rowgraph_weighted.h"
41 #include "graph_gcg.h"
42 #include "graphalgorithms.h"
43 #include "priority_graph.h"
44 #include <algorithm>
45 #include <iostream>
46 #include <vector>
47 #include <map>
48 #include <set>
49 #include <climits>
50 #include <queue>
51 
52 using namespace std;
53 
54 namespace gcg {
55 
56 template <class T>
58  SCIP* scip, /**< SCIP data structure */
59  Weights w /**< weights for the given graph */
60  ) : RowGraph<T>(scip,w)
61 {
62  this->name = string("rowgraph_weighted");
63  n_blocks = -1;
64  non_cl = INT_MAX;
65 }
66 
67 template <class T>
69 {
70  // Auto-generated destructor stub
71 }
72 
73 
74 template <class T>
76  SCIP_CONS** conss, /**< constraints for which graph should be created */
77  SCIP_VAR** vars, /**< variables for which graph should be created */
78  int nconss_, /**< number of constraints */
79  int nvars_, /**< number of variables */
80  DISTANCE_MEASURE dist, /**< Here we define the distance measure between two rows */
81  WEIGHT_TYPE w_type /**< Depending on the algorithm we can build distance or similarity graph */
82  )
83 {
84  int i;
85  int j;
86  int k;
87  int l;
88  SCIP_Bool success;
89 
90  assert(conss != NULL);
91  assert(vars != NULL);
92  assert(nvars_ > 0);
93  assert(nconss_ > 0);
94 
95  this->nvars = nvars_;
96  this->nconss = nconss_;
97 
98  SCIP_CALL( this->graph.addNNodes(this->nconss) );
99 
100  /* go through all constraints */
101  for( i = 0; i < this->nconss; ++i )
102  {
103  SCIP_VAR **curvars1;
104 
105  int ncurvars1;
106  SCIP_CALL( SCIPgetConsNVars(this->scip_, conss[i], &ncurvars1, &success) );
107  assert(success);
108  if( ncurvars1 == 0 )
109  continue;
110 
111  /*
112  * may work as is, as we are copying the constraint later regardless
113  * if there are variables in it or not
114  */
115  SCIP_CALL( SCIPallocBufferArray(this->scip_, &curvars1, ncurvars1) );
116  SCIP_CALL( SCIPgetConsVars(this->scip_, conss[i], curvars1, ncurvars1, &success) );
117  assert(success);
118 
119  /* go through all constraints again */
120  for( j = 0; j < i; ++j )
121  {
122  SCIP_VAR **curvars2;
123  int ncurvars2;
124  SCIP_CALL( SCIPgetConsNVars(this->scip_, conss[j], &ncurvars2, &success) );
125  assert(success);
126  if( ncurvars2 == 0 )
127  continue;
128 
129 
130  /*
131  * may work as is, as we are copying the constraint later regardless
132  * if there are variables in it or not
133  */
134  SCIP_CALL( SCIPallocBufferArray(this->scip_, &curvars2, ncurvars2) );
135  SCIP_CALL( SCIPgetConsVars(this->scip_, conss[j], curvars2, ncurvars2, &success) );
136  assert(success);
137 
138 
139  /** @todo skip all variables that have a zero coeffient or where all coefficients add to zero */
140  /** @todo Do more then one entry per variable actually work? */
141 
142  int a = 0; // number of common variables
143  int b = 0; // number of variables that appear ONLY in the second row
144  int c = 0; // number of variables that appear ONLY in the first row
145  for( k = 0; k < ncurvars1; ++k )
146  {
147  SCIP_VAR* var1;
148  int varIndex1;
149 
150  if( !GCGisVarRelevant(curvars1[k]) )
151  continue;
152 
153  if( SCIPgetStage(this->scip_) >= SCIP_STAGE_TRANSFORMED)
154  var1 = SCIPvarGetProbvar(curvars1[k]);
155  else
156  var1 = curvars1[k];
157 
158  assert(var1 != NULL);
159  varIndex1 = SCIPvarGetProbindex(var1);
160  assert(varIndex1 >= 0);
161  assert(varIndex1 < this->nvars);
162 
163  for( l = 0; l < ncurvars2; ++l )
164  {
165  SCIP_VAR* var2;
166  int varIndex2;
167 
168  if( !GCGisVarRelevant(curvars2[l]) )
169  continue;
170 
171  if( SCIPgetStage(this->scip_) >= SCIP_STAGE_TRANSFORMED)
172  var2 = SCIPvarGetProbvar(curvars2[l]);
173  else
174  var2 = curvars2[l];
175 
176  assert(var2 != NULL);
177  varIndex2 = SCIPvarGetProbindex(var2);
178  assert(varIndex2 >= 0);
179  assert(varIndex2 < this->nvars);
180 
181  if(varIndex1 == varIndex2)
182  {
183  a++;
184  break; // stop comparing the variable from the 1st const. with the rest of vars. in the 2nd const.
185  }
186  }
187  }
188  b = ncurvars2 - a;
189  c = ncurvars1 - a;
190  assert(a >= 0); // number of common var
191  assert(b >= 0); // number of variables in the second conss
192  assert(c >= 0); // number of variables in the first conss
193  if(a != 0){
194  double edge_weight = calculateSimilarity(a, b, c, dist, w_type, i==j);
195  this->graph.addEdge(i, j, edge_weight);
196  }
197 
198  SCIPfreeBufferArray(this->scip_, &curvars2);
199  }
200  SCIPfreeBufferArray(this->scip_, &curvars1);
201  }
202 
203  if(dist == INTERSECTION)
204  {
205  this->graph.normalize();
206  if(w_type == DIST)
207  {
208  return SCIP_INVALIDCALL;
209  }
210  }
211 
212  SCIP_CALL( this->graph.flush() );
213 
214  assert(this->graph.getNNodes() == nconss_);
215 
216  return SCIP_OKAY;
217 }
218 
219 template <class T>
221  DETPROBDATA* detprobdata,
222  PARTIALDECOMP* partialdec,
223  DISTANCE_MEASURE dist, /**< Here we define the distance measure between two rows */
224  WEIGHT_TYPE w_type /**< Depending on the algorithm we can build distance or similarity graph */
225  )
226 {
227 
228  int i;
229  int j;
230  int k;
231  int l;
232  int m;
233  vector<int> conssForGraph; /** stores the conss included by the graph */
234  vector<int> varsForGraph; /** stores the vars included by the graph */
235  vector<bool> varsBool(partialdec->getNVars(), false); /**< true, if the var will be part of the graph */
236  vector<bool> conssBool(partialdec->getNConss(), false); /**< true, if the cons will be part of the graph */
237  unordered_map<int, int> oldToNewConsIndex; /** stores new index of the conss */
238  unordered_map<int, int> oldToNewVarIndex; /** stores new index of the vars */
239 
240  for(int c = 0; c < partialdec->getNOpenconss(); ++c)
241  {
242  int cons = partialdec->getOpenconss()[c];
243  for(int v = 0; v < partialdec->getNOpenvars(); ++v)
244  {
245  int var = partialdec->getOpenvars()[v];
246  for(i = 0; i < detprobdata->getNVarsForCons(cons); ++i)
247  {
248  if(var == detprobdata->getVarsForCons(cons)[i])
249  {
250  varsBool[var] = true;
251  conssBool[cons] = true;
252  }
253  }
254  }
255  }
256 
257  for(int v = 0; v < partialdec->getNOpenvars(); ++v)
258  {
259  int var = partialdec->getOpenvars()[v];
260  if(varsBool[var])
261  varsForGraph.push_back(var);
262  }
263  for(int c = 0; c < partialdec->getNOpenconss(); ++c)
264  {
265  int cons = partialdec->getOpenconss()[c];
266  if(conssBool[cons])
267  conssForGraph.push_back(cons);
268  }
269 
270  this->nvars = (int)varsForGraph.size();
271  this->nconss = (int)conssForGraph.size();
272  assert(this->nconss > 0);
273  assert(this->nvars > 0);
274 
275  for(int v = 0; v < (int)varsForGraph.size(); ++v)
276  {
277  int oldVarId = varsForGraph[v];
278  oldToNewVarIndex.insert({oldVarId,v});
279  }
280  for(int c = 0; c < (int)conssForGraph.size(); ++c)
281  {
282  int oldConsId = conssForGraph[c];
283  oldToNewConsIndex.insert({oldConsId,c});
284  }
285 
286 
287 
288  SCIP_CALL( this->graph.addNNodes(this->nconss) );
289 
290  /* go through all constraints */
291  for( i = 0; i < this->nconss; ++i )
292  {
293  int cons1 = conssForGraph[i];
294  assert(conssBool[cons1]);
295 
296  /* go through all constraints again */
297  for( j = 0; j < i; ++j )
298  {
299  int cons2 = conssForGraph[j];
300 
301  int a = 0; // number of common variables
302  int b = 0; // number of variables that appear ONLY in the second row
303  int c = 0; // number of variables that appear ONLY in the first row
304 
305 
306  for( k = 0; k < detprobdata->getNVarsForCons(cons1); ++k)
307  {
308  int var1 = detprobdata->getVarsForCons(cons1)[k];
309  if(!varsBool[var1])
310  continue;
311  assert(varsBool[var1]);
312 
313  for(l = 0; l < detprobdata->getNVarsForCons(cons2); ++l)
314  {
315  int var2 = detprobdata->getVarsForCons(cons2)[l];
316  if(!varsBool[var2])
317  continue;
318 
319  if(var1 == var2)
320  {
321  a++;
322  break; // stop comparing the variable from the 1st const. with the rest of vars. in the 2nd const.
323  }
324  }
325  for(m = 0; m < detprobdata->getNVarsForCons(cons2); ++m)
326  {
327  int var = detprobdata->getVarsForCons(cons2)[m];
328  if(varsBool[var])
329  b++;
330  }
331  b = b - a;
332 
333  for(m = 0; m < detprobdata->getNVarsForCons(cons1); ++m)
334  {
335  int var = detprobdata->getVarsForCons(cons1)[m];
336  if(varsBool[var])
337  c++;
338  }
339  c = c - a;
340 
341  assert(a >= 0); // number of common var
342  assert(b >= 0); // number of variables in the second conss
343  assert(c >= 0); // number of variables in the first conss
344  if(a != 0){
345  double edge_weight = calculateSimilarity(a, b, c, dist, w_type, i==j);
346  this->graph.addEdge(oldToNewConsIndex[cons1], oldToNewConsIndex[cons2], edge_weight);
347  }
348  }
349  }
350  }
351 
352  if(dist == INTERSECTION)
353  {
354  this->graph.normalize();
355  if(w_type == DIST)
356  {
357  return SCIP_INVALIDCALL;
358  }
359  }
360 
361  SCIP_CALL( this->graph.flush() );
362 
363  return SCIP_OKAY;
364 }
365 
366 template <class T>
367 double RowGraphWeighted<T>::calculateSimilarity(int _a, int _b, int _c, DISTANCE_MEASURE dist, WEIGHT_TYPE w_type, bool itself)
368 {
369  if(w_type == DIST )
370  {
371  if(_c == 0 && _b == 0) return 1e-10;
372  }
373  else
374  {
375  if(_c == 0 && _b == 0) return (1.0 - 1e-10);
376  }
377  double result = 0.0;
378  double a = (double)_a;
379  double b = (double)_b;
380  double c = (double)_c;
381  switch( dist ) {
382  case JOHNSON:
383  result = (a/(a+b) + a/(a+c)) / 2.0;
384  break;
385  case INTERSECTION:
386  result = a;
387  break;
388  case JACCARD:
389  result = a / (a+b+c);
390  break;
391  case COSINE:
392  result = a / (sqrt(a+b)*sqrt(a+c));
393  break;
394  case SIMPSON:
395  result = a / MIN(a+b, a+c);
396  break;
397  }
398 
399 
400 
401  if(dist != INTERSECTION)
402  {
403  assert(result >= 0.0);
404  assert(result <= 1.0);
405  }
406 
407  if(!itself)
408  {
409  result *= (1 - 1e-10);
410  }
411 
412  if(w_type == DIST && dist != INTERSECTION)
413  {
414  result = 1.0 - result;
415  }
416 
417  return result;
418 }
419 
420 template <>
421 SCIP_RETCODE RowGraphWeighted<GraphGCG>::postProcess(vector<int>& labels, bool enabled)
422 {
423  assert((int)labels.size() == graph.getNNodes());
424  set<int> diff_blocks_beginning;
425  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
426  {
427  diff_blocks_beginning.insert(*curr_int);
428  }
429  //std::cout << "diff_blocks_beginning: " << diff_blocks_beginning.size() << std::endl;
430  bool skip_me = false;
431  if(diff_blocks_beginning.size() == labels.size())
432  {
433  skip_me = true;
434  }
435  // If the post processing is enabled, remove the coliding conss, otherwise just set the partition
436  if(enabled && !skip_me)
437  {
438  this->non_cl = (int)labels.size();
439  // for each column in the conss matrix we save labels of all the constraints where the variable appears
440  vector< vector<int> > all_labels_in_col(this->nvars);
441 
442  // for each column in the conss matrix we count the number of occurrences of each label
443  vector< map<int, int> > all_label_occ_in_col(this->nvars);
444 
445  // item i saves number which appears most often in the all_labels_in_col[i]
446  vector<int> col_labels(this->nvars, -1);
447 
448  SCIP_CONS** conss = SCIPgetConss(this->scip_);
449  SCIP_Bool success;
450 
451  // For each var save the labels of all the constraints where this var appears.
452  for(auto i = 0; i < this->nconss; i++)
453  {
454  SCIP_VAR **curvars;
455  int ncurvars;
456  SCIP_CALL( SCIPgetConsNVars(this->scip_, conss[i], &ncurvars, &success) );
457  assert(success);
458  if( ncurvars == 0 )
459  continue;
460 
461  /*
462  * may work as is, as we are copying the constraint later regardless
463  * if there are variables in it or not
464  */
465  SCIP_CALL( SCIPallocBufferArray(this->scip_, &curvars, ncurvars) );
466  SCIP_CALL( SCIPgetConsVars(this->scip_, conss[i], curvars, ncurvars, &success) );
467  assert(success);
468 
469  for(auto j = 0; j < ncurvars; j++)
470  {
471  SCIP_VAR* var;
472 
473  if( !GCGisVarRelevant(curvars[j]) )
474  continue;
475 
476  if( SCIPgetStage(this->scip_) >= SCIP_STAGE_TRANSFORMED)
477  var = SCIPvarGetProbvar(curvars[j]);
478  else
479  var = curvars[j];
480 
481  assert(var != NULL);
482  int varIndex = SCIPvarGetProbindex(var);
483  assert(varIndex >= 0);
484  assert(varIndex < this->nvars);
485 
486  // push the label of the constraint to the columns where the variable appears
487  all_labels_in_col[varIndex].push_back(labels[i]);
488  all_label_occ_in_col[varIndex][labels[i]]++;
489  }
490  SCIPfreeBufferArray(this->scip_, &curvars);
491  }
492 
493  // fill the col_labels
494  for(auto i = 0; i < this->nvars; i++)
495  {
496  auto pr = max_element
497  (
498  all_label_occ_in_col[i].begin(), all_label_occ_in_col[i].end(),
499  [] (const pair<int,int> & p1, const pair<int,int> & p2) {
500  return p1.second < p2.second;
501  }
502  );
503  // new code
504  col_labels[i] = pr->first;
505  }
506 
507  // Iterate all the conss and remove them (i.e. set label to -1) if necessary
508  for(auto i = 0; i < this->nconss; i++)
509  {
510  SCIP_VAR **curvars1;
511  int ncurvars1;
512  SCIP_CALL( SCIPgetConsNVars(this->scip_, conss[i], &ncurvars1, &success) );
513  assert(success);
514  if( ncurvars1 == 0 )
515  continue;
516 
517  /*
518  * may work as is, as we are copying the constraint later regardless
519  * if there are variables in it or not
520  */
521  SCIP_CALL( SCIPallocBufferArray(this->scip_, &curvars1, ncurvars1) );
522  SCIP_CALL( SCIPgetConsVars(this->scip_, conss[i], curvars1, ncurvars1, &success) );
523  assert(success);
524 
525  for(auto j = 0; j < ncurvars1; j++)
526  {
527  SCIP_VAR* var1;
528 
529  if( !GCGisVarRelevant(curvars1[j]) )
530  continue;
531 
532  if( SCIPgetStage(this->scip_) >= SCIP_STAGE_TRANSFORMED)
533  var1 = SCIPvarGetProbvar(curvars1[j]);
534  else
535  var1 = curvars1[j];
536 
537  assert(var1 != NULL);
538  int varIndex = SCIPvarGetProbindex(var1);
539  assert(varIndex >= 0);
540  assert(varIndex < this->nvars);
541 
542  // Check if in a conss we have found a var with different label than the conss label.
543  // This means that this var is mostly belonging to some other block, so remove it
544  if(col_labels[varIndex] != labels[i])
545  {
546  labels[i] = -1;
547 
548  // this is new part
549  // it updates the column labels each time after eliminating some conss
550  all_label_occ_in_col[varIndex][labels[i]]--;
551  auto pr = max_element
552  (
553  all_label_occ_in_col[varIndex].begin(), all_label_occ_in_col[varIndex].end(),
554  [] (const pair<int,int> & p1, const pair<int,int> & p2) {
555  return p1.second < p2.second;
556  }
557  );
558  col_labels[varIndex] = pr->first;
559  }
560  }
561  SCIPfreeBufferArray(this->scip_, &curvars1);
562 
563  }
564  }
565 
566  if(!skip_me)
567  {
568  // Fix the labeling so that it starts from 0 without skipping the enumeration order
569  // And set the graph partition accordingly.
570  set<int> diff_blocks;
571 
572  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
573  {
574  diff_blocks.insert(*curr_int);
575  }
576 
577  const int non_cl_pts = count(labels.begin(), labels.end(), -1);
578  if(non_cl_pts > 0)
579  {
580  this->n_blocks = diff_blocks.size() - 1;
581  }
582  else
583  {
584  this->n_blocks = diff_blocks.size();
585  }
586  this->non_cl = non_cl_pts;
587 
588  map<int,int> labels_fix;
589  int new_label;
590  if(this->non_cl > 0) new_label = -1;
591  else new_label = 0;
592 
593  for(int old_label: diff_blocks)
594  {
595  labels_fix[old_label] = new_label;
596  new_label++;
597  }
598  for(int i = 0; i < (int)labels.size(); i++)
599  {
600  labels[i] = labels_fix[labels[i]];
601  }
602  }
603 
604  // put the labels as the partition...
605  for(int i = 0; i < (int)labels.size(); i++)
606  {
607  this->graph.setPartition(i, labels[i]);
608  }
609  return SCIP_OKAY;
610 }
611 
612 template <>
613 SCIP_RETCODE RowGraphWeighted<GraphGCG>::postProcessForPartialGraph(gcg::DETPROBDATA* detprobdata, gcg::PARTIALDECOMP* partialdec, vector<int>& labels, bool enabled)
614 {
615  assert((int)labels.size() == graph.getNNodes());
616  set<int> diff_blocks_beginning;
617  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
618  {
619  diff_blocks_beginning.insert(*curr_int);
620  }
621  bool skip_me = false;
622  if(diff_blocks_beginning.size() == labels.size())
623  {
624  skip_me = true;
625  }
626  // If the post processing is enabled, remove the coliding conss, otherwise just set the partition
627  if(enabled && !skip_me)
628  {
629  //fillout conssForGraph and varsForGraph
630  vector<int> conssForGraph; /* stores the conss included by the graph */
631  vector<int> varsForGraph; /* stores the vars included by the graph */
632  vector<bool> varsBool(partialdec->getNVars(), false); /* true, if the var will be part of the graph */
633  vector<bool> conssBool(partialdec->getNConss(), false); /* true, if the cons will be part of the graph */
634  unordered_map<int, int> oldToNewConsIndex; /* stores new index of the conss */
635  unordered_map<int, int> oldToNewVarIndex; /* stores new index of the vars */
636 
637  for(int c = 0; c < partialdec->getNOpenconss(); ++c)
638  {
639  int cons = partialdec->getOpenconss()[c];
640  for(int v = 0; v < partialdec->getNOpenvars(); ++v)
641  {
642  int var = partialdec->getOpenvars()[v];
643  for(int i = 0; i < detprobdata->getNVarsForCons(cons); ++i)
644  {
645  if(var == detprobdata->getVarsForCons(cons)[i])
646  {
647  varsBool[var] = true;
648  conssBool[cons] = true;
649  }
650  }
651  }
652  }
653 
654  for(int v = 0; v < partialdec->getNOpenvars(); ++v)
655  {
656  int var = partialdec->getOpenvars()[v];
657  if(varsBool[var] == true)
658  varsForGraph.push_back(var);
659  }
660  for(int c = 0; c < partialdec->getNOpenconss(); ++c)
661  {
662  int cons = partialdec->getOpenconss()[c];
663  if(conssBool[cons] == true)
664  conssForGraph.push_back(cons);
665  }
666 
667  assert(this->nvars == (int) varsForGraph.size());
668  assert(this->nconss == (int) conssForGraph.size());
669 
670  sort(conssForGraph.begin(), conssForGraph.end());
671  sort(varsForGraph.begin(), varsForGraph.end());
672 
673  //fillout oldToNewVarIndex and oldToNewConsIndex
674  for(int v = 0; v < this->nvars; ++v)
675  {
676  int oldVarId = varsForGraph[v];
677  oldToNewVarIndex.insert({oldVarId,v});
678  }
679 
680  for(int c = 0; c < this->nconss; ++c)
681  {
682  int oldConsId = conssForGraph[c];
683  oldToNewConsIndex.insert({oldConsId,c});
684  }
685 
686  this->non_cl = (int)labels.size();
687  // for each column in the conss matrix we save labels of all the constraints where the variable appears
688  vector< vector<int> > all_labels_in_col(this->nvars);
689 
690  // for each column in the conss matrix we count the number of occurrences of each label
691  vector< map<int, int> > all_label_occ_in_col(this->nvars);
692 
693  // item i saves number which appears most often in the all_labels_in_col[i]
694  vector<int> col_labels(this->nvars, -1);
695 
696 
697  // For each var save the labels of all the constraints where this var appears.
698  for(size_t c = 0; c < conssForGraph.size(); c++)
699  {
700  int cons = conssForGraph[c];
701  int consIndex = oldToNewConsIndex[cons];
702  assert(consIndex >= 0);
703  assert(consIndex < this->nconss);
704  for(int v = 0; v < detprobdata->getNVarsForCons(cons); ++v)
705  {
706  int var = detprobdata->getVarsForCons(cons)[v];
707  if(find(varsForGraph.begin(), varsForGraph.end(), var) == varsForGraph.end())
708  continue;
709  int varIndex = oldToNewVarIndex[var];
710  assert(varIndex >= 0);
711  assert(varIndex < this->nvars);
712  all_labels_in_col[varIndex].push_back(labels[consIndex]);
713  }
714  }
715 
716  // fill the col_labels
717  for(size_t v = 0; v < varsForGraph.size(); ++v)
718  {
719  int var = varsForGraph[v];
720  int varIndex = oldToNewVarIndex[var];
721  assert(varIndex >= 0);
722  assert(varIndex < this->nvars);
723 
724  auto pr = max_element
725  (
726  all_label_occ_in_col[varIndex].begin(), all_label_occ_in_col[varIndex].end(),
727  [] (const pair<int,int> & p1, const pair<int,int> & p2) {
728  return p1.second < p2.second;
729  }
730  );
731  col_labels[varIndex] = pr->first;
732  }
733 
734 
735  // Iterate all the conss and remove them (i.e. set label to -1) if necessary
736  for(size_t c = 0; c < conssForGraph.size(); ++c)
737  {
738  int cons = conssForGraph[c];
739  assert(cons >= 0);
740  int consIndex = oldToNewConsIndex[cons];
741  assert(consIndex >= 0);
742  assert(consIndex < this->nconss);
743  for(int v = 0; v < detprobdata->getNVarsForCons(cons); ++v)
744  {
745  int var = detprobdata->getVarsForCons(cons)[v];
746  if(find(varsForGraph.begin(), varsForGraph.end(), var) == varsForGraph.end())
747  continue;
748  int varIndex = oldToNewVarIndex[var];
749  assert(varIndex >= 0);
750  assert(varIndex < this->nvars);
751  // Check if in a conss we have found a var with different label than the conss label.
752  // This means that this var is mostly belonging to some other block, so remove it
753  if(col_labels[varIndex] != labels[consIndex])
754  {
755  labels.at(consIndex) = -1;
756 
757  // this is new part
758  // it updates the column labels each time after eliminating some conss
759  all_label_occ_in_col[varIndex][labels[consIndex]]--;
760  auto pr = max_element
761  (
762  all_label_occ_in_col[varIndex].begin(), all_label_occ_in_col[varIndex].end(),
763  [] (const pair<int,int> & p1, const pair<int,int> & p2) {
764  return p1.second < p2.second;
765  }
766  );
767  col_labels[varIndex] = pr->first;
768  }
769  }
770  }
771  }
772 
773  if(!skip_me)
774  {
775  // Fix the labeling so that it starts from 0 without skipping the enumeration order
776  // And set the graph partition accordingly.
777  set<int> diff_blocks;
778 
779  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
780  {
781  diff_blocks.insert(*curr_int);
782  }
783 
784  const int non_cl_pts = count(labels.begin(), labels.end(), -1);
785  if(non_cl_pts > 0)
786  {
787  this->n_blocks = diff_blocks.size() - 1;
788  }
789  else
790  {
791  this->n_blocks = diff_blocks.size();
792  }
793  this->non_cl = non_cl_pts;
794 
795  map<int,int> labels_fix;
796  int new_label;
797  if(this->non_cl > 0) new_label = -1;
798  else new_label = 0;
799 
800  for(int old_label: diff_blocks)
801  {
802  labels_fix[old_label] = new_label;
803  new_label++;
804  }
805  for(int i = 0; i < (int)labels.size(); i++)
806  {
807  labels[i] = labels_fix[labels[i]];
808  }
809  }
810 
811  // put the labels as the partition...
812  for(int i = 0; i < (int)labels.size(); i++)
813  {
814  this->graph.setPartition(i, labels[i]);
815  }
816  return SCIP_OKAY;
817 }
818 
819 
820 // this function is obsolete
821 template <>
822 SCIP_RETCODE RowGraphWeighted<GraphGCG>::postProcessStableSet(vector<int>& labels, bool enabled)
823 {
824  assert((int)labels.size() == graph.getNNodes());
825  set<int> diff_blocks_beginning;
826  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
827  {
828  diff_blocks_beginning.insert(*curr_int);
829  }
830  bool skip_me = false;
831  if(diff_blocks_beginning.size() == labels.size())
832  {
833  skip_me = true;
834  }
835 
836 
837  // If the post processing is enabled, remove the coliding conss, otherwise just set the partition
838  if(enabled && !skip_me)
839  {
840  priority_graph stable_set_graph;
841  //SCIPverbMessage(this->scip_, SCIP_VERBLEVEL_NORMAL, NULL, " running postProcessStableSet\n");
842  this->non_cl = (int)labels.size();
843  // for each column in the conss matrix we save labels of all the constraints where the variable appears
844  vector< vector<int> > all_ind_in_col(this->nvars);
845 
846 
847  SCIP_CONS** conss = SCIPgetConss(this->scip_);
848  SCIP_Bool success;
849 
850  /* go through all constraints */
851  for(int i = 0; i < this->nconss; ++i )
852  {
853  SCIP_VAR **curvars1;
854 
855  int ncurvars1;
856  SCIP_CALL( SCIPgetConsNVars(this->scip_, conss[i], &ncurvars1, &success) );
857  assert(success);
858  if( ncurvars1 == 0 )
859  continue;
860 
861  /*
862  * may work as is, as we are copying the constraint later regardless
863  * if there are variables in it or not
864  */
865  SCIP_CALL( SCIPallocBufferArray(this->scip_, &curvars1, ncurvars1) );
866  SCIP_CALL( SCIPgetConsVars(this->scip_, conss[i], curvars1, ncurvars1, &success) );
867  assert(success);
868 
869  /* go through all constraints */
870  for(int j = 0; j < i; ++j )
871  {
872  if(labels[i] == labels[j]) continue;
873  SCIP_VAR **curvars2;
874  SCIP_Bool continueloop;
875  int ncurvars2;
876  SCIP_CALL( SCIPgetConsNVars(this->scip_, conss[j], &ncurvars2, &success) );
877  assert(success);
878  if( ncurvars2 == 0 )
879  continue;
880 
881  continueloop = FALSE;
882  /*
883  * may work as is, as we are copying the constraint later regardless
884  * if there are variables in it or not
885  */
886  SCIP_CALL( SCIPallocBufferArray(this->scip_, &curvars2, ncurvars2) );
887  SCIP_CALL( SCIPgetConsVars(this->scip_, conss[j], curvars2, ncurvars2, &success) );
888  assert(success);
889 
890 
891  /** @todo skip all variables that have a zero coeffient or where all coefficients add to zero */
892  /** @todo Do more then one entry per variable actually work? */
893 
894  for(int k = 0; k < ncurvars1; ++k )
895  {
896  SCIP_VAR* var1;
897  int varIndex1;
898 
899  if( !GCGisVarRelevant(curvars1[k]) )
900  continue;
901 
902  if( SCIPgetStage(this->scip_) >= SCIP_STAGE_TRANSFORMED)
903  var1 = SCIPvarGetProbvar(curvars1[k]);
904  else
905  var1 = curvars1[k];
906 
907  assert(var1 != NULL);
908  varIndex1 = SCIPvarGetProbindex(var1);
909  assert(varIndex1 >= 0);
910  assert(varIndex1 < this->nvars);
911 
912  for(int l = 0; l < ncurvars2; ++l )
913  {
914  SCIP_VAR* var2;
915  int varIndex2;
916 
917  if( !GCGisVarRelevant(curvars2[l]) )
918  continue;
919 
920  if( SCIPgetStage(this->scip_) >= SCIP_STAGE_TRANSFORMED)
921  var2 = SCIPvarGetProbvar(curvars2[l]);
922  else
923  var2 = curvars2[l];
924 
925  assert(var2 != NULL);
926  varIndex2 = SCIPvarGetProbindex(var2);
927  assert(varIndex2 >= 0);
928  assert(varIndex2 < this->nvars);
929 
930  if(varIndex1 == varIndex2)
931  {
932  stable_set_graph.addNode(i);
933  stable_set_graph.addNode(j);
934  stable_set_graph.addEdge(i, j);
935 
936  /*
937  * this->graph.flush();
938  */
939 
940  continueloop = TRUE;
941  break;
942  }
943  }
944  if(continueloop)
945  break;
946  }
947  SCIPfreeBufferArray(this->scip_, &curvars2);
948  }
949  SCIPfreeBufferArray(this->scip_, &curvars1);
950  }
951 
952  // run greedy heuristic for stable set
953  vector<int> stable_set;
954  vector<int> no_stable_set;
955  while(!stable_set_graph.empty()){
956  int current = stable_set_graph.top().first;
957  stable_set.push_back(current);
958  set<int> neighbors = stable_set_graph.getNeighbors(current);
959  stable_set_graph.pop();
960  for(auto neighbor : neighbors){
961  stable_set_graph.removeNode(neighbor, no_stable_set);
962  }
963  }
964 
965 
966  // Iterate all the conss and remove them (i.e. set label to -1) if necessary
967  for(int to_remove : no_stable_set)
968  {
969  //SCIPverbMessage(this->scip_, SCIP_VERBLEVEL_NORMAL, NULL, " to_remove: %d \n", to_remove);
970  labels[to_remove] = -1;
971  }
972  }
973 
974 
975  if(!skip_me)
976  {
977  // Fix the labeling so that it starts from 0 without skipping the enumeration order
978  // And set the graph partition accordingly.
979  set<int> diff_blocks;
980  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
981  {
982  diff_blocks.insert(*curr_int);
983  }
984 
985  const int non_cl_pts = count(labels.begin(), labels.end(), -1);
986  if(non_cl_pts > 0)
987  {
988  this->n_blocks = diff_blocks.size() - 1;
989  }
990  else
991  {
992  this->n_blocks = diff_blocks.size();
993  }
994  this->non_cl = non_cl_pts;
995 
996  map<int,int> labels_fix;
997  int new_label;
998  if(this->non_cl > 0) new_label = -1;
999  else new_label = 0;
1000 
1001  for(int old_label: diff_blocks)
1002  {
1003  labels_fix[old_label] = new_label;
1004  new_label++;
1005  }
1006  for(int i = 0; i < (int)labels.size(); i++)
1007  {
1008  labels[i] = labels_fix[labels[i]];
1009  }
1010  }
1011 
1012  // put the labels as the partition...
1013  for(int i = 0; i < (int)labels.size(); i++)
1014  {
1015  this->graph.setPartition(i, labels[i]);
1016  }
1017  return SCIP_OKAY;
1018 }
1019 
1020 // this function is obsolete
1021 template <>
1022 SCIP_RETCODE RowGraphWeighted<GraphGCG>::postProcessStableSetForPartialGraph(gcg::DETPROBDATA* detprobdata, gcg::PARTIALDECOMP* partialdec, vector<int>& labels, bool enabled)
1023 {
1024  assert((int)labels.size() == graph.getNNodes());
1025  set<int> diff_blocks_beginning;
1026  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
1027  {
1028  diff_blocks_beginning.insert(*curr_int);
1029  }
1030  bool skip_me = false;
1031  if(diff_blocks_beginning.size() == labels.size())
1032  {
1033  skip_me = true;
1034  }
1035 
1036 
1037 
1038  // If the post processing is enabled, remove the coliding conss, otherwise just set the partition
1039  if(enabled && !skip_me)
1040  {
1041  //fillout conssForGraph and varsForGraph
1042  vector<int> conssForGraph; /** stores the conss included by the graph */
1043  vector<int> varsForGraph; /** stores the vars included by the graph */
1044  vector<bool> varsBool(partialdec->getNVars(), false); /**< true, if the var will be part of the graph */
1045  vector<bool> conssBool(partialdec->getNConss(), false); /**< true, if the cons will be part of the graph */
1046  unordered_map<int, int> oldToNewConsIndex; /** stores new index of the conss */
1047  unordered_map<int, int> oldToNewVarIndex; /** stores new index of the vars */
1048 
1049  for(int c = 0; c < partialdec->getNOpenconss(); ++c)
1050  {
1051  int cons = partialdec->getOpenconss()[c];
1052  for(int v = 0; v < partialdec->getNOpenvars(); ++v)
1053  {
1054  int var = partialdec->getOpenvars()[v];
1055  for(int i = 0; i < detprobdata->getNVarsForCons(cons); ++i)
1056  {
1057  if(var == detprobdata->getVarsForCons(cons)[i])
1058  {
1059  varsBool[var] = true;
1060  conssBool[cons] = true;
1061  }
1062  }
1063  }
1064  }
1065 
1066  for(int v = 0; v < partialdec->getNOpenvars(); ++v)
1067  {
1068  int var = partialdec->getOpenvars()[v];
1069  if(varsBool[var] == true)
1070  varsForGraph.push_back(var);
1071  }
1072  for(int c = 0; c < partialdec->getNOpenconss(); ++c)
1073  {
1074  int cons = partialdec->getOpenconss()[c];
1075  if(conssBool[cons] == true)
1076  conssForGraph.push_back(cons);
1077  }
1078 
1079  assert(this->nvars == (int) varsForGraph.size());
1080  assert(this->nconss == (int) conssForGraph.size());
1081 
1082  sort(conssForGraph.begin(), conssForGraph.end());
1083  sort(varsForGraph.begin(), varsForGraph.end());
1084 
1085  //fillout oldToNewVarIndex and oltToNewConsIndex
1086  for(int v = 0; v < this->nvars; ++v)
1087  {
1088  int oldVarId = varsForGraph[v];
1089  oldToNewVarIndex.insert({oldVarId,v});
1090  }
1091 
1092  for(int c = 0; c < this->nconss; ++c)
1093  {
1094  int oldConsId = conssForGraph[c];
1095  oldToNewConsIndex.insert({oldConsId,c});
1096  }
1097 
1098  priority_graph stable_set_graph;
1099  this->non_cl = (int)labels.size();
1100  // for each column in the conss matrix we save labels of all the constraints where the variable appears
1101  vector< vector<int> > all_ind_in_col(this->nvars);
1102 
1103  /* go through all constraints */
1104  for(int c = 0; c < this->nconss; ++c)
1105  {
1106  int cons1 = conssForGraph[c];
1107  int consIndex1 = oldToNewConsIndex[cons1];
1108  assert(consIndex1 >= 0);
1109  assert(consIndex1 < this->nconss);
1110 
1111  /*
1112  * may work as is, as we are copying the constraint later regardless
1113  * if there are variables in it or not
1114  */
1115 
1116  /* go through all constraints */
1117  for(int d = 0; d < c; ++d )
1118  {
1119  int cons2 = conssForGraph[d];
1120  int consIndex2 = oldToNewConsIndex[cons2];
1121  assert(consIndex2 >= 0);
1122  assert(consIndex2 < this->nconss);
1123  if(labels[consIndex1] == labels[consIndex2])
1124  continue;
1125  SCIP_Bool continueloop = FALSE;
1126  /*
1127  * may work as is, as we are copying the constraint later regardless
1128  * if there are variables in it or not
1129  */
1130 
1131  /** @todo skip all variables that have a zero coeffient or where all coefficients add to zero */
1132  /** @todo Do more then one entry per variable actually work? */
1133  for(int v = 0; v < detprobdata->getNVarsForCons(cons1); ++v)
1134  {
1135  int var1 = detprobdata->getVarsForCons(cons1)[v];
1136  if(find(varsForGraph.begin(), varsForGraph.end(), var1) == varsForGraph.end())
1137  continue;
1138  int varIndex1 = oldToNewVarIndex[var1];
1139  assert(varIndex1 >= 0);
1140  assert(varIndex1 < this->nvars);
1141  for(int w = 0; w < detprobdata->getNVarsForCons(cons2); ++w)
1142  {
1143  int var2 = detprobdata->getVarsForCons(cons2)[w];
1144  if(find(varsForGraph.begin(), varsForGraph.end(), var2) == varsForGraph.end())
1145  continue;
1146  int varIndex2 = oldToNewVarIndex[var2];
1147  assert(varIndex2 >= 0);
1148  assert(varIndex2 < this->nvars);
1149  if(varIndex1 == varIndex2)
1150  {
1151  stable_set_graph.addNode(consIndex1);
1152  stable_set_graph.addNode(consIndex2);
1153  stable_set_graph.addEdge(consIndex1, consIndex2);
1154  continueloop = TRUE;
1155  break;
1156  }
1157  }
1158  if(continueloop)
1159  break;
1160  }
1161  }
1162  }
1163 
1164  // run greedy heuristic for stable set
1165  vector<int> stable_set;
1166  vector<int> no_stable_set;
1167  while(!stable_set_graph.empty()){
1168  int current = stable_set_graph.top().first;
1169  stable_set.push_back(current);
1170  set<int> neighbors = stable_set_graph.getNeighbors(current);
1171  stable_set_graph.pop();
1172  for(auto neighbor : neighbors){
1173  stable_set_graph.removeNode(neighbor, no_stable_set);
1174  }
1175  }
1176 
1177 
1178  // Iterate all the conss and remove them (i.e. set label to -1) if necessary
1179  for(int to_remove : no_stable_set)
1180  {
1181  labels[to_remove] = -1;
1182  }
1183  }
1184 
1185 
1186  if(!skip_me)
1187  {
1188  // Fix the labeling so that it starts from 0 without skipping the enumeration order
1189  // And set the graph partition accordingly.
1190  set<int> diff_blocks;
1191  for(auto curr_int = labels.begin(), end = labels.end(); curr_int != end; ++curr_int)
1192  {
1193  diff_blocks.insert(*curr_int);
1194  }
1195 
1196  const int non_cl_pts = count(labels.begin(), labels.end(), -1);
1197  if(non_cl_pts > 0)
1198  {
1199  this->n_blocks = diff_blocks.size() - 1;
1200  }
1201  else
1202  {
1203  this->n_blocks = diff_blocks.size();
1204  }
1205  this->non_cl = non_cl_pts;
1206 
1207  map<int,int> labels_fix;
1208  int new_label;
1209  if(this->non_cl > 0) new_label = -1;
1210  else new_label = 0;
1211 
1212  for(int old_label: diff_blocks)
1213  {
1214  labels_fix[old_label] = new_label;
1215  new_label++;
1216  }
1217  for(int i = 0; i < (int)labels.size(); i++)
1218  {
1219  labels[i] = labels_fix[labels[i]];
1220  }
1221  }
1222 
1223  // put the labels as the partition...
1224  for(int i = 0; i < (int)labels.size(); i++)
1225  {
1226  this->graph.setPartition(i, labels[i]);
1227  }
1228  return SCIP_OKAY;
1229 }
1230 
1231 template <>
1232 SCIP_RETCODE RowGraphWeighted<GraphGCG>::computePartitionDBSCAN(double eps, bool postprocenable)
1233 {
1234  vector<int> labels;
1235  labels = GraphAlgorithms<GraphGCG>::dbscan(graph, eps);
1236  assert((int)labels.size() == graph.getNNodes());
1237 
1238  SCIP_CALL( postProcess(labels, postprocenable) );
1239  return SCIP_OKAY;
1240 }
1241 
1242 template <>
1243 SCIP_RETCODE RowGraphWeighted<GraphGCG>::computePartitionDBSCANForPartialGraph(gcg::DETPROBDATA* detprobdata, gcg::PARTIALDECOMP* partialdec, double eps, bool postprocenable)
1244 {
1245  vector<int> labels;
1246  labels = GraphAlgorithms<GraphGCG>::dbscan(graph, eps);
1247  assert((int)labels.size() == graph.getNNodes());
1248 
1249  SCIP_CALL( postProcessForPartialGraph(detprobdata, partialdec, labels, postprocenable) );
1250  return SCIP_OKAY;
1251 }
1252 
1253 
1254 template <>
1255 SCIP_RETCODE RowGraphWeighted<GraphGCG>::computePartitionMST(double eps, bool postprocenable)
1256 {
1257  vector<int> labels;
1258  labels = GraphAlgorithms<GraphGCG>::mst(graph, eps);
1259  assert((int)labels.size() == graph.getNNodes());
1260 
1261  SCIP_CALL( postProcess(labels, postprocenable) );
1262  return SCIP_OKAY;
1263 }
1264 
1265 template <>
1266 SCIP_RETCODE RowGraphWeighted<GraphGCG>::computePartitionMSTForPartialGraph(gcg::DETPROBDATA* detprobdata, gcg::PARTIALDECOMP* partialdec, double eps, bool postprocenable)
1267 {
1268  vector<int> labels;
1269  labels = GraphAlgorithms<GraphGCG>::mst(graph, eps);
1270  assert((int)labels.size() == graph.getNNodes());
1271 
1272  SCIP_CALL( postProcessForPartialGraph(detprobdata, partialdec, labels, postprocenable) );
1273  return SCIP_OKAY;
1274 }
1275 
1276 template <>
1277 SCIP_RETCODE RowGraphWeighted<GraphGCG>::computePartitionMCL(int& stoppedAfter, double inflatefactor, bool postprocenable)
1278 {
1279  vector<int> labels;
1280  labels = GraphAlgorithms<GraphGCG>::mcl(graph, stoppedAfter, inflatefactor);
1281  assert((int)labels.size() == graph.getNNodes());
1282 
1283  SCIP_CALL( postProcess(labels, postprocenable) );
1284  return SCIP_OKAY;
1285 }
1286 
1287 template <>
1288 SCIP_RETCODE RowGraphWeighted<GraphGCG>::computePartitionMCLForPartialGraph(gcg::DETPROBDATA* detprobdata, gcg::PARTIALDECOMP* partialdec, int& stoppedAfter, double inflatefactor, bool postprocenable)
1289 {
1290  vector<int> labels;
1291  labels = GraphAlgorithms<GraphGCG>::mcl(graph, stoppedAfter, inflatefactor);
1292  assert((int)labels.size() == graph.getNNodes());
1293 
1294  SCIP_CALL( postProcessForPartialGraph(detprobdata, partialdec, labels, postprocenable) );
1295  return SCIP_OKAY;
1296 }
1297 
1298 template <class T>
1299 SCIP_RETCODE RowGraphWeighted<T>::getNBlocks(int& _n_blocks)
1300 {
1301  _n_blocks = n_blocks;
1302  return SCIP_OKAY;
1303 }
1304 
1305 template <class T>
1306 SCIP_RETCODE RowGraphWeighted<T>::nonClustered(int& _non_cl)
1307 {
1308  _non_cl = non_cl;
1309  return SCIP_OKAY;
1310 }
1311 
1312 template <class T>
1314 {
1315  return this->graph.getEdgeWeightPercentile(q);
1316 }
1317 
1318 } /* namespace gcg */
1319 #endif
virtual SCIP_RETCODE createFromMatrix(SCIP_CONS **conss, SCIP_VAR **vars, int nconss_, int nvars_, DISTANCE_MEASURE dist, WEIGHT_TYPE w_type)
int getNOpenvars()
Gets size of vector containing variables not assigned yet.
static std::vector< int > dbscan(Graph< GraphGCG > &graph, double eps, int minPts=4)
void addNode(int id)
virtual SCIP_RETCODE getNBlocks(int &_n_blocks)
virtual SCIP_RETCODE nonClustered(int &_non_cl)
A row graph where each row is a node and rows are adjacent if they share a variable....
virtual SCIP_RETCODE computePartitionDBSCANForPartialGraph(gcg::DETPROBDATA *detprobdata, gcg::PARTIALDECOMP *partialdec, double eps, bool postprocenable)
virtual SCIP_RETCODE computePartitionMCL(int &stoppedAfter, double inflatefactor, bool postprocenable)
enum DistanceMeasure DISTANCE_MEASURE
SCIP_Bool GCGisVarRelevant(SCIP_VAR *var)
Definition: scip_misc.c:41
static std::vector< int > mcl(Graph< GraphGCG > &graph, int &stoppedAfter, double inflatefac, int maxiters=25, int expandfac=2)
@ INTERSECTION
virtual SCIP_RETCODE computePartitionMCLForPartialGraph(gcg::DETPROBDATA *detprobdata, gcg::PARTIALDECOMP *partialdec, int &stoppedAfter, double inflatefactor, bool postprocenable)
void addEdge(int node_i, int node_j)
bool removeNode(int node, vector< int > &removed)
virtual SCIP_RETCODE computePartitionMSTForPartialGraph(gcg::DETPROBDATA *detprobdata, gcg::PARTIALDECOMP *partialdec, double eps, bool postprocenable)
static std::vector< int > mst(Graph< GraphGCG > &graph, double cutoff, int minPts=4)
const int * getOpenconss()
Gets array containing constraints not assigned yet.
int getNConss()
Gets the number of constraints.
virtual SCIP_RETCODE createFromPartialMatrix(DETPROBDATA *detprobdata, PARTIALDECOMP *partialdec, DISTANCE_MEASURE dist, WEIGHT_TYPE w_type)
enum WeightType WEIGHT_TYPE
std::string name
Definition: matrixgraph.h:56
virtual SCIP_RETCODE computePartitionMST(double eps, bool postprocenable)
class to manage partial decompositions
int getNVarsForCons(int consIndex)
returns the number of variables for a given constraint
Implementation of the graph which supports both node and edge weights.
several metrics for graphs
int getNOpenconss()
Gets size of vector containing constraints not assigned yet.
virtual double getEdgeWeightPercentile(double q)
set< int > getNeighbors(int node)
virtual SCIP_RETCODE computePartitionDBSCAN(double eps, bool postprocenable)
std::vector< int > & getVarsForCons(int consIndex)
returns the variable indices of the coefficient matrix for a constraint
static double calculateSimilarity(int a, int b, int c, DISTANCE_MEASURE dist, WEIGHT_TYPE w_type, bool itself)
const int * getOpenvars()
Gets array containing variables not assigned yet.
int getNVars()
Gets number of vars.