reader_gp.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-2018 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 
35 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
36 
37 #include <assert.h>
38 #include <string.h>
39 
40 #include <cstring>
41 #include <fstream>
42 
43 #include "scip/scip.h"
44 
45 #include "reader_gp.h"
46 #include "scip_misc.h"
47 #include "struct_decomp.h"
48 #include "cons_decomp.h"
49 #include "pub_decomp.h"
50 #include "params_visu.h"
51 #include "wrapper_seeed.h"
52 
53 #include "class_seeed.h"
54 #include "class_seeedpool.h"
56 
57 #define READER_NAME "gpreader"
58 #define READER_DESC "gnuplot file writer for seeed visualization"
59 #define READER_EXTENSION "gp"
60 
61 
62 using namespace gcg;
63 
64 /*
65  * Callback methods of reader
66  */
67 
68 
70 static
71 SCIP_DECL_READERFREE(readerFreeGp)
72 {
73  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
74  return SCIP_OKAY;
75 }
76 
77 
79 static
80 SCIP_DECL_READERWRITE(readerWriteGp)
81 {
83  SEEED_WRAPPER seeedwr;
84  SeeedPtr seeed;
85  char* filename;
86  char outputname[SCIP_MAXSTRLEN];
87 
88  assert(scip != NULL);
89  assert(file != NULL);
90 
91  /* get seeed to write */
93 
94  if(seeedwr.seeed == NULL)
95  {
96  SCIPerrorMessage("Could not find best Seeed!\n");
97  *result = SCIP_DIDNOTRUN;
98  }
99  else
100  {
101  SCIP_Bool plotmiplib;
102  seeed = seeedwr.seeed;
103 
104  /* reader internally works with the filename instead of the C FILE type */
105  filename = misc->GCGgetFilePath(scip, file);
106 
107  SCIPgetBoolParam(scip, "write/miplib2017plotsanddecs", &plotmiplib );
108 
109  if( !plotmiplib )
110  {
111  /* get filename for compiled file */
112  misc->GCGgetVisualizationFilename(scip, seeed, "pdf", outputname);
113  strcat(outputname, ".pdf");
114 
115  GCGwriteGpVisualization(scip, filename, outputname, seeed->getID() );
116  }
117  else
118  {
119  char problemname[SCIP_MAXSTRLEN];
120  char* outname2;
121  (void) SCIPsnprintf(problemname, SCIP_MAXSTRLEN, "%s", GCGgetFilename(scip));
122  SCIPsplitFilename(problemname, NULL, &outname2, NULL, NULL);
123 
124  strcat(outname2, ".png");
125  GCGwriteGpVisualization(scip, filename, outname2, seeed->getID() );
126  }
127 
128  *result = SCIP_SUCCESS;
129  }
130 
131  delete misc;
132 
133  return SCIP_OKAY;
134 }
135 
136 
138 static
139 SCIP_RETCODE writeGpHeader(
140  SCIP* scip,
141  char* filename,
142  const char* outputname
143  )
144 {
145  std::ofstream ofs;
146  SCIP_Bool plotformiplib;
147 
148  SCIPgetBoolParam(scip, "write/miplib2017plotsanddecs", &plotformiplib);
149  ofs.open( filename, std::ofstream::out );
150 
151 
152 
153  /* set output format and file */
154  ofs << "set encoding utf8" << std::endl;
155  if( !plotformiplib )
156  ofs << "set terminal pdf" << std::endl;
157  else
158  ofs << "set terminal pngcairo" << std::endl;
159 
160  ofs << "set output \"" << outputname << "\"" << std::endl;
161 
162  ofs.close();
163 
164  return SCIP_OKAY;
165 }
166 
167 
168 /* writes gp code to given file that contains a box with given coordinates and color */
169 static
170 SCIP_RETCODE drawGpBox(
171  char* filename,
172  int objectid,
173  int x1,
174  int y1,
175  int x2,
176  int y2,
177  char* color
178  )
179 {
180  std::ofstream ofs;
181  ofs.open( filename, std::ofstream::out | std::ofstream::app );
182 
183  ofs << "set object " << objectid << " rect from " << x1 << "," << y1 << " to " << x2 << "," << y2
184  << " fc rgb \"" << color << "\"" << " lc rgb \"" << SCIPvisuGetColorLine() << "\"" << std::endl;
185 
186  ofs.close();
187  return SCIP_OKAY;
188 }
189 
190 
192 static
193 SCIP_RETCODE writeGpNonzeros(
194  const char* filename,
195  Seeed* seeed,
196  Seeedpool* seeedpool,
197  float radius
198  )
199 {
200  int radiusscale;
201  SCIP_Bool plotmiplib;
202  std::vector<int> orderToRows(seeed->getNConss(), -1);
203  std::vector<int> rowToOrder(seeed->getNConss(), -1);
204  std::vector<int> orderToCols(seeed->getNVars(), -1);
205  std::vector<int> colsToOrder(seeed->getNVars(), -1);
206  int counterrows = 0;
207  int countercols = 0;
208  std::ofstream ofs;
209 
211  /* master constraints */
212  for( int i = 0; i < seeed->getNMasterconss() ; ++i )
213  {
214  int rowidx = seeed->getMasterconss()[i];
215  orderToRows[counterrows] = rowidx;
216  rowToOrder[rowidx] = counterrows;
217  ++counterrows;
218  }
219 
220  /* block constraints */
221  for( int b = 0; b < seeed->getNBlocks(); ++b )
222  {
223  for(int i = 0; i < seeed->getNConssForBlock(b); ++i )
224  {
225  int rowidx = seeed->getConssForBlock(b)[i];
226  orderToRows[counterrows] = rowidx;
227  rowToOrder[rowidx] = counterrows;
228  ++counterrows;
229  }
230  }
231 
233  for( int i = 0; i < seeed->getNOpenconss(); ++i )
234  {
235  int rowidx = seeed->getOpenconss()[i];
236  orderToRows[counterrows] = rowidx;
237  rowToOrder[rowidx] = counterrows;
238  ++counterrows;
239  }
240 
243  /* linking variables */
244  for( int i = 0; i < seeed->getNLinkingvars() ; ++i )
245  {
246  int colidx = seeed->getLinkingvars()[i];
247  orderToCols[countercols] = colidx;
248  colsToOrder[colidx] = countercols;
249  ++countercols;
250  }
251 
252  /* master variables */
253  for( int i = 0; i < seeed->getNMastervars() ; ++i )
254  {
255  int colidx = seeed->getMastervars()[i];
256  orderToCols[countercols] = colidx;
257  colsToOrder[colidx] = countercols;
258  ++countercols;
259  }
260 
261  /* block variables */
262  for( int b = 0; b < seeed->getNBlocks(); ++b )
263  {
264  for(int i = 0; i < seeed->getNVarsForBlock(b); ++i )
265  {
266  int colidx = seeed->getVarsForBlock(b)[i];
267  orderToCols[countercols] = colidx;
268  colsToOrder[colidx] = countercols;
269  ++countercols;
270  }
271  for(int i = 0; i < seeed->getNStairlinkingvars(b); ++i )
272  {
273  int colidx = seeed->getStairlinkingvars(b)[i];
274  orderToCols[countercols] = colidx;
275  colsToOrder[colidx] = countercols;
276  ++countercols;
277  }
278  }
279 
280  /* open vars */
281  for( int i = 0; i < seeed->getNOpenvars() ; ++i )
282  {
283  int colidx = seeed->getOpenvars()[i];
284  orderToCols[countercols] = colidx;
285  colsToOrder[colidx] = countercols;
286  ++countercols;
287  }
288 
289  ofs.open (filename, std::ofstream::out | std::ofstream::app );
290 
291  SCIPgetIntParam(seeedpool->getScip(), "visual/nonzeroradius", &radiusscale);
292  SCIPgetBoolParam(seeedpool->getScip(), "write/miplib2017plotsanddecs", &plotmiplib);
293 
294  radius *= radiusscale;
295 
296  if ( radius < 0.01 )
297  radius = 0.01;
298 
299  /* start writing dots */
300  ofs << "set style line 99 lc rgb \"" << SCIPvisuGetColorNonzero() << "\" " << std::endl;
301  ofs << "plot \"-\" using 1:2:(" << radius << ") with dots ls 99 notitle " << std::endl;
302  /* write scatter plot */
303  for( int row = 0; row < seeed->getNConss(); ++row )
304  {
305  for ( int col = 0; col < seeed->getNVars(); ++col )
306  {
307  assert( orderToRows[row] != -1 );
308  assert( orderToCols[col] != -1 );
309  if( seeedpool->getVal( orderToRows[row], orderToCols[col] ) != 0 )
310  ofs << col + 0.5 << " " << row + 0.5 << std::endl;
311  }
312  }
313 
314  /* end writing dots */
315  ofs << "e" << std::endl;
316 
317  ofs.close();
318 
319  return SCIP_OKAY;
320 }
321 
322 
323 static
324 SCIP_RETCODE writeGpSeeed(
325  char* filename,
326  Seeed* seeed,
327  Seeedpool* seeedpool
328  )
329 {
330  int rowboxcounter = 0;
331  int colboxcounter = 0;
332  int objcounter = 0;
333  int nvars;
334  int nconss;
335  SCIP_Bool writematrix;
336  SCIP_Bool noticsbutlabels;
337 
338  nvars = seeed->getNVars();
339  nconss = seeed->getNConss();
340 
341  std::ofstream ofs;
342  ofs.open( filename, std::ofstream::out | std::ofstream::app );
343 
344  writematrix = FALSE;
345  noticsbutlabels = FALSE;
346 
347  if ( seeed->getNBlocks() == 1 && seeed->isComplete() && seeed->getNMasterconss() == 0 && seeed->getNLinkingvars() == 0 && seeed->getNMastervars() == 0 )
348  writematrix = TRUE;
349 
350  SCIPgetBoolParam(seeedpool->getScip(), "write/miplib2017plotsanddecs", &noticsbutlabels);
351 
352  /* set coordinate range */
353  if( !writematrix && !noticsbutlabels )
354  {
355  ofs << "set xrange [-1:" << nvars << "]" << std::endl;
356  ofs << "set yrange[" << nconss << ":-1]" << std::endl;
357  }
358  else
359  {
360  ofs << "set xrange [0:" << nvars << "]" << std::endl;
361  ofs << "set yrange[" << nconss << ":0]" << std::endl;
362 
363  ofs << " set xtics nomirror " << std::endl;
364  ofs << " set ytics nomirror" << std::endl;
365  ofs << " set xtics out " << std::endl;
366  ofs << " set ytics out" << std::endl;
367  }
368 
369 
370 
371  /* --- draw boxes ---*/
372 
373  if( !writematrix )
374  {
375  /* linking vars */
376  if(seeed->getNLinkingvars() != 0)
377  {
378  ++objcounter; /* has to start at 1 for gnuplot */
379  drawGpBox( filename, objcounter, 0, 0, seeed->getNLinkingvars(), seeed->getNConss(),
381  colboxcounter += seeed->getNLinkingvars();
382  }
383 
384  /* masterconss */
385  if(seeed->getNMasterconss() != 0)
386  {
387  ++objcounter;
388  drawGpBox( filename, objcounter, 0, 0, seeed->getNVars(), seeed->getNMasterconss(),
390  rowboxcounter += seeed->getNMasterconss();
391  }
392 
393  /* mastervars */
394  if(seeed->getNMastervars() != 0)
395  {
396  ++objcounter;
397  // drawGpBox( filename, objcounter, colboxcounter, 0, seeed->getNMastervars()+colboxcounter,
398  // seeed->getNMasterconss(), SCIPvisuGetColorMastervars() );
399  colboxcounter += seeed->getNMastervars();
400  }
401 
402  /* blocks (blocks are not empty) */
403  for( int b = 0; b < seeed->getNBlocks() ; ++b )
404  {
405  ++objcounter;
406  drawGpBox(filename, objcounter, colboxcounter, rowboxcounter,
407  colboxcounter + seeed->getNVarsForBlock(b), rowboxcounter + seeed->getNConssForBlock(b), SCIPvisuGetColorBlock());
408  colboxcounter += seeed->getNVarsForBlock(b);
409 
410  if( seeed->getNStairlinkingvars(b) != 0 )
411  {
412  ++objcounter;
413  drawGpBox( filename, objcounter, colboxcounter, rowboxcounter,
414  colboxcounter + seeed->getNStairlinkingvars(b),
415  rowboxcounter + seeed->getNConssForBlock(b) + seeed->getNConssForBlock(b+1), SCIPvisuGetColorStairlinking() );
416  }
417  colboxcounter += seeed->getNStairlinkingvars(b);
418  rowboxcounter += seeed->getNConssForBlock(b);
419  }
420 
421  /* open */
422  if(seeed->getNOpenvars() != 0)
423  {
424  ++objcounter;
425  drawGpBox( filename, objcounter, colboxcounter, rowboxcounter, colboxcounter + seeed->getNOpenvars(),
426  rowboxcounter+seeed->getNOpenconss(), SCIPvisuGetColorOpen() );
427  colboxcounter += seeed->getNOpenvars();
428  rowboxcounter += seeed->getNOpenconss();
429  }
430  }
431  /* --- draw nonzeros --- */
432  if( SCIPvisuGetDraftmode() == FALSE )
433  {
434  /* scale nonzero radius with 2% of maximal index */
435  int radiusscale;
436  if(seeed->getNVars() > seeed->getNConss())
437  radiusscale = seeed->getNVars() / 200;
438  else
439  radiusscale = seeed->getNConss() / 200;
440 
441  radiusscale = 0.6;
442  writeGpNonzeros( filename, seeed, seeedpool, SCIPvisuGetNonzeroRadius(seeed->getNVars(), seeed->getNConss(), radiusscale) );
443  }
444  else
445  {
446  ofs << "plot \"-\" using 1:2:(0) notitle with circles fill solid lw 2 fc rgb \"black\" "
447  << std::endl << "0 0" << std::endl << "e" << std::endl;
448  }
449 
450  ofs.close();
451 
452  return SCIP_OKAY;
453 }
454 
455 
458  SCIP* scip,
459  char* filename,
460  char* outputname,
461  int seeedid
462  )
463 {
464  MiscVisualization* misc = new MiscVisualization();
465  SEEED_WRAPPER seeedwr;
466  Seeedpool* seeedpool;
467  SeeedPtr seeed;
468 
469 
470  /* get seeed and seeedpool */
471  GCGgetSeeedFromID(scip, &seeedid, &seeedwr);
472  seeed = seeedwr.seeed;
473  seeedpool = misc->GCGgetSeeedpoolForSeeed(scip, seeedid);
474 
475  if( seeed == NULL )
476  {
477  SCIPerrorMessage("Could not find Seeed!\n");
478  return SCIP_ERROR;
479  }
480  if( seeedpool == NULL )
481  {
482  SCIPerrorMessage("Could not find Seeedpool!\n");
483  return SCIP_ERROR;
484  }
485 
486  /* write file */
487  writeGpHeader(scip, filename, outputname );
488  writeGpSeeed( filename, seeed, seeedpool );
489 
490  return SCIP_OKAY;
491 }
492 
493 
494 /*
495  * reader include
496  */
498 SCIP_RETCODE SCIPincludeReaderGp(
499  SCIP* scip
500  )
501 {
502  /* include gp reader */
503  SCIP_CALL( SCIPincludeReader(scip, READER_NAME, READER_DESC, READER_EXTENSION,
504  NULL, readerFreeGp, NULL, readerWriteGp, NULL) );
505 
506  return SCIP_OKAY;
507 }
508 
gcg::Seeed * seeed
Definition: wrapper_seeed.h:45
static SCIP_DECL_READERFREE(readerFreeGp)
Definition: reader_gp.cpp:71
static SCIP_RETCODE writeGpSeeed(char *filename, Seeed *seeed, Seeedpool *seeedpool)
Definition: reader_gp.cpp:324
const int * getOpenconss()
returns array containing constraints not assigned yet
char * SCIPvisuGetColorNonzero()
Definition: params_visu.c:401
char * SCIPvisuGetColorLinking()
Definition: params_visu.c:337
static SCIP_DECL_READERWRITE(readerWriteGp)
Definition: reader_gp.cpp:80
int getNConssForBlock(int block)
returns size of the vector containing conss assigned to a block
miscellaneous methods for visualizations
int getNLinkingvars()
returns size of the vector containing linking vars
const int * getMasterconss()
static SCIP_RETCODE drawGpBox(char *filename, int objectid, int x1, int y1, int x2, int y2, char *color)
Definition: reader_gp.cpp:170
char * SCIPvisuGetColorLine()
Definition: params_visu.c:417
int getNVars()
returns number of vars
int getNConss()
returns the number of constraints
Seeedpool * GCGgetSeeedpoolForSeeed(SCIP *scip, int seeedid)
int getNOpenvars()
returns size of vector containing variables not assigned yet
SCIP_RETCODE GCGgetVisualizationFilename(SCIP *scip, SeeedPtr seeed, const char *extension, char *filename)
#define READER_DESC
Definition: reader_gp.cpp:58
const int * getLinkingvars()
returns array containing all linking vars indices
const int * getVarsForBlock(int block)
returns array containing vars of a block
GP file reader writing gnuplot files.
various SCIP helper methods
class to manage partial decompositions (aka seeed), each seeed corresponds to one seeedpool which con...
Definition: class_seeed.h:71
char * GCGgetFilePath(SCIP *scip, FILE *file)
int getID()
returns the unique id of the seeed
char * SCIPvisuGetColorOpen()
Definition: params_visu.c:385
#define READER_NAME
Definition: reader_gp.cpp:57
char * SCIPvisuGetColorStairlinking()
Definition: params_visu.c:353
SCIP_Bool SCIPvisuGetDraftmode()
Definition: params_visu.c:272
float SCIPvisuGetNonzeroRadius(int maxindx, int maxindy, float scalingfactor)
Definition: params_visu.c:506
bool isComplete()
returns true if this seeed is complete, i.e. it has no more open constraints and variables ...
int getNBlocks()
returns the number of blocks
char * SCIPvisuGetColorBlock()
Definition: params_visu.c:369
const int * getConssForBlock(int block)
returns array containing constraints assigned to a block
Provides wrapping to have Seeeds and Seeedpools as parameters in C-conform function headers with C++ ...
SCIP_RETCODE SCIPincludeReaderGp(SCIP *scip)
Definition: reader_gp.cpp:498
static SCIP_RETCODE writeGpNonzeros(const char *filename, Seeed *seeed, Seeedpool *seeedpool, float radius)
Definition: reader_gp.cpp:193
const int * getOpenvars()
returns array containing variables not assigned yet
SCIP_RETCODE DECgetSeeedToWrite(SCIP *scip, SCIP_Bool transformed, SEEED_WRAPPER *seeedwrapper)
int getNStairlinkingvars(int block)
returns size of the vector containing stairlinking vars
int getNMasterconss()
returns size of the vector containing master conss
SCIP * getScip()
returns the corresponding scip data structure
int getNVarsForBlock(int block)
returns size of the vector containing vars assigned to a block
SCIP_Real getVal(int row, int col)
returns a coefficient from the coefficient matrix
int getNOpenconss()
returns size of vector containing constraints not assigned yet
SCIP_RETCODE GCGwriteGpVisualization(SCIP *scip, char *filename, char *outputname, int seeedid)
Definition: reader_gp.cpp:457
class with functions for seeed pool where a seeed is a (potentially incomplete) description of a deco...
const int * getMastervars()
const int * getStairlinkingvars(int block)
returns array containing stairlinking vars,
static SCIP_RETCODE writeGpHeader(SCIP *scip, char *filename, const char *outputname)
Definition: reader_gp.cpp:139
SCIP_RETCODE GCGgetSeeedFromID(SCIP *scip, int *seeedid, SEEED_WRAPPER *seeedwr)
const char * GCGgetFilename(SCIP *scip)
Definition: relax_gcg.c:4850
constraint handler for structure detection
int getNMastervars()
returns size of the vector containing master vars (hitting only constraints in the master) ...
public methods for working with decomposition structures
char * SCIPvisuGetColorMasterconss()
Definition: params_visu.c:305
#define READER_EXTENSION
Definition: reader_gp.cpp:59