Scippy

GCG

Branch-and-Price & Column Generation for Everyone

dialog_explore.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 dialog_explore.cpp
29  * @brief dialog menu for exploring decompositions
30  * @author Michael Bastubbe
31  * @author Hanna Franzen
32  *
33  * This file contains all dialog calls to build and use the explore menu.
34  * The explore menu gives the user detailed information about all decompositions and a possibility to edit such.
35  */
36 
37 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
38 
39 #include <cassert>
40 #include <cstddef>
41 #include <cstdlib>
42 
43 #include <string>
44 #include <iostream>
45 #include <regex>
46 #include <map>
47 #include <sstream>
48 #include <iomanip>
49 
50 #include "class_partialdecomp.h"
51 #include "cons_decomp.h"
52 #include "cons_decomp.hpp"
53 #include "scoretype.h"
54 
55 /* column headers */
56 #define DEFAULT_COLUMN_MIN_WIDTH 4 /**< min width of a column in the menu table */
57 #define DEFAULT_SORT_HEADER "score"
58 
59 #define DEFAULT_MENULENGTH 10 /**< initial number of entries in menu */
60 
61 /**< default column headers */
62 const char* DEFAULT_COLUMNS[] {"nr", "id", "nbloc", "nmacon", "nlivar", "nmavar", "nstlva", "score", "history", "pre", "nopcon", "nopvar", "sel"};
63 
64 namespace gcg
65 {
66 
67 /** RETTYPE is used to store the return type of a callback function */
68 enum RETTYPE
69 {
70  UNKNOWN, /**< dummy default to catch errors */
71  INTEGER, /**< integer */
72  FLOAT, /**< float */
73  BOOLEAN, /**< Boolean */
74  STRING /**< char* */
75 };
76 
77 using UNKNOWN_DUMMY_TYPE = bool;
78 static
80 {
81  return UNKNOWN_DUMMY_TYPE();
82 }
83 
84 /** storage for column information */
86 {
87 public:
88  AbstractColumn(const char* columnHeader, const char* columnDesc, RETTYPE columnType) :
89  header(columnHeader), desc(columnDesc), type(columnType) {}
90 
91  virtual ~AbstractColumn() = default;
92 
93  virtual int compareValues(SCIP* scip, int firstId, int secondId) = 0;
94 
95  virtual std::string getValueAsString(SCIP* scip, int id) = 0;
96 
97  RETTYPE getReturnType() const { return type; }
98 
99  std::string header; /**< table header of the column */
100  std::string desc; /**< description of the column entries used in the menu help */
101 
102 private:
103  RETTYPE type; /**< return type of the getter */
104 };
105 
106 template <class T>
107 class Column: public AbstractColumn
108 {
109 public:
110  Column(const char* columnHeader, const char* columnDesc, T (*columnCallback)(SCIP*, int), RETTYPE columnType) :
111  AbstractColumn(columnHeader, columnDesc, columnType), callback(columnCallback) {}
112 
113  ~Column() override = default;
114 
115  T getValue(SCIP* scip, int id) { return callback(scip, id); }
116 
117  std::string getValueAsString(SCIP* scip, int id) override
118  {
119  std::ostringstream sstream;
120  sstream << std::fixed << std::setprecision(2) << getValue(scip, id);
121  return sstream.str();
122  }
123 
124  int compareValues(SCIP* scip, int firstId, int secondId) override
125  {
126  if( getReturnType() == UNKNOWN )
127  {
128  return 0;
129  }
130  else
131  {
132  T val1 = getValue(scip, firstId);
133  T val2 = getValue(scip, secondId);
134  if( val1 == val2 )
135  return 0;
136  else if( val1 < val2 )
137  return -1;
138  else
139  return 1;
140  }
141  }
142 
143 private:
144  T (*callback)(SCIP*, int);
145 };
146 
148  SCIP* scip,
149  std::vector<int>& idlist,
150  unsigned int& npartialdecs,
151  bool includeopenpartialdecs
152  )
153 {
154  unsigned int newnpartialdecs = GCGconshdlrDecompGetNPartialdecs(scip);
155  if( newnpartialdecs != npartialdecs || (includeopenpartialdecs != (npartialdecs == idlist.size())) )
156  {
157  std::vector<PARTIALDECOMP*>* partialdecs = GCGconshdlrDecompGetPartialdecs(scip);
158 
159  npartialdecs = newnpartialdecs;
160  idlist.clear();
161  idlist.reserve(npartialdecs);
162 
163  for( PARTIALDECOMP* partialdec: *partialdecs )
164  {
165  if( includeopenpartialdecs || partialdec->isComplete() )
166  {
167  idlist.push_back(partialdec->getID());
168  }
169  }
170  return true;
171  }
172  return false;
173 }
174 
175 /** @brief local sorting function for partialdec id vectors
176  *
177  * avoids redundant sorting calls,
178  * sorts by score in given order
179  */
180 static
182  SCIP* scip, /**< SCIP data structure */
183  std::vector<int>& idlist, /**< current list of partialdec ids */
184  std::string& header, /**< header of column to sort by */
185  std::vector<AbstractColumn*>& columns, /**< vector of pointers to columns */
186  bool asc /**< whether to sort ascending or descending */
187  )
188 {
189  /* find the column infos for the given header */
190  for( auto column : columns )
191  {
192  if( column->header.find(header) == 0 )
193  {
194  /* sort the id list according to given order using the callback getter of the column */
195  if( column->getReturnType() != UNKNOWN )
196  {
197  /* the callback has to be parsed to expect an int output */
198  if( asc )
199  std::stable_sort(idlist.begin(), idlist.end(), [&](const int a, const int b) { return column->compareValues(scip, a, b) < 0; });
200  else
201  std::stable_sort(idlist.begin(), idlist.end(), [&](const int a, const int b) { return column->compareValues(scip, b, a) < 0; });
202  }
203  break;
204  }
205  }
206 }
207 
208 
209 /** modifies menulength according to input and updates menu accordingly
210  * @returns SCIP return code */
211 static
212 SCIP_RETCODE GCGdialogSetNEntires(
213  SCIP* scip, /**< SCIP data structure */
214  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
215  SCIP_DIALOG* dialog, /**< dialog for user input management */
216  int listlength, /**< length of partialdec id list */
217  int& menulength /**< current menu length to be modified */
218  )
219 {
220  char* ntovisualize;
221  SCIP_Bool endoffile;
222  int newlength;
223  int commandlen;
224 
225  SCIPdialogMessage(scip, NULL, "Please specify the amount of entries to be shown in this menu:\n");
226  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &ntovisualize, &endoffile) );
227  commandlen = strlen(ntovisualize);
228 
229  newlength = -1;
230  if( commandlen != 0 )
231  newlength = atoi(ntovisualize);
232 
233  /* check whether there are decompositions,
234  * (preventing "Why doesn't it show anything? Maybe the entry number is 0") */
235  if( GCGconshdlrDecompGetNPartialdecs(scip) == 0 )
236  {
237  SCIPinfoMessage(scip, NULL, "No decompositions available. Please detect first.\n");
238  return SCIP_OKAY;
239  }
240 
241  /* check for invalid input */
242  if( commandlen == 0 || newlength < 1 )
243  {
244  SCIPdialogMessage( scip, NULL, "The input was not a valid number." );
245  return SCIP_OKAY;
246  }
247 
248  /* set new length (max listlength) */
249  if( newlength < listlength )
250  menulength = newlength;
251  else
252  menulength = listlength;
253 
254  return SCIP_OKAY;
255 }
256 
257 
258 /** sets the used score according to user input
259  *
260  * @returns SCIP return code
261  */
262 static
263 SCIP_RETCODE GCGdialogChangeScore(
264  SCIP* scip, /**< SCIP data structure */
265  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
266  SCIP_DIALOG* dialog /**< dialog for user input management */
267  )
268 {
269  char* getscore;
270  SCIP_Bool endoffile;
271  int commandlen;
272 
273  SCIPdialogMessage(scip, NULL, "\nPlease specify the new score:\n");
274  SCIPdialogMessage(scip, NULL, "0: max white, \n1: border area, \n2: classic, \n3: max foreseeing white, \n4: ppc-max-white, \n");
275  SCIPdialogMessage(scip, NULL, "5: max foreseeing white with aggregation info, \n6: ppc-max-white with aggregation info, \n7: experimental benders score\n");
276  SCIPdialogMessage(scip, NULL, "8: strong decomposition score\n");
277  SCIPdialogMessage(scip, NULL, "Note: Sets the detection/score/scoretype parameter to the given score.\n");
278 
279  /* get input */
280  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &getscore, &endoffile) );
281  commandlen = strlen(getscore);
282  if( commandlen != 0 )
283  {
284  /* convert to int (if value is invalid, this results in 0) */
285  int scorenr = atoi(getscore);
286 
287  /* check if the value is in valid range */
288  if(scorenr >= 0 && scorenr <= 8)
289  {
290  /* set score */
291  SCIPsetIntParam(scip, "detection/score/scoretype", scorenr);
292  GCGconshdlrDecompSetScoretype(scip, static_cast<SCORETYPE>(scorenr));
293  SCIPdialogMessage(scip, NULL, "Score set to %d.\n", scorenr);
294  }
295  }
296 
297  return SCIP_OKAY;
298 }
299 
300 
301 /**
302  * Outputs the given char x times as SCIPdialogMessage
303  * @returns SCIP status
304  */
305 static
306 SCIP_RETCODE outputCharXTimes(
307  SCIP* scip, /**< SCIP data structure */
308  const char letter, /**< char to write */
309  int x /**< write char x times */
310  )
311 {
312  for(int i = 0; i < x; i++)
313  SCIPdialogMessage(scip, NULL, "%c", letter);
314 
315  return SCIP_OKAY;
316 }
317 
318 /** @brief show current menu containing partialdec information
319  *
320  * Update partialdec list in case it changed since the last command
321  * and show the table of partialdecs.
322  * @returns SCIP status
323  */
324 static
325 SCIP_RETCODE GCGdialogShowMenu(
326  SCIP* scip, /**< SCIP data structure */
327  std::vector<AbstractColumn*>& columns, /**< vector of pointers to columns */
328  unsigned int& npartialdecs, /**< max number of partialdecs */
329  const int startindex, /**< index (in partialdec list) of uppermost partialdec in extract */
330  int menulength, /**< number of menu entries */
331  std::vector<int>& idlist, /**< current list of partialdec ids */
332  bool sortasc, /**< true iff sorting should be ascending */
333  std::string sortby, /**< table header of column to sort by */
334  bool listopenpartialdecs /**< open partialdecs will be listed iff set to true*/
335  )
336 {
337  assert(scip != NULL);
338 
339  /* update partialdec list in case it changed (in which case the amount of partialdecs should have changed)*/
340  updateIdList(scip, idlist, npartialdecs, listopenpartialdecs);
341 
342  /* sort partialdec ids by score, descending (in case score was changed or id list was updated)*/
343  sortPartialdecList(scip, idlist, sortby, columns, sortasc);
344 
345  /* count corresponding partialdecs for overview statistics */
346  int ndetectedpresolved = 0;
347  int ndetectedunpresolved = 0;
348 
349  for(int i : idlist)
350  {
352  if(partialdec->isComplete())
353  {
354  /* from presolved problem */
355  if(partialdec->isAssignedToOrigProb())
356  {
357  ++ndetectedunpresolved;
358  }
359  /* from original problem */
360  else
361  {
362  ++ndetectedpresolved;
363  }
364  }
365  }
366 
367  /* count width of menu table by summing width of column headers,
368  * make header line, and border line for header (will be beneath the column headers) as follows:
369  * a border line of the length of the column width as '-' for each column and a space between the columns,
370  * e.g. header line " nr id nbloc nmacon sel ",
371  * e.g. underscores " ---- ---- ----- ------ ---- " */
372  std::string headerline;
373  std::string borderline;
374  std::map<std::string, int> columnlength;
375  int linelength = 0;
376 
377  /* line starts with a space */
378  headerline = " ";
379  borderline = " ";
380 
381  /* add each column header */
382  for( auto column : columns )
383  {
384  /* "score" is a wildcard for the current score, relace it with actual scoretype */
385  std::string header = column->header;
386  std::string newheader;
387  if( header != "score" )
388  newheader = header;
389  else
391 
392  /* make sure the header name is unique and add a length for header */
393  assert(columnlength.find(header) == columnlength.end());
394  columnlength.insert(std::pair<std::string,int>(header, 0));
395  /* if header is smaller than min column width, add spaces to header first */
396  if( newheader.size() < DEFAULT_COLUMN_MIN_WIDTH )
397  {
398  for( int i = 0; i < (DEFAULT_COLUMN_MIN_WIDTH - (int) newheader.size()); i++ )
399  {
400  headerline += " ";
401  borderline += "-";
402  columnlength.at(header)++;
403  }
404  }
405  /* add header to headerline and add #chars of header as '-' to borderline*/
406  headerline += newheader;
407  for( int i = 0; i < (int) newheader.size(); i++ )
408  borderline += "-";
409  columnlength.at(header) += (int) newheader.size();
410  /* add space to both lines as column border */
411  headerline += " ";
412  borderline += " ";
413  /* add columnlength (+1 for border space) to overall linelength */
414  linelength += columnlength.at(header) + 1;
415  }
416 
417  /* display overview statistics */
418  SCIPdialogMessage(scip, NULL, "\n");
419  outputCharXTimes(scip, '=', linelength);
420  SCIPdialogMessage(scip, NULL, " \n");
421  SCIPdialogMessage(scip, NULL, "Summary presolved original \n");
422  SCIPdialogMessage(scip, NULL, " --------- -------- \n");
423  SCIPdialogMessage(scip, NULL, "detected ");
424  SCIPdialogMessage(scip, NULL, "%9d ", ndetectedpresolved );
425  SCIPdialogMessage(scip, NULL, "%8d\n", ndetectedunpresolved );
426  outputCharXTimes(scip, '=', linelength);
427  SCIPdialogMessage(scip, NULL, " \n");
428  /* display header of table */
429  SCIPdialogMessage(scip, NULL, "%s\n", headerline.c_str());
430  SCIPdialogMessage(scip, NULL, "%s\n", borderline.c_str());
431 
432  /* go through all partialdecs that should currently be displayed,
433  * so from startindex on menulength many entries if there are that much left in the list */
434  for( int i = startindex; i < startindex + menulength && i < (int) idlist.size(); ++i )
435  {
436  /* get current partialdec id */
437  int partialdecid = idlist.at(i);
438 
439  /* each line starts with a space */
440  SCIPdialogMessage(scip, NULL, " ");
441 
442  /* go through the columns and write the entry for each one */
443  for( auto column : columns )
444  {
445  std::ostringstream sstream;
446  std::string header = column->header;
447 
448  /* write spaces to fill out the columnwidth */
449  sstream << std::setw(columnlength.at(header));
450 
451  /* call the getter of the column depending on the given return type */
452  if( header == "nr" )
453  {
454  sstream << i;
455  }
456  else
457  {
458  sstream << column->getValueAsString(scip, partialdecid);
459  }
460  SCIPdialogMessage(scip, NULL, "%s ", sstream.str().c_str());
461  }
462 
463  /* continue to next line */
464  SCIPdialogMessage(scip, NULL, "\n");
465  }
466 
467  /* at the end of the table add a line */
468  outputCharXTimes(scip, '=', linelength);
469  SCIPdialogMessage(scip, NULL, "\n");
470 
471  return SCIP_OKAY;
472 }
473 
474 
475 /** Shows information about the explore screen and its abbreviations
476  *
477  * @returns SCIP status */
478 static
479 SCIP_RETCODE GCGdialogShowLegend(
480  SCIP* scip, /**< SCIP data structure */
481  std::vector<AbstractColumn*>& columns /**< vector of pointers to columns */
482  )
483 {
484  assert(scip != NULL);
485  DEC_DETECTOR** detectors;
486 
487  /* print header for detector list */
488  SCIPdialogMessage(scip, NULL, "List of included detectors for decompositions histories: \n");
489 
490  SCIPdialogMessage(scip, NULL, "\n%30s %4s\n", "detector" , "char");
491  SCIPdialogMessage(scip, NULL, "%30s %4s\n", "--------" , "----");
492 
493  /* get and print char of each detector */
494  detectors = GCGconshdlrDecompGetDetectors(scip);
495 
496  for( int det = 0; det < GCGconshdlrDecompGetNDetectors(scip); ++det )
497  {
498  DEC_DETECTOR* detector;
499  detector = detectors[det];
500 
501  SCIPdialogMessage(scip, NULL, "%30s %4c\n", DECdetectorGetName(detector), DECdetectorGetChar(detector));
502  }
503  /* print usergiven as part of detector chars */
504  SCIPdialogMessage(scip, NULL, "%30s %4s\n", "given by user" , "U");
505  SCIPdialogMessage(scip, NULL, "\n" );
506 
507  SCIPdialogMessage(scip, NULL, "=================================================================================================== \n");
508 
509  SCIPdialogMessage(scip, NULL, "\n" );
510 
511  /* print header of abbreviation table */
512  SCIPdialogMessage(scip, NULL, "List of abbreviations of decomposition table \n" );
513  SCIPdialogMessage(scip, NULL, "\n" );
514  SCIPdialogMessage(scip, NULL, "%30s %s\n", "abbreviation", "description");
515  SCIPdialogMessage(scip, NULL, "%30s %s\n", "------------", "-----------");
516 
517  /* add legend entry for each header abbreviation */
518  for( auto column : columns )
519  {
520  /* get table header */
521  std::string& header = column->header;
522 
523  /* print the header with the description */
524  if( header != "score" )
525  {
526  SCIPdialogMessage(scip, NULL, "%30s %s\n", header.c_str(), column->desc.c_str());
527  }
528  /* if the header is "score" replace with shortname of the current score */
529  else
530  {
531  SCIPdialogMessage(scip, NULL, "%30s %s\n", GCGscoretypeGetShortName(GCGconshdlrDecompGetScoretype(scip)),
533  }
534 
535  }
536  SCIPdialogMessage(scip, NULL, "\n=================================================================================================== \n");
537 
538  return SCIP_OKAY;
539 }
540 
541 /** @brief Shows help section of explore menu
542  *
543  * Outputs al ist of commands and a description of their function
544  * @returns SCIP status */
545 static
546 SCIP_RETCODE GCGdialogShowHelp(
547  SCIP* scip /**< SCIP data structure */
548  )
549 {
550  assert(scip != NULL);
551 
552  SCIPdialogMessage(scip, NULL, "=================================================================================================== \n");
553  SCIPdialogMessage(scip, NULL, "\n" );
554  SCIPdialogMessage(scip, NULL, "List of selection commands \n" );
555  SCIPdialogMessage(scip, NULL, "\n" );
556  SCIPdialogMessage(scip, NULL, "%30s %s\n", "command", "description");
557  SCIPdialogMessage(scip, NULL, "%30s %s\n", "-------", "-----------");
558  SCIPdialogMessage(scip, NULL, "%30s %s\n", "help", "displays this help");
559  SCIPdialogMessage(scip, NULL, "%30s %s\n", "legend", "displays the legend for table header and history abbreviations");
560  SCIPdialogMessage(scip, NULL, "%30s %s\n", "select", "selects/unselects decomposition with given nr");
561  SCIPdialogMessage(scip, NULL, "%30s %s\n", "previous", "displays the preceding decompositions (if there are any)");
562  SCIPdialogMessage(scip, NULL, "%30s %s\n", "next", "displays the subsequent decompositions (if there are any)");
563  SCIPdialogMessage(scip, NULL, "%30s %s\n", "top", "displays the first decompositions");
564  SCIPdialogMessage(scip, NULL, "%30s %s\n", "end", "displays the last decompositions");
565  SCIPdialogMessage(scip, NULL, "%30s %s\n", "entries", "modifies the number of decompositions to display per page");
566  SCIPdialogMessage(scip, NULL, "%30s %s\n", "export", "generates visualization of the specified decomposition in gnuplot format");
567  SCIPdialogMessage(scip, NULL, "%30s %s\n", "visualize", "generates visualization and opens it (requires gnuplot)");
568  SCIPdialogMessage(scip, NULL, "%30s %s\n", "inspect", "displays detailed information for the specified decomposition");
569  SCIPdialogMessage(scip, NULL, "%30s %s\n", "score", "sets the score by which the quality of decompositions is evaluated");
570  SCIPdialogMessage(scip, NULL, "%30s %s\n", "sort", "sets the column by which the decompositions are sorted (default: by score)");
571  SCIPdialogMessage(scip, NULL, "%30s %s\n", "ascending", "sort decompositions in ascending (true) or descending (false) order");
572  SCIPdialogMessage(scip, NULL, "%30s %s\n", "list", "specify whether all decompositions should be listed");
573  SCIPdialogMessage(scip, NULL, "%30s %s\n", "quit", "return to main menu");
574 
575  SCIPdialogMessage(scip, NULL, "\n=================================================================================================== \n");
576 
577  return SCIP_OKAY;
578 }
579 
580 
581 /** Shows a visualization of the partialdec specified by the user via the dialog
582  *
583  * @returns SCIP status */
584 static
586  SCIP* scip, /**< SCIP data structure */
587  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
588  SCIP_DIALOG* dialog, /**< dialog for user input management */
589  std::vector<int>& idlist, /**< current list of partialdec ids */
590  SCIP_Bool open /**< compile and open gnuplot file? */
591  )
592 {
593  char* ntovisualize;
594  SCIP_Bool endoffile;
595  int idtovisu;
596  int commandlen;
597 
598  assert(scip != NULL);
599 
600  SCIPdialogMessage(scip, NULL, "Please specify the nr of the decomposition to be visualized:\n");
601  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &ntovisualize, &endoffile) );
602  commandlen = strlen(ntovisualize);
603 
604  idtovisu = -1;
605  if( commandlen != 0 )
606  idtovisu = atoi(ntovisualize);
607 
608  /* check whether the partialdec exists */
609  if( commandlen == 0 || idtovisu < 0 || idtovisu >= (int) idlist.size() )
610  {
611  SCIPdialogMessage( scip, NULL, "This nr is out of range." );
612  return SCIP_OKAY;
613  }
614 
615  /* get and show partialdec */
616  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, idlist.at(idtovisu));
617  if( open )
618  partialdec->showVisualization();
619  else
620  partialdec->exportVisualization();
621 
622  return SCIP_OKAY;
623 }
624 
625 
626 /**
627  * Displays information about a partialdec that is chosen by the user in a dialog.
628  *
629  * @returns SCIP status
630  */
631 static
633  SCIP* scip, /**< SCIP data structure */
634  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
635  SCIP_DIALOG* dialog, /**< dialog for user input management */
636  std::vector<int>& idlist /**< current list of partialdec ids */
637  )
638 {
639  char* ntoinspect;
640  char* ndetaillevel;
641  SCIP_Bool endoffile;
642  int idtoinspect;
643  int detaillevel;
644 
645  int commandlen;
646 
647  assert( scip != NULL );
648 
649  /* read the id of the decomposition to be inspected */
650  SCIPdialogMessage( scip, NULL, "Please specify the nr of the decomposition to be inspected:\n");
651  SCIP_CALL( SCIPdialoghdlrGetWord( dialoghdlr, dialog, " ", &ntoinspect, &endoffile ) );
652  commandlen = strlen( ntoinspect );
653 
654  idtoinspect = -1;
655  if( commandlen != 0 )
656  idtoinspect = atoi( ntoinspect );
657 
658  if(idtoinspect < 0 || idtoinspect >= (int) idlist.size()){
659  SCIPdialogMessage( scip, NULL, "This nr is out of range." );
660  return SCIP_OKAY;
661  }
662 
663  /* check whether ID is in valid range */
664  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, idlist.at(idtoinspect));
665 
666  /* read the desired detail level; for wrong input, it is set to 1 by default */
667  SCIPdialogMessage( scip, NULL,
668  "Please specify the detail level:\n 0 - brief overview\n 1 - block and detector info (default)\n 2 - cons and var assignments\n" );
669  SCIP_CALL( SCIPdialoghdlrGetWord( dialoghdlr, dialog, " ", &ndetaillevel, &endoffile ) );
670  commandlen = strlen( ndetaillevel );
671 
672  detaillevel = 1;
673  if( commandlen != 0 )
674  {
675  std::stringstream convert( ndetaillevel );
676  convert >> detaillevel;
677 
678  if( detaillevel < 0 || ( detaillevel == 0 && ndetaillevel[0] != '0' ) )
679  {
680  detaillevel = 1;
681  }
682  }
683 
684  /* call displayInfo method according to chosen parameters */
685  partialdec->displayInfo( detaillevel );
686 
687  return SCIP_OKAY;
688 }
689 
690 
691 /** Lets the user select decompositions from the explore menu
692  *
693  * @returns SCIP status */
694 static
695 SCIP_RETCODE GCGdialogSelect(
696  SCIP* scip, /**< SCIP data structure */
697  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
698  SCIP_DIALOG* dialog, /**< dialog for user input management */
699  std::vector<int> idlist /**< current list of partialdec ids */
700  )
701 {
702  char* ntovisualize;
703  SCIP_Bool endoffile;
704  int idtovisu;
705 
706  int commandlen;
707 
708  assert(scip != NULL);
709 
710  /* get input */
711  SCIPdialogMessage(scip, NULL, "\nPlease specify the nr of the decomposition to be selected:\n");
712  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &ntovisualize, &endoffile) );
713  commandlen = strlen(ntovisualize);
714 
715  idtovisu = -1;
716  if( commandlen != 0)
717  idtovisu = atoi(ntovisualize);
718 
719  /* check if the input is a valid number */
720  if( commandlen == 0 || idtovisu < 0 || idtovisu >= (int) idlist.size() )
721  {
722  SCIPdialogMessage( scip, NULL, "This nr is out of range, nothing was selected." );
723  return SCIP_OKAY;
724  }
725 
726  /* get partialdec from id*/
727  PARTIALDECOMP* partialdec = GCGconshdlrDecompGetPartialdecFromID(scip, idlist.at(idtovisu));
728 
729  /* reverse selection (deselects if partialdec was previously selected) */
730  partialdec->setSelected(!partialdec->isSelected() );
731 
732  return SCIP_OKAY;
733 }
734 
735 /** Set whether order in menu should be ascending/descending
736  *
737  * @returns SCIP return code */
738 static
739 SCIP_RETCODE GCGdialogSortAsc(
740  SCIP* scip, /**< SCIP data structure */
741  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
742  SCIP_DIALOG* dialog, /**< dialog for user input management */
743  bool& asc /**< true iff sorting should be ascending */
744  )
745 {
746  char* ascen;
747  SCIP_Bool endoffile;
748  int commandlen;
749 
750  assert(scip != NULL);
751 
752  /* get input */
753  SCIPdialogMessage(scip, NULL, "\nPlease enter \"true\"/\"1\" for ascending or \"false\"/\"0\" for descending order:\n");
754  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &ascen, &endoffile) );
755  commandlen = strlen(ascen);
756 
757  std::string input = ascen;
758  if( commandlen != 0)
759  {
760  /* check if input if is true, set ascending */
761  if(input == "true" || input == "1")
762  asc = true;
763  /* check if input if is false, set descending */
764  else if(input == "false" || input == "0")
765  asc = false;
766  /* all other inputs are considered invalid and do nothing */
767  }
768 
769  return SCIP_OKAY;
770 }
771 
772 
773 /** Checks whether the given header is valid
774  * @returns true iff header is valid
775  */
776 static
777 bool isHeader(
778  std::string& header, /**< header to check */
779  std::vector<AbstractColumn*>& columns /**< vector of pointers to columns */
780  )
781 {
782  /* check if the given header is a (prefix of a) registered table header */
783  for( auto column : columns )
784  {
785  if(column->header.find(header) == 0 )
786  return true;
787  }
788  /* else return false */
789  return false;
790 }
791 
792 
793 /** Set whether order in menu should be ascending/descending
794  *
795  * @returns SCIP return code */
796 static
797 SCIP_RETCODE GCGdialogSortBy(
798  SCIP* scip, /**< SCIP data structure */
799  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
800  SCIP_DIALOG* dialog, /**< dialog for user input management */
801  std::vector<AbstractColumn*>& columns, /**< vector of pointers to columns */
802  std::string& sortby /**< table header, identifies by which column to sort by */
803  )
804 {
805  char* newsort;
806  SCIP_Bool endoffile;
807  int commandlen;
808 
809  assert(scip != NULL);
810 
811  /* get input */
812  SCIPdialogMessage(scip, NULL, "\nPlease enter the table header of the column by which you would like to sort:\n");
813  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &newsort, &endoffile) );
814  commandlen = strlen(newsort);
815 
816  /* if the input is a valid table header, change sortby */
817  std::string input = newsort;
818  if( commandlen != 0 )
819  {
820  /* all headers (including the "score" wildcard) are valid */
821  if( isHeader(input, columns) )
822  sortby = input;
823  /* if the score abbreviation is entered, the header would not be in the column info */
825  sortby = "score";
826  }
827  return SCIP_OKAY;
828 }
829 
830 
831 /** Set whether order in menu should be ascending/descending
832  *
833  * @returns SCIP return code */
834 static
836  SCIP* scip, /**< SCIP data structure */
837  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
838  SCIP_DIALOG* dialog, /**< dialog for user input management */
839  bool& listopenpartialdecs /** will be updated */
840  )
841 {
842  char* input;
843  SCIP_Bool endoffile;
844  int commandlen;
845 
846  assert(scip != NULL);
847 
848  /* get input */
849  SCIPdialogMessage(scip, NULL, "\nShould incomplete decompositions be listed? Please enter \"true\" or \"false\":\n");
850  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog, " ", &input, &endoffile) );
851  commandlen = strlen(input);
852 
853  if( commandlen != 0)
854  {
855  /* check if input if is true, set ascending */
856  if( strncmp(input, "true", commandlen) == 0 || strncmp(input, "1", commandlen) == 0 )
857  listopenpartialdecs = true;
858  /* check if input if is false, set descending */
859  else if( strncmp(input, "false", commandlen) == 0 || strncmp(input, "0", commandlen) == 0 )
860  listopenpartialdecs = false;
861  /* all other inputs are considered invalid and do nothing */
862  }
863  return SCIP_OKAY;
864 }
865 
866 
867 static
868 SCIP_RETCODE GCGdialogExecCommand(
869  SCIP* scip, /**< SCIP data structure */
870  SCIP_DIALOGHDLR* dialoghdlr, /**< dialog handler for user input management */
871  SCIP_DIALOG* dialog, /**< dialog for user input management */
872  std::vector<AbstractColumn*>& columns, /**< vector of pointers to columns */
873  char* command, /**< the command that was entered */
874  int& startindex, /**< number of partialdec there the menu extract starts */
875  int& menulength, /**< current menu length to be modified */
876  bool& finished, /**< whether to quit the menu */
877  std::vector<int>& idlist, /**< current list of partialdec ids */
878  bool& sortasc, /**< true iff sorting should be ascending */
879  std::string& sortby, /**< name of table header to identify sorting column */
880  bool& listopenpartialdecs /** whether open patialdecs should be listed*/
881  )
882 {
883  int commandlen = strlen(command);
884 
885  if( strncmp( command, "previous", commandlen) == 0 )
886  {
887  startindex = startindex - menulength;
888  if(startindex < 0 )
889  startindex = 0;
890  }
891  else if( strncmp( command, "next", commandlen) == 0 )
892  {
893  startindex = startindex + menulength;
894  if( startindex > (int) idlist.size() - menulength )
895  startindex = (int) idlist.size() - menulength;
896  }
897  else if( strncmp( command, "top", commandlen) == 0 )
898  {
899  startindex = 0;
900  }
901  else if( strncmp( command, "end", commandlen) == 0 )
902  {
903  startindex = (int) idlist.size() - menulength;
904  if (startindex < 0)
905  startindex = 0;
906  }
907 
908  else if( strncmp( command, "quit", commandlen) == 0 || strncmp( command, "..", commandlen) == 0 )
909  {
910  finished = TRUE;
911  }
912 
913  else if( strncmp( command, "legend", commandlen) == 0 )
914  {
915  SCIP_CALL( GCGdialogShowLegend(scip, columns) );
916  }
917 
918  else if( strncmp( command, "help", commandlen) == 0 )
919  {
920  SCIP_CALL( GCGdialogShowHelp(scip) );
921  }
922 
923  else if( strncmp( command, "entries", commandlen) == 0 )
924  {
925  SCIP_CALL( GCGdialogSetNEntires(scip, dialoghdlr, dialog, (int) idlist.size(), menulength) );
926  }
927 
928  else if( strncmp( command, "visualize", commandlen) == 0 )
929  {
930  SCIP_CALL( GCGdialogSelectVisualize(scip, dialoghdlr, dialog, idlist, TRUE) );
931  }
932 
933  else if( strncmp( command, "export", commandlen) == 0 )
934  {
935  SCIP_CALL( GCGdialogSelectVisualize(scip, dialoghdlr, dialog, idlist, FALSE) );
936  }
937 
938  else if( strncmp( command, "inspect", commandlen) == 0 )
939  {
940  SCIP_CALL( GCGdialogInspectPartialdec( scip, dialoghdlr, dialog, idlist) );
941  }
942 
943  else if( strncmp( command, "select", commandlen) == 0 )
944  {
945  SCIP_CALL( GCGdialogSelect(scip, dialoghdlr, dialog, idlist) );
946  }
947 
948  else if( strncmp( command, "score", commandlen) == 0 )
949  {
950  SCIP_CALL( GCGdialogChangeScore(scip, dialoghdlr, dialog) );
951  }
952 
953  else if( strncmp( command, "ascending", commandlen) == 0 )
954  {
955  SCIP_CALL( GCGdialogSortAsc(scip, dialoghdlr, dialog, sortasc) );
956  }
957  else if( strncmp( command, "sort", commandlen) == 0 )
958  {
959  SCIP_CALL( GCGdialogSortBy(scip, dialoghdlr, dialog, columns, sortby) );
960  }
961  else if( strncmp( command, "list", commandlen) == 0 )
962  {
963  SCIP_CALL( GCGdialogChangeListMode(scip, dialoghdlr, dialog, listopenpartialdecs) );
964  }
965 
966  return SCIP_OKAY;
967 }
968 
969 static
971  SCIP* scip,
972  int id
973  )
974 {
975  return id;
976 }
977 
978 extern "C" {
979 
980 SCIP_RETCODE GCGdialogExecExplore(
981  SCIP* scip,
982  SCIP_DIALOGHDLR* dialoghdlr,
983  SCIP_DIALOG* dialog
984  )
985 {
986  /* set navigation defaults */
987  int startindex = 0; /**< number of partialdec there the menu extract starts */
988  int menulength = DEFAULT_MENULENGTH; /**< number of entries shown in menu */
989  bool sortasc = false; /**< whether to show entries in ascending order (score) */
990  std::string sortby = DEFAULT_SORT_HEADER; /**< table header, identifies by which column to sort by */
991  bool listopenpartialdecs = false;
992 
993  /* check for available partialdecs */
994  unsigned int npartialdecs = 0; /**< stores the last known number of partialdecs, is handed down to check for changes in partialdec number */
995  std::vector<int> idlist;
996  updateIdList(scip, idlist, npartialdecs, listopenpartialdecs);
997 
998  if(npartialdecs == 0)
999  {
1000  SCIPdialogMessage( scip, NULL, "There are no decompositions to explore yet, please detect first.\n" );
1001  return SCIP_OKAY;
1002  }
1003 
1004  /* set initial columns */
1005  /* the column information has the header, a getter for the column info and the return type of the getter */
1006  std::vector<AbstractColumn*> columns;
1007  /* go through each column header and determine its getter */
1008  for( auto columnname : DEFAULT_COLUMNS )
1009  {
1010  /**@note devs: if you want to add new headers, please specify their getters here! */
1011  AbstractColumn* column;
1012 
1013  if( strcmp(columnname, "nr") == 0 )
1014  {
1015  /* special case: "nr" represents the position in the menu table and is determined by the menu */
1016  column = new Column<UNKNOWN_DUMMY_TYPE>(
1017  columnname,
1018  "number of the decomposition (use this number for selecting the decomposition)",
1020  UNKNOWN);
1021  }
1022  else if( strcmp(columnname, "id") == 0 )
1023  {
1024  /* "id" is the partialdec id, the list of ids is known to the menu */
1025  column = new Column<int>(
1026  columnname,
1027  "id of the decomposition (identifies the decomposition in reports/statistics/visualizations/etc.)",
1029  INTEGER);
1030  }
1031  else if( strcmp(columnname, "nbloc") == 0 )
1032  {
1033  column = new Column<int>(
1034  columnname,
1035  "number of blocks",
1037  INTEGER);
1038  }
1039  else if( strcmp(columnname, "nmacon") == 0 )
1040  {
1041  column = new Column<int>(
1042  columnname,
1043  "number of master constraints",
1045  INTEGER);
1046  }
1047  else if( strcmp(columnname, "nmavar") == 0 )
1048  {
1049  column = new Column<int>(
1050  columnname,
1051  "number of \"master only\" variables (also called \"static\", do not occur in blocks)",
1053  INTEGER);
1054  }
1055  else if( strcmp(columnname, "nlivar") == 0 )
1056  {
1057  column = new Column<int>(
1058  columnname,
1059  "number of linking variables",
1061  INTEGER);
1062  }
1063  else if( strcmp(columnname, "nstlva") == 0 )
1064  {
1065  column = new Column<int>(
1066  columnname,
1067  "number of stair linking variables",
1069  INTEGER);
1070  }
1071  else if( strcmp(columnname, "score") == 0 )
1072  {
1073  column = new Column<float>(
1074  columnname,
1075  " ",
1077  FLOAT);
1078  }
1079  else if( strcmp(columnname, "history") == 0 )
1080  {
1081  column = new Column<std::string>(
1082  columnname,
1083  "list of detectors (their chars) which worked on this decomposition",
1085  STRING);
1086  }
1087  else if( strcmp(columnname, "pre") == 0 )
1088  {
1089  column = new Column<SCIP_Bool>(
1090  columnname,
1091  "is this decomposition for the presolved problem?",
1093  BOOLEAN);
1094  }
1095  else if( strcmp(columnname, "nopcon") == 0 )
1096  {
1097  column = new Column<int>(
1098  columnname,
1099  "number of open (=unassigned) constraints",
1101  INTEGER);
1102  }
1103  else if( strcmp(columnname, "nopvar") == 0 )
1104  {
1105  column = new Column<int>(
1106  columnname,
1107  "number of open (=unassigned) variables",
1109  INTEGER);
1110  }
1111  else if( strcmp(columnname, "sel") == 0 )
1112  {
1113  column = new Column<SCIP_Bool>(
1114  columnname,
1115  "is this decomposition selected?",
1117  BOOLEAN);
1118  }
1119 
1120  columns.push_back(column);
1121  }
1122 
1123  /* check that the given default sorting header is valid */
1124  assert(isHeader(sortby, columns));
1125 
1126  /* sort by default, descending */
1127  sortPartialdecList(scip, idlist, sortby, columns, sortasc);
1128 
1129  /* while user has not aborted: show current list extract and catch commands */
1130  bool finished = false;
1131  char* command;
1132  SCIP_Bool endoffile;
1133  while( !finished )
1134  {
1135  GCGdialogShowMenu(scip, columns, npartialdecs, startindex, menulength, idlist, sortasc, sortby, listopenpartialdecs);
1136 
1137  SCIP_CALL( SCIPdialoghdlrGetWord(dialoghdlr, dialog,
1138  "Please enter command (or \"h\" for help) : \nGCG/explore> ", &command, &endoffile) );
1139 
1140  GCGdialogExecCommand(scip, dialoghdlr, dialog, columns, command, startindex, menulength, finished, idlist, sortasc, sortby, listopenpartialdecs);
1141  }
1142 
1143  for( auto column : columns )
1144  delete column;
1145 
1146  return SCIP_OKAY;
1147 }
1148 
1149 } // extern "C"
1150 
1151 } // namespace gcg
static SCIP_RETCODE GCGdialogSetNEntires(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, int listlength, int &menulength)
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
SCIP_RETCODE GCGdialogExecExplore(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog)
method to handle user input for "explore" command
const char * DEFAULT_COLUMNS[]
miscellaneous methods for working with SCORETYPE
static SCIP_RETCODE GCGdialogSelect(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, std::vector< int > idlist)
std::string GCGconshdlrDecompGetDetectorHistoryByPartialdecId(SCIP *scip, int id)
gets detector history of partialdec with given id
std::string getValueAsString(SCIP *scip, int id) override
virtual ~AbstractColumn()=default
static int partialdecIdDummyGetter(SCIP *scip, int id)
float GCGconshdlrDecompGetScoreByPartialdecId(SCIP *scip, int id)
gets score of partialdec with given id
const char * GCGscoretypeGetShortName(SCORETYPE sctype)
Gets the shortname of the given scoretype.
Definition: scoretype.c:80
static SCIP_RETCODE GCGdialogShowMenu(SCIP *scip, std::vector< AbstractColumn * > &columns, unsigned int &npartialdecs, const int startindex, int menulength, std::vector< int > &idlist, bool sortasc, std::string sortby, bool listopenpartialdecs)
show current menu containing partialdec information
~Column() override=default
void displayInfo(int detailLevel)
displays the relevant information of the partialdec
static SCIP_RETCODE GCGdialogChangeScore(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog)
constraint handler for structure detection
static SCIP_RETCODE GCGdialogSortBy(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, std::vector< AbstractColumn * > &columns, std::string &sortby)
static SCIP_RETCODE GCGdialogSortAsc(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, bool &asc)
const char * GCGscoretypeGetDescription(SCORETYPE sctype)
returns the description of the given scoretype
Definition: scoretype.c:73
static SCIP_RETCODE GCGdialogShowLegend(SCIP *scip, std::vector< AbstractColumn * > &columns)
bool isComplete()
Gets whether this partialdec is complete, i.e. it has no more open constraints and variables.
void GCGconshdlrDecompSetScoretype(SCIP *scip, SCORETYPE sctype)
Sets the currently used scoretype.
unsigned int GCGconshdlrDecompGetNPartialdecs(SCIP *scip)
Gets the number of all partialdecs.
T getValue(SCIP *scip, int id)
void showVisualization()
generates and opens a gp visualization of the partialdec
RETTYPE getReturnType() const
static void sortPartialdecList(SCIP *scip, std::vector< int > &idlist, std::string &header, std::vector< AbstractColumn * > &columns, bool asc)
local sorting function for partialdec id vectors
virtual std::string getValueAsString(SCIP *scip, int id)=0
int GCGconshdlrDecompGetNStairlinkingVarsByPartialdecId(SCIP *scip, int id)
gets number of stairlinking variables of partialdec with given id
std::vector< PARTIALDECOMP * > * GCGconshdlrDecompGetPartialdecs(SCIP *scip)
gets vector of all partialdecs
DEC_DETECTOR ** GCGconshdlrDecompGetDetectors(SCIP *scip)
Gets an array of all detectors.
void exportVisualization()
generates a gp visualization of the partialdec without compilation or opening
int GCGconshdlrDecompGetNMasterConssByPartialdecId(SCIP *scip, int id)
gets number of master constraints of partialdec with given id
char DECdetectorGetChar(DEC_DETECTOR *detector)
Gets the character of the detector.
static SCIP_RETCODE GCGdialogChangeListMode(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, bool &listopenpartialdecs)
int GCGconshdlrDecompGetNOpenVarsByPartialdecId(SCIP *scip, int id)
gets number of open variables of partialdec with given id
Column(const char *columnHeader, const char *columnDesc, T(*columnCallback)(SCIP *, int), RETTYPE columnType)
static SCIP_RETCODE GCGdialogShowHelp(SCIP *scip)
Shows help section of explore menu.
#define DEFAULT_COLUMN_MIN_WIDTH
C++ interface of cons_decomp.
static UNKNOWN_DUMMY_TYPE UNKNOWN_DUMMY_CALLBACK(SCIP *scip, int id)
virtual int compareValues(SCIP *scip, int firstId, int secondId)=0
int compareValues(SCIP *scip, int firstId, int secondId) override
static SCIP_RETCODE GCGdialogSelectVisualize(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, std::vector< int > &idlist, SCIP_Bool open)
void setSelected(bool selected)
set the selection status of this partialdecs
SCIP_Bool GCGconshdlrDecompIsPresolvedByPartialdecId(SCIP *scip, int id)
gets whether partialdec with given id is presolved
#define DEFAULT_SORT_HEADER
static bool isHeader(std::string &header, std::vector< AbstractColumn * > &columns)
int GCGconshdlrDecompGetNBlocksByPartialdecId(SCIP *scip, int id)
gets block number of partialdec with given id
class to manage partial decompositions
PARTIALDECOMP * GCGconshdlrDecompGetPartialdecFromID(SCIP *scip, int partialdecid)
local method to find a partialdec for a given id or NULL if no partialdec with such id is found
static SCIP_RETCODE outputCharXTimes(SCIP *scip, const char letter, int x)
static SCIP_RETCODE GCGdialogInspectPartialdec(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, std::vector< int > &idlist)
int GCGconshdlrDecompGetNLinkingVarsByPartialdecId(SCIP *scip, int id)
gets number of linking variables of partialdec with given id
int GCGconshdlrDecompGetNDetectors(SCIP *scip)
Gets the number of all detectors.
SCIP_Bool GCGconshdlrDecompIsSelectedByPartialdecId(SCIP *scip, int id)
gets whether partialdec with given id is selected
class storing (potentially incomplete) decompositions
SCORETYPE GCGconshdlrDecompGetScoretype(SCIP *scip)
Gets the currently selected scoretype.
AbstractColumn(const char *columnHeader, const char *columnDesc, RETTYPE columnType)
int GCGconshdlrDecompGetNMasterVarsByPartialdecId(SCIP *scip, int id)
gets number of master variables of partialdec with given id
#define DEFAULT_MENULENGTH
bool UNKNOWN_DUMMY_TYPE
int GCGconshdlrDecompGetNOpenConssByPartialdecId(SCIP *scip, int id)
gets number of open constraints of partialdec with given id
bool isAssignedToOrigProb()
Gets whether the partialdec is from the presolved problem.
enum scoretype SCORETYPE
static SCIP_RETCODE GCGdialogExecCommand(SCIP *scip, SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, std::vector< AbstractColumn * > &columns, char *command, int &startindex, int &menulength, bool &finished, std::vector< int > &idlist, bool &sortasc, std::string &sortby, bool &listopenpartialdecs)
bool updateIdList(SCIP *scip, std::vector< int > &idlist, unsigned int &npartialdecs, bool includeopenpartialdecs)