reader_ref.c
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 <stdlib.h>
38 #include <assert.h>
39 #include <string.h>
40 #if defined(_WIN32) || defined(_WIN64)
41 #else
42 #include <strings.h> /*lint --e{766}*/ /* needed for strcasecmp() */
43 #endif
44 #include <ctype.h>
45 
46 #include "reader_ref.h"
47 #include "gcg.h"
48 #include "scip/cons_linear.h"
49 #include "cons_decomp.h"
50 
51 #define READER_NAME "refreader"
52 #define READER_DESC "file reader for blocks corresponding to a mip in lpb format"
53 #define READER_EXTENSION "ref"
54 
55 /*
56  * Data structures
57  */
58 #define REF_MAX_LINELEN 65536
59 #define REF_MAX_PUSHEDTOKENS 2
60 
63 {
65 };
66 typedef enum RefSection REFSECTION;
67 
69 {
71 };
72 typedef enum RefExpType REFEXPTYPE;
73 
74 
76 struct RefInput
77 {
78  SCIP_FILE* file;
80  char* token;
81  char* tokenbuf;
84  int linenumber;
85  int linepos;
86  int nblocks;
87  int blocknr;
89  int* blocksizes;
90  int totalconss;
92  SCIP_CONS** masterconss;
95  SCIP_Bool haserror;
96  SCIP_HASHMAP* vartoblock;
97  SCIP_HASHMAP* constoblock;
98 };
99 typedef struct RefInput REFINPUT;
100 
101 static const char delimchars[] = " \f\n\r\t\v";
102 static const char tokenchars[] = "-+:<>=";
103 static const char commentchars[] = "\\";
104 
105 
106 /*
107  * Local methods (for reading)
108  */
109 
111 static
113  SCIP* scip,
114  REFINPUT* refinput,
115  const char* msg
116  )
117 {
118  char formatstr[256];
119 
120  assert(refinput != NULL);
121 
122  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error in line %d: %s ('%s')\n",
123  refinput->linenumber, msg, refinput->token);
124  if( refinput->linebuf[strlen(refinput->linebuf)-1] == '\n' )
125  {
126  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", refinput->linebuf);
127  }
128  else
129  {
130  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", refinput->linebuf);
131  }
132  (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", refinput->linepos);
133  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, formatstr, "^");
134  refinput->section = REF_END;
135  refinput->haserror = TRUE;
136 }
137 
139 static
140 SCIP_Bool hasError(
141  REFINPUT* refinput
142  )
143 {
144  assert(refinput != NULL);
145 
146  return refinput->haserror;
147 }
148 
150 static
151 SCIP_Bool isDelimChar(
152  char c
153  )
154 {
155  return (c == '\0') || (strchr(delimchars, c) != NULL);
156 }
157 
159 static
160 SCIP_Bool isTokenChar(
161  char c
162  )
163 {
164  return (strchr(tokenchars, c) != NULL);
165 }
166 
168 static
169 SCIP_Bool isValueChar(
170  char c,
171  char nextc,
172  SCIP_Bool firstchar,
173  SCIP_Bool* hasdot,
174  REFEXPTYPE* exptype
175  )
176 {
177  assert(hasdot != NULL);
178  assert(exptype != NULL);
179 
180  if( isdigit(c) )
181  return TRUE;
182  else if( (*exptype == REF_EXP_NONE) && !(*hasdot) && (c == '.') )
183  {
184  *hasdot = TRUE;
185  return TRUE;
186  }
187  else if( !firstchar && (*exptype == REF_EXP_NONE) && (c == 'e' || c == 'E') )
188  {
189  if( nextc == '+' || nextc == '-' )
190  {
191  *exptype = REF_EXP_SIGNED;
192  return TRUE;
193  }
194  else if( isdigit(nextc) )
195  {
196  *exptype = REF_EXP_UNSIGNED;
197  return TRUE;
198  }
199  }
200  else if( (*exptype == REF_EXP_SIGNED) && (c == '+' || c == '-') )
201  {
202  *exptype = REF_EXP_UNSIGNED;
203  return TRUE;
204  }
205 
206  return FALSE;
207 }
208 
212 static
213 SCIP_Bool getNextLine(
214  REFINPUT* refinput
215  )
216 {
217  int i;
218 
219  assert(refinput != NULL);
220 
221  /* clear the line */
222  BMSclearMemoryArray(refinput->linebuf, REF_MAX_LINELEN);
223 
224  /* read next line */
225  refinput->linepos = 0;
226  refinput->linebuf[REF_MAX_LINELEN-2] = '\0';
227  if( SCIPfgets(refinput->linebuf, REF_MAX_LINELEN, refinput->file) == NULL )
228  return FALSE;
229  refinput->linenumber++;
230  if( refinput->linebuf[REF_MAX_LINELEN-2] != '\0' )
231  {
232  SCIPerrorMessage("Error: line %d exceeds %d characters\n", refinput->linenumber, REF_MAX_LINELEN-2);
233  refinput->haserror = TRUE;
234  return FALSE;
235  }
236  refinput->linebuf[REF_MAX_LINELEN-1] = '\0';
237  refinput->linebuf[REF_MAX_LINELEN-2] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
238 
239  /* skip characters after comment symbol */
240  for( i = 0; commentchars[i] != '\0'; ++i )
241  {
242  char* commentstart;
243 
244  commentstart = strchr(refinput->linebuf, commentchars[i]);
245  if( commentstart != NULL )
246  {
247  *commentstart = '\0';
248  *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
249  }
250  }
251 
252  return TRUE;
253 }
254 
256 static
257 SCIP_Bool getNextToken(
258  REFINPUT* refinput
259  )
260 {
261  SCIP_Bool hasdot;
262  REFEXPTYPE exptype;
263  char* buf;
264  int tokenlen;
265 
266  assert(refinput != NULL);
267  assert(refinput->linepos < REF_MAX_LINELEN);
268 
269  /* check the token stack */
270  if( refinput->npushedtokens > 0 )
271  {
272  SCIPswapPointers((void**)&refinput->token, (void**)&refinput->pushedtokens[refinput->npushedtokens-1]);
273  refinput->npushedtokens--;
274  SCIPdebugMessage("(line %d) read token again: '%s'\n", refinput->linenumber, refinput->token);
275  return TRUE;
276  }
277 
278  /* skip delimiters */
279  buf = refinput->linebuf;
280  while( isDelimChar(buf[refinput->linepos]) )
281  {
282  if( buf[refinput->linepos] == '\0' )
283  {
284  if( !getNextLine(refinput) )
285  {
286  refinput->section = REF_END;
287  refinput->blocknr++;
288  SCIPdebugMessage("(line %d) end of file\n", refinput->linenumber);
289  return FALSE;
290  }
291  else
292  {
293  if( refinput->section == REF_START )
294  refinput->section = REF_NBLOCKS;
295  else if( refinput->section == REF_BLOCKSIZES )
296  {
297  refinput->section = REF_BLOCKS;
298  refinput->blocknr = 0;
299  }
300  return FALSE;
301  }
302  }
303  else
304  refinput->linepos++;
305  }
306  assert(refinput->linepos < REF_MAX_LINELEN);
307  assert(!isDelimChar(buf[refinput->linepos]));
308 
309  /* check if the token is a value */
310  hasdot = FALSE;
311  exptype = REF_EXP_NONE;
312  if( isValueChar(buf[refinput->linepos], buf[refinput->linepos+1], TRUE, &hasdot, &exptype) ) /*lint !e679*/
313  {
314  /* read value token */
315  tokenlen = 0;
316  do
317  {
318  assert(tokenlen < REF_MAX_LINELEN);
319  assert(!isDelimChar(buf[refinput->linepos]));
320  refinput->token[tokenlen] = buf[refinput->linepos];
321  ++tokenlen;
322  ++(refinput->linepos);
323  assert(refinput->linepos < REF_MAX_LINELEN);
324  }
325  while( isValueChar(buf[refinput->linepos], buf[refinput->linepos+1], FALSE, &hasdot, &exptype) ); /*lint !e679*/
326  }
327  else
328  {
329  /* read non-value token */
330  tokenlen = 0;
331  do
332  {
333  assert(tokenlen < REF_MAX_LINELEN);
334  refinput->token[tokenlen] = buf[refinput->linepos];
335  tokenlen++;
336  refinput->linepos++;
337  if( tokenlen == 1 && isTokenChar(refinput->token[0]) )
338  break;
339  }
340  while( !isDelimChar(buf[refinput->linepos]) && !isTokenChar(buf[refinput->linepos]) );
341 
342  /* if the token is an equation sense '<', '>', or '=', skip a following '='
343  * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
344  */
345  if( tokenlen >= 1
346  && (refinput->token[tokenlen-1] == '<' || refinput->token[tokenlen-1] == '>' || refinput->token[tokenlen-1] == '=')
347  && buf[refinput->linepos] == '=' )
348  {
349  refinput->linepos++;
350  }
351  else if( refinput->token[tokenlen-1] == '=' && (buf[refinput->linepos] == '<' || buf[refinput->linepos] == '>') )
352  {
353  refinput->token[tokenlen-1] = buf[refinput->linepos];
354  refinput->linepos++;
355  }
356  }
357  assert(tokenlen < REF_MAX_LINELEN);
358  refinput->token[tokenlen] = '\0';
359 
360  return TRUE;
361 }
362 
364 static
365 SCIP_Bool isInt(
366  SCIP* scip,
367  REFINPUT* refinput,
368  int* value
369  )
370 {
371  long val;
372  char* endptr;
373 
374  assert(refinput != NULL);
375  assert(value != NULL);
376  assert(!(strcasecmp(refinput->token, "INFINITY") == 0) && !(strcasecmp(refinput->token, "INF") == 0));
377 
378  val = strtol(refinput->token, &endptr, 0);
379  if( endptr != refinput->token && *endptr == '\0' )
380  {
381  if( val < INT_MIN || val > INT_MAX ) /*lint !e685*/
382  return FALSE;
383 
384  *value = (int) val;
385  return TRUE;
386  }
387 
388 
389  return FALSE;
390 }
391 
393 static
394 SCIP_RETCODE readStart(
395  SCIP* scip,
396  REFINPUT* refinput
397  )
398 {
399  assert(refinput != NULL);
400 
401  (void) getNextToken(refinput);
402 
403  return SCIP_OKAY;
404 }
405 
407 static
408 SCIP_RETCODE readNBlocks(
409  SCIP* scip,
410  REFINPUT* refinput
411  )
412 {
413  int nblocks;
414 
415  assert(refinput != NULL);
416 
417  if( getNextToken(refinput) )
418  {
419  /* read number of blocks */
420  if( isInt(scip, refinput, &nblocks) )
421  {
422  if( refinput->nblocks == -1 )
423  {
424  refinput->nblocks = nblocks;
425  SCIP_CALL( SCIPallocBufferArray(scip, &refinput->blocksizes, nblocks) );
426  }
427  SCIPdebugMessage("Number of blocks = %d\n", refinput->nblocks);
428  }
429  else
430  syntaxError(scip, refinput, "NBlocks: Value not an integer.\n");
431  }
432  else
433  syntaxError(scip, refinput, "Could not read number of blocks.\n");
434 
435  refinput->section = REF_BLOCKSIZES;
436 
437  return SCIP_OKAY;
438 }
439 
441 static
442 SCIP_RETCODE readBlockSizes(
443  SCIP* scip,
444  REFINPUT* refinput
445  )
446 {
447  int blocknr;
448  int blocksize;
449 
450  assert(refinput != NULL);
451 
452  for( blocknr = 0; getNextToken(refinput) && blocknr < refinput->nblocks; blocknr++ )
453  {
454  if( isInt(scip, refinput, &blocksize) )
455  {
456  refinput->blocksizes[blocknr] = blocksize;
457  refinput->totalconss += blocksize;
458  }
459  else
460  syntaxError(scip, refinput, "Blocksize: Value not integer.\n");
461  }
462  if( blocknr != refinput->nblocks )
463  syntaxError(scip, refinput, "Could not get sizes for all blocks.\n");
464 
465  return SCIP_OKAY;
466 }
467 
469 static
470 SCIP_RETCODE readBlocks(
471  SCIP* scip,
472  REFINPUT* refinput
473  )
474 {
475  int consctr;
476 
477  assert(refinput != NULL);
478 
479  consctr = 0;
480 
481  while( refinput->blocknr < refinput->nblocks )
482  {
483  SCIPdebugMessage("Reading constraints of block %d/%d\n", refinput->blocknr + 1, refinput->nblocks);
484  while( getNextToken(refinput) )
485  {
486  SCIP_VAR** vars;
487  int consnr;
488  SCIP_CONS** conss = SCIPgetConss(scip);
489 
490  if( isInt(scip, refinput, &consnr) )
491  {
492  SCIP_CONSHDLR* conshdlr;
493  int nvars;
494  int v;
495  SCIP_CONS* cons;
496 
497  SCIPdebugMessage(" -> constraint %d\n", consnr);
498 
499  cons = conss[consnr];
500  conshdlr = SCIPconsGetHdlr(cons);
501 
502  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") == 0 )
503  {
504  vars = SCIPgetVarsLinear(scip, cons);
505  nvars = SCIPgetNVarsLinear(scip, cons);
506  }
507  else
508  {
509  SCIPdebugMessage(" constraint of unknown type.\n");
510  continue;
511  }
512 
513  SCIP_CALL( SCIPhashmapSetImage(refinput->constoblock, cons, (void*) (size_t) (refinput->blocknr+1) ) );
514 
515  for( v = 0; v < nvars; v++ )
516  {
517  SCIP_VAR* var = vars[v];
518 
519  SCIPdebugMessage(" -> variable %s\n", SCIPvarGetName(var));
520 
521  /* set the block number of the variable to the number of the current block */
522  if( SCIPhashmapExists(refinput->vartoblock, var) )
523  {
524  int block;
525  block = (int)(size_t) SCIPhashmapGetImage(refinput->vartoblock, var); /*lint !e507*/
526  if( block != refinput->blocknr+1 && block != refinput->nblocks+1 )
527  {
528  SCIP_CALL( SCIPhashmapRemove(refinput->vartoblock, var) );
529  SCIP_CALL( SCIPhashmapSetImage(refinput->vartoblock, var, (void*) (size_t) (refinput->nblocks+1)) );
530  }
531  }
532  else
533  {
534  SCIP_CALL( SCIPhashmapSetImage(refinput->vartoblock, var, (void*) (size_t) (refinput->blocknr+1)) );
535  }
536  refinput->nassignedvars++;
537  }
538  consctr++;
539  refinput->totalreadconss++;
540  }
541  else
542  syntaxError(scip, refinput, "ConsNr: Value not an integer.\n");
543  }
544 
545  if( consctr == refinput->blocksizes[refinput->blocknr] )
546  {
547  refinput->blocknr++;
548  consctr = 0;
549  }
550  }
551 
552  return SCIP_OKAY;
553 }
554 
555 
557 static
558 SCIP_RETCODE readREFFile(
559  SCIP* scip,
560  SCIP_READER* reader,
561  REFINPUT* refinput,
562  DEC_DECOMP* decomp,
563  const char* filename
564  )
565 {
566 
567  assert(scip != NULL);
568  assert(reader != NULL);
569  assert(refinput != NULL);
570  assert(filename != NULL);
571 
572  if( SCIPgetStage(scip) < SCIP_STAGE_TRANSFORMED )
573  SCIP_CALL( SCIPtransformProb(scip) );
574 
575  /* open file */
576  refinput->file = SCIPfopen(filename, "r");
577  if( refinput->file == NULL )
578  {
579  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
580  SCIPprintSysError(filename);
581  return SCIP_NOFILE;
582  }
583 
584  if( SCIPgetStage(scip) >= SCIP_STAGE_PRESOLVED )
585  {
586  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Reader 'ref' can only read in unpresolved structures.\n Please re-read the problem and read the decomposition again.\n");
587  return SCIP_OKAY;
588  }
589 
590  /* parse the file */
591  refinput->section = REF_START;
592  while( refinput->section != REF_END && !hasError(refinput) )
593  {
594  switch( refinput->section )
595  {
596  case REF_START:
597  SCIP_CALL( readStart(scip, refinput) );
598  break;
599 
600  case REF_NBLOCKS:
601  SCIP_CALL( readNBlocks(scip, refinput) );
602  DECdecompSetNBlocks(decomp, refinput->nblocks);
603  break;
604 
605  case REF_BLOCKSIZES:
606  SCIP_CALL( readBlockSizes(scip, refinput) );
607  break;
608 
609  case REF_BLOCKS:
610  SCIP_CALL( readBlocks(scip, refinput) );
611  break;
612 
613  case REF_END: /* this is already handled in the while() loop */
614  default:
615  SCIPerrorMessage("invalid REF file section <%d>\n", refinput->section);
616  return SCIP_INVALIDDATA;
617  }
618  }
619 
620  /* close file */
621  SCIPfclose(refinput->file);
622 
623  /* copy information to decomp */
624  SCIP_CALL_QUIET( DECfilloutDecompFromHashmaps(scip, decomp, refinput->vartoblock, refinput->constoblock, refinput->nblocks, FALSE) );
625 
626  DECdecompSetPresolved(decomp, FALSE);
627  DECdecompSetDetector(decomp, NULL);
628 
629  return SCIP_OKAY;
630 }
631 
633 static
634 SCIP_RETCODE writeREFFile(
635  SCIP* scip,
636  SCIP_READER* reader,
637  FILE* file
639  )
640 {
641  SCIP_HASHMAP *cons2origindex;
642  DEC_DECOMP* decomp;
643 
644  SCIP_CONS** conss;
645  int nconss;
646  SCIP_CONS*** subscipconss;
647  int* nsubscipconss;
648  int i;
649  int j;
650  int nblocks;
651  assert(scip != NULL);
652  assert(reader != NULL);
653  assert(file != NULL);
654 
655  decomp = DECgetBestDecomp(scip);
656 
657  if( decomp == NULL )
658  {
659  decomp = GCGgetStructDecdecomp(scip);
660  }
661 
662  if( decomp == NULL )
663  {
664  SCIPwarningMessage(scip, "No reformulation exists, cannot write reformulation file!\n");
665  return SCIP_OKAY;
666  }
667  nblocks = DECdecompGetNBlocks(decomp);
668  conss = SCIPgetOrigConss(scip);
669  nconss = SCIPgetNOrigConss(scip);
670 
671  SCIP_CALL( SCIPhashmapCreate(&cons2origindex, SCIPblkmem(scip), 2*nconss) );
672  for( i = 0; i < nconss; ++i )
673  {
674  int ind;
675  SCIP_CONS* cons;
676 
677  ind = i+1;
678 
679  assert(ind > 0);
680  assert(ind <= nconss);
681  cons = SCIPfindCons(scip, SCIPconsGetName(conss[i]));
682 
683  SCIPdebugMessage("cons added: %d\t%p\t%s\n", ind, (void*)cons, SCIPconsGetName(cons));
684  SCIP_CALL( SCIPhashmapInsert(cons2origindex, cons, (void*)(size_t)(ind)) ); /* shift by 1 to enable error checking */
685  }
686 
687  subscipconss = DECdecompGetSubscipconss(decomp);
688  nsubscipconss = DECdecompGetNSubscipconss(decomp);
689  SCIPinfoMessage(scip, file, "%d ", nblocks);
690 
691  assert(nsubscipconss != NULL);
692  assert(subscipconss != NULL);
693 
694  for( i = 0; i < nblocks; ++i )
695  {
696  SCIPinfoMessage(scip, file, "%d ", nsubscipconss[i]);
697  }
698  SCIPinfoMessage(scip, file, "\n", nblocks);
699 
700  for( i = 0; i < nblocks; ++i )
701  {
702  for( j = 0; j < nsubscipconss[i]; ++j )
703  {
704  int ind;
705  SCIP_CONS* cons;
706 
707  cons = SCIPfindCons(scip, SCIPconsGetName(subscipconss[i][j]));
708  ind = (int)(size_t) SCIPhashmapGetImage(cons2origindex, cons); /*lint !e507*/
709  SCIPdebugMessage("cons retrieve (o): %d\t%p\t%s\n", ind, (void*)cons, SCIPconsGetName(cons));
710 
711  assert(ind > 0); /* shift by 1 */
712  assert(ind <= nconss); /* shift by 1 */
713  SCIPinfoMessage(scip, file, "%d ", ind-1);
714  }
715  SCIPinfoMessage(scip, file, "\n", nblocks);
716  }
717  SCIPhashmapFree(&cons2origindex);
718 
719  DECdecompFree(scip, &decomp);
720 
721  return SCIP_OKAY;
722 }
723 
724 
725 /*
726  * Callback methods of reader
727  */
728 
730 #define readerFreeRef NULL
731 
733 static
734 SCIP_DECL_READERREAD(readerReadRef)
735 {
736  if( SCIPgetStage(scip) == SCIP_STAGE_INIT || SCIPgetNVars(scip) == 0 || SCIPgetNConss(scip) == 0 )
737  {
738  SCIPverbMessage(scip, SCIP_VERBLEVEL_DIALOG, NULL, "No problem exists, will not detect structure!\n");
739  return SCIP_OKAY;
740  }
741 
742  SCIP_CALL( SCIPreadRef(scip, reader, filename, result) );
743 
744  return SCIP_OKAY;
745 }
746 
747 
749 static
750 SCIP_DECL_READERWRITE(readerWriteRef)
751 {
752  /*lint --e{715}*/
753  SCIP_CALL( writeREFFile(scip, reader, file) );
754  *result = SCIP_SUCCESS;
755  return SCIP_OKAY;
756 }
757 
758 /*
759  * reader specific interface methods
760  */
761 
763 SCIP_RETCODE SCIPincludeReaderRef(
764  SCIP* scip
765  )
766 {
767  assert(scip != NULL);
768  /* include lp reader */
769  SCIP_CALL( SCIPincludeReader(scip, READER_NAME, READER_DESC, READER_EXTENSION,
770  NULL, readerFreeRef, readerReadRef, readerWriteRef, NULL) );
771 
772  return SCIP_OKAY;
773 }
774 
775 
777 SCIP_RETCODE SCIPreadRef(
778  SCIP* scip,
779  SCIP_READER* reader,
780  const char* filename,
781  SCIP_RESULT* result
782  )
783 {
784  SCIP_RETCODE retcode;
785  REFINPUT refinput;
786  DEC_DECOMP* decomp;
787  int i;
788 #ifdef SCIP_DEBUG
789  SCIP_VAR** vars;
790  int nvars;
791 #endif
792 
793  /* initialize REF input data */
794  refinput.file = NULL;
795  refinput.linebuf[0] = '\0';
796  SCIP_CALL( SCIPallocMemoryArray(scip, &refinput.token, REF_MAX_LINELEN) ); /*lint !e506*/
797  refinput.token[0] = '\0';
798  SCIP_CALL( SCIPallocMemoryArray(scip, &refinput.tokenbuf, REF_MAX_LINELEN) ); /*lint !e506*/
799  refinput.tokenbuf[0] = '\0';
800  for( i = 0; i < REF_MAX_PUSHEDTOKENS; ++i )
801  {
802  SCIP_CALL( SCIPallocMemoryArray(scip, &refinput.pushedtokens[i], REF_MAX_LINELEN) ); /*lint !e506 !e866*/
803  }
804  SCIP_CALL( SCIPallocBufferArray(scip, &refinput.masterconss, 1) );
805 
806  refinput.npushedtokens = 0;
807  refinput.linenumber = 0;
808  refinput.linepos = 0;
809  refinput.nblocks = -1;
810  refinput.blocknr = -2;
811  refinput.totalconss = 0;
812  refinput.totalreadconss = 0;
813  refinput.nassignedvars = 0;
814  refinput.nmasterconss = 0;
815  refinput.haserror = FALSE;
816 
817  SCIP_CALL( SCIPhashmapCreate(&refinput.vartoblock, SCIPblkmem(scip), SCIPgetNVars(scip)) );
818  SCIP_CALL( SCIPhashmapCreate(&refinput.constoblock, SCIPblkmem(scip), SCIPgetNConss(scip)) );
819 
820  /* read the file */
821  SCIP_CALL( DECdecompCreate(scip, &decomp) );
822 
823  retcode = readREFFile(scip, reader, &refinput, decomp, filename);
824 
825  if( retcode == SCIP_OKAY )
826  {
827  SCIP_CALL( SCIPconshdlrDecompAddDecdecomp(scip, decomp) );
828  SCIPdebugMessage("Read %d/%d conss in ref-file\n", refinput.totalreadconss, refinput.totalconss);
829  SCIPdebugMessage("Assigned %d variables to %d blocks.\n", refinput.nassignedvars, refinput.nblocks);
830 #ifdef SCIP_DEBUG
831  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
832 
833  for( i = 0; i < nvars; i++ )
834  {
835  if( GCGvarGetBlock(vars[i]) == -1 )
836  {
837  SCIPdebugMessage(" -> not assigned: variable %s\n", SCIPvarGetName(vars[i]));
838  }
839  }
840 #endif
841  }
842  else
843  {
844  SCIP_CALL( DECdecompFree(scip, &decomp) );
845  }
846 
847 
848  /* free dynamically allocated memory */
849  SCIPfreeMemoryArray(scip, &refinput.token);
850  SCIPfreeMemoryArray(scip, &refinput.tokenbuf);
851  for( i = 0; i < REF_MAX_PUSHEDTOKENS; ++i )
852  {
853  SCIPfreeMemoryArray(scip, &refinput.pushedtokens[i]);
854  }
855  SCIPfreeBufferArray(scip, &refinput.masterconss);
856  SCIPfreeBufferArray(scip, &refinput.blocksizes);
857 
858  /* evaluate the result */
859  if( refinput.haserror )
860  return SCIP_READERROR;
861  else if( retcode == SCIP_OKAY )
862  {
863  *result = SCIP_SUCCESS;
864  }
865 
866  return retcode;
867 }
#define READER_NAME
Definition: reader_ref.c:51
#define READER_EXTENSION
Definition: reader_ref.c:53
SCIP_CONS *** DECdecompGetSubscipconss(DEC_DECOMP *decomp)
Definition: decomp.c:903
SCIP_FILE * file
Definition: reader_ref.c:78
static SCIP_RETCODE readStart(SCIP *scip, REFINPUT *refinput)
Definition: reader_ref.c:394
#define readerFreeRef
Definition: reader_ref.c:730
static const char tokenchars[]
Definition: reader_ref.c:102
DEC_DECOMP * DECgetBestDecomp(SCIP *scip)
int linepos
Definition: reader_ref.c:85
static SCIP_Bool isDelimChar(char c)
Definition: reader_ref.c:151
DEC_DECOMP * GCGgetStructDecdecomp(SCIP *scip)
Definition: relax_gcg.c:4831
GCG interface methods.
SCIP_RETCODE SCIPconshdlrDecompAddDecdecomp(SCIP *scip, DEC_DECOMP *decdecomp)
sets (and adds) the decomposition structure
static SCIP_RETCODE readREFFile(SCIP *scip, SCIP_READER *reader, REFINPUT *refinput, DEC_DECOMP *decomp, const char *filename)
Definition: reader_ref.c:558
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, REFEXPTYPE *exptype)
Definition: reader_ref.c:169
static SCIP_RETCODE readBlockSizes(SCIP *scip, REFINPUT *refinput)
Definition: reader_ref.c:442
int totalconss
Definition: reader_ref.c:90
static SCIP_DECL_READERWRITE(readerWriteRef)
Definition: reader_ref.c:750
SCIP_RETCODE DECdecompFree(SCIP *scip, DEC_DECOMP **decdecomp)
Definition: decomp.c:525
char * tokenbuf
Definition: reader_ref.c:81
enum RefExpType REFEXPTYPE
Definition: reader_ref.c:72
void DECdecompSetNBlocks(DEC_DECOMP *decomp, int nblocks)
Definition: decomp.c:728
RefSection
Definition: reader_ref.c:62
static SCIP_RETCODE readNBlocks(SCIP *scip, REFINPUT *refinput)
Definition: reader_ref.c:408
int npushedtokens
Definition: reader_ref.c:83
int totalreadconss
Definition: reader_ref.c:91
static SCIP_Bool getNextLine(REFINPUT *refinput)
Definition: reader_ref.c:213
int nmasterconss
Definition: reader_ref.c:93
static SCIP_RETCODE readBlocks(SCIP *scip, REFINPUT *refinput)
Definition: reader_ref.c:470
int DECdecompGetNBlocks(DEC_DECOMP *decomp)
Definition: decomp.c:740
#define REF_MAX_LINELEN
Definition: reader_ref.c:58
char linebuf[REF_MAX_LINELEN]
Definition: reader_ref.c:79
static void syntaxError(SCIP *scip, REFINPUT *refinput, const char *msg)
Definition: reader_ref.c:112
SCIP_HASHMAP * vartoblock
Definition: reader_ref.c:96
static SCIP_Bool getNextToken(REFINPUT *refinput)
Definition: reader_ref.c:257
void DECdecompSetDetector(DEC_DECOMP *decomp, DEC_DETECTOR *detector)
Definition: decomp.c:1578
static SCIP_Bool hasError(REFINPUT *refinput)
Definition: reader_ref.c:140
SCIP_CONS ** masterconss
Definition: reader_ref.c:92
SCIP_RETCODE DECdecompCreate(SCIP *scip, DEC_DECOMP **decdecomp)
Definition: decomp.c:467
int * DECdecompGetNSubscipconss(DEC_DECOMP *decomp)
Definition: decomp.c:912
SCIP_RETCODE SCIPincludeReaderRef(SCIP *scip)
Definition: reader_ref.c:763
int GCGvarGetBlock(SCIP_VAR *var)
Definition: gcgvar.c:936
int blocknr
Definition: reader_ref.c:87
enum RefSection REFSECTION
Definition: reader_ref.c:66
int nassignedvars
Definition: reader_ref.c:88
static SCIP_RETCODE writeREFFile(SCIP *scip, SCIP_READER *reader, FILE *file)
Definition: reader_ref.c:634
static SCIP_DECL_READERREAD(readerReadRef)
Definition: reader_ref.c:734
char * token
Definition: reader_ref.c:80
int linenumber
Definition: reader_ref.c:84
REF file reader for structure information.
static const char delimchars[]
Definition: reader_ref.c:101
char * pushedtokens[REF_MAX_PUSHEDTOKENS]
Definition: reader_ref.c:82
void DECdecompSetPresolved(DEC_DECOMP *decomp, SCIP_Bool presolved)
Definition: decomp.c:707
static SCIP_Bool isTokenChar(char c)
Definition: reader_ref.c:160
#define READER_DESC
Definition: reader_ref.c:52
static SCIP_Bool isInt(SCIP *scip, REFINPUT *refinput, int *value)
Definition: reader_ref.c:365
constraint handler for structure detection
SCIP_RETCODE DECfilloutDecompFromHashmaps(SCIP *scip, DEC_DECOMP *decomp, SCIP_HASHMAP *vartoblock, SCIP_HASHMAP *constoblock, int nblocks, SCIP_Bool staircase)
Definition: decomp.c:1268
SCIP_Bool haserror
Definition: reader_ref.c:95
REFSECTION section
Definition: reader_ref.c:94
struct DecDecomp DEC_DECOMP
Definition: type_decomp.h:43
SCIP_HASHMAP * constoblock
Definition: reader_ref.c:97
static const char commentchars[]
Definition: reader_ref.c:103
int * blocksizes
Definition: reader_ref.c:89
int nblocks
Definition: reader_ref.c:86
RefExpType
Definition: reader_ref.c:68
#define REF_MAX_PUSHEDTOKENS
Definition: reader_ref.c:59
SCIP_RETCODE SCIPreadRef(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_ref.c:777