Scippy

GCG

Branch-and-Price & Column Generation for Everyone

reader_dec.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 reader_dec.cpp
29  * @brief DEC file reader for structure information
30  * @author Lukas Kirchhart
31  * @author Martin Bergner
32  * @author Gerald Gamrath
33  * @author Christian Puchert
34  * @author Michael Bastubbe
35  */
36 
37 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
38 
39 /* #define SCIP_DEBUG */
40 
41 #include <assert.h>
42 #include <string.h>
43 #if defined(_WIN32) || defined(_WIN64)
44 #else
45 #include <strings.h> /*lint --e{766}*/ /* needed for strcasecmp() */
46 #endif
47 #include <ctype.h>
48 
49 #include "reader_dec.h"
50 #include "scip_misc.h"
51 #include "pub_gcgvar.h"
52 
53 #include "cons_decomp.h"
54 #include "cons_decomp.hpp"
55 #include "pub_decomp.h"
56 
57 #include "class_partialdecomp.h"
58 #include "class_detprobdata.h"
59 
60 #define READER_NAME "decreader"
61 #define READER_DESC "file reader for blocks in dec format"
62 #define READER_EXTENSION "dec"
63 
64 
65 /*
66  * Data structures
67  */
68 #define DEC_MAX_LINELEN 65536
69 #define DEC_MAX_PUSHEDTOKENS 2
70 
71 /** section in DEC File */
73 {
75 };
76 typedef enum DecSection DECSECTION;
77 
78 /** exponent indicator of the a value */
80 {
82 };
83 typedef enum DecExpType DECEXPTYPE;
84 
85 /** DEC reading data */
86 struct DecInput
87 {
88  SCIP_FILE* file; /**< file to read */
89  char linebuf[DEC_MAX_LINELEN]; /**< line buffer */
90  char* token; /**< current token */
91  char* tokenbuf; /**< token buffer */
92  char* pushedtokens[DEC_MAX_PUSHEDTOKENS]; /**< token stack */
93  int npushedtokens; /**< size of token buffer */
94  int linenumber; /**< current line number */
95  int linepos; /**< current line position (column) */
96  SCIP_Bool presolved; /**< does the decomposition refer to the presolved problem? */
97  SCIP_Bool haspresolvesection; /**< does the decomposition have a presolved section */
98  SCIP_Bool incomplete; /**< if false the unspecified constraints should be forced to the master (for downward compatibility) */
99  int nblocks; /**< number of blocks */
100  int blocknr; /**< number of the currentblock between 0 and Nblocks-1*/
101  DECSECTION section; /**< current section */
102  SCIP_Bool haserror; /**< flag to indicate an error occurence */
103  gcg::PARTIALDECOMP* partialdec; /**< incomplete decomposition */
104 };
105 typedef struct DecInput DECINPUT;
106 
107 /** data for dec reader */
108 struct SCIP_ReaderData
109 {
110 
111 };
112 static const int NOVALUE = -1;
113 static const int LINKINGVALUE = -2;
114 static const char delimchars[] = " \f\n\r\t\v";
115 static const char tokenchars[] = "-+:<>=";
116 static const char commentchars[] = "\\";
117 
118 /*
119  * Local methods (for reading)
120  */
121 
122 /** issues an error message and marks the DEC data to have errors */
123 static
125  SCIP* scip, /**< SCIP data structure */
126  DECINPUT* decinput, /**< DEC reading data */
127  const char* msg /**< error message */
128  )
129 {
130  char formatstr[256];
131 
132  assert(decinput != NULL);
133 
134  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error in line %d: %s ('%s')\n",
135  decinput->linenumber, msg, decinput->token);
136  if( decinput->linebuf[strlen(decinput->linebuf) - 1] == '\n' )
137  {
138  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s", decinput->linebuf);
139  }
140  else
141  {
142  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, " input: %s\n", decinput->linebuf);
143  }
144  (void) SCIPsnprintf(formatstr, 256, " %%%ds\n", decinput->linepos);
145  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, formatstr, "^");
146  decinput->section = DEC_END;
147  decinput->haserror = TRUE;
148 }
149 
150 /** returns whether a syntax error was detected */
151 static
152 SCIP_Bool hasError(
153  DECINPUT* decinput /**< DEC reading data */
154  )
155 {
156  assert(decinput != NULL);
157  return decinput->haserror;
158 }
159 
160 /** returns whether the given character is a token delimiter */
161 static
162 SCIP_Bool isDelimChar(
163  char c /**< input character */
164  )
165 {
166  return (c == '\0') || (strchr(delimchars, c) != NULL);
167 }
168 
169 /** returns whether the given character is a single token */
170 static
171 SCIP_Bool isTokenChar(
172  char c /**< input character */
173  )
174 {
175  return (strchr(tokenchars, c) != NULL);
176 }
177 
178 /** returns whether the current character is member of a value string */
179 static
180 SCIP_Bool isValueChar(
181  char c, /**< input character */
182  char nextc, /**< next input character */
183  SCIP_Bool firstchar, /**< is the given character the first char of the token? */
184  SCIP_Bool* hasdot, /**< pointer to update the dot flag */
185  DECEXPTYPE* exptype /**< pointer to update the exponent type */
186  )
187 { /*lint --e{715}*/
188  assert(hasdot != NULL);
189  assert(exptype != NULL);
190 
191  if( isdigit(c) )
192  return TRUE;
193 
194  return FALSE;
195 }
196 
197 /** reads the next line from the input file into the line buffer; skips comments;
198  * returns whether a line could be read
199  */
200 static
201 SCIP_Bool getNextLine(
202  DECINPUT* decinput /**< DEC reading data */
203  )
204 {
205  int i;
206 
207  assert(decinput != NULL);
208 
209  /* clear the line */
210  BMSclearMemoryArray(decinput->linebuf, DEC_MAX_LINELEN);
211 
212  /* read next line */
213  decinput->linepos = 0;
214  decinput->linebuf[DEC_MAX_LINELEN - 2] = '\0';
215  if( SCIPfgets(decinput->linebuf, DEC_MAX_LINELEN, decinput->file) == NULL )
216  return FALSE;
217  decinput->linenumber ++;
218  if( decinput->linebuf[DEC_MAX_LINELEN - 2] != '\0' )
219  {
220  SCIPerrorMessage("Error: line %d exceeds %d characters\n", decinput->linenumber, DEC_MAX_LINELEN - 2);
221  decinput->haserror = TRUE;
222  return FALSE;
223  }
224  decinput->linebuf[DEC_MAX_LINELEN - 1] = '\0';
225  decinput->linebuf[DEC_MAX_LINELEN - 2] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
226 
227  /* skip characters after comment symbol */
228  for( i = 0; commentchars[i] != '\0'; ++ i )
229  {
230  char* commentstart;
231 
232  commentstart = strchr(decinput->linebuf, commentchars[i]);
233  if( commentstart != NULL )
234  {
235  *commentstart = '\0';
236  *(commentstart + 1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
237  }
238  }
239 
240  return TRUE;
241 }
242 
243 /** swaps the addresses of two pointers */
244 static
246  char** pointer1, /**< first pointer */
247  char** pointer2 /**< second pointer */
248  )
249 {
250  char* tmp;
251 
252  tmp = * pointer1;
253  *pointer1 = * pointer2;
254  *pointer2 = tmp;
255 }
256 
257 /** reads the next token from the input file into the token buffer; returns whether a token was read */
258 static
259 SCIP_Bool getNextToken(
260  DECINPUT* decinput /**< DEC reading data */
261  )
262 {
263  SCIP_Bool hasdot;
264  DECEXPTYPE exptype;
265  char* buf;
266  int tokenlen;
267 
268  assert(decinput != NULL);
269  assert(decinput->linepos < DEC_MAX_LINELEN);
270 
271  /* check the token stack */
272  if( decinput->npushedtokens > 0 )
273  {
274  swapPointers(&decinput->token, &decinput->pushedtokens[decinput->npushedtokens - 1]);
275  decinput->npushedtokens --;
276  SCIPdebugMessage("(line %d) read token again: '%s'\n", decinput->linenumber, decinput->token);
277  return TRUE;
278  }
279 
280  /* skip delimiters */
281  buf = decinput->linebuf;
282  while( isDelimChar(buf[decinput->linepos]) )
283  {
284  if( buf[decinput->linepos] == '\0' )
285  {
286  if( !getNextLine(decinput) )
287  {
288  decinput->section = DEC_END;
289  SCIPdebugMessage("(line %d) end of file\n", decinput->linenumber);
290  return FALSE;
291  }
292  assert(decinput->linepos == 0);
293  }
294  else
295  decinput->linepos ++;
296  }
297  assert(decinput->linepos < DEC_MAX_LINELEN);
298  assert(! isDelimChar(buf[decinput->linepos]));
299 
300  /* check if the token is a value */
301  hasdot = FALSE;
302  exptype = DEC_EXP_NONE;
303  if( isValueChar(buf[decinput->linepos], buf[decinput->linepos + 1], TRUE, &hasdot, &exptype) ) /*lint !e679*/
304  {
305  /* read value token */
306  tokenlen = 0;
307  do
308  {
309  assert(tokenlen < DEC_MAX_LINELEN);
310  assert(! isDelimChar(buf[decinput->linepos]));
311  decinput->token[tokenlen] = buf[decinput->linepos];
312  ++tokenlen;
313  ++(decinput->linepos);
314  assert(decinput->linepos < DEC_MAX_LINELEN-1);
315  }
316  while( isValueChar(buf[decinput->linepos], buf[decinput->linepos + 1], FALSE, &hasdot, &exptype) ); /*lint !e679*/
317  }
318  else
319  {
320  /* read non-value token */
321  tokenlen = 0;
322  do
323  {
324  assert(tokenlen < DEC_MAX_LINELEN);
325  decinput->token[tokenlen] = buf[decinput->linepos];
326  tokenlen ++;
327  decinput->linepos ++;
328  if( tokenlen == 1 && isTokenChar(decinput->token[0]) )
329  break;
330  }
331  while( !isDelimChar(buf[decinput->linepos]) && ! isTokenChar(buf[decinput->linepos]) );
332 
333  /* if the token is an equation sense '<', '>', or '=', skip a following '='
334  * if the token is an equality token '=' and the next character is a '<' or '>', replace the token by the inequality sense
335  */
336  if( tokenlen >= 1
337  && (decinput->token[tokenlen - 1] == '<' || decinput->token[tokenlen - 1] == '>' || decinput->token[tokenlen - 1] == '=')
338  && buf[decinput->linepos] == '=' )
339  {
340  decinput->linepos ++;
341  }
342  else if( decinput->token[tokenlen - 1] == '=' && (buf[decinput->linepos] == '<' || buf[decinput->linepos] == '>') )
343  {
344  decinput->token[tokenlen - 1] = buf[decinput->linepos];
345  decinput->linepos ++;
346  }
347  }
348  assert(tokenlen < DEC_MAX_LINELEN);
349  decinput->token[tokenlen] = '\0';
350 
351  SCIPdebugMessage("(line %d) read token: '%s'\n", decinput->linenumber, decinput->token);
352 
353  return TRUE;
354 }
355 
356 /** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
357 static
359  DECINPUT* decinput /**< DEC reading data */
360  )
361 {
362  assert(decinput != NULL);
363  assert(decinput->npushedtokens < DEC_MAX_PUSHEDTOKENS);
364 
365  swapPointers(&decinput->pushedtokens[decinput->npushedtokens], &decinput->token);
366  decinput->npushedtokens ++;
367 }
368 
369 /** swaps the current token with the token buffer */
370 static
372  DECINPUT* decinput /**< DEC reading data */
373  )
374 {
375  assert(decinput != NULL);
376 
377  swapPointers(&decinput->token, &decinput->tokenbuf);
378 }
379 
380 /** returns whether the current token is a value */
381 static
382 SCIP_Bool isInt(
383  SCIP* scip, /**< SCIP data structure */
384  DECINPUT* decinput, /**< DEC reading data */
385  int* value /**< pointer to store the value (unchanged, if token is no value) */
386  )
387 {
388  long val;
389  char* endptr;
390 
391  assert(decinput != NULL);
392  assert(value != NULL);
393  assert(!(strcasecmp(decinput->token, "INFINITY") == 0) && !(strcasecmp(decinput->token, "INF") == 0));
394 
395  val = strtol(decinput->token, &endptr, 0);
396  if( endptr != decinput->token && * endptr == '\0' )
397  {
398  if( val < INT_MIN || val > INT_MAX ) /*lint !e685*/
399  return FALSE;
400 
401  *value = (int) val;
402  return TRUE;
403  }
404 
405  return FALSE;
406 }
407 
408 /** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
409 static
410 SCIP_Bool isNewSection(
411  SCIP* scip, /**< SCIP data structure */
412  DECINPUT* decinput /**< DEC reading data */
413  )
414 {
415 
416  assert(decinput != NULL);
417 
418  /* remember first token by swapping the token buffer */
419  swapTokenBuffer(decinput);
420 
421  /* look at next token: if this is a ':', the first token is a name and no section keyword */
422  if( getNextToken(decinput) )
423  {
424  pushToken(decinput);
425  }
426 
427  /* reinstall the previous token by swapping back the token buffer */
428  swapTokenBuffer(decinput);
429 
430  if( strcasecmp(decinput->token, "INCOMPLETE") == 0 )
431  {
432  SCIPdebugMessage("(line %d) new section: INCOMPLETE\n", decinput->linenumber);
433  decinput->section = DEC_INCOMPLETE;
434  return TRUE;
435  }
436 
437  if( strcasecmp(decinput->token, "PRESOLVED") == 0 )
438  {
439  SCIPdebugMessage("(line %d) new section: PRESOLVED\n", decinput->linenumber);
440  decinput->section = DEC_PRESOLVED;
441  return TRUE;
442  }
443 
444  if( strcasecmp(decinput->token, "NBLOCKS") == 0 )
445  {
446  SCIPdebugMessage("(line %d) new section: NBLOCKS\n", decinput->linenumber);
447  decinput->section = DEC_NBLOCKS;
448  return TRUE;
449  }
450 
451  if( strcasecmp(decinput->token, "BLOCK") == 0 || strcasecmp(decinput->token, "BLOCKCONSS") == 0 || strcasecmp(decinput->token, "BLOCKCONS") == 0)
452  {
453  int blocknr;
454 
455  decinput->section = DEC_BLOCKCONSS;
456 
457  if( getNextToken(decinput) )
458  {
459  /* read block number */
460  if( isInt(scip, decinput, &blocknr) )
461  {
462  assert(blocknr >= 0);
463  assert(blocknr <= decinput->nblocks);
464 
465  decinput->blocknr = blocknr - 1;
466  }
467  else
468  syntaxError(scip, decinput, "no block number after block keyword!\n");
469  }
470  else
471  syntaxError(scip, decinput, "no block number after block keyword!\n");
472 
473  SCIPdebugMessage("new section: BLOCKCONSS %d\n", decinput->blocknr);
474 
475  return TRUE;
476 
477  }
478 
479  if( strcasecmp(decinput->token, "MASTERCONSS") == 0 || strcasecmp(decinput->token, "MASTERCONS") == 0 )
480  {
481  decinput->section = DEC_MASTERCONSS;
482 
483  SCIPdebugMessage("new section: MASTERCONSS\n");
484 
485  return TRUE;
486  }
487 
488  if( strcasecmp(decinput->token, "BLOCKVARS") == 0 || strcasecmp(decinput->token, "BLOCKVAR") == 0 )
489  {
490  int blocknr;
491 
492  decinput->section = DEC_BLOCKVARS;
493 
494  if( getNextToken(decinput) )
495  {
496  /* read block number */
497  if( isInt(scip, decinput, &blocknr) )
498  {
499  assert(blocknr >= 0);
500  assert(blocknr <= decinput->nblocks);
501 
502  decinput->blocknr = blocknr - 1;
503  }
504  else
505  syntaxError(scip, decinput, "no block number after block keyword!\n");
506  }
507  else
508  syntaxError(scip, decinput, "no block number after block keyword!\n");
509 
510  SCIPdebugMessage("new section: BLOCKVARS %d\n", decinput->blocknr);
511 
512  return TRUE;
513 
514  }
515 
516  if( strcasecmp(decinput->token, "MASTERVARS") == 0 || strcasecmp(decinput->token, "MASTERVAR") == 0
517  || strcasecmp(decinput->token, "STATICVAR") == 0 || strcasecmp(decinput->token, "STATICVARS") == 0 )
518  {
519  decinput->section = DEC_MASTERVARS;
520 
521  SCIPdebugMessage("new section: MASTERVARS\n");
522 
523  return TRUE;
524  }
525 
526  if( strcasecmp(decinput->token, "LINKINGVARS") == 0 || strcasecmp(decinput->token, "LINKINGVAR") == 0 )
527  {
528  decinput->section = DEC_LINKINGVARS;
529 
530  SCIPdebugMessage("new section: LINKINGVARS\n");
531 
532  return TRUE;
533  }
534 
535  return FALSE;
536 }
537 
538 /** reads the header of the file */
539 static
540 SCIP_RETCODE readStart(
541  SCIP* scip, /**< SCIP data structure */
542  DECINPUT* decinput /**< DEC reading data */
543  )
544 {
545  assert(decinput != NULL);
546 
547  /* everything before first section is treated as comment */
548  do
549  {
550  /* get token */
551  if( !getNextToken(decinput) )
552  return SCIP_OKAY;
553  }
554  while( !isNewSection(scip, decinput) );
555 
556  return SCIP_OKAY;
557 }
558 
559 /** reads the incomplete section */
560 static
561 SCIP_RETCODE readIncomplete(
562  SCIP* scip, /**< SCIP data structure */
563  DECINPUT* decinput /**< DEC reading data */
564  )
565 {
566  int incomplete;
567 
568  assert(scip != NULL);
569  assert(decinput != NULL);
570 
571  while( getNextToken(decinput) )
572  {
573  /* check if we reached a new section */
574  if( isNewSection(scip, decinput) )
575  return SCIP_OKAY;
576 
577  /* read if the consdefaultmaster */
578  if( isInt(scip, decinput, &incomplete) )
579  {
580  if( incomplete == 1 )
581  decinput->incomplete = TRUE;
582  else if ( incomplete == 0 )
583  decinput->incomplete = FALSE;
584  else
585  syntaxError(scip, decinput, "incomplete parameter must be 0 or 1");
586 
587  SCIPdebugMessage("The constraints that are not specified in this decomposition are %s forced to the master\n",
588  decinput->incomplete ? "" : " not");
589  }
590  }
591 
592  return SCIP_OKAY;
593 }
594 
595 
596 /** reads the presolved section */
597 static
598 SCIP_RETCODE readPresolved(
599  SCIP* scip, /**< SCIP data structure */
600  DECINPUT* decinput /**< DEC reading data */
601  )
602 {
603  int presolved;
604 
605  assert(scip != NULL);
606  assert(decinput != NULL);
607 
608  while( getNextToken(decinput) )
609  {
610  /* check if we reached a new section */
611  if( isNewSection(scip, decinput) )
612  return SCIP_OKAY;
613 
614  /* read number of blocks */
615  if( isInt(scip, decinput, &presolved) )
616  {
617  decinput->haspresolvesection = TRUE;
618  if( presolved == 1 )
619  {
620  decinput->presolved = TRUE;
621  }
622  else if ( presolved == 0 )
623  {
624  decinput->presolved = FALSE;
625  }
626  else
627  syntaxError(scip, decinput, "presolved parameter must be 0 or 1");
628  SCIPdebugMessage("Decomposition is%s from presolved problem\n",
629  decinput->presolved ? "" : " not");
630  }
631  }
632 
633  return SCIP_OKAY;
634 }
635 
636 /** reads the nblocks section */
637 static
638 SCIP_RETCODE readNBlocks(
639  SCIP* scip, /**< SCIP data structure */
640  DECINPUT* decinput /**< DEC reading data */
641  )
642 {
643  int nblocks;
644 
645  assert(scip != NULL);
646  assert(decinput != NULL);
647  assert(decinput->partialdec != NULL);
648 
649  while( getNextToken(decinput) )
650  {
651  /* check if we reached a new section */
652  if( isNewSection(scip, decinput) )
653  {
654  if( decinput->nblocks == NOVALUE )
655  syntaxError(scip, decinput, "no integer value in nblocks section");
656  else
657  return SCIP_OKAY;
658  }
659 
660  /* read number of blocks */
661  if( isInt(scip, decinput, &nblocks) )
662  {
663  if( decinput->nblocks == NOVALUE )
664  {
665  decinput->nblocks = nblocks;
666  decinput->partialdec->setNBlocks(nblocks);
667  }
668  else
669  syntaxError(scip, decinput, "2 integer values in nblocks section");
670  SCIPdebugMessage("Number of blocks = %d\n", decinput->nblocks);
671  }
672  }
673 
674  return SCIP_OKAY;
675 }
676 
677 /** reads the blocks section */
678 static
679 SCIP_RETCODE readBlockconss(
680  SCIP* scip, /**< SCIP data structure */
681  DECINPUT* decinput, /**< DEC reading data */
682  SCIP_READERDATA* readerdata /**< reader data */
683  )
684 {
685  int blockid;
686  int currblock;
687 
688  SCIP_Bool success;
689  assert(decinput != NULL);
690  assert(readerdata != NULL);
691  assert(decinput->partialdec != NULL);
692 
693  currblock = 0;
694 
695  while( getNextToken(decinput) )
696  {
697  int i;
698  SCIP_CONS* cons;
699  SCIP_VAR** curvars = NULL;
700  int ncurvars;
701 
702  SCIP_Bool conshasvar = FALSE;
703  /* check if we reached a new section */
704  if( isNewSection(scip, decinput) )
705  break;
706 
707  /* the token must be the name of an existing cons */
708  if( decinput->presolved )
709  cons = SCIPfindCons(scip, decinput->token);
710  else
711  cons = SCIPfindOrigCons(scip, decinput->token);
712  if( cons == NULL )
713  {
714  syntaxError(scip, decinput, "unknown constraint in block section");
715  decinput->haserror = TRUE;
716  break;
717  }
718 
719  if( !SCIPconsIsActive(cons) && decinput->presolved )
720  {
721  SCIPdebugMessage("cons is not active, skip it \n");
722  continue;
723  }
724 
725  /* get all curvars for the specific constraint */
726  SCIP_CALL( SCIPgetConsNVars(scip, cons, &ncurvars, &success) );
727  assert(success);
728  if( ncurvars > 0 )
729  {
730  SCIP_CALL( SCIPallocBufferArray(scip, &curvars, ncurvars) );
731  SCIP_CALL( SCIPgetConsVars(scip, cons, curvars, ncurvars, &success) );
732  assert(success);
733  }
734 
735  blockid = decinput->blocknr;
736 
737  for( i = 0; i < ncurvars; i ++ )
738  {
739  assert(curvars != NULL); /* for flexelint */
740  if( decinput->presolved )
741  {
742  SCIP_VAR* var = SCIPvarGetProbvar(curvars[i]);
743  if( !GCGisVarRelevant(var) )
744  continue;
745  }
746 
747  conshasvar = TRUE;
748  break; /* found var */
749  }
750 
751  SCIPfreeBufferArrayNull(scip, &curvars);
752 
753  if( !conshasvar )
754  {
755  SCIPdebugMessage("Cons <%s> has been deleted by presolving or has no variable at all.\n", SCIPconsGetName(cons) );
756  decinput->partialdec->fixConsToBlockByName(decinput->token, currblock);
757  ++currblock;
758  currblock = currblock % decinput->nblocks;
759  continue;
760  }
761  /*
762  * saving block <-> constraint
763  */
764 
765  if( !decinput->partialdec->isConsOpencons(decinput->partialdec->getDetprobdata()->getIndexForCons(cons)) )
766  {
767  decinput->haserror = TRUE;
768  SCIPwarningMessage(scip, "cons %s is already assigned but is supposed to assigned to %d\n", SCIPconsGetName(cons), (blockid+1));
769  return SCIP_OKAY;
770  }
771 
772  SCIPdebugMessage("cons %s is in block %d\n", SCIPconsGetName(cons), blockid);
773  decinput->partialdec->fixConsToBlockByName(decinput->token, blockid);
774  }
775 
776  return SCIP_OKAY;
777 }
778 
779 /** reads the block vars section */
780 static
781 SCIP_RETCODE readBlockvars(
782  SCIP* scip, /**< SCIP data structure */
783  DECINPUT* decinput, /**< DEC reading data */
784  SCIP_READERDATA* readerdata /**< reader data */
785  )
786 {
787  int blockid;
788 
789  assert(decinput != NULL);
790  assert(readerdata != NULL);
791  assert(decinput->partialdec != NULL);
792 
793  while( getNextToken(decinput) )
794  {
795  SCIP_Var* var;
796 
797  /* check if we reached a new section */
798  if( isNewSection(scip, decinput) )
799  break;
800 
801  /* the token must be the name of an existing cons */
802  var = SCIPfindVar(scip, decinput->token);
803  if( var == NULL )
804  {
805  syntaxError(scip, decinput, "unknown variable in block section");
806  break;
807  }
808 
809  if( !SCIPvarIsActive(var) )
810  {
811  SCIPwarningMessage(scip, "Var <%s> has been fixed or aggregated by presolving, skipping.\n", SCIPvarGetName(var));
812  continue;
813  }
814 
815  blockid = decinput->blocknr;
816  decinput->partialdec->fixVarToBlockByName(decinput->token, blockid);
817  }
818 
819  return SCIP_OKAY;
820 }
821 
822 /** reads the masterconss section */
823 static
824 SCIP_RETCODE readMasterconss(
825  SCIP* scip, /**< SCIP data structure */
826  DECINPUT* decinput, /**< DEC reading data */
827  SCIP_READERDATA* readerdata /**< reader data */
828  )
829 {
830  assert(scip != NULL);
831  assert(decinput != NULL);
832  assert(readerdata != NULL);
833  assert(decinput->partialdec != NULL);
834 
835  while( getNextToken(decinput) )
836  {
837  int cons;
838 
839  /* check if we reached a new section */
840  if( isNewSection(scip, decinput) )
841  break;
842 
843  /* the token must be the name of an existing constraint */
844  cons = decinput->partialdec->getDetprobdata()->getIndexForCons(decinput->token);
845 
846  if( cons < 0 )
847  {
848  syntaxError(scip, decinput, "unknown or deleted constraint in masterconss section");
849  break;
850  }
851  else
852  {
853  decinput->partialdec->fixConsToMaster(cons);
854  SCIPdebugMessage("cons %s is linking constraint\n", decinput->token);
855  }
856  }
857 
858  return SCIP_OKAY;
859 }
860 
861 /** reads the mastervars section */
862 static
863 SCIP_RETCODE readMastervars(
864  SCIP* scip, /**< SCIP data structure */
865  DECINPUT* decinput, /**< DEC reading data */
866  SCIP_READERDATA* readerdata /**< reader data */
867  )
868 {
869  assert(scip != NULL);
870  assert(decinput != NULL);
871  assert(readerdata != NULL);
872  assert(decinput->partialdec != NULL);
873 
874  while( getNextToken(decinput) )
875  {
876  SCIP_VAR* var;
877 
878  /* check if we reached a new section */
879  if( isNewSection(scip, decinput) )
880  break;
881 
882  /* the token must be the name of an existing constraint */
883  var = SCIPfindVar(scip, decinput->token);
884  if( var == NULL )
885  {
886  syntaxError(scip, decinput, "unknown constraint in mastervars section");
887  break;
888  }
889  else
890  {
891  if( !SCIPvarIsActive(var) )
892  {
893  SCIPdebugMessage("Var <%s> has been fixed or aggregated by presolving, skipping.\n", SCIPvarGetName(var));
894  continue;
895  }
896 
897  decinput->partialdec->fixVarToMasterByName(decinput->token);
898 
899  SCIPdebugMessage("var %s is master constraint\n", decinput->token);
900  }
901  }
902 
903  return SCIP_OKAY;
904 }
905 
906 /** reads the linkingvars section */
907 static
908 SCIP_RETCODE readLinkingvars(
909  SCIP* scip, /**< SCIP data structure */
910  DECINPUT* decinput, /**< DEC reading data */
911  SCIP_READERDATA* readerdata /**< reader data */
912  )
913 {
914  assert(scip != NULL);
915  assert(decinput != NULL);
916  assert(readerdata != NULL);
917  assert(decinput->partialdec != NULL);
918 
919  while( getNextToken(decinput) )
920  {
921  SCIP_Var* var;
922 
923  /* check if we reached a new section */
924  if( isNewSection(scip, decinput) )
925  break;
926 
927  /* the token must be the name of an existing constraint */
928  var = SCIPfindVar(scip, decinput->token);
929  if( var == NULL )
930  {
931  syntaxError(scip, decinput, "unknown constraint in masterconss section");
932  break;
933  }
934  else
935  {
936  if( !SCIPvarIsActive(var) )
937  {
938  SCIPwarningMessage(scip, "Var <%s> has been fixed or aggregated by presolving, skipping.\n", SCIPvarGetName(var));
939  continue;
940  }
941 
942  decinput->partialdec->fixVarToLinkingByName(decinput->token);
943 
944  SCIPdebugMessage("cons %s is linking constraint\n", decinput->token);
945  }
946  }
947 
948  return SCIP_OKAY;
949 }
950 
951 /** Reads the file and sets the decinput->presolved flag. Resets the file stream afterward.*/
952 static
953 SCIP_RETCODE setPresolved(
954  SCIP* scip, /**< SCIP data structure */
955  DECINPUT* decinput /**< DEC reading data */
956  )
957 {
958  while( getNextToken(decinput) )
959  {
960  if( isNewSection(scip, decinput) && decinput->section == DEC_PRESOLVED )
961  {
962  SCIP_CALL( readPresolved(scip, decinput) );
963  break;
964  }
965  }
966  SCIPrewind(decinput->file);
967  decinput->section = DEC_START;
968  return SCIP_OKAY;
969 }
970 
971 /** reads a DEC file */
972 static
973 SCIP_RETCODE readDECFile(
974  SCIP* scip, /**< SCIP data structure */
975  SCIP_READER* reader, /**< Reader data structure */
976  DECINPUT* decinput, /**< DEC reading data */
977  const char* filename /**< name of the input file */
978  )
979 {
980  SCIP_READERDATA* readerdata;
981 
982  assert(decinput != NULL);
983  assert(scip != NULL);
984  assert(reader != NULL);
985 
986  if( SCIPgetStage(scip) == SCIP_STAGE_INIT || SCIPgetNVars(scip) == 0 || SCIPgetNConss(scip) == 0 )
987  {
988  SCIPverbMessage(scip, SCIP_VERBLEVEL_DIALOG, NULL, "No problem exists, will not read structure!\n");
989  return SCIP_OKAY;
990  }
991 
992  /* open file */
993  decinput->file = SCIPfopen(filename, "r");
994  if( decinput->file == NULL )
995  {
996  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
997  SCIPprintSysError(filename);
998  return SCIP_NOFILE;
999  }
1000 
1001  readerdata = SCIPreaderGetData(reader);
1002  assert(readerdata != NULL);
1003 
1004  /* parse the file */
1005  decinput->section = DEC_START;
1006 
1007  setPresolved(scip, decinput);
1008  if( decinput->presolved && SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED )
1009  {
1010  SCIPinfoMessage(scip, NULL, "read presolved decomposition but problem is not presolved yet -> presolve()\n");
1011  SCIPpresolve(scip);
1012  assert(decinput->haspresolvesection);
1013  }
1014 
1015  decinput->partialdec = new gcg::PARTIALDECOMP(scip, !decinput->presolved);
1016 
1017  while( decinput->section != DEC_END && !hasError(decinput) )
1018  {
1019  switch( decinput->section )
1020  {
1021  case DEC_START:
1022  SCIP_CALL( readStart(scip, decinput) );
1023  break;
1024  case DEC_INCOMPLETE:
1025  SCIP_CALL( readIncomplete(scip, decinput) );
1026  break;
1027  case DEC_PRESOLVED:
1028  while( getNextToken(decinput) )
1029  {
1030  if( isNewSection(scip, decinput) )
1031  {
1032  break;
1033  }
1034  }
1035  break;
1036  case DEC_NBLOCKS:
1037  SCIP_CALL( readNBlocks(scip, decinput) );
1038  if( decinput->haspresolvesection && !decinput->presolved && SCIPgetStage(scip) >= SCIP_STAGE_PRESOLVED )
1039  {
1040  SCIPwarningMessage(scip, "decomposition belongs to the unpresolved problem, but the problem is already presolved, please consider to re-read the problem and read the decomposition without presolving when transforming do not succeed.\n");
1041  break;
1042 
1043  }
1044  if( !decinput->haspresolvesection )
1045  {
1046  SCIPwarningMessage(scip, "decomposition has no presolve section at beginning. The behaviour is undefined. Please add a presolve section. File reading is aborted. \n");
1047  }
1048  break;
1049 
1050  case DEC_BLOCKCONSS:
1051  SCIP_CALL( readBlockconss(scip, decinput, readerdata) );
1052  break;
1053 
1054  case DEC_MASTERCONSS:
1055  SCIP_CALL( readMasterconss(scip, decinput, readerdata) );
1056  break;
1057 
1058  case DEC_BLOCKVARS:
1059  SCIP_CALL( readBlockvars(scip, decinput, readerdata) );
1060  break;
1061 
1062  case DEC_MASTERVARS:
1063  SCIP_CALL( readMastervars(scip, decinput, readerdata) );
1064  break;
1065 
1066  case DEC_LINKINGVARS:
1067  SCIP_CALL( readLinkingvars(scip, decinput, readerdata) );
1068  break;
1069 
1070  case DEC_END: /* this is already handled in the while() loop */
1071  default:
1072  SCIPerrorMessage("invalid DEC file section <%d>\n", decinput->section);
1073  return SCIP_INVALIDDATA;
1074  }
1075  }
1076 
1077  decinput->partialdec->prepare();
1078 
1079  if( !decinput->partialdec->isComplete() && !decinput->incomplete )
1081 
1082  if( decinput->haserror)
1083  {
1084  SCIPinfoMessage(scip, NULL, "error occurred while reading dec file");
1085  delete decinput->partialdec;
1086  }
1087  else
1088  {
1089  SCIPinfoMessage(scip, NULL, "just read dec file:\n");
1090  decinput->partialdec->sort();
1091  /* if the partialdec was to be completed, add a "vanilla" version as well */
1092  if( decinput->partialdec->shouldCompletedByConsToMaster() )
1093  {
1094  gcg::PARTIALDECOMP* partial = new gcg::PARTIALDECOMP(decinput->partialdec);
1097  }
1099  }
1100 
1101  /* close file */
1102  SCIPfclose(decinput->file);
1103 
1104  return SCIP_OKAY;
1105 }
1106 
1107 
1108 /**
1109  * @brief write partialdec to file in dec format
1110 
1111  * @return scip return code
1112  */
1113 static
1114 SCIP_RETCODE writePartialdec(
1115  SCIP* scip, /**< SCIP data structure */
1116  FILE* file, /**< pointer to file to write to */
1117  gcg::PARTIALDECOMP* partialdec, /**< partialdec to write */
1118  SCIP_RESULT* result /**< will be set to SCIP_SUCCESS if writing was successful */
1119  )
1120 {
1121  int nconss;
1122  int nvars;
1123  std::vector<int> consindex;
1124  std::vector<int> varindex;
1125 
1126  assert(partialdec != NULL);
1127 
1128  gcg::DETPROBDATA* detprobdata = partialdec->getDetprobdata();
1129 
1130  nconss = detprobdata->getNConss();
1131  nvars = detprobdata->getNVars();
1132 
1133  consindex = std::vector<int>(nconss);
1134  varindex = std::vector<int>(nvars);
1135 
1136  for( int i = 0; i < nconss; ++i )
1137  consindex[i] = i;
1138  for( int i = 0; i < nvars; ++i )
1139  varindex[i] = i;
1140 
1141  /* write meta data of decomposition as comment */
1142  if( partialdec->getUsergiven() == gcg::USERGIVEN::PARTIAL )
1143  SCIPinfoMessage(scip, file, "%s%s stems from a partial decomposition provided by the user\n", commentchars, commentchars);
1144  else if( partialdec->getUsergiven() != gcg::USERGIVEN::NOT )
1145  SCIPinfoMessage(scip, file, "%s%s provided by the user\n", commentchars, commentchars);
1146  auto& detectorchain = partialdec->getDetectorchain();
1147  auto& detectorchaininfo = partialdec->getDetectorchainInfo();
1148  SCIPinfoMessage(scip, file, "%s%s ndetectors \n", commentchars, commentchars);
1149  SCIPinfoMessage(scip, file, "%s%s %ld \n", commentchars, commentchars, detectorchain.size());
1150 
1151  SCIPinfoMessage(scip, file,
1152  "%s%s name info time nnewblocks %%ofnewborderconss %%ofnewblockconss %%ofnewlinkingvars %%ofnewblockvars\n",
1154 
1155  for( unsigned int i = 0; i < detectorchain.size(); ++i )
1156  {
1157  SCIPinfoMessage(scip, file, "%s%s %s %s %f %d %f %f %f %f \n", commentchars, commentchars,
1158  DECdetectorGetName(detectorchain[i]), detectorchaininfo[i].c_str(), partialdec->getDetectorClockTimes().at(i),
1159  partialdec->getNNewBlocks(i), partialdec->getPctConssToBorder(i), partialdec->getPctConssToBlock(i),
1160  partialdec->getPctVarsToBorder(i), partialdec->getPctVarsToBlock(i)) ;
1161  }
1162 
1163  if( !partialdec->isComplete() )
1164  SCIPinfoMessage(scip, file, "INCOMPLETE\n1\n");
1165 
1166  if( partialdec->isAssignedToOrigProb() )
1167  SCIPinfoMessage(scip, file, "PRESOLVED\n0\n");
1168  else
1169  SCIPinfoMessage(scip, file, "PRESOLVED\n1\n");
1170 
1171  SCIPinfoMessage(scip, file, "NBLOCKS\n%d\n", partialdec->getNBlocks());
1172 
1173  for( int b = 0; b < partialdec->getNBlocks(); ++b )
1174  {
1175  SCIPinfoMessage(scip, file, "BLOCK %d\n", b+1 );
1176  for( int c = 0; c < partialdec->getNConssForBlock(b); ++c )
1177  {
1178  SCIPinfoMessage(scip, file, "%s\n", SCIPconsGetName(detprobdata->getCons(partialdec->getConssForBlock(b)[c])));
1179  }
1180  }
1181 
1182  SCIPinfoMessage(scip, file, "MASTERCONSS\n" );
1183  for( int mc = 0; mc < partialdec->getNMasterconss(); ++mc )
1184  {
1185  SCIPinfoMessage(scip, file, "%s\n", SCIPconsGetName(detprobdata->getCons(partialdec->getMasterconss()[mc])));
1186  }
1187 
1188  if( partialdec->isComplete() )
1189  {
1190  *result = SCIP_SUCCESS;
1191  return SCIP_OKAY;
1192  }
1193 
1194  SCIPinfoMessage(scip, file, "LINKINGVARS\n" );
1195  for( int lv = 0; lv < partialdec->getNLinkingvars(); ++lv )
1196  {
1197  SCIPinfoMessage(scip, file, "%s\n", SCIPvarGetName(detprobdata->getVar(partialdec->getLinkingvars()[lv])));
1198  }
1199 
1200  SCIPinfoMessage(scip, file, "MASTERVARS\n%s%s aka STATICVARS\n", commentchars, commentchars );
1201  for( int mv = 0; mv < partialdec->getNMastervars(); ++mv )
1202  {
1203  SCIPinfoMessage(scip, file, "%s\n", SCIPvarGetName(detprobdata->getVar(partialdec->getMastervars()[mv])));
1204  }
1205 
1206  for( int b = 0; b < partialdec->getNBlocks(); ++b )
1207  {
1208  SCIPinfoMessage(scip, file, "BLOCKVARS %d\n", b+1 );
1209  for( int v = 0; v < partialdec->getNVarsForBlock(b); ++v )
1210  {
1211  SCIPinfoMessage(scip, file, "%s\n", SCIPvarGetName(detprobdata->getVar(partialdec->getVarsForBlock(b)[v])));
1212  }
1213  }
1214 
1215  *result = SCIP_SUCCESS;
1216 
1217  return SCIP_OKAY;
1218 }
1219 
1220 
1221 /* reads problem from file */
1222 SCIP_RETCODE readDec(
1223  SCIP* scip, /**< SCIP data structure */
1224  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
1225  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
1226 )
1227 {
1228  SCIP_RETCODE retcode;
1229  SCIP_READER* reader;
1230  DECINPUT decinput;
1231  int i;
1232 
1233  reader = SCIPfindReader(scip, READER_NAME);
1234  assert(reader != NULL);
1235 
1236  /* initialize DEC input data */
1237  decinput.file = NULL;
1238  decinput.linebuf[0] = '\0';
1239  SCIP_CALL( SCIPallocMemoryArray(scip, &decinput.token, DEC_MAX_LINELEN) ); /*lint !e506*/
1240  decinput.token[0] = '\0';
1241  SCIP_CALL( SCIPallocMemoryArray(scip, &decinput.tokenbuf, DEC_MAX_LINELEN) ); /*lint !e506*/
1242  decinput.tokenbuf[0] = '\0';
1243  for( i = 0; i < DEC_MAX_PUSHEDTOKENS; ++ i )
1244  {
1245  SCIP_CALL( SCIPallocMemoryArray(scip, &decinput.pushedtokens[i], DEC_MAX_LINELEN) ); /*lint !e506 !e866*/
1246  }
1247 
1248  decinput.npushedtokens = 0;
1249  decinput.linenumber = 0;
1250  decinput.linepos = 0;
1251  decinput.section = DEC_START;
1252  decinput.presolved = FALSE;
1253  decinput.haspresolvesection = FALSE;
1254  decinput.nblocks = NOVALUE;
1255  decinput.blocknr = - 2;
1256  decinput.haserror = FALSE;
1257  decinput.incomplete = FALSE;
1258 
1259  /* read the file */
1260  retcode = readDECFile(scip, reader, &decinput, filename);
1261 
1262  /* free dynamically allocated memory */
1263  SCIPfreeMemoryArray(scip, &decinput.token);
1264  SCIPfreeMemoryArray(scip, &decinput.tokenbuf);
1265  for( i = 0; i < DEC_MAX_PUSHEDTOKENS; ++ i )
1266  {
1267  SCIPfreeMemoryArray(scip, &decinput.pushedtokens[i]);
1268  }
1269 
1270  /* evaluate the result */
1271  if( decinput.haserror )
1272  return SCIP_READERROR;
1273  else if( retcode == SCIP_OKAY )
1274  {
1275  *result = SCIP_SUCCESS;
1276  }
1277 
1278  return retcode;
1279 }
1280 
1281 
1282 /*
1283  * Callback methods of reader
1284  */
1285 
1286 /** destructor of reader to free user data (called when SCIP is exiting) */
1287 static
1288 SCIP_DECL_READERFREE(readerFreeDec)
1289 {
1290  SCIP_READERDATA* readerdata;
1291 
1292  readerdata = SCIPreaderGetData(reader);
1293  assert(readerdata != NULL);
1294 
1295  SCIPfreeMemory(scip, &readerdata);
1296 
1297  return SCIP_OKAY;
1298 }
1299 
1300 /** problem reading method of reader */
1301 static
1302 SCIP_DECL_READERREAD(readerReadDec)
1303 { /*lint --e{715}*/
1304 
1305  if( SCIPgetStage(scip) == SCIP_STAGE_INIT || SCIPgetNVars(scip) == 0 || SCIPgetNConss(scip) == 0 )
1306  {
1307  SCIPverbMessage(scip, SCIP_VERBLEVEL_DIALOG, NULL, "Please read in a problem before reading in the corresponding structure file!\n");
1308  return SCIP_OKAY;
1309  }
1310 
1311  SCIP_CALL( readDec(scip, filename, result) );
1312 
1313  return SCIP_OKAY;
1314 }
1315 
1316 /** problem writing method of reader */
1317 static
1318 SCIP_DECL_READERWRITE(readerWriteDec)
1319 { /*lint --e{715}*/
1320  assert(scip != NULL);
1321  assert(reader != NULL);
1322 
1323  gcg::PARTIALDECOMP* partialdec = DECgetPartialdecToWrite(scip, transformed);
1324 
1325  if(partialdec == NULL) {
1326  SCIPwarningMessage(scip, "There is no writable partialdec!\n");
1327  return SCIP_OKAY;
1328  }
1329 
1330  writePartialdec(scip, file, partialdec, result);
1331 
1332  return SCIP_OKAY;
1333 }
1334 
1335 /*
1336  * reader specific interface methods
1337  */
1338 
1339 /** includes the dec file reader in SCIP */
1340 SCIP_RETCODE GCGincludeReaderDec(
1341  SCIP* scip /**< SCIP data structure */
1342  )
1343 {
1344  SCIP_READERDATA* readerdata;
1345 
1346  /* create dec reader data */
1347  SCIP_CALL( SCIPallocMemory(scip, &readerdata) );
1348 
1349  /* include dec reader */
1350  SCIP_CALL(SCIPincludeReader(scip, READER_NAME, READER_DESC, READER_EXTENSION, NULL,
1351  readerFreeDec, readerReadDec, readerWriteDec, readerdata));
1352 
1353  return SCIP_OKAY;
1354 }
#define DEC_MAX_LINELEN
Definition: reader_dec.cpp:68
SCIP_RETCODE readDec(SCIP *scip, const char *filename, SCIP_RESULT *result)
int getNConss()
returns the number of variables considered in the detprobdata
const char * DECdetectorGetName(DEC_DETECTOR *detector)
returns the name of the provided detector
@ DEC_BLOCKCONSS
Definition: reader_dec.cpp:74
SCIP_RETCODE GCGincludeReaderDec(SCIP *scip)
static SCIP_DECL_READERREAD(readerReadDec)
#define DEC_MAX_PUSHEDTOKENS
Definition: reader_dec.cpp:69
std::vector< int > & getMastervars()
Gets array containing all master vars indices.
static SCIP_RETCODE readBlockconss(SCIP *scip, DECINPUT *decinput, SCIP_READERDATA *readerdata)
Definition: reader_dec.cpp:679
enum DecSection DECSECTION
Definition: reader_dec.cpp:76
std::vector< int > & getVarsForBlock(int block)
Gets array containing vars of a block.
static void swapTokenBuffer(DECINPUT *decinput)
Definition: reader_dec.cpp:371
@ DEC_BLOCKVARS
Definition: reader_dec.cpp:74
std::vector< int >::const_iterator fixConsToMaster(std::vector< int >::const_iterator itr)
fixes a constraint to the master constraints
static void pushToken(DECINPUT *decinput)
Definition: reader_dec.cpp:358
DecSection
Definition: reader_dec.cpp:72
static SCIP_Bool isTokenChar(char c)
Definition: reader_dec.cpp:171
static void syntaxError(SCIP *scip, DECINPUT *decinput, const char *msg)
Definition: reader_dec.cpp:124
void setNBlocks(int nblocks)
sets number of blocks, only increasing number allowed
static const char tokenchars[]
Definition: reader_dec.cpp:115
constraint handler for structure detection
static const int LINKINGVALUE
Definition: reader_dec.cpp:113
std::vector< int > & getMasterconss()
Gets array containing all master conss indices.
bool isComplete()
Gets whether this partialdec is complete, i.e. it has no more open constraints and variables.
@ DEC_EXP_NONE
Definition: reader_dec.cpp:81
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, DECEXPTYPE *exptype)
Definition: reader_dec.cpp:180
static SCIP_RETCODE readMastervars(SCIP *scip, DECINPUT *decinput, SCIP_READERDATA *readerdata)
Definition: reader_dec.cpp:863
USERGIVEN getUsergiven()
Gets the USERGIVEN status of this partialdecs.
int getNVarsForBlock(int block)
Gets size of the vector containing vars assigned to a block.
static const char commentchars[]
Definition: reader_dec.cpp:116
char * token
Definition: reader_dec.cpp:90
DEC file reader for structure information.
@ DEC_LINKINGVARS
Definition: reader_dec.cpp:74
SCIP_Bool GCGisVarRelevant(SCIP_VAR *var)
Definition: scip_misc.c:41
bool fixVarToMasterByName(const char *varname)
assigns a variable with given name as master
char * tokenbuf
Definition: reader_dec.cpp:91
@ DEC_INCOMPLETE
Definition: reader_dec.cpp:74
static SCIP_Bool isNewSection(SCIP *scip, DECINPUT *decinput)
Definition: reader_dec.cpp:410
PARTIALDECOMP * DECgetPartialdecToWrite(SCIP *scip, SCIP_Bool transformed)
various SCIP helper methods
bool fixVarToLinkingByName(const char *varname)
assigns a variable by name to the linking variables
static SCIP_RETCODE readBlockvars(SCIP *scip, DECINPUT *decinput, SCIP_READERDATA *readerdata)
Definition: reader_dec.cpp:781
void setUsergiven(USERGIVEN usergiven)
sets whether this partialdec is user given
#define READER_EXTENSION
Definition: reader_dec.cpp:62
char * pushedtokens[DEC_MAX_PUSHEDTOKENS]
Definition: reader_dec.cpp:92
static SCIP_RETCODE readStart(SCIP *scip, DECINPUT *decinput)
Definition: reader_dec.cpp:540
@ DEC_MASTERVARS
Definition: reader_dec.cpp:74
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_dec.cpp:245
static const int NOVALUE
Definition: reader_dec.cpp:112
int getNConssForBlock(int block)
Gets size of the vector containing conss assigned to a block.
static SCIP_Bool getNextToken(DECINPUT *decinput)
Definition: reader_dec.cpp:259
SCIP_CONS * getCons(int consIndex)
returns the SCIP constraint related to a constraint index
SCIP_Bool shouldCompletedByConsToMaster()
Checks whether this partialdec is a userpartialdec that should be completed.
SCIP_Real getPctConssToBorder(int detectorchainindex)
Gets fraction of constraints assigned to the border for a detector.
char linebuf[DEC_MAX_LINELEN]
Definition: reader_dec.cpp:89
SCIP_FILE * file
Definition: reader_dec.cpp:88
static SCIP_RETCODE readDECFile(SCIP *scip, SCIP_READER *reader, DECINPUT *decinput, const char *filename)
Definition: reader_dec.cpp:973
gcg::PARTIALDECOMP * partialdec
Definition: reader_dec.cpp:103
SCIP_Real getPctConssToBlock(int detectorchainindex)
Gets fraction of constraints assigned to a block for a detector.
SCIP_Bool presolved
Definition: reader_dec.cpp:96
@ DEC_PRESOLVED
Definition: reader_dec.cpp:74
int getNVars()
return the number of variables considered in the detprobdata
DecExpType
Definition: reader_dec.cpp:79
int getIndexForCons(SCIP_CONS *cons)
returns the constraint index related to a SCIP constraint
int getNLinkingvars()
Gets size of the vector containing linking vars.
bool sort()
sorts the vars and conss data structures by their indices
static SCIP_Bool isInt(SCIP *scip, DECINPUT *decinput, int *value)
Definition: reader_dec.cpp:382
C++ interface of cons_decomp.
DECSECTION section
Definition: reader_dec.cpp:101
#define READER_DESC
Definition: reader_dec.cpp:61
SCIP_Real getPctVarsToBorder(int detectorchainindex)
Gets fraction of variables assigned to the border for a detector.
int getNNewBlocks(int detectorchainindex)
Gets number of blocks a detector added.
static const char delimchars[]
Definition: reader_dec.cpp:114
int npushedtokens
Definition: reader_dec.cpp:93
static SCIP_DECL_READERWRITE(readerWriteDec)
std::vector< std::string > & getDetectorchainInfo()
Gets the detectorchain info vector.
static SCIP_RETCODE writePartialdec(SCIP *scip, FILE *file, gcg::PARTIALDECOMP *partialdec, SCIP_RESULT *result)
write partialdec to file in dec format
static SCIP_RETCODE readIncomplete(SCIP *scip, DECINPUT *decinput)
Definition: reader_dec.cpp:561
static SCIP_RETCODE readNBlocks(SCIP *scip, DECINPUT *decinput)
Definition: reader_dec.cpp:638
static SCIP_RETCODE readMasterconss(SCIP *scip, DECINPUT *decinput, SCIP_READERDATA *readerdata)
Definition: reader_dec.cpp:824
std::vector< SCIP_Real > & getDetectorClockTimes()
returns a vector of the clock times that each detector needed that was involved in this partialdec
std::vector< int > & getConssForBlock(int block)
returns array containing constraints assigned to a block
@ DEC_MASTERCONSS
Definition: reader_dec.cpp:74
static SCIP_DECL_READERFREE(readerFreeDec)
@ DEC_NBLOCKS
Definition: reader_dec.cpp:74
class to manage partial decompositions
int getNBlocks()
Gets the number of blocks.
SCIP_RETCODE GCGconshdlrDecompAddPreexisitingPartialDec(SCIP *scip, PARTIALDECOMP *partialdec)
adds a preexisting partial dec to be considered at the beginning of the detection
DETPROBDATA * getDetprobdata()
Gets the corresponding detprobdata.
SCIP_Bool haspresolvesection
Definition: reader_dec.cpp:97
#define READER_NAME
Definition: reader_dec.cpp:60
static SCIP_Bool hasError(DECINPUT *decinput)
Definition: reader_dec.cpp:152
SCIP_Bool incomplete
Definition: reader_dec.cpp:98
enum DecExpType DECEXPTYPE
Definition: reader_dec.cpp:83
std::vector< int > & getLinkingvars()
returns array containing all linking vars indices
bool fixVarToBlockByName(const char *varname, int blockid)
assigns a variable by name to a block
int linepos
Definition: reader_dec.cpp:95
static SCIP_RETCODE readPresolved(SCIP *scip, DECINPUT *decinput)
Definition: reader_dec.cpp:598
SCIP_Bool haserror
Definition: reader_dec.cpp:102
bool isConsOpencons(int cons)
Gets whether the cons is an open cons.
@ DEC_START
Definition: reader_dec.cpp:74
bool fixConsToBlockByName(const char *consname, int blockid)
assigns a constraint by name to a block
SCIP_Real getPctVarsToBlock(int detectorchainindex)
Gets fraction of variables assigned to a block for a detector.
class storing (potentially incomplete) decompositions
public methods for GCG variables
static SCIP_RETCODE readLinkingvars(SCIP *scip, DECINPUT *decinput, SCIP_READERDATA *readerdata)
Definition: reader_dec.cpp:908
std::vector< DEC_DETECTOR * > & getDetectorchain()
returns detector chain as vector of detector pointers
int linenumber
Definition: reader_dec.cpp:94
static SCIP_Bool isDelimChar(char c)
Definition: reader_dec.cpp:162
int getNMasterconss()
Gets size of the vector containing master conss.
bool isAssignedToOrigProb()
Gets whether the partialdec is from the presolved problem.
@ DEC_END
Definition: reader_dec.cpp:74
SCIP_VAR * getVar(int varIndex)
returns SCIP variable related to a variable index
int getNMastervars()
Gets size of the vector containing master vars.
class storing partialdecs and the problem matrix
int nblocks
Definition: reader_dec.cpp:99
static SCIP_RETCODE setPresolved(SCIP *scip, DECINPUT *decinput)
Definition: reader_dec.cpp:953
@ COMPLETED_CONSTOMASTER
static SCIP_Bool getNextLine(DECINPUT *decinput)
Definition: reader_dec.cpp:201
public methods for working with decomposition structures