Scippy

SCIP

Solving Constraint Integer Programs

reader_ppm.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2014 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file reader_ppm.c
17  * @brief file writer for portable pixmap file format (PPM), open with common graphic viewer programs (e.g. xview)
18  * @author Michael Winkler
19  *
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <stdlib.h>
25 #include <assert.h>
26 #include <string.h>
27 
28 #include "scip/reader_ppm.h"
29 #include "scip/cons_knapsack.h"
30 #include "scip/cons_linear.h"
31 #include "scip/cons_logicor.h"
32 #include "scip/cons_setppc.h"
33 #include "scip/cons_varbound.h"
34 #include "scip/pub_misc.h"
35 
36 #define READER_NAME "ppmreader"
37 #define READER_DESC "file writer for portable pixmap file format (PPM), open with common graphic viewer programs (e.g. xview)"
38 #define READER_EXTENSION "ppm"
39 
40 /*
41  * Data structures
42  */
43 #define PPM_MAX_LINELEN 71 /**< the maximum length of any line is 70 + '\\0' = 71*/
44 #define DEFAULT_PPM_RGB_LIMIT 160
45 #define DEFAULT_PPM_COEF_LIMIT 3
46 #define DEFAULT_PPM_RGB_RELATIVE TRUE
47 #define DEFAULT_PPM_RGB_ASCII TRUE
48 
49 /** PPM reading data */
50 struct SCIP_ReaderData
51 {
52  SCIP_Bool rgb_relativ;
53  SCIP_Bool rgb_ascii;
54  int rgb_limit;
55  int coef_limit;
56 };
57 
58 /*
59  * Local methods (for writing)
60  */
61 
62 /** initializes the reader data */
63 static
65  SCIP_READERDATA* readerdata /**< reader data */
66  )
67 {
68  assert(readerdata != NULL);
69 
70  readerdata->rgb_relativ = DEFAULT_PPM_RGB_RELATIVE;
71  readerdata->rgb_ascii = DEFAULT_PPM_RGB_ASCII;
72  readerdata->rgb_limit = DEFAULT_PPM_RGB_LIMIT;
73  readerdata->coef_limit = DEFAULT_PPM_COEF_LIMIT;
74 }
75 
76 
77 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
78 static
80  SCIP* scip, /**< SCIP data structure */
81  SCIP_VAR** vars, /**< vars array to get active variables for */
82  SCIP_Real* scalars, /**< scalars a_1, ..., a_n inrc/scip/reader_ppm.c linear sum a_1*x_1 + ... + a_n*x_n + c */
83  int* nvars, /**< pointer to number of variables and values in vars and vals array */
84  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
85  SCIP_Bool transformed /**< transformed constraint? */
86  )
87 {
88  int requiredsize;
89  int v;
90 
91  assert( scip != NULL );
92  assert( vars != NULL );
93  assert( scalars != NULL );
94  assert( nvars != NULL );
95  assert( constant != NULL );
96 
97  if( transformed )
98  {
99  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
100 
101  if( requiredsize > *nvars )
102  {
103  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
104  SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
105 
106  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
107  assert( requiredsize <= *nvars );
108  }
109  }
110  else
111  {
112  for( v = 0; v < *nvars; ++v )
113  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalars[v], constant) );
114  }
115  return SCIP_OKAY;
116 }
117 
118 /** clears the given line buffer */
119 static
121  char* linebuffer, /**< line */
122  int* linecnt /**< number of characters in line */
123  )
124 {
125  assert( linebuffer != NULL );
126  assert( linecnt != NULL );
127 
128  (*linecnt) = 0;
129  linebuffer[0] = '\0';
130 }
131 
132 /** ends the given line with '\\0' and prints it to the given file stream */
133 static
134 void endLine(
135  SCIP* scip, /**< SCIP data structure */
136  FILE* file, /**< output file (or NULL for standard output) */
137  SCIP_READERDATA* readerdata, /**< information for reader */
138  char* linebuffer, /**< line */
139  int* linecnt /**< number of characters in line */
140  )
141 {
142  assert( scip != NULL );
143  assert( linebuffer != NULL );
144  assert( linecnt != NULL );
145 
146  if( (*linecnt) > 0 )
147  {
148  linebuffer[(*linecnt)] = '\0';
149 
150  if(readerdata->rgb_ascii)
151  SCIPinfoMessage(scip, file, "%s", linebuffer);
152  else
153  SCIPinfoMessage(scip, file, "%s\n", linebuffer);
154  clearLine(linebuffer, linecnt);
155  }
156 }
157 
158 /** appends extension to line and prints it to the give file stream if the line exceeded
159  PPM_PRINTLEN */
160 static
162  SCIP* scip, /**< SCIP data structure */
163  FILE* file, /**< output file (or NULL for standard output) */
164  SCIP_READERDATA* readerdata, /**< information for reader */
165  char* linebuffer, /**< line */
166  int* linecnt, /**< number of characters in line */
167  const char* extension /**< string to extent the line */
168  )
169 {
170  assert( scip != NULL );
171  assert( linebuffer != NULL );
172  assert( linecnt != NULL );
173  assert( extension != NULL );
174 
175  if( *linecnt + strlen(extension) > PPM_MAX_LINELEN - 1 )
176  endLine(scip, file, readerdata, linebuffer, linecnt);
177 
178  /* append extension to linebuffer */
179  strncat(linebuffer, extension, PPM_MAX_LINELEN - (unsigned int)(*linecnt) - 1);
180  (*linecnt) += (int) strlen(extension);
181 }
182 
183 
184 /* calculates the color value for a given coefficient */
185 static
187  SCIP* scip, /**< SCIP data structure */
188  SCIP_READERDATA* readerdata, /**< information for reader */
189  SCIP_Real coef, /**< Coefficient to scale */
190  int* red, /**< red part */
191  int* green, /**< green part */
192  int* blue, /**< blue part */
193  SCIP_Real scale /**< maximal coefficient */
194  )
195 {
196  SCIP_Real coeflog;
197 
198  assert (scip != NULL);
199  assert (readerdata != NULL);
200 
201  coeflog = SCIPfloor(scip,log10(coef));
202 
203  if(!(readerdata->rgb_relativ))
204  {
205  (*red) = 255;
206  (*blue) = ((readerdata->rgb_limit) - (unsigned short) (coef/scale*(readerdata->rgb_limit)));
207  (*green) = *blue;
208  }
209  else
210  {
211  if( coeflog >= 0 )
212  {
213  (*red) = 255;
214  if( coeflog >= (readerdata->coef_limit) )
215  {
216  (*blue) = 0;
217  (*green) = 0;
218  }
219  else
220  {
221  (*blue) = (readerdata->rgb_limit) - (unsigned short) ((readerdata->rgb_limit)*coeflog/(readerdata->coef_limit));
222  (*green) = *blue;
223  }
224  }
225  else
226  {
227  (*blue) = 255;
228  coeflog = -1.0*coeflog;
229  if( coeflog >= (readerdata->coef_limit) )
230  {
231  (*red) = 0;
232  (*green) = 0;
233  }
234  else
235  {
236  (*red) = (readerdata->rgb_limit) - (unsigned short) ((readerdata->rgb_limit)*coeflog/(readerdata->coef_limit));
237  (*green) = *red;
238  }
239  }
240  }
241 }
242 
243 
244 /* print row in PPM format to file stream */
245 static
246 void printRow(
247  SCIP* scip, /**< SCIP data structure */
248  FILE* file, /**< output file (or NULL for standard output) */
249  SCIP_READERDATA* readerdata, /**< information for reader */
250  SCIP_VAR** vars, /**< array of constraint variables */
251  SCIP_Real* vals, /**< array of constraint values */
252  int nvars, /**< number of constraint variables */
253  int ntotalvars, /**< number of variables */
254  SCIP_Real maxcoef /**< maximal coefficient */
255  )
256 {
257  int v;
258  int i;
259  int j;
260 
261  int red;
262  int green;
263  int blue;
264 
265  char linebuffer[PPM_MAX_LINELEN];
266  int linecnt;
267  int varindex;
268  int actvarindex;
269  int maxvarindex;
270  int indexvar = 0;
271 
272  char buffer[PPM_MAX_LINELEN];
273  const unsigned char max = (unsigned char)255;
274  char white[4];
275 
276  assert( scip != NULL );
277  assert (nvars > 0);
278  assert (readerdata != NULL);
279 
280  i = 0;
281  varindex = -1;
282  maxvarindex = 0;
283 
284  (void) SCIPsnprintf(white, 4, "%c%c%c", max, max, max);
285  clearLine(linebuffer, &linecnt);
286 
287  /* calculate maximum index of the variables in this constraint */
288  for( v = 0; v < nvars; ++v )
289  {
290  if(maxvarindex < SCIPvarGetProbindex(vars[v]))
291  maxvarindex = SCIPvarGetProbindex(vars[v]);
292  }
293 
294  assert(maxvarindex < ntotalvars);
295 
296  /* print coefficients */
297  for(v = 0; v < nvars; ++v)
298  {
299  actvarindex = maxvarindex;
300  for(j = 0; j < nvars; ++j)
301  {
302  if( varindex < SCIPvarGetProbindex(vars[j]) && SCIPvarGetProbindex(vars[j]) <= actvarindex )
303  {
304  actvarindex = SCIPvarGetProbindex(vars[j]);
305  indexvar = j;
306  }
307  }
308  varindex = actvarindex;
309 
310  /* fill in white points since these variables indices do not exits in this constraint */
311  for( ; i < varindex; ++i )
312  {
313  if(readerdata->rgb_ascii)
314  appendLine(scip, file, readerdata, linebuffer, &linecnt, white);
315  else
316  appendLine(scip, file, readerdata, linebuffer, &linecnt, " 255 255 255 ");
317  }
318 
319 
320  calcColorValue(scip, readerdata, vals[indexvar], &red, &green, &blue, maxcoef);
321  if(readerdata->rgb_ascii)
322  {
323  if(red == 35 || red == 0) red++;
324  if(green==35 || green == 0) green++;
325  if(blue==35 || blue == 0) blue++;
326  (void) SCIPsnprintf(buffer, PPM_MAX_LINELEN, "%c%c%c", (unsigned char)red, (unsigned char)green, (unsigned char)blue);
327  }
328  else
329  (void) SCIPsnprintf(buffer, PPM_MAX_LINELEN, " %d %d %d ", red, green, blue);
330 
331  appendLine(scip, file, readerdata, linebuffer, &linecnt, buffer);
332  i++;
333  }
334 
335  /* fill in white points since these variables indices do not exits in this constraint */
336  for( ; i < ntotalvars; ++i )
337  {
338  if(readerdata->rgb_ascii)
339  appendLine(scip, file, readerdata, linebuffer, &linecnt, white);
340  else
341  appendLine(scip, file, readerdata, linebuffer, &linecnt, " 255 255 255 ");
342  }
343 
344  endLine(scip, file, readerdata, linebuffer, &linecnt);
345 }
346 
347 
348 /** prints given linear constraint information in PPM format to file stream */
349 static
351  SCIP* scip, /**< SCIP data structure */
352  FILE* file, /**< output file (or NULL for standard output) */
353  SCIP_READERDATA* readerdata, /**< information for reader */
354  SCIP_VAR** vars, /**< array of variables */
355  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
356  int nvars, /**< number of variables */
357  int ncompletevars, /**< number of variables in whole problem */
358  SCIP_Bool transformed, /**< transformed constraint? */
359  SCIP_Real* maxcoef, /**< maximal coefficient */
360  SCIP_Bool printbool /**< print row or calculate maximum coefficient */
361  )
362 {
363  int v;
364  SCIP_VAR** activevars;
365  SCIP_Real* activevals;
366  int nactivevars;
367  SCIP_Real activeconstant = 0.0;
368 
369  assert( scip != NULL );
370  assert( vars != NULL );
371  assert( nvars > 0 );
372  assert( readerdata != NULL );
373 
374  /* duplicate variable and value array */
375  nactivevars = nvars;
376  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
377  if( vals != NULL )
378  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
379  else
380  {
381  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
382 
383  for( v = 0; v < nactivevars; ++v )
384  activevals[v] = 1.0;
385  }
386 
387  /* retransform given variables to active variables */
388  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
389 
390  if(!readerdata->rgb_relativ)
391  {
392  if(!printbool)
393  for(v = 0; v < nactivevars; ++v)
394  {
395  if( REALABS(activevals[v]) > *maxcoef)
396  *maxcoef = REALABS(activevals[v]);
397  }
398  else
399  {
400  assert (*maxcoef > 0);
401  /* print constraint */
402  printRow(scip, file, readerdata, activevars, activevals, nactivevars, ncompletevars, *maxcoef);
403  }
404  }
405  else
406  {
407  /* print constraint */
408  printRow(scip, file, readerdata, activevars, activevals, nactivevars, ncompletevars, *maxcoef);
409  }
410 
411  /* free buffer arrays */
412  SCIPfreeBufferArray(scip, &activevars);
413  SCIPfreeBufferArray(scip, &activevals);
414 
415  return SCIP_OKAY;
416 }
417 
418 
419 /*
420  * Callback methods of reader
421  */
422 
423 /** copy method for reader plugins (called when SCIP copies plugins) */
424 static
425 SCIP_DECL_READERCOPY(readerCopyPpm)
426 { /*lint --e{715}*/
427  assert(scip != NULL);
428  assert(reader != NULL);
429  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
430 
431  /* call inclusion method of reader */
433 
434  return SCIP_OKAY;
435 }
436 
437 /** destructor of reader to free user data (called when SCIP is exiting) */
438 static
439 SCIP_DECL_READERFREE(readerFreePpm)
440 {
441  SCIP_READERDATA* readerdata;
442 
443  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
444  readerdata = SCIPreaderGetData(reader);
445  assert(readerdata != NULL);
446  SCIPfreeMemory(scip, &readerdata);
447 
448  return SCIP_OKAY;
449 }
450 
451 
452 /** problem writing method of reader */
453 static
454 SCIP_DECL_READERWRITE(readerWritePpm)
455 { /*lint --e{715}*/
456 
457  SCIP_READERDATA* readerdata;
458 
459  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
460  readerdata = SCIPreaderGetData(reader);
461  assert(readerdata != NULL);
462 
463  SCIP_CALL( SCIPwritePpm(scip, file, name, readerdata, transformed, vars, nvars, conss, nconss, result) );
464 
465  return SCIP_OKAY;
466 }
467 
468 /*
469  * reader specific interface methods
470  */
471 
472 /** includes the ppm file reader in SCIP */
474  SCIP* scip /**< SCIP data structure */
475  )
476 {
477  SCIP_READERDATA* readerdata;
478  SCIP_READER* reader;
479 
480  /* create ppm reader data */
481  SCIP_CALL( SCIPallocMemory(scip, &readerdata) );
482  initReaderdata(readerdata);
483 
484  /* include reader */
486 
487  assert(reader != NULL);
488 
489  /* set non fundamental callbacks via setter functions */
490  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyPpm) );
491  SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreePpm) );
492  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWritePpm) );
493 
494  /* add ppm reader parameters */
496  "reading/ppmreader/rgbrelativ", "should the coloring values be relativ or absolute",
497  &readerdata->rgb_relativ, FALSE, DEFAULT_PPM_RGB_RELATIVE, NULL, NULL) );
499  "reading/ppmreader/rgbascii", "should the output format be binary(P6) (otherwise plain(P3) format)",
500  &readerdata->rgb_ascii, FALSE, DEFAULT_PPM_RGB_ASCII, NULL, NULL) );
502  "reading/ppmreader/coefficientlimit",
503  "splitting coefficients in this number of intervals",
504  &readerdata->coef_limit, FALSE, DEFAULT_PPM_COEF_LIMIT, 3, 16, NULL, NULL) );
506  "reading/ppmreader/rgblimit",
507  "maximal color value",
508  &readerdata->rgb_limit, FALSE, DEFAULT_PPM_RGB_LIMIT, 0, 255, NULL, NULL) );
509 
510  return SCIP_OKAY;
511 }
512 
513 
514 /** writes problem to file */
516  SCIP* scip, /**< SCIP data structure */
517  FILE* file, /**< output file, or NULL if standard output should be used */
518  const char* name, /**< problem name */
519  SCIP_READERDATA* readerdata, /**< information for reader */
520  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
521  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
522  int nvars, /**< number of active variables in the problem */
523  SCIP_CONS** conss, /**< array with constraints of the problem */
524  int nconss, /**< number of constraints in the problem */
525  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
526  )
527 { /*lint --e{715}*/
528  int c;
529  int v;
530  int i;
531 
532  int linecnt;
533  char linebuffer[PPM_MAX_LINELEN];
534 
535  SCIP_CONSHDLR* conshdlr;
536  const char* conshdlrname;
537  SCIP_CONS* cons;
538 
539  SCIP_VAR** consvars;
540  SCIP_Real* consvals;
541  int nconsvars;
542  int i_max = 1;
543  SCIP_Real maxcoef = 0;
544  SCIP_Bool printbool = FALSE;
545 
546  assert( scip != NULL );
547  assert(readerdata != NULL);
548 
549  /* print statistics as comment to file */
550  if(readerdata->rgb_ascii)
551  SCIPinfoMessage(scip, file, "P6\n");
552  else
553  SCIPinfoMessage(scip, file, "P3\n");
554  SCIPinfoMessage(scip, file, "# %s\n", name);
555  SCIPinfoMessage(scip, file, "%d %d\n", nvars, nconss);
556  SCIPinfoMessage(scip, file, "255\n");
557 
558  clearLine(linebuffer, &linecnt);
559 
560  if(!(readerdata->rgb_relativ))
561  {
562  i_max = 2;
563  }
564 
565  for(i = 0; i < i_max; ++i)
566  {
567  if(i)
568  {
569  printbool = TRUE;
570  SCIPdebugPrintf("Maximal coefficient = %g\n", maxcoef);
571  }
572 
573 
574  for(c = 0; c < nconss; ++c)
575  {
576  cons = conss[c];
577  assert( cons != NULL);
578 
579  /* in case the transformed is written only constraint are posted which are enabled in the current node */
580  assert(!transformed || SCIPconsIsEnabled(cons));
581 
582  conshdlr = SCIPconsGetHdlr(cons);
583  assert( conshdlr != NULL );
584 
585  conshdlrname = SCIPconshdlrGetName(conshdlr);
586  assert( transformed == SCIPconsIsTransformed(cons) );
587 
588  if( strcmp(conshdlrname, "linear") == 0 )
589  {
590  consvars = SCIPgetVarsLinear(scip, cons);
591  nconsvars = SCIPgetNVarsLinear(scip, cons);
592  assert( consvars != NULL || nconsvars == 0 );
593 
594  if( nconsvars > 0 )
595  {
596  SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, SCIPgetValsLinear(scip, cons),
597  nconsvars, nvars, transformed, &maxcoef, printbool) );
598  }
599  }
600  else if( strcmp(conshdlrname, "setppc") == 0 )
601  {
602  consvars = SCIPgetVarsSetppc(scip, cons);
603  nconsvars = SCIPgetNVarsSetppc(scip, cons);
604  assert( consvars != NULL || nconsvars == 0 );
605 
606  if( nconsvars > 0 )
607  {
608  SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, NULL,
609  nconsvars, nvars, transformed, &maxcoef, printbool) );
610  }
611  }
612  else if( strcmp(conshdlrname, "logicor") == 0 )
613  {
614  consvars = SCIPgetVarsLogicor(scip, cons);
615  nconsvars = SCIPgetNVarsLogicor(scip, cons);
616  assert( consvars != NULL || nconsvars == 0 );
617 
618  if( nconsvars > 0 )
619  {
620  SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, NULL,
621  nconsvars, nvars, transformed, &maxcoef, printbool) );
622  }
623  }
624  else if( strcmp(conshdlrname, "knapsack") == 0 )
625  {
626  SCIP_Longint* weights;
627 
628  consvars = SCIPgetVarsKnapsack(scip, cons);
629  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
630  assert( consvars != NULL || nconsvars == 0 );
631 
632  /* copy Longint array to SCIP_Real array */
633  weights = SCIPgetWeightsKnapsack(scip, cons);
634  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
635  for( v = 0; v < nconsvars; ++v )
636  consvals[v] = (SCIP_Real)weights[v];
637 
638  if( nconsvars > 0 )
639  {
640  SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, consvals, nconsvars, nvars, transformed, &maxcoef, printbool) );
641  }
642 
643  SCIPfreeBufferArray(scip, &consvals);
644  }
645  else if( strcmp(conshdlrname, "varbound") == 0 )
646  {
647  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
648  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
649 
650  consvars[0] = SCIPgetVarVarbound(scip, cons);
651  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
652 
653  consvals[0] = 1.0;
654  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
655 
656  SCIP_CALL( printLinearCons(scip, file, readerdata, consvars, consvals, 2, nvars, transformed, &maxcoef, printbool) );
657 
658  SCIPfreeBufferArray(scip, &consvars);
659  SCIPfreeBufferArray(scip, &consvals);
660  }
661  else
662  {
663  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
664  SCIPinfoMessage(scip, file, "\\ ");
665  SCIP_CALL( SCIPprintCons(scip, cons, file) );
666  SCIPinfoMessage(scip, file, ";\n");
667  }
668  }
669  }
670 
671  *result = SCIP_SUCCESS;
672 
673  return SCIP_OKAY;
674 }
675