Scippy

SCIP

Solving Constraint Integer Programs

reader_opb.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-2021 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 visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file reader_opb.c
17  * @ingroup DEFPLUGINS_READER
18  * @brief pseudo-Boolean file reader (opb format)
19  * @author Stefan Heinz
20  * @author Michael Winkler
21  *
22  * This file reader parses the @a opb format and is also used by the @a wbo reader for the @a wbo format. For a
23  * detailed description of this format see
24  *
25  * - http://www.cril.univ-artois.fr/PB07/solver_req.html
26  * - http://www.cril.univ-artois.fr/PB10/format.pdf
27  *
28  * The syntax of the input file format can be described by a simple Backus-Naur
29  * form. <formula> is the start symbol of this grammar.
30  *
31  * <formula>::= <sequence_of_comments>
32  * [<objective>] | [<softheader>]
33  * <sequence_of_comments_or_constraints>
34  *
35  * <sequence_of_comments>::= <comment> [<sequence_of_comments>]
36  * <comment>::= "*" <any_sequence_of_characters_other_than_EOL> <EOL>
37  * <sequence_of_comments_or_constraints>::=<comment_or_constraint> [<sequence_of_comments_or_constraints>]
38  * <comment_or_constraint>::=<comment>|<constraint>
39  *
40  * <objective>::= "min:" <zeroOrMoreSpace> <sum> ";"
41  * <constraint>::= <sum> <relational_operator> <zeroOrMoreSpace> <integer> <zeroOrMoreSpace> ";"
42  *
43  * <sum>::= <weightedterm> | <weightedterm> <sum>
44  * <weightedterm>::= <integer> <oneOrMoreSpace> <term> <oneOrMoreSpace>
45  *
46  * <integer>::= <unsigned_integer> | "+" <unsigned_integer> | "-" <unsigned_integer>
47  * <unsigned_integer>::= <digit> | <digit><unsigned_integer>
48  *
49  * <relational_operator>::= ">=" | "="
50  *
51  * <variablename>::= "x" <unsigned_integer>
52  *
53  * <oneOrMoreSpace>::= " " [<oneOrMoreSpace>]
54  * <zeroOrMoreSpace>::= [" " <zeroOrMoreSpace>]
55  *
56  * For linear pseudo-Boolean instances, <term> is defined as
57  *
58  * <term>::=<variablename>
59  *
60  * For non-linear instances, <term> is defined as
61  *
62  * <term>::= <oneOrMoreLiterals>
63  * <oneOrMoreLiterals>::= <literal> | <literal> <oneOrMoreSpace> <oneOrMoreLiterals>
64  * <literal>::= <variablename> | "~"<variablename>
65  *
66  * For wbo-files are the following additional/changed things possible.
67  *
68  * <softheader>::= "soft:" [<unsigned integer>] ";"
69  *
70  * <comment_or_constraint>::=<comment>|<constraint>|<softconstraint>
71  *
72  * <softconstraint>::= "[" <zeroOrMoreSpace> <unsigned integer> <zeroOrMoreSpace> "]" <constraint>
73  *
74  */
75 
76 /* Our parser should also be lax by handling variable names and it's possible to read doubles instead of integer and
77  * possible some more :). */
78 
79 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
80 
81 #include "blockmemshell/memory.h"
82 #include <ctype.h>
83 #include "scip/cons_and.h"
84 #include "scip/cons_indicator.h"
85 #include "scip/cons_knapsack.h"
86 #include "scip/cons_linear.h"
87 #include "scip/cons_logicor.h"
89 #include "scip/cons_setppc.h"
90 #include "scip/cons_varbound.h"
91 #include "scip/debug.h"
92 #include "scip/pub_cons.h"
93 #include "scip/pub_fileio.h"
94 #include "scip/pub_message.h"
95 #include "scip/pub_misc.h"
96 #include "scip/pub_misc_sort.h"
97 #include "scip/pub_reader.h"
98 #include "scip/pub_var.h"
99 #include "scip/reader_opb.h"
100 #include "scip/scip_cons.h"
101 #include "scip/scip_mem.h"
102 #include "scip/scip_message.h"
103 #include "scip/scip_numerics.h"
104 #include "scip/scip_param.h"
105 #include "scip/scip_prob.h"
106 #include "scip/scip_reader.h"
107 #include "scip/scip_solvingstats.h"
108 #include "scip/scip_var.h"
109 #include <stdlib.h>
110 #include <string.h>
111 
112 #if !defined(_WIN32) && !defined(_WIN64)
113 #include <strings.h> /*lint --e{766}*/ /* needed for strncasecmp() */
114 #endif
115 
116 #define READER_NAME "opbreader"
117 #define READER_DESC "file reader for pseudo-Boolean problem in opb format"
118 #define READER_EXTENSION "opb"
119 
120 #define GENCONSNAMES TRUE /* remove if no constraint names should be generated */
121 #define LINEAROBJECTIVE TRUE /* will all non-linear parts inside the objective function be linearized or will
122  * an artificial integer variable be created which will represent the objective
123  * function
124  */
125 
126 #define INDICATORVARNAME "indicatorvar" /* standard part of name for all indicator variables */
127 #define INDICATORSLACKVARNAME "indslack" /* standard part of name for all indicator slack variables; should be the same in cons_indicator */
128 #define TOPCOSTCONSNAME "topcostcons" /* standard name for artificial topcost constraint in wbo problems */
129 
130 /*
131  * Data structures
132  */
133 #define OPB_MAX_LINELEN 65536 /**< size of the line buffer for reading or writing */
134 #define OPB_MAX_PUSHEDTOKENS 2
135 #define OPB_INIT_COEFSSIZE 8192
136 
137 /** Section in OPB File */
139 {
143 };
144 typedef enum OpbExpType OPBEXPTYPE;
145 
147 {
152 };
153 typedef enum OpbSense OPBSENSE;
154 
155 /** OPB reading data */
156 struct OpbInput
157 {
158  SCIP_FILE* file;
159  char linebuf[OPB_MAX_LINELEN+1];
160  char* token;
161  char* tokenbuf;
162  char* pushedtokens[OPB_MAX_PUSHEDTOKENS];
163  int npushedtokens;
164  int linenumber;
165  int linepos;
166  int bufpos;
167  SCIP_OBJSENSE objsense;
168  SCIP_Bool comment;
169  SCIP_Bool endline;
170  SCIP_Bool eof;
171  SCIP_Bool haserror;
172  int nproblemcoeffs;
173  SCIP_Bool wbo;
174  SCIP_Real topcost;
175  int nindvars;
176 #if GENCONSNAMES == TRUE
177  int consnumber;
178 #endif
179 };
180 
181 typedef struct OpbInput OPBINPUT;
182 
183 static const char commentchars[] = "*";
184 /*
185  * Local methods (for reading)
186  */
187 
188 /** issues an error message and marks the OPB data to have errors */
189 static
191  SCIP* scip, /**< SCIP data structure */
192  OPBINPUT* opbinput, /**< OPB reading data */
193  const char* msg /**< error message */
194  )
195 {
196  assert(scip != NULL);
197  assert(opbinput != NULL);
198 
199  SCIPerrorMessage("Syntax error in line %d: %s found <%s>\n", opbinput->linenumber, msg, opbinput->token);
200  if( opbinput->linebuf[strlen(opbinput->linebuf)-1] == '\n' )
201  {
202  SCIPerrorMessage(" input: %s", opbinput->linebuf);
203  }
204  else
205  {
206  SCIPerrorMessage(" input: %s\n", opbinput->linebuf);
207  }
208 
209  opbinput->haserror = TRUE;
210 }
211 
212 /** returns whether a syntax error was detected */
213 static
215  OPBINPUT* opbinput /**< OPB reading data */
216  )
217 {
218  assert(opbinput != NULL);
219 
220  return opbinput->haserror;
221 }
222 
223 /** returns whether the given character is a token delimiter */
224 static
226  char c /**< input character */
227  )
228 {
229  switch (c)
230  {
231  case ' ':
232  case '\f':
233  case '\n':
234  case '\r':
235  case '\t':
236  case '\v':
237  case '\0':
238  return TRUE;
239  default:
240  return FALSE;
241  }
242 }
243 
244 /** returns whether the given character is a single token */
245 static
247  char c /**< input character */
248  )
249 {
250  switch (c)
251  {
252  case '-':
253  case '+':
254  case ':':
255  case '<':
256  case '>':
257  case '=':
258  case '[':
259  case ']':
260  case ';':
261  return TRUE;
262  default:
263  return FALSE;
264  }
265 }
266 
267 /** returns whether the current character is member of a value string */
268 static
270  char c, /**< input character */
271  char nextc, /**< next input character */
272  SCIP_Bool firstchar, /**< is the given character the first char of the token? */
273  SCIP_Bool* hasdot, /**< pointer to update the dot flag */
274  OPBEXPTYPE* exptype /**< pointer to update the exponent type */
275  )
276 {
277  assert(hasdot != NULL);
278  assert(exptype != NULL);
279 
280  if( isdigit((unsigned char)c) )
281  return TRUE;
282  else if( (*exptype == OPB_EXP_NONE) && !(*hasdot) && (c == '.') )
283  {
284  *hasdot = TRUE;
285  return TRUE;
286  }
287  else if( !firstchar && (*exptype == OPB_EXP_NONE) && (c == 'e' || c == 'E') )
288  {
289  if( nextc == '+' || nextc == '-' )
290  {
291  *exptype = OPB_EXP_SIGNED;
292  return TRUE;
293  }
294  else if( isdigit((unsigned char)nextc) )
295  {
296  *exptype = OPB_EXP_UNSIGNED;
297  return TRUE;
298  }
299  }
300  else if( (*exptype == OPB_EXP_SIGNED) && (c == '+' || c == '-') )
301  {
302  *exptype = OPB_EXP_UNSIGNED;
303  return TRUE;
304  }
305 
306  return FALSE;
307 }
308 
309 /** reads the next line from the input file into the line buffer; skips comments;
310  * returns whether a line could be read
311  */
312 static
314  SCIP* scip, /**< SCIP data structure */
315  OPBINPUT* opbinput /**< OPB reading data */
316  )
317 {
318  int i;
319 
320  assert(opbinput != NULL);
321 
322  /* if we previously detected a comment we have to parse the remaining line away if there is something left */
323  if( !opbinput->endline && opbinput->comment )
324  {
325  SCIPdebugMsg(scip, "Throwing rest of comment away.\n");
326 
327  do
328  {
329  opbinput->linebuf[OPB_MAX_LINELEN-2] = '\0';
330  (void)SCIPfgets(opbinput->linebuf, (int) sizeof(opbinput->linebuf), opbinput->file);
331  }
332  while( opbinput->linebuf[OPB_MAX_LINELEN-2] != '\0' );
333 
334  opbinput->comment = FALSE;
335  opbinput->endline = TRUE;
336  }
337 
338  /* clear the line */
339  opbinput->linebuf[OPB_MAX_LINELEN-2] = '\0';
340 
341  /* set line position */
342  if( opbinput->endline )
343  {
344  opbinput->linepos = 0;
345  opbinput->linenumber++;
346  }
347  else
348  opbinput->linepos += OPB_MAX_LINELEN - 2;
349 
350  if( SCIPfgets(opbinput->linebuf, (int) sizeof(opbinput->linebuf), opbinput->file) == NULL )
351  return FALSE;
352 
353  opbinput->bufpos = 0;
354 
355  if( opbinput->linebuf[OPB_MAX_LINELEN-2] != '\0' )
356  {
357  char* last;
358 
359  /* buffer is full; erase last token since it might be incomplete */
360  opbinput->endline = FALSE;
361  last = strrchr(opbinput->linebuf, ' ');
362 
363  if( last == NULL )
364  {
365  SCIPwarningMessage(scip, "we read %d character from the file; these might indicates a corrupted input file!",
366  OPB_MAX_LINELEN - 2);
367  opbinput->linebuf[OPB_MAX_LINELEN-2] = '\0';
368  SCIPdebugMsg(scip, "the buffer might be corrupted\n");
369  }
370  else
371  {
372  SCIPfseek(opbinput->file, -(long) strlen(last), SEEK_CUR);
373  SCIPdebugMsg(scip, "correct buffer, reread the last %ld characters\n", (long) strlen(last));
374  *last = '\0';
375  }
376  }
377  else
378  {
379  /* found end of line */
380  opbinput->endline = TRUE;
381  }
382 
383  opbinput->linebuf[OPB_MAX_LINELEN-1] = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
384 
385  opbinput->comment = FALSE;
386 
387  /* skip characters after comment symbol */
388  for( i = 0; commentchars[i] != '\0'; ++i )
389  {
390  char* commentstart;
391 
392  commentstart = strchr(opbinput->linebuf, commentchars[i]);
393  if( commentstart != NULL )
394  {
395  *commentstart = '\0';
396  *(commentstart+1) = '\0'; /* we want to use lookahead of one char -> we need two \0 at the end */
397  opbinput->comment = TRUE;
398  break;
399  }
400  }
401 
402  SCIPdebugMsg(scip, "%s\n", opbinput->linebuf);
403 
404  return TRUE;
405 }
406 
407 /** swaps the addresses of two pointers */
408 static
410  char** pointer1, /**< first pointer */
411  char** pointer2 /**< second pointer */
412  )
413 {
414  char* tmp;
415 
416  tmp = *pointer1;
417  *pointer1 = *pointer2;
418  *pointer2 = tmp;
419 }
420 
421 /** reads the next token from the input file into the token buffer; returns whether a token was read */
422 static
424  SCIP* scip, /**< SCIP data structure */
425  OPBINPUT* opbinput /**< OPB reading data */
426  )
427 {
428  SCIP_Bool hasdot;
429  OPBEXPTYPE exptype;
430  char* buf;
431  int tokenlen;
432 
433  assert(opbinput != NULL);
434  assert(opbinput->bufpos < OPB_MAX_LINELEN);
435 
436  /* check the token stack */
437  if( opbinput->npushedtokens > 0 )
438  {
439  swapPointers(&opbinput->token, &opbinput->pushedtokens[opbinput->npushedtokens-1]);
440  opbinput->npushedtokens--;
441  SCIPdebugMsg(scip, "(line %d) read token again: '%s'\n", opbinput->linenumber, opbinput->token);
442  return TRUE;
443  }
444 
445  /* skip delimiters */
446  buf = opbinput->linebuf;
447  while( isDelimChar(buf[opbinput->bufpos]) )
448  {
449  if( buf[opbinput->bufpos] == '\0' )
450  {
451  if( !getNextLine(scip, opbinput) )
452  {
453  SCIPdebugMsg(scip, "(line %d) end of file\n", opbinput->linenumber);
454  return FALSE;
455  }
456  assert(opbinput->bufpos == 0);
457  }
458  else
459  {
460  opbinput->bufpos++;
461  opbinput->linepos++;
462  }
463  }
464  assert(opbinput->bufpos < OPB_MAX_LINELEN);
465  assert(!isDelimChar(buf[opbinput->bufpos]));
466 
467  /* check if the token is a value */
468  hasdot = FALSE;
469  exptype = OPB_EXP_NONE;
470  if( isValueChar(buf[opbinput->bufpos], buf[opbinput->bufpos+1], TRUE, &hasdot, &exptype) )
471  {
472  /* read value token */
473  tokenlen = 0;
474  do
475  {
476  assert(tokenlen < OPB_MAX_LINELEN);
477  assert(!isDelimChar(buf[opbinput->bufpos]));
478  opbinput->token[tokenlen] = buf[opbinput->bufpos];
479  tokenlen++;
480  opbinput->bufpos++;
481  opbinput->linepos++;
482  }
483  while( isValueChar(buf[opbinput->bufpos], buf[opbinput->bufpos+1], FALSE, &hasdot, &exptype) );
484  }
485  else
486  {
487  /* read non-value token */
488  tokenlen = 0;
489  do
490  {
491  assert(tokenlen < OPB_MAX_LINELEN);
492  opbinput->token[tokenlen] = buf[opbinput->bufpos];
493  tokenlen++;
494  opbinput->bufpos++;
495  opbinput->linepos++;
496  if( tokenlen == 1 && isTokenChar(opbinput->token[0]) )
497  break;
498  }
499  while( !isDelimChar(buf[opbinput->bufpos]) && !isTokenChar(buf[opbinput->bufpos]) );
500 
501  /* if the token is an equation sense '<', '>', or '=', skip a following '='
502  * if the token is an equality token '=' and the next character is a '<' or '>',
503  * replace the token by the inequality sense
504  */
505  if( tokenlen >= 1
506  && (opbinput->token[tokenlen-1] == '<' || opbinput->token[tokenlen-1] == '>' || opbinput->token[tokenlen-1] == '=')
507  && buf[opbinput->bufpos] == '=' )
508  {
509  opbinput->bufpos++;
510  opbinput->linepos++;
511  }
512  else if( opbinput->token[tokenlen-1] == '=' && (buf[opbinput->bufpos] == '<' || buf[opbinput->bufpos] == '>') )
513  {
514  opbinput->token[tokenlen-1] = buf[opbinput->bufpos];
515  opbinput->bufpos++;
516  opbinput->linepos++;
517  }
518  }
519  assert(tokenlen < OPB_MAX_LINELEN);
520  opbinput->token[tokenlen] = '\0';
521 
522  SCIPdebugMsg(scip, "(line %d) read token: '%s'\n", opbinput->linenumber, opbinput->token);
523 
524  return TRUE;
525 }
526 
527 /** puts the current token on the token stack, such that it is read at the next call to getNextToken() */
528 static
530  OPBINPUT* opbinput /**< OPB reading data */
531  )
532 {
533  assert(opbinput != NULL);
534  assert(opbinput->npushedtokens < OPB_MAX_PUSHEDTOKENS);
535 
536  swapPointers(&opbinput->pushedtokens[opbinput->npushedtokens], &opbinput->token);
537  opbinput->npushedtokens++;
538 }
539 
540 /** puts the buffered token on the token stack, such that it is read at the next call to getNextToken() */
541 static
543  OPBINPUT* opbinput /**< OPB reading data */
544  )
545 {
546  assert(opbinput != NULL);
547  assert(opbinput->npushedtokens < OPB_MAX_PUSHEDTOKENS);
548 
549  swapPointers(&opbinput->pushedtokens[opbinput->npushedtokens], &opbinput->tokenbuf);
550  opbinput->npushedtokens++;
551 }
552 
553 /** swaps the current token with the token buffer */
554 static
556  OPBINPUT* opbinput /**< OPB reading data */
557  )
558 {
559  assert(opbinput != NULL);
560 
561  swapPointers(&opbinput->token, &opbinput->tokenbuf);
562 }
563 
564 /** checks whether the current token is a section identifier, and if yes, switches to the corresponding section */
565 static
567  OPBINPUT* opbinput /**< OPB reading data */
568  )
569 {
570  assert(opbinput != NULL);
571 
572  if( *(opbinput->token) == ';')
573  return TRUE;
574 
575  return FALSE;
576 }
577 
578 /** returns whether the current token is a sign */
579 static
581  OPBINPUT* opbinput, /**< OPB reading data */
582  int* sign /**< pointer to update the sign */
583  )
584 {
585  assert(opbinput != NULL);
586  assert(sign != NULL);
587  assert(*sign == +1 || *sign == -1);
588 
589  if( strlen(opbinput->token) == 1 )
590  {
591  assert(opbinput->token[1] == '\0');
592 
593  if( *opbinput->token == '+' )
594  return TRUE;
595  else if( *opbinput->token == '-' )
596  {
597  *sign *= -1;
598  return TRUE;
599  }
600  }
601 
602  return FALSE;
603 }
604 
605 /** returns whether the current token is a value */
606 static
608  SCIP* scip, /**< SCIP data structure */
609  OPBINPUT* opbinput, /**< OPB reading data */
610  SCIP_Real* value /**< pointer to store the value (unchanged, if token is no value) */
611  )
612 {
613  assert(opbinput != NULL);
614  assert(value != NULL);
615 
616  if( strcasecmp(opbinput->token, "INFINITY") == 0 || strcasecmp(opbinput->token, "INF") == 0 )
617  {
618  *value = SCIPinfinity(scip);
619  return TRUE;
620  }
621  else
622  {
623  double val;
624  char* endptr;
625 
626  val = strtod(opbinput->token, &endptr);
627  if( endptr != opbinput->token && *endptr == '\0' )
628  {
629  *value = val;
630  if( strlen(opbinput->token) > 18 )
631  opbinput->nproblemcoeffs++;
632  return TRUE;
633  }
634  }
635 
636  return FALSE;
637 }
638 
639 /** returns whether the current token is an equation sense */
640 static
642  OPBINPUT* opbinput, /**< OPB reading data */
643  OPBSENSE* sense /**< pointer to store the equation sense, or NULL */
644  )
645 {
646  assert(opbinput != NULL);
647 
648  if( strcmp(opbinput->token, "<") == 0 )
649  {
650  if( sense != NULL )
651  *sense = OPB_SENSE_LE;
652  return TRUE;
653  }
654  else if( strcmp(opbinput->token, ">") == 0 )
655  {
656  if( sense != NULL )
657  *sense = OPB_SENSE_GE;
658  return TRUE;
659  }
660  else if( strcmp(opbinput->token, "=") == 0 )
661  {
662  if( sense != NULL )
663  *sense = OPB_SENSE_EQ;
664  return TRUE;
665  }
666 
667  return FALSE;
668 }
669 
670 /** returns whether the current token is a value */
671 static
673  SCIP* scip, /**< SCIP data structure */
674  OPBINPUT* opbinput /**< OPB reading data */
675  )
676 {
677  assert(scip != NULL);
678  assert(opbinput != NULL);
679 
680  if( strcmp(opbinput->token, "[") == 0 )
681  return TRUE;
682 
683  return FALSE;
684 }
685 
686 /** returns whether the current token is a value */
687 static
689  SCIP* scip, /**< SCIP data structure */
690  OPBINPUT* opbinput /**< OPB reading data */
691  )
692 {
693  assert(scip != NULL);
694  assert(opbinput != NULL);
695 
696  if( strcmp(opbinput->token, "]") == 0 )
697  return TRUE;
698 
699  return FALSE;
700 }
701 
702 /** create binary variable with given name */
703 static
705  SCIP* scip, /**< SCIP data structure */
706  SCIP_VAR** var, /**< pointer to store the variable */
707  char* name /**< name for the variable */
708  )
709 {
710  SCIP_VAR* newvar;
711  SCIP_Bool dynamiccols;
712  SCIP_Bool initial;
713  SCIP_Bool removable;
714 
715  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
716  initial = !dynamiccols;
717  removable = dynamiccols;
718 
719  /* create new variable of the given name */
720  SCIPdebugMsg(scip, "creating new variable: <%s>\n", name);
721 
722  SCIP_CALL( SCIPcreateVar(scip, &newvar, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
723  initial, removable, NULL, NULL, NULL, NULL, NULL) );
724  SCIP_CALL( SCIPaddVar(scip, newvar) );
725  *var = newvar;
726 
727  /* because the variable was added to the problem, it is captured by SCIP and we
728  * can safely release it right now without making the returned *var invalid */
729  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
730 
731  return SCIP_OKAY;
732 }
733 
734 /** returns the variable with the given name, or creates a new variable if it does not exist */
735 static
737  SCIP* scip, /**< SCIP data structure */
738  OPBINPUT* opbinput, /**< OPB reading data */
739  SCIP_VAR*** vars, /**< pointer to store the variables */
740  int* nvars, /**< pointer to store the number of variables */
741  int* varssize /**< pointer to store the varsize, if changed (should already be initialized) */
742  )
743 {
744  SCIP_Bool negated;
745  char* name;
746 
747  assert(scip != NULL);
748  assert(opbinput != NULL);
749  assert(vars != NULL);
750  assert(nvars != NULL);
751  assert(varssize != NULL);
752  assert(*varssize >= 0);
753 
754  *nvars = 0;
755 
756  name = opbinput->token;
757  assert(name != NULL);
758 
759  /* parse AND terms */
760  while(!isdigit((unsigned char) *name ) && !isTokenChar(*name) && !opbinput->haserror )
761  {
762  SCIP_VAR* var;
763 
764  negated = FALSE;
765  if( *name == '~' )
766  {
767  negated = TRUE;
768  ++name;
769  }
770 
771  var = SCIPfindVar(scip, name);
772  if( var == NULL )
773  {
774  SCIP_CALL( createVariable(scip, &var, name) );
775  }
776 
777  if( negated )
778  {
779  SCIP_VAR* negvar;
780  SCIP_CALL( SCIPgetNegatedVar(scip, var, &negvar) );
781 
782  var = negvar;
783  }
784 
785  /* reallocated memory */
786  if( *nvars == *varssize )
787  {
788  *varssize = SCIPcalcMemGrowSize(scip, *varssize + 1);
789  SCIP_CALL( SCIPreallocBufferArray(scip, vars, *varssize) );
790  }
791 
792  (*vars)[*nvars] = var;
793  ++(*nvars);
794 
795  if( !getNextToken(scip, opbinput) )
796  opbinput->haserror = TRUE;
797 
798  name = opbinput->token;
799  }
800 
801  /* check if we found at least on variable */
802  if( *nvars == 0 )
803  syntaxError(scip, opbinput, "expected a variable name");
804 
805  pushToken(opbinput);
806 
807  return SCIP_OKAY;
808 }
809 
810 /** reads an objective or constraint with name and coefficients */
811 static
813  SCIP*const scip, /**< SCIP data structure */
814  OPBINPUT*const opbinput, /**< OPB reading data */
815  char*const name, /**< pointer to store the name of the line; must be at least of size
816  * OPB_MAX_LINELEN */
817  SCIP_VAR*** linvars, /**< pointer to store the array with linear variables (must be freed by caller) */
818  SCIP_Real** lincoefs, /**< pointer to store the array with linear coefficients (must be freed by caller) */
819  int*const nlincoefs, /**< pointer to store the number of linear coefficients */
820  SCIP_VAR**** terms, /**< pointer to store the array with nonlinear variables (must be freed by caller) */
821  SCIP_Real** termcoefs, /**< pointer to store the array with nonlinear coefficients (must be freed by caller) */
822  int** ntermvars, /**< pointer to store the number of nonlinear variables in the terms (must be freed by caller) */
823  int*const ntermcoefs, /**< pointer to store the number of nonlinear coefficients */
824  SCIP_Bool*const newsection, /**< pointer to store whether a new section was encountered */
825  SCIP_Bool*const isNonlinear, /**< pointer to store if we have a nonlinear constraint */
826  SCIP_Bool*const issoftcons, /**< pointer to store whether it is a soft constraint (for wbo files) */
827  SCIP_Real*const weight /**< pointer to store the weight of the soft constraint */
828  )
829 {
830  SCIP_VAR** tmpvars;
831  SCIP_Real* tmpcoefs;
832  SCIP_Bool havesign;
833  SCIP_Bool havevalue;
834  SCIP_Bool haveweightstart;
835  SCIP_Bool haveweightend;
836  SCIP_Real coef;
837  int coefsign;
838  int lincoefssize;
839  int termcoefssize;
840  int tmpvarssize;
841  int ntmpcoefs;
842  int ntmpvars;
843 
844  assert(opbinput != NULL);
845  assert(name != NULL);
846  assert(linvars != NULL);
847  assert(lincoefs != NULL);
848  assert(nlincoefs != NULL);
849  assert(terms != NULL);
850  assert(termcoefs != NULL);
851  assert(ntermvars != NULL);
852  assert(ntermcoefs != NULL);
853  assert(newsection != NULL);
854 
855  *linvars = NULL;
856  *lincoefs = NULL;
857  *terms = NULL;
858  *termcoefs = NULL;
859  *ntermvars = NULL;
860  *name = '\0';
861  *nlincoefs = 0;
862  *ntermcoefs = 0;
863  *newsection = FALSE;
864  *isNonlinear = FALSE;
865  *issoftcons = FALSE;
866 
867  SCIPdebugMsg(scip, "read coefficients\n");
868 
869  /* read the first token, which may be the name of the line */
870  if( getNextToken(scip, opbinput) )
871  {
872  /* remember the token in the token buffer */
873  swapTokenBuffer(opbinput);
874 
875  /* get the next token and check, whether it is a colon */
876  if( getNextToken(scip, opbinput) )
877  {
878  if( strcmp(opbinput->token, ":") == 0 )
879  {
880  /* the second token was a colon ':' the first token is a constraint name */
881  (void)SCIPmemccpy(name, opbinput->tokenbuf, '\0', SCIP_MAXSTRLEN);
882 
883  name[SCIP_MAXSTRLEN-1] = '\0';
884  SCIPdebugMsg(scip, "(line %d) read constraint name: '%s'\n", opbinput->linenumber, name);
885 
886  /* all but the first coefficient need a sign */
887  if( strcmp(name, "soft") == 0 && (SCIPgetNVars(scip) > 0 || SCIPgetNConss(scip) > 0) )
888  {
889  syntaxError(scip, opbinput, "Soft top cost line needs to be the first non-comment line, and without any objective function.\n");
890  return SCIP_OKAY;
891  }
892  }
893  else
894  {
895  /* the second token was no colon: push the tokens back onto the token stack and parse them as coefficients */
896  SCIPdebugMsg(scip, "(line %d) constraint has no name\n", opbinput->linenumber);
897  pushToken(opbinput);
898  pushBufferToken(opbinput);
899  }
900  }
901  else
902  {
903  /* there was only one token left: push it back onto the token stack and parse it as coefficient */
904  pushBufferToken(opbinput);
905  }
906  }
907  else
908  {
909  assert(SCIPfeof( opbinput->file ) );
910  opbinput->eof = TRUE;
911  return SCIP_OKAY;
912  }
913 
914  /* initialize buffers for storing the coefficients */
915  lincoefssize = OPB_INIT_COEFSSIZE;
916  termcoefssize = OPB_INIT_COEFSSIZE;
917  tmpvarssize = OPB_INIT_COEFSSIZE;
918  SCIP_CALL( SCIPallocBufferArray(scip, linvars, lincoefssize) );
919  SCIP_CALL( SCIPallocBufferArray(scip, lincoefs, lincoefssize) );
920  SCIP_CALL( SCIPallocBufferArray(scip, terms, termcoefssize) );
921  SCIP_CALL( SCIPallocBufferArray(scip, termcoefs, termcoefssize) );
922  SCIP_CALL( SCIPallocBufferArray(scip, ntermvars, termcoefssize) );
923  SCIP_CALL( SCIPallocBufferArray(scip, &tmpvars, tmpvarssize) );
924  SCIP_CALL( SCIPallocBufferArray(scip, &tmpcoefs, tmpvarssize) );
925 
926  /* read the coefficients */
927  coefsign = +1;
928  coef = 1.0;
929  havesign = FALSE;
930  havevalue = FALSE;
931  haveweightstart = FALSE;
932  haveweightend = FALSE;
933  ntmpcoefs = 0;
934  ntmpvars = 0;
935  while( getNextToken(scip, opbinput) && !hasError(opbinput) )
936  {
937  if( isEndLine(opbinput) )
938  {
939  *newsection = TRUE;
940  goto TERMINATE;
941  }
942 
943  /* check if we reached an equation sense */
944  if( isSense(opbinput, NULL) )
945  {
946  /* put the sense back onto the token stack */
947  pushToken(opbinput);
948  goto TERMINATE;
949  }
950 
951  /* check if we read a sign */
952  if( isSign(opbinput, &coefsign) )
953  {
954  SCIPdebugMsg(scip, "(line %d) read coefficient sign: %+d\n", opbinput->linenumber, coefsign);
955  havesign = TRUE;
956  continue;
957  }
958 
959  /* check if we read a value */
960  if( isValue(scip, opbinput, &coef) )
961  {
962  /* coefficients without a sign are treated as "+" */
963  if( (*nlincoefs > 0 || *ntermcoefs > 0 || ntmpcoefs > 0) && !havesign )
964  {
965  coefsign = 1;
966  havesign = TRUE;
967  }
968 
969  SCIPdebugMsg(scip, "(line %d) read coefficient value: %g with sign %+d\n", opbinput->linenumber, coef, coefsign);
970  if( havevalue )
971  {
972  syntaxError(scip, opbinput, "two consecutive values");
973  goto TERMINATE;
974  }
975  havevalue = TRUE;
976 
977  /* if we read a wbo file, the first line should be something like "soft: <weight>;", where weight is a value or nothing */
978  if( strcmp(name, "soft") == 0 )
979  {
980  assert(ntmpcoefs == 0);
981 
982  tmpcoefs[ntmpcoefs] = coefsign * coef;
983  ++ntmpcoefs;
984  }
985 
986  continue;
987  }
988 
989  /* check if we are reading a soft constraint line, it start with "[<weight>]", where weight is a value */
990  if( *nlincoefs == 0 && *ntermcoefs == 0 && ntmpcoefs == 0 && !havesign && !havevalue && strcmp(name, "soft") != 0 && isStartingSoftConstraintWeight(scip, opbinput) )
991  {
992  if( !opbinput->wbo )
993  {
994  SCIPwarningMessage(scip, "Found in line %d a soft constraint, without having read a starting top-cost line.\n", opbinput->linenumber);
995  }
996  haveweightstart = TRUE;
997 
998  continue;
999  }
1000  if( *nlincoefs == 0 && *ntermcoefs == 0 && ntmpcoefs == 0 && havevalue && haveweightstart && isEndingSoftConstraintWeight(scip, opbinput) )
1001  {
1002  *weight = coefsign * coef;
1003  SCIPdebugMsg(scip, "(line %d) found soft constraint weight: %g\n", opbinput->linenumber, *weight);
1004 
1005  coefsign = +1;
1006  havesign = FALSE;
1007  havevalue = FALSE;
1008  haveweightend = TRUE;
1009  *issoftcons = TRUE;
1010 
1011  continue;
1012  }
1013 
1014  /* if we read a '[' we should already read a ']', which indicates that we read a soft constraint,
1015  * we have a parsing error */
1016  if( haveweightstart != haveweightend )
1017  {
1018  syntaxError(scip, opbinput, "Wrong soft constraint.");
1019  goto TERMINATE;
1020  }
1021 
1022  /* if we read the first non-comment line of a wbo file we should never be here */
1023  if( strcmp(name, "soft") == 0 )
1024  {
1025  syntaxError(scip, opbinput, "Wrong soft top cost line.");
1026  goto TERMINATE;
1027  }
1028 
1029  /* the token is a variable name: get the corresponding variables (or create a new ones) */
1030  SCIP_CALL( getVariableOrTerm(scip, opbinput, &tmpvars, &ntmpvars, &tmpvarssize) );
1031 
1032  if( ntmpvars > 1 )
1033  {
1034  /* insert non-linear term */
1035  *isNonlinear = TRUE;
1036 
1037  SCIPdebugMsg(scip, "(line %d) found linear term: %+g", opbinput->linenumber, coefsign * coef);
1038 #ifndef NDEBUG
1039  {
1040  int v;
1041  for( v = 0; v < ntmpvars; ++v )
1042  {
1043  SCIPdebugMsgPrint(scip, " %s * ", SCIPvarGetName(tmpvars[v]));
1044  }
1045  SCIPdebugMsgPrint(scip, "\n");
1046  }
1047 #endif
1048  if( !SCIPisZero(scip, coef) )
1049  {
1050  assert(*ntermcoefs <= termcoefssize);
1051  /* resize the terms, ntermvars, and termcoefs array if needed */
1052  if( *ntermcoefs == termcoefssize )
1053  {
1054  termcoefssize = SCIPcalcMemGrowSize(scip, termcoefssize + 1);
1055  SCIP_CALL( SCIPreallocBufferArray(scip, terms, termcoefssize) );
1056  SCIP_CALL( SCIPreallocBufferArray(scip, termcoefs, termcoefssize) );
1057  SCIP_CALL( SCIPreallocBufferArray(scip, ntermvars, termcoefssize) );
1058  }
1059  assert(*ntermcoefs < termcoefssize);
1060 
1061  /* get memory for the last term */
1062  SCIP_CALL( SCIPallocBufferArray(scip, &((*terms)[*ntermcoefs]), ntmpvars) ); /*lint !e866 */
1063 
1064  /* set the number of variable in this term */
1065  (*ntermvars)[*ntermcoefs] = ntmpvars;
1066 
1067  /* add all variables */
1068  for( --ntmpvars; ntmpvars >= 0; --ntmpvars )
1069  {
1070  (*terms)[*ntermcoefs][ntmpvars] = tmpvars[ntmpvars];
1071  }
1072  /* add coefficient */
1073  (*termcoefs)[*ntermcoefs] = coefsign * coef;
1074 
1075  /***********************/
1076  if( !SCIPisIntegral(scip, (*termcoefs)[*ntermcoefs]) )
1077  {
1078  SCIPwarningMessage(scip, "coefficient %g in line %d not integral.\n", (*termcoefs)[*ntermcoefs], opbinput->linenumber);
1079  }
1080 
1081  ++(*ntermcoefs);
1082  }
1083 
1084  /* reset the flags and coefficient value for the next coefficient */
1085  coefsign = +1;
1086  coef = 1.0;
1087  havesign = FALSE;
1088  havevalue = FALSE;
1089  ntmpvars = 0;
1090  }
1091  else
1092  {
1093  assert(ntmpvars == 1);
1094  /* insert linear term */
1095  SCIPdebugMsg(scip, "(line %d) found linear term: %+g<%s>\n", opbinput->linenumber, coefsign * coef, SCIPvarGetName(tmpvars[0]));
1096  if( !SCIPisZero(scip, coef) )
1097  {
1098  assert(*nlincoefs <= lincoefssize);
1099  /* resize the vars and coefs array if needed */
1100  if( *nlincoefs >= lincoefssize )
1101  {
1102  lincoefssize = SCIPcalcMemGrowSize(scip, lincoefssize + 1);
1103  SCIP_CALL( SCIPreallocBufferArray(scip, linvars, lincoefssize) );
1104  SCIP_CALL( SCIPreallocBufferArray(scip, lincoefs, lincoefssize) );
1105  }
1106  assert(*nlincoefs < lincoefssize);
1107 
1108  /* add coefficient */
1109  (*linvars)[*nlincoefs] = tmpvars[0];
1110  (*lincoefs)[*nlincoefs] = coefsign * coef;
1111 
1112  /***********************/
1113  if( !SCIPisIntegral(scip, (*lincoefs)[*nlincoefs]) )
1114  {
1115  SCIPwarningMessage(scip, "coefficient %g in line %d not integral.\n", (*lincoefs)[*nlincoefs], opbinput->linenumber);
1116  }
1117 
1118  ++(*nlincoefs);
1119  }
1120 
1121  /* reset the flags and coefficient value for the next coefficient */
1122  coefsign = +1;
1123  coef = 1.0;
1124  havesign = FALSE;
1125  havevalue = FALSE;
1126  ntmpvars = 0;
1127  }
1128  }
1129 
1130  TERMINATE:
1131  if( !opbinput->haserror )
1132  {
1133  /* all variables should be in the right arrays */
1134  assert(ntmpvars == 0);
1135  /* the following is only the case if we read topcost's of a wbo file, we need to move this topcost value to the
1136  * right array */
1137  if( ntmpcoefs > 0 )
1138  {
1139  /* maximal one topcost value is possible */
1140  assert(ntmpcoefs == 1);
1141  /* no other coefficient should be found here */
1142  assert(*nlincoefs == 0 && *ntermcoefs == 0);
1143 
1144  /* copy value */
1145  (*lincoefs)[*nlincoefs] = tmpcoefs[0];
1146 
1147  /***********************/
1148  if( !SCIPisIntegral(scip, (*lincoefs)[*nlincoefs]) )
1149  {
1150  SCIPwarningMessage(scip, "topcost not integral.\n");
1151  }
1152 
1153  *nlincoefs = 1;
1154  }
1155  }
1156  /* clear memory */
1157  SCIPfreeBufferArray(scip, &tmpcoefs);
1158  SCIPfreeBufferArray(scip, &tmpvars);
1159 
1160  return SCIP_OKAY;
1161 }
1162 
1163 /** set the objective section */
1164 static
1166  SCIP*const scip, /**< SCIP data structure */
1167  OPBINPUT*const opbinput, /**< OPB reading data */
1168  const char* sense, /**< objective sense */
1169  SCIP_VAR**const linvars, /**< array of linear variables */
1170  SCIP_Real*const coefs, /**< array of objective values for linear variables */
1171  int const ncoefs, /**< number of coefficients for linear part */
1172  SCIP_VAR***const terms, /**< array with nonlinear variables */
1173  SCIP_Real*const termcoefs, /**< array of objective values for nonlinear variables */
1174  int*const ntermvars, /**< number of nonlinear variables in the terms */
1175  int const ntermcoefs /**< number of nonlinear coefficients */
1176  )
1177 {
1178  assert(scip != NULL);
1179  assert(opbinput != NULL);
1180  assert(isEndLine(opbinput));
1181  assert(ncoefs == 0 || (linvars != NULL && coefs != NULL));
1182  assert(ntermcoefs == 0 || (terms != NULL && ntermvars != NULL && termcoefs != NULL));
1183 
1184  if( !hasError(opbinput) )
1185  {
1186  SCIP_VAR* var;
1187  int v;
1188  char name[SCIP_MAXSTRLEN];
1189 
1190  if( strcmp(sense, "max" ) == 0 )
1191  opbinput->objsense = SCIP_OBJSENSE_MAXIMIZE;
1192 
1193  /* @todo: what todo with non-linear objectives, maybe create the necessary and-constraints and add the arising linear
1194  * objective (with and-resultants) or add a integer variable to this constraint and put only this variable in the
1195  * objective, for this we need to expand the pseudo-boolean constraints to handle integer variables
1196  *
1197  * integer variant is not implemented
1198  */
1199  if( ntermcoefs > 0 )
1200  {
1201 #if (LINEAROBJECTIVE == TRUE)
1202  /* all non-linear parts are created as and-constraints, even if the same non-linear part was already part of the objective function */
1203 
1204  SCIP_VAR** vars;
1205  int nvars;
1206  int t;
1207  SCIP_CONS* andcons;
1208 
1209  for( t = 0; t < ntermcoefs; ++t )
1210  {
1211  assert(terms != NULL); /* for lint */
1212  assert(ntermvars != NULL);
1213  assert(termcoefs != NULL);
1214 
1215  vars = terms[t];
1216  nvars = ntermvars[t];
1217  assert(vars != NULL);
1218  assert(nvars > 1);
1219 
1220  /* create auxiliary variable */
1221  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, ARTIFICIALVARNAMEPREFIX"obj_%d", t);
1222  SCIP_CALL( SCIPcreateVar(scip, &var, name, 0.0, 1.0, termcoefs[t], SCIP_VARTYPE_BINARY,
1223  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
1224 
1225  /* @todo: check if it is better to change the branching priority for the artificial variables */
1226 #if 1
1227  /* change branching priority of artificial variable to -1 */
1228  SCIP_CALL( SCIPchgVarBranchPriority(scip, var, -1) );
1229 #endif
1230 
1231  /* add auxiliary variable to the problem */
1232  SCIP_CALL( SCIPaddVar(scip, var) );
1233 
1234 #ifdef WITH_DEBUG_SOLUTION
1235  if( SCIPdebugIsMainscip(scip) )
1236  {
1237  SCIP_Real val = 0.0;
1238 
1239  for( v = nvars - 1; v >= 0; --v )
1240  {
1241  SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
1242  assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
1243 
1244  if( val < 0.5 )
1245  break;
1246  }
1247  SCIP_CALL( SCIPdebugAddSolVal(scip, var, (val < 0.5) ? 0.0 : 1.0) );
1248  }
1249 #endif
1250 
1251  /* @todo: check whether all constraint creation flags are the best option */
1252  /* create and-constraint */
1253  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "obj_andcons_%d", t);
1254  SCIP_CALL( SCIPcreateConsAnd(scip, &andcons, name, var, nvars, vars,
1255  TRUE, TRUE, TRUE, TRUE, TRUE,
1256  FALSE, FALSE, FALSE, FALSE, FALSE) );
1257  SCIP_CALL( SCIPaddCons(scip, andcons) );
1258  SCIPdebugPrintCons(scip, andcons, NULL);
1259  SCIP_CALL( SCIPreleaseCons(scip, &andcons) );
1260 
1261  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1262  }
1263 #else /* now the integer variant */
1264  SCIP_CONS* pseudocons;
1265  SCIP_Real lb;
1266  SCIP_Real ub;
1267 
1268  lb = 0.0;
1269  ub = 0.0;
1270 
1271  /* add all non linear coefficients up */
1272  for( v = 0; v < ntermcoefs; ++v )
1273  {
1274  if( termcoefs[v] < 0 )
1275  lb += termcoefs[v];
1276  else
1277  ub += termcoefs[v];
1278  }
1279  /* add all linear coefficients up */
1280  for( v = 0; v < ncoefs; ++v )
1281  {
1282  if( coefs[v] < 0 )
1283  lb += coefs[v];
1284  else
1285  ub += coefs[v];
1286  }
1287  assert(lb < ub);
1288 
1289  /* create auxiliary variable */
1290  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "artificial_int_obj");
1291  SCIP_CALL( SCIPcreateVar(scip, &var, name, lb, ub, 1.0, SCIP_VARTYPE_INTEGER,
1292  TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
1293 
1294  /* @todo: check if it is better to change the branching priority for the artificial variables */
1295 #if 1
1296  /* change branching priority of artificial variable to -1 */
1297  SCIP_CALL( SCIPchgVarBranchPriority(scip, var, -1) );
1298 #endif
1299  /* add auxiliary variable to the problem */
1300  SCIP_CALL( SCIPaddVar(scip, var) );
1301 
1302 #ifdef WITH_DEBUG_SOLUTION
1303  if( SCIPdebugIsMainscip(scip) )
1304  {
1305  SCIP_Real artval = 0.0;
1306  SCIP_Real val;
1307 
1308  for( t = 0; t < ntermcoefs; ++t )
1309  {
1310  vars = terms[t];
1311  nvars = ntermvars[t];
1312  assert(vars != NULL);
1313  assert(nvars > 1);
1314 
1315  for( v = nvars - 1; v >= 0; --v )
1316  {
1317  SCIP_CALL( SCIPdebugGetSolVal(scip, vars[v], &val) );
1318  assert(SCIPisFeasZero(scip, val) || SCIPisFeasEQ(scip, val, 1.0));
1319 
1320  if( val < 0.5 )
1321  break;
1322  }
1323 
1324  artval += (((val < 0.5) ? 0.0 : 1.0) * termcoefs[t]);
1325  }
1326  assert(SCIPisFeasLE(scip, lb, artval) && SCIPisFeasGE(scip, ub, artval));
1327 
1328  SCIP_CALL( SCIPdebugAddSolVal(scip, var, artval) );
1329  }
1330 #endif
1331 
1332  /* create artificial objection function constraint containing the artificial integer variable */
1333  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "artificial_obj_cons");
1334  SCIP_CALL( SCIPcreateConsPseudoboolean(scip, &pseudocons, name, linvars, ncoefs, coefs, terms, ntermcoefs,
1335  ntermvars, termcoefs, NULL, 0.0, FALSE, var, 0.0, 0.0,
1336  TRUE, TRUE, TRUE, TRUE, TRUE,
1337  FALSE, FALSE, FALSE, FALSE, FALSE) );
1338 
1339  SCIP_CALL( SCIPaddCons(scip, pseudocons) );
1340  SCIPdebugPrintCons(scip, pseudocons, NULL);
1341  SCIP_CALL( SCIPreleaseCons(scip, &pseudocons) );
1342 
1343  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1344 
1345  return SCIP_OKAY;
1346 #endif
1347  }
1348  /* set the objective values */
1349  for( v = 0; v < ncoefs; ++v )
1350  {
1351  assert(linvars != NULL); /* for lint */
1352  assert(coefs != NULL);
1353 
1354  if( SCIPvarIsNegated(linvars[v]) )
1355  {
1356  SCIP_VAR* negvar = SCIPvarGetNegationVar(linvars[v]);
1357 
1358  SCIP_CALL( SCIPaddOrigObjoffset(scip, coefs[v]) );
1359  SCIP_CALL( SCIPchgVarObj(scip, negvar, SCIPvarGetObj(negvar) - coefs[v]) );
1360  }
1361  else
1362  {
1363  SCIP_CALL( SCIPchgVarObj(scip, linvars[v], SCIPvarGetObj(linvars[v]) + coefs[v]) );
1364  }
1365  }
1366  }
1367 
1368  return SCIP_OKAY;
1369 }
1370 
1371 /** reads the constraints section */
1372 static
1374  SCIP* scip, /**< SCIP data structure */
1375  OPBINPUT* opbinput, /**< OPB reading data */
1376  int* nNonlinearConss /**< pointer to store number of nonlinear constraints */
1377  )
1378 {
1379  char name[OPB_MAX_LINELEN];
1380  SCIP_CONS* cons;
1381  SCIP_VAR** linvars;
1382  SCIP_Real* lincoefs;
1383  int nlincoefs;
1384  SCIP_VAR*** terms;
1385  SCIP_Real* termcoefs;
1386  int* ntermvars;
1387  int ntermcoefs;
1388  OPBSENSE sense;
1389  SCIP_RETCODE retcode;
1390  SCIP_Real sidevalue;
1391  SCIP_Real lhs;
1392  SCIP_Real rhs;
1393  SCIP_Bool newsection;
1394  SCIP_Bool initialconss;
1395  SCIP_Bool dynamicconss;
1396  SCIP_Bool dynamicrows;
1397  SCIP_Bool initial;
1398  SCIP_Bool separate;
1399  SCIP_Bool enforce;
1400  SCIP_Bool check;
1401  SCIP_Bool propagate;
1402  SCIP_Bool local;
1403  SCIP_Bool modifiable;
1404  SCIP_Bool dynamic;
1405  SCIP_Bool removable;
1406  SCIP_Bool isNonlinear;
1407  int sidesign;
1408  SCIP_Bool issoftcons;
1409  SCIP_Real weight;
1410  SCIP_VAR* indvar;
1411  char indname[SCIP_MAXSTRLEN];
1412  int t;
1413 
1414  assert(scip != NULL);
1415  assert(opbinput != NULL);
1416  assert(nNonlinearConss != NULL);
1417 
1418  weight = -SCIPinfinity(scip);
1419  retcode = SCIP_OKAY;
1420 
1421  /* read the objective coefficients */
1422  SCIP_CALL( readCoefficients(scip, opbinput, name, &linvars, &lincoefs, &nlincoefs, &terms, &termcoefs, &ntermvars, &ntermcoefs, &newsection, &isNonlinear, &issoftcons, &weight) );
1423 
1424  if( hasError(opbinput) || opbinput->eof )
1425  goto TERMINATE;
1426  if( newsection )
1427  {
1428  if( strcmp(name, "min") == 0 || strcmp(name, "max") == 0 )
1429  {
1430  if( opbinput->wbo )
1431  {
1432  syntaxError(scip, opbinput, "Cannot have an objective function when having soft constraints.\n");
1433  goto TERMINATE;
1434  }
1435 
1436  /* set objective function */
1437  SCIP_CALL( setObjective(scip, opbinput, name, linvars, lincoefs, nlincoefs, terms, termcoefs, ntermvars, ntermcoefs) );
1438  }
1439  else if( strcmp(name, "soft") == 0 )
1440  {
1441  /* we have a "weighted boolean optimization"-file(wbo) */
1442  opbinput->wbo = TRUE;
1443  if( nlincoefs == 0 )
1444  opbinput->topcost = SCIPinfinity(scip);
1445  else
1446  {
1447  assert(nlincoefs == 1);
1448  assert(lincoefs != NULL);
1449  opbinput->topcost = lincoefs[0];
1450  }
1451  SCIPdebugMsg(scip, "Weighted Boolean Optimization problem has topcost of %g\n", opbinput->topcost);
1452  }
1453  else if( nlincoefs > 0 )
1454  syntaxError(scip, opbinput, "expected constraint sense '=' or '>='");
1455  goto TERMINATE;
1456  }
1457 
1458  /* read the constraint sense */
1459  if( !getNextToken(scip, opbinput) )
1460  {
1461  syntaxError(scip, opbinput, "expected constraint sense.");
1462  goto TERMINATE;
1463  }
1464  if( !isSense(opbinput, &sense) )
1465  {
1466  syntaxError(scip, opbinput, "expected constraint sense '=' or '>='.");
1467  goto TERMINATE;
1468  }
1469 
1470  /* read the right hand side */
1471  sidesign = +1;
1472  if( !getNextToken(scip, opbinput) )
1473  {
1474  syntaxError(scip, opbinput, "missing right hand side");
1475  goto TERMINATE;
1476  }
1477  if( isSign(opbinput, &sidesign) )
1478  {
1479  if( !getNextToken(scip, opbinput) )
1480  {
1481  syntaxError(scip, opbinput, "missing value of right hand side");
1482  goto TERMINATE;
1483  }
1484  }
1485  if( !isValue(scip, opbinput, &sidevalue) )
1486  {
1487  syntaxError(scip, opbinput, "expected value as right hand side");
1488  goto TERMINATE;
1489  }
1490  sidevalue *= sidesign;
1491 
1492  /* check if we reached the line end */
1493  if( !getNextToken(scip, opbinput) || !isEndLine(opbinput) )
1494  {
1495  syntaxError(scip, opbinput, "expected endline character ';'");
1496  goto TERMINATE;
1497  }
1498 
1499  /* assign the left and right hand side, depending on the constraint sense */
1500  switch( sense ) /*lint !e530*/
1501  {
1502  case OPB_SENSE_GE:
1503  lhs = sidevalue;
1504  rhs = SCIPinfinity(scip);
1505  break;
1506  case OPB_SENSE_LE:
1507  lhs = -SCIPinfinity(scip);
1508  rhs = sidevalue;
1509  break;
1510  case OPB_SENSE_EQ:
1511  lhs = sidevalue;
1512  rhs = sidevalue;
1513  break;
1514  case OPB_SENSE_NOTHING:
1515  default:
1516  SCIPerrorMessage("invalid constraint sense <%d>\n", sense);
1517  return SCIP_INVALIDDATA;
1518  }
1519 
1520  /* create and add the linear constraint */
1521  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &initialconss) );
1522  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
1523  SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/dynamicconss", &dynamicconss) );
1524 
1525  initial = initialconss;
1526  separate = TRUE;
1527  enforce = TRUE;
1528  check = TRUE;
1529  propagate = TRUE;
1530  local = FALSE;
1531  modifiable = FALSE;
1532  dynamic = FALSE;/*dynamicconss;*/
1533  removable = dynamicrows;
1534 
1535  /* create corresponding constraint */
1536  if( issoftcons )
1537  {
1538  (void) SCIPsnprintf(indname, SCIP_MAXSTRLEN, INDICATORVARNAME"%d", opbinput->nindvars);
1539  ++(opbinput->nindvars);
1540  SCIP_CALL( createVariable(scip, &indvar, indname) );
1541 
1542  assert(!SCIPisInfinity(scip, -weight));
1543  SCIP_CALL( SCIPchgVarObj(scip, indvar, weight) );
1544  }
1545  else
1546  indvar = NULL;
1547 
1548  if( ntermcoefs > 0 || issoftcons )
1549  {
1550 #if GENCONSNAMES == TRUE
1551  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean%d", opbinput->consnumber);
1552  ++(opbinput->consnumber);
1553 #else
1554  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "pseudoboolean");
1555 #endif
1556  retcode = SCIPcreateConsPseudoboolean(scip, &cons, name, linvars, nlincoefs, lincoefs, terms, ntermcoefs,
1557  ntermvars, termcoefs, indvar, weight, issoftcons, NULL, lhs, rhs,
1558  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1559  if( retcode != SCIP_OKAY )
1560  goto TERMINATE;
1561  }
1562  else
1563  {
1564 #if GENCONSNAMES == TRUE
1565  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear%d", opbinput->consnumber);
1566  ++(opbinput->consnumber);
1567 #else
1568  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "linear");
1569 #endif
1570  retcode = SCIPcreateConsLinear(scip, &cons, name, nlincoefs, linvars, lincoefs, lhs, rhs,
1571  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE);
1572  if( retcode != SCIP_OKAY )
1573  goto TERMINATE;
1574  }
1575 
1576  SCIP_CALL( SCIPaddCons(scip, cons) );
1577  SCIPdebugMsg(scip, "(line %d) created constraint: ", opbinput->linenumber);
1578  SCIPdebugPrintCons(scip, cons, NULL);
1579  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1580 
1581  if( isNonlinear )
1582  ++(*nNonlinearConss);
1583 
1584  TERMINATE:
1585 
1586  /* free memory */
1587  for( t = ntermcoefs - 1; t >= 0; --t )
1588  {
1589  assert(terms != NULL); /* for lint */
1590  SCIPfreeBufferArrayNull(scip, &(terms[t]));
1591  }
1592 
1593  SCIPfreeBufferArrayNull(scip, &ntermvars);
1594  SCIPfreeBufferArrayNull(scip, &termcoefs);
1595  SCIPfreeBufferArrayNull(scip, &terms);
1596  SCIPfreeBufferArrayNull(scip, &lincoefs);
1597  SCIPfreeBufferArrayNull(scip, &linvars);
1598 
1599  SCIP_CALL( retcode );
1600 
1601  return SCIP_OKAY;
1602 }
1603 
1604 /** tries to read the first comment line which usually contains information about the max size of "and" products */
1605 static
1607  SCIP* scip, /**< SCIP data structure */
1608  OPBINPUT* opbinput, /**< OPB reading data */
1609  const char* filename, /**< name of the input file */
1610  SCIP_Real* objoffset /**< pointer to store objective offset */
1611  )
1612 {
1613  SCIP_Bool stop;
1614  char* commentstart;
1615  char* nproducts;
1616  char* str;
1617  int i;
1618 
1619  assert(scip != NULL);
1620  assert(opbinput != NULL);
1621  assert(objoffset != NULL);
1622 
1623  stop = FALSE;
1624  commentstart = NULL;
1625  nproducts = NULL;
1626 
1627  *objoffset = 0.0;
1628 
1629  do
1630  {
1631  if( SCIPfgets(opbinput->linebuf, (int) sizeof(opbinput->linebuf), opbinput->file) == NULL )
1632  {
1633  assert(SCIPfeof( opbinput->file ) );
1634  break;
1635  }
1636 
1637  /* read characters after comment symbol */
1638  for( i = 0; commentchars[i] != '\0'; ++i )
1639  {
1640  commentstart = strchr(opbinput->linebuf, commentchars[i]);
1641 
1642  /* found a comment line */
1643  if( commentstart != NULL )
1644  {
1645  /* search for "#product= xyz" in comment line, where xyz represents the number of and constraints */
1646  nproducts = strstr(opbinput->linebuf, "#product= ");
1647  if( nproducts != NULL )
1648  {
1649  const char delimchars[] = " \t";
1650  char* pos;
1651 
1652  nproducts += strlen("#product= ");
1653 
1654  pos = strtok(nproducts, delimchars);
1655 
1656  if( pos != NULL )
1657  {
1658  SCIPdebugMsg(scip, "%d products supposed to be in file.\n", atoi(pos));
1659  }
1660 
1661  pos = strtok (NULL, delimchars);
1662 
1663  if( pos != NULL && strcmp(pos, "sizeproduct=") == 0 )
1664  {
1665  pos = strtok (NULL, delimchars);
1666  if( pos != NULL )
1667  {
1668  SCIPdebugMsg(scip, "sizeproducts = %d\n", atoi(pos));
1669  }
1670  }
1671 
1672  stop = TRUE;
1673  }
1674 
1675  /* search for "Obj. offset : <number>" in comment line */
1676  str = strstr(opbinput->linebuf, "Obj. offset : ");
1677  if( str != NULL )
1678  {
1679  str += strlen("Obj. offset : ");
1680  *objoffset = atof(str);
1681  break;
1682  }
1683 
1684  break;
1685  }
1686  }
1687  }
1688  while(commentstart != NULL && !stop);
1689 
1690  opbinput->linebuf[0] = '\0';
1691 
1692 #if 0 /* following lines should be correct, but it seems that gzseek does not reset the position if standing at the end of a file */
1693  /* reset filereader pointer to the beginning */
1694  (void) SCIPfseek(opbinput->file, 0, SEEK_SET);
1695 #else
1696  SCIPfclose(opbinput->file);
1697  opbinput->file = SCIPfopen(filename, "r");
1698 #endif
1699 
1700  return SCIP_OKAY;
1701 }
1702 
1703 /** reads an OPB file */
1704 static
1706  SCIP* scip, /**< SCIP data structure */
1707  OPBINPUT* opbinput, /**< OPB reading data */
1708  const char* filename /**< name of the input file */
1709  )
1710 {
1711  SCIP_Real objoffset;
1712  int nNonlinearConss;
1713  int i;
1714 
1715  assert(scip != NULL);
1716  assert(opbinput != NULL);
1717 
1718  /* open file */
1719  opbinput->file = SCIPfopen(filename, "r");
1720  if( opbinput->file == NULL )
1721  {
1722  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
1723  SCIPprintSysError(filename);
1724  return SCIP_NOFILE;
1725  }
1726 
1727  /* @todo: reading additional information about the number of and constraints in comments to avoid reallocating
1728  * "opbinput.andconss"
1729  */
1730 
1731  /* tries to read the first comment line which usually contains information about the max size of "and" products */
1732  SCIP_CALL( getMaxAndConsDim(scip, opbinput, filename, &objoffset) );
1733 
1734  BMSclearMemoryArray(opbinput->linebuf, OPB_MAX_LINELEN);
1735 
1736  /* create problem */
1737  SCIP_CALL( SCIPcreateProb(scip, filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL) );
1738 
1739  if( ! SCIPisZero(scip, objoffset) )
1740  {
1741  SCIP_CALL( SCIPaddOrigObjoffset(scip, objoffset) );
1742  }
1743 
1744  nNonlinearConss = 0;
1745 
1746  while( !SCIPfeof( opbinput->file ) && !hasError(opbinput) )
1747  {
1748  SCIP_CALL( readConstraints(scip, opbinput, &nNonlinearConss) );
1749  }
1750 
1751  /* if we read a wbo file we need to make sure that the top cost won't be exceeded */
1752  if( opbinput->wbo )
1753  {
1754  SCIP_VAR** topcostvars;
1755  SCIP_Real* topcosts;
1756  SCIP_VAR** vars;
1757  int nvars;
1758  int ntopcostvars;
1759  SCIP_Longint topcostrhs;
1760  SCIP_CONS* topcostcons;
1761 
1762  nvars = SCIPgetNVars(scip);
1763  vars = SCIPgetVars(scip);
1764  assert(nvars > 0 || vars != NULL);
1765 
1766  SCIP_CALL( SCIPallocBufferArray(scip, &topcostvars, nvars) );
1767  SCIP_CALL( SCIPallocBufferArray(scip, &topcosts, nvars) );
1768 
1769  ntopcostvars = 0;
1770  for( i = nvars - 1; i >= 0; --i )
1771  if( !SCIPisZero(scip, SCIPvarGetObj(vars[i])) )
1772  {
1773  topcostvars[ntopcostvars] = vars[i];
1774  topcosts[ntopcostvars] = SCIPvarGetObj(vars[i]);
1775  ++ntopcostvars;
1776  }
1777 
1778  if( SCIPisIntegral(scip, opbinput->topcost) )
1779  topcostrhs = (SCIP_Longint) SCIPfloor(scip, opbinput->topcost - 1);
1780  else
1781  topcostrhs = (SCIP_Longint) SCIPfloor(scip, opbinput->topcost);
1782 
1783  SCIP_CALL( SCIPcreateConsLinear(scip, &topcostcons, TOPCOSTCONSNAME, ntopcostvars, topcostvars, topcosts, -SCIPinfinity(scip),
1784  (SCIP_Real) topcostrhs, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
1785  SCIP_CALL( SCIPaddCons(scip, topcostcons) );
1786  SCIPdebugPrintCons(scip, topcostcons, NULL);
1787  SCIP_CALL( SCIPreleaseCons(scip, &topcostcons) );
1788 
1789  SCIPfreeBufferArray(scip, &topcosts);
1790  SCIPfreeBufferArray(scip, &topcostvars);
1791  }
1792 
1793  /* close file */
1794  SCIPfclose(opbinput->file);
1795 
1796  return SCIP_OKAY;
1797 }
1798 
1799 
1800 /*
1801  * Local methods (for writing)
1802  */
1803 
1804 /** transforms given and constraint variables to the corresponding active or negated variables */
1805 static
1807  SCIP*const scip, /**< SCIP data structure */
1808  SCIP_VAR**const vars, /**< vars array to get active variables for */
1809  int const nvars, /**< pointer to number of variables and values in vars and vals array */
1810  SCIP_Bool const transformed /**< transformed constraint? */
1811  )
1812 {
1813  SCIP_Bool negated;
1814  int v;
1815 
1816  assert( scip != NULL );
1817  assert( vars != NULL );
1818  assert( nvars > 0 );
1819 
1820  if( transformed )
1821  {
1822  for( v = nvars - 1; v >= 0; --v )
1823  {
1824  /* gets a binary variable that is equal to the given binary variable, and that is either active, fixed, or
1825  * multi-aggregated, or the negated variable of an active, fixed, or multi-aggregated variable
1826  */
1827  SCIP_CALL( SCIPgetBinvarRepresentative( scip, vars[v], &vars[v], &negated) );
1828  }
1829  }
1830  else
1831  {
1832  SCIP_Real scalar;
1833  SCIP_Real constant;
1834 
1835  for( v = nvars - 1; v >= 0; --v )
1836  {
1837  scalar = 1.0;
1838  constant = 0.0;
1839 
1840  /* retransforms given variable, scalar and constant to the corresponding original variable, scalar and constant,
1841  * if possible; if the retransformation is impossible, NULL is returned as variable
1842  */
1843  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalar, &constant) );
1844 
1845  if( vars[v] == NULL )
1846  {
1847  SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable.\n");
1848  return SCIP_INVALIDDATA;
1849  }
1850  if( SCIPisEQ(scip, scalar, -1.0) && SCIPisEQ(scip, constant, 1.0) )
1851  {
1852  SCIP_CALL( SCIPgetNegatedVar(scip, vars[v], &vars[v]) );
1853  }
1854  else
1855  {
1856  if( !SCIPisEQ(scip, scalar, 1.0) || !SCIPisZero(scip, constant) )
1857  {
1858  SCIPdebugMsg(scip, "A variable couldn't retransformed to an original variable or a negated variable of an original variable (scalar = %g, constant = %g).\n", scalar, constant);
1859  return SCIP_INVALIDDATA;
1860  }
1861  }
1862  }
1863  }
1864 
1865  return SCIP_OKAY;
1866 }
1867 
1868 /** transforms given variables, scalars, and constant to the corresponding active variables, scalars, and constant */
1869 static
1871  SCIP* scip, /**< SCIP data structure */
1872  SCIP_VAR** vars, /**< vars array to get active variables for */
1873  SCIP_Real* scalars, /**< scalars a_1, ..., a_n in linear sum a_1*x_1 + ... + a_n*x_n + c */
1874  int* nvars, /**< pointer to number of variables and values in vars and vals array */
1875  SCIP_Real* constant, /**< pointer to constant c in linear sum a_1*x_1 + ... + a_n*x_n + c */
1876  SCIP_Bool transformed /**< transformed constraint? */
1877  )
1878 {
1879  int requiredsize;
1880  int v;
1881 
1882  assert(scip != NULL);
1883  assert(vars != NULL);
1884  assert(scalars != NULL);
1885  assert(nvars != NULL);
1886  assert(constant != NULL);
1887 
1888  if( transformed )
1889  {
1890  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, *nvars, constant, &requiredsize, TRUE) );
1891 
1892  if( requiredsize > *nvars )
1893  {
1894  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
1895  SCIP_CALL( SCIPreallocBufferArray(scip, &scalars, requiredsize) );
1896 
1897  SCIP_CALL( SCIPgetProbvarLinearSum(scip, vars, scalars, nvars, requiredsize, constant, &requiredsize, TRUE) );
1898  assert( requiredsize <= *nvars );
1899  }
1900  }
1901  else
1902  for( v = 0; v < *nvars; ++v )
1903  {
1904  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &scalars[v], constant) );
1905 
1906  if( vars[v] == NULL )
1907  return SCIP_INVALIDDATA;
1908  }
1909 
1910  return SCIP_OKAY;
1911 }
1912 
1913 /* computes all and-resultants and their corresponding constraint variables */
1914 static
1916  SCIP*const scip, /**< SCIP data structure */
1917  SCIP_Bool const transformed, /**< transformed problem? */
1918  SCIP_VAR*** resvars, /**< pointer to store all resultant variables */
1919  int* nresvars, /**< pointer to store the number of all resultant variables */
1920  SCIP_VAR**** andvars, /**< pointer to store to all resultant variables their corresponding active( or negated) and-constraint variables */
1921  int** nandvars, /**< pointer to store the number of all corresponding and-variables to their corresponding resultant variable */
1922  SCIP_Bool*const existandconshdlr, /**< pointer to store whether the and-constrainthandler exists*/
1923  SCIP_Bool*const existands /**< pointer to store if their exists some and-constraints */
1924  )
1925 {
1926  SCIP_CONSHDLR* conshdlr;
1927 
1928  assert(scip != NULL);
1929  assert(resvars != NULL);
1930  assert(nresvars != NULL);
1931  assert(andvars != NULL);
1932  assert(nandvars != NULL);
1933  assert(existandconshdlr != NULL);
1934  assert(existands != NULL);
1935 
1936  *resvars = NULL;
1937  *nandvars = NULL;
1938  *andvars = NULL;
1939  *nresvars = 0;
1940 
1941  /* detect all and-resultants */
1942  conshdlr = SCIPfindConshdlr(scip, "and");
1943  if( conshdlr != NULL )
1944  {
1945  SCIP_CONS** andconss;
1946  int nandconss;
1947  int* shouldnotbeinand;
1948  int a;
1949  int c;
1950  int r;
1951  int v;
1952  int pos;
1953  int ncontainedands;
1954 
1955  andconss = NULL;
1956  nandconss = 0;
1957  *existandconshdlr = TRUE;
1958 
1959  /* if we write the original problem we need to get the original and constraints */
1960  if( !transformed )
1961  {
1962  SCIP_CONS** origconss;
1963  int norigconss;
1964 
1965  origconss = SCIPgetOrigConss(scip);
1966  norigconss = SCIPgetNOrigConss(scip);
1967 
1968  /* allocate memory for all possible and-constraints */
1969  SCIP_CALL( SCIPallocBufferArray(scip, &andconss, norigconss) );
1970 
1971  /* collect all original and-constraints */
1972  for( c = norigconss - 1; c >= 0; --c )
1973  {
1974  conshdlr = SCIPconsGetHdlr(origconss[c]);
1975  assert( conshdlr != NULL );
1976 
1977  if( strcmp(SCIPconshdlrGetName(conshdlr), "and") == 0 )
1978  {
1979  andconss[nandconss] = origconss[c];
1980  ++nandconss;
1981  }
1982  }
1983  }
1984  else
1985  {
1986  nandconss = SCIPconshdlrGetNConss(conshdlr);
1987  andconss = SCIPconshdlrGetConss(conshdlr);
1988  }
1989 
1990  assert(andconss != NULL || nandconss == 0);
1991 
1992  *nresvars = nandconss;
1993 
1994  if( nandconss > 0 )
1995  {
1996  *existands = TRUE;
1997 
1998  assert(andconss != NULL);
1999 
2000  SCIP_CALL( SCIPallocMemoryArray(scip, resvars, *nresvars) );
2001  SCIP_CALL( SCIPallocMemoryArray(scip, andvars, *nresvars) );
2002  SCIP_CALL( SCIPallocMemoryArray(scip, nandvars, *nresvars) );
2003 
2004  /* collect all and-constraint variables */
2005  for( c = nandconss - 1; c >= 0; --c )
2006  {
2007  SCIP_VAR** scipandvars;
2008 
2009  assert(andconss[c] != NULL);
2010 
2011  scipandvars = SCIPgetVarsAnd(scip, andconss[c]);
2012  (*nandvars)[c] = SCIPgetNVarsAnd(scip, andconss[c]);
2013  SCIP_CALL( SCIPduplicateMemoryArray(scip, &((*andvars)[c]), scipandvars, (*nandvars)[c]) ); /*lint !e866 */
2014  SCIP_CALL( getBinVarsRepresentatives(scip, (*andvars)[c], (*nandvars)[c], transformed) );
2015 
2016  (*resvars)[c] = SCIPgetResultantAnd(scip, andconss[c]);
2017 
2018  assert((*andvars)[c] != NULL && (*nandvars)[c] > 0);
2019  assert((*resvars)[c] != NULL);
2020  }
2021 
2022  /* sorted the array */
2023  SCIPsortPtrPtrInt((void**)(*resvars), (void**)(*andvars), (*nandvars), SCIPvarComp, (*nresvars));
2024  }
2025  else
2026  *existands = FALSE;
2027 
2028  SCIP_CALL( SCIPallocBufferArray(scip, &shouldnotbeinand, *nresvars) );
2029 
2030  /* check that all and-constraints doesn't contain any and-resultants, if they do try to resolve this */
2031  /* attention: if resolving leads to x = x*y*... , we can't do anything here ( this only means (... >=x and) y >= x, so normally the and-constraint needs to be
2032  deleted and the inequality from before needs to be added ) */
2033  assert(*nandvars != NULL || *nresvars == 0);
2034  for( r = *nresvars - 1; r >= 0; --r )
2035  {
2036  ncontainedands = 0;
2037  shouldnotbeinand[ncontainedands] = r;
2038  ++ncontainedands;
2039  v = 0;
2040 
2041  assert(*nandvars != NULL);
2042  while( v < (*nandvars)[r] )
2043  {
2044  assert(*andvars != NULL);
2045  assert(*resvars != NULL);
2046  if( SCIPsortedvecFindPtr((void**)(*resvars), SCIPvarComp, (*andvars)[r][v], *nresvars, &pos) )
2047  {
2048  /* check if the found position "pos" is equal to an already visited and resultant in this constraint,
2049  * than here could exist a directed cycle
2050  */
2051  /* better use tarjan's algorithm
2052  * <http://algowiki.net/wiki/index.php?title=Tarjan%27s_algorithm>,
2053  * <http://en.wikipedia.org/wiki/Tarjan%E2%80%99s_strongly_connected_components_algorithm>
2054  * because it could be that the same resultant is part of this and-constraint and than it would fail
2055  * without no cycle
2056  * Note1: tarjans standard algorithm doesn't find cycle from one node to the same;
2057  * Note2: when tarjan's algorithm find a cycle, it's still possible that this cycle is not "real" e.g.
2058  * y = y ~y z (z can also be a product) where y = 0 follows and therefor only "0 = z" is necessary
2059  */
2060  for( a = ncontainedands - 1; a >= 0; --a )
2061  if( shouldnotbeinand[a] == pos )
2062  {
2063  SCIPwarningMessage(scip, "This should not happen here. The and-constraint with resultant variable: ");
2064  SCIP_CALL( SCIPprintVar(scip, (*resvars)[r], NULL) );
2065  SCIPwarningMessage(scip, "possible contains a loop with and-resultant:");
2066  SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) );
2067 
2068  /* free memory iff necessary */
2069  SCIPfreeBufferArray(scip, &shouldnotbeinand);
2070  if( !transformed )
2071  {
2072  SCIPfreeBufferArray(scip, &andconss);
2073  }
2074  return SCIP_INVALIDDATA;
2075  }
2076  SCIPdebugMsg(scip, "Another and-constraint contains and-resultant:");
2077  SCIPdebug( SCIP_CALL( SCIPprintVar(scip, (*resvars)[pos], NULL) ) );
2078  SCIPdebugMsg(scip, "Trying to resolve.\n");
2079 
2080  shouldnotbeinand[ncontainedands] = pos;
2081  ++ncontainedands;
2082 
2083  /* try to resolve containing ands */
2084 
2085  /* resize array and number of variables */
2086  (*nandvars)[r] = (*nandvars)[r] + (*nandvars)[pos] - 1;
2087  SCIP_CALL( SCIPreallocMemoryArray(scip, &((*andvars)[r]), (*nandvars)[r]) ); /*lint !e866 */
2088 
2089  /* copy all variables */
2090  for( a = (*nandvars)[pos] - 1; a >= 0; --a )
2091  (*andvars)[r][(*nandvars)[r] - a - 1] = (*andvars)[pos][a];
2092 
2093  /* check same position with new variable, so we do not increase v */
2094  }
2095  else
2096  ++v;
2097  }
2098  }
2099  SCIPfreeBufferArray(scip, &shouldnotbeinand);
2100 
2101  /* free memory iff necessary */
2102  if( !transformed )
2103  {
2104  SCIPfreeBufferArray(scip, &andconss);
2105  }
2106  }
2107  else
2108  {
2109  SCIPdebugMsg(scip, "found no and-constraint-handler\n");
2110  *existands = FALSE;
2111  *existandconshdlr = FALSE;
2112  }
2113 
2114  return SCIP_OKAY;
2115 }
2116 
2117 /** clears the given line buffer */
2118 static
2120  char* linebuffer, /**< line */
2121  int* linecnt /**< number of characters in line */
2122  )
2123 {
2124  assert( linebuffer != NULL );
2125  assert( linecnt != NULL );
2126 
2127  (*linecnt) = 0;
2128  linebuffer[0] = '\0';
2129 }
2130 
2131 
2132 /** ends the given line with '\\0' and prints it to the given file stream */
2133 static
2135  SCIP* scip, /**< SCIP data structure */
2136  FILE* file, /**< output file (or NULL for standard output) */
2137  char* linebuffer, /**< line */
2138  int* linecnt /**< number of characters in line */
2139  )
2140 {
2141  assert( scip != NULL );
2142  assert( linebuffer != NULL );
2143  assert( linecnt != NULL );
2144  assert( 0 <= *linecnt && *linecnt < OPB_MAX_LINELEN );
2145 
2146  if( (*linecnt) > 0 )
2147  {
2148  linebuffer[(*linecnt)] = '\0';
2149  SCIPinfoMessage(scip, file, "%s", linebuffer);
2150  clearBuffer(linebuffer, linecnt);
2151  }
2152 }
2153 
2154 
2155 /** appends extension to line and prints it to the give file stream if the line buffer get full */
2156 static
2158  SCIP* scip, /**< SCIP data structure */
2159  FILE* file, /**< output file (or NULL for standard output) */
2160  char* linebuffer, /**< line buffer */
2161  int* linecnt, /**< number of characters in line */
2162  const char* extension /**< string to extent the line */
2163  )
2164 {
2165  assert(scip != NULL);
2166  assert(linebuffer != NULL);
2167  assert(linecnt != NULL);
2168  assert(extension != NULL);
2169 
2170  if( (*linecnt) + (int) strlen(extension) >= OPB_MAX_LINELEN - 1 )
2171  writeBuffer(scip, file, linebuffer, linecnt);
2172 
2173  /* append extension to linebuffer */
2174  (void) strncat(linebuffer, extension, OPB_MAX_LINELEN - (unsigned int)(*linecnt));
2175  (*linecnt) += (int) strlen(extension);
2176 }
2177 
2178 /** write objective function */
2179 static
2181  SCIP*const scip, /**< SCIP data structure */
2182  FILE*const file, /**< output file, or NULL if standard output should be used */
2183  SCIP_VAR**const vars, /**< array with active (binary) variables */
2184  int const nvars, /**< number of active variables in the problem */
2185  SCIP_VAR** const resvars, /**< array of resultant variables */
2186  int const nresvars, /**< number of resultant variables */
2187  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2188  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2189  SCIP_OBJSENSE const objsense, /**< objective sense */
2190  SCIP_Real const objscale, /**< scalar applied to objective function; external objective value is
2191  * extobj = objsense * objscale * (intobj + objoffset) */
2192  SCIP_Real const objoffset, /**< objective offset from bound shifting and fixing */
2193  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
2194  SCIP_Bool const existands, /**< does some and-constraints exist? */
2195  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
2196  )
2197 {
2198  SCIP_VAR* var;
2199  char linebuffer[OPB_MAX_LINELEN+1];
2200  char buffer[OPB_MAX_LINELEN];
2201  SCIP_Longint mult;
2202  SCIP_Bool objective;
2203  int v;
2204  int linecnt;
2205  int pos;
2206 
2207  assert(scip != NULL);
2208  assert(file != NULL);
2209  assert(vars != NULL || nvars == 0);
2210  assert(resvars != NULL || nresvars == 0);
2211  assert(andvars != NULL || nandvars == NULL);
2212  assert(multisymbol != NULL);
2213 
2214  mult = 1;
2215  objective = FALSE;
2216 
2217  clearBuffer(linebuffer, &linecnt);
2218 
2219  /* check if a objective function exits and compute the multiplier to
2220  * shift the coefficients to integers */
2221  for( v = 0; v < nvars; ++v )
2222  {
2223  var = vars[v]; /*lint !e613 */
2224 
2225 #ifndef NDEBUG
2226  {
2227  /* in case the original problem has to be posted the variables have to be either "original" or "negated" */
2228  if( !transformed )
2229  assert( SCIPvarGetStatus(var) == SCIP_VARSTATUS_ORIGINAL ||
2231  }
2232 #endif
2233 
2234  /* we found a indicator variable so we assume this is a wbo file */
2235  if( strstr(SCIPvarGetName(var), INDICATORVARNAME) != NULL )
2236  {
2237  /* find the topcost linear inequality which gives us the maximal cost which could be violated by our
2238  * solution, which is an artificial constraint and print this at first
2239  *
2240  * @note: only linear constraint handler is enough in problem stage, otherwise it could be any upgraded linear
2241  * constraint which handles pure binary variables
2242  */
2243  SCIP_CONSHDLR* conshdlr;
2244  SCIP_CONS* topcostcons;
2245  SCIP_Bool printed;
2246 
2247  printed = FALSE;
2248  topcostcons = SCIPfindCons(scip, TOPCOSTCONSNAME);
2249 
2250  if( topcostcons != NULL )
2251  {
2252  conshdlr = SCIPconsGetHdlr(topcostcons);
2253  assert(conshdlr != NULL);
2254 
2255  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") == 0 )
2256  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %g;\n", SCIPgetRhsLinear(scip, topcostcons));
2257  else if( strcmp(SCIPconshdlrGetName(conshdlr), "knapsack") == 0 )
2258  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %SCIP_LONGINT_FORMAT;\n",
2259  SCIPgetCapacityKnapsack(scip, topcostcons));
2260  else if( strcmp(SCIPconshdlrGetName(conshdlr), "setppc") == 0 )
2261  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: 1;\n");
2262  else
2263  {
2264  SCIPABORT();
2265  return SCIP_INVALIDDATA; /*lint !e527 */
2266  }
2267  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2268  writeBuffer(scip, file, linebuffer, &linecnt);
2269  printed = TRUE;
2270  }
2271  /* following works only in transformed stage */
2272  else
2273  {
2274  /* first try linear constraints */
2275  conshdlr = SCIPfindConshdlr(scip, "linear");
2276 
2277  if( conshdlr != NULL )
2278  {
2279  SCIP_CONS** conss;
2280  int nconss;
2281  int c;
2282 
2283  conss = SCIPconshdlrGetConss(conshdlr);
2284  nconss = SCIPconshdlrGetNConss(conshdlr);
2285 
2286  assert(conss != NULL || nconss == 0);
2287 
2288  for( c = 0; c < nconss; ++c )
2289  {
2290  SCIP_VAR** linvars;
2291  int nlinvars;
2292  int w;
2293  SCIP_Bool topcostfound;
2294  SCIP_CONS* cons;
2295 
2296  cons = conss[c]; /*lint !e613 */
2297  assert(cons != NULL);
2298 
2299  linvars = SCIPgetVarsLinear(scip, cons);
2300  nlinvars = SCIPgetNVarsLinear(scip, cons);
2301 
2302  assert(linvars != NULL || nlinvars == 0);
2303  topcostfound = FALSE;
2304 
2305  for( w = 0; w < nlinvars; ++w )
2306  {
2307  if( strstr(SCIPvarGetName(linvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2308  topcostfound = TRUE;
2309  else
2310  {
2311  assert(!topcostfound);
2312  topcostfound = FALSE;
2313  }
2314  }
2315 
2316  if( topcostfound )
2317  {
2318  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %g;\n", SCIPgetRhsLinear(scip, cons));
2319  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2320  writeBuffer(scip, file, linebuffer, &linecnt);
2321  printed = TRUE;
2322  break;
2323  }
2324  }
2325  }
2326 
2327  if( !printed )
2328  {
2329  /* second try knapsack constraints */
2330  conshdlr = SCIPfindConshdlr(scip, "knapsack");
2331 
2332  if( conshdlr != NULL )
2333  {
2334  SCIP_CONS** conss;
2335  int nconss;
2336  int c;
2337 
2338  conss = SCIPconshdlrGetConss(conshdlr);
2339  nconss = SCIPconshdlrGetNConss(conshdlr);
2340 
2341  assert(conss != NULL || nconss == 0);
2342 
2343  for( c = 0; c < nconss; ++c )
2344  {
2345  SCIP_VAR** topvars;
2346  int ntopvars;
2347  int w;
2348  SCIP_Bool topcostfound;
2349  SCIP_CONS* cons;
2350 
2351  cons = conss[c]; /*lint !e613 */
2352  assert(cons != NULL);
2353 
2354  topvars = SCIPgetVarsKnapsack(scip, cons);
2355  ntopvars = SCIPgetNVarsKnapsack(scip, cons);
2356 
2357  assert(topvars != NULL || ntopvars == 0);
2358  topcostfound = FALSE;
2359 
2360  for( w = 0; w < ntopvars; ++w )
2361  {
2362  if( strstr(SCIPvarGetName(topvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2363  topcostfound = TRUE;
2364  else
2365  {
2366  assert(!topcostfound);
2367  topcostfound = FALSE;
2368  }
2369  }
2370 
2371  if( topcostfound )
2372  {
2373  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: %SCIP_LONGINT_FORMAT;\n",
2374  SCIPgetCapacityKnapsack(scip, cons));
2375  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2376  writeBuffer(scip, file, linebuffer, &linecnt);
2377  printed = TRUE;
2378  break;
2379  }
2380  }
2381  }
2382  }
2383 
2384  if( !printed )
2385  {
2386  /* third try setppc constraints */
2387  conshdlr = SCIPfindConshdlr(scip, "setppc");
2388 
2389  if( conshdlr != NULL )
2390  {
2391  SCIP_CONS** conss;
2392  int nconss;
2393  int c;
2394 
2395  conss = SCIPconshdlrGetConss(conshdlr);
2396  nconss = SCIPconshdlrGetNConss(conshdlr);
2397 
2398  assert(conss != NULL || nconss == 0);
2399 
2400  for( c = 0; c < nconss; ++c )
2401  {
2402  SCIP_VAR** topvars;
2403  int ntopvars;
2404  int w;
2405  SCIP_Bool topcostfound;
2406  SCIP_CONS* cons;
2407 
2408  cons = conss[c]; /*lint !e613 */
2409  assert(cons != NULL);
2410 
2411  topvars = SCIPgetVarsSetppc(scip, cons);
2412  ntopvars = SCIPgetNVarsSetppc(scip, cons);
2413 
2414  assert(topvars != NULL || ntopvars == 0);
2415  topcostfound = FALSE;
2416 
2417  for( w = 0; w < ntopvars; ++w )
2418  {
2419  if( strstr(SCIPvarGetName(topvars[w]), INDICATORVARNAME) != NULL ) /*lint !e613 */
2420  topcostfound = TRUE;
2421  else
2422  {
2423  assert(!topcostfound);
2424  topcostfound = FALSE;
2425  }
2426  }
2427 
2428  if( topcostfound )
2429  {
2430  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: 1;\n");
2431  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2432  writeBuffer(scip, file, linebuffer, &linecnt);
2433  printed = TRUE;
2434  break;
2435  }
2436  }
2437  }
2438  }
2439  }
2440 
2441  /* no topcost constraint found, so print empty topcost line, which means there is no upper bound on violated soft constraints */
2442  if( !printed )
2443  {
2444  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "soft: ;\n");
2445  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2446  writeBuffer(scip, file, linebuffer, &linecnt);
2447  }
2448 
2449  return SCIP_OKAY;
2450  }
2451 
2452  if( !SCIPisZero(scip, SCIPvarGetObj(var)) )
2453  {
2454  objective = TRUE;
2455  while( !SCIPisIntegral(scip, SCIPvarGetObj(var) * mult) )
2456  {
2457  assert(mult * 10 > mult);
2458  mult *= 10;
2459  }
2460  }
2461  }
2462 
2463  if( objective )
2464  {
2465  /* there exist a objective function*/
2466  SCIPinfoMessage(scip, file, "* Obj. scale : %.15g\n", objscale * mult);
2467  SCIPinfoMessage(scip, file, "* Obj. offset : %.15g\n", objoffset);
2468 
2469  clearBuffer(linebuffer, &linecnt);
2470 
2471  /* opb format supports only minimization; therefore, a maximization problem has to be converted */
2472  if( objsense == SCIP_OBJSENSE_MAXIMIZE )
2473  mult *= -1;
2474 
2475  SCIPdebugMsg(scip, "print objective function multiplied with %" SCIP_LONGINT_FORMAT "\n", mult);
2476 
2477  appendBuffer(scip, file, linebuffer, &linecnt, "min:");
2478 
2479 #ifndef NDEBUG
2480  if( existands )
2481  {
2482  int c;
2483  /* check that these variables are sorted */
2484  for( c = nresvars - 1; c > 0; --c )
2485  assert(SCIPvarGetIndex(resvars[c]) >= SCIPvarGetIndex(resvars[c - 1])); /*lint !e613 */
2486  }
2487 #endif
2488 
2489  for( v = nvars - 1; v >= 0; --v )
2490  {
2491  SCIP_Bool negated;
2492  var = vars[v]; /*lint !e613 */
2493 
2494  assert(var != NULL);
2495 
2496  if( SCIPisZero(scip, SCIPvarGetObj(var)) )
2497  continue;
2498 
2499  negated = SCIPvarIsNegated(var);
2500 
2501  assert( linecnt != 0 );
2502 
2503  if( SCIPvarGetObj(var) * mult > (SCIP_Real)SCIP_LONGINT_MAX )
2504  {
2505  SCIPerrorMessage("Integral objective value to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", mult, SCIPvarGetObj(var), SCIPvarGetObj(var) * mult, (SCIP_Longint) SCIPround(scip, SCIPvarGetObj(var) * mult));
2506  }
2507 
2508  /* replace and-resultant with corresponding variables */
2509  if( existands && SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
2510  {
2511  int a;
2512 
2513  assert(andvars != NULL);
2514  assert(nandvars != NULL);
2515  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
2516  assert(andvars[pos][nandvars[pos] - 1] != NULL);
2517 
2518  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
2519 
2520  /* print and-vars */
2521  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
2522  (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "",
2523  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
2524  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2525 
2526  for(a = nandvars[pos] - 2; a >= 0; --a )
2527  {
2528  negated = SCIPvarIsNegated(andvars[pos][a]);
2529 
2530  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
2531  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2532  }
2533  }
2534  else
2535  {
2536  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " %+" SCIP_LONGINT_FORMAT "%s%s%s",
2537  (SCIP_Longint) (SCIPvarGetObj(var) * mult), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2538  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2539  }
2540  }
2541 
2542  /* and objective function line ends with a ';' */
2543  appendBuffer(scip, file, linebuffer, &linecnt, " ;\n");
2544  writeBuffer(scip, file, linebuffer, &linecnt);
2545  }
2546 
2547  return SCIP_OKAY;
2548 }
2549 
2550 /* print maybe non linear row in OPB format to file stream */
2551 static
2553  SCIP*const scip, /**< SCIP data structure */
2554  FILE*const file, /**< output file (or NULL for standard output) */
2555  char const*const type, /**< row type ("=" or ">=") */
2556  SCIP_VAR**const vars, /**< array of variables */
2557  SCIP_Real const*const vals, /**< array of values */
2558  int const nvars, /**< number of variables */
2559  SCIP_Real lhs, /**< left hand side */
2560  SCIP_VAR** const resvars, /**< array of resultant variables */
2561  int const nresvars, /**< number of resultant variables */
2562  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2563  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2564  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2565  SCIP_Longint*const mult, /**< multiplier for the coefficients */
2566  char const*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
2567  )
2568 {
2569  SCIP_VAR* var;
2570  char buffer[OPB_MAX_LINELEN];
2571  char linebuffer[OPB_MAX_LINELEN + 1];
2572  int v;
2573  int pos;
2574  int linecnt;
2575 
2576  assert(scip != NULL);
2577  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2578  assert(mult != NULL);
2579  assert(resvars != NULL);
2580  assert(nresvars > 0);
2581  assert(andvars != NULL && nandvars != NULL);
2582 
2583  clearBuffer(linebuffer, &linecnt);
2584 
2585  /* check if all coefficients are internal; if not commentstart multiplier */
2586  for( v = 0; v < nvars; ++v )
2587  {
2588  while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
2589  {
2590  if( ABS(*mult) > ABS(*mult * 10) )
2591  return SCIP_INVALIDDATA;
2592  (*mult) *= 10;
2593  }
2594  }
2595 
2596  while( !SCIPisIntegral(scip, lhs * (*mult)) )
2597  {
2598  if( ABS(*mult) > ABS(*mult * 10) )
2599  return SCIP_INVALIDDATA;
2600  (*mult) *= 10;
2601  }
2602 
2603  /* print comment line if we have to multiply the coefficients to get integrals */
2604  if( ABS(*mult) != 1 )
2605  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
2606 
2607 #ifndef NDEBUG
2608  /* check that these variables are sorted */
2609  for( v = nresvars - 1; v > 0; --v )
2610  assert(SCIPvarGetIndex(resvars[v]) >= SCIPvarGetIndex(resvars[v - 1]));
2611 #endif
2612 
2613  /* if we have a soft constraint print the weight*/
2614  if( weight != 0 )
2615  {
2616  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "] ", weight);
2617  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2618  }
2619 
2620  /* print coefficients */
2621  for( v = 0; v < nvars; ++v )
2622  {
2623  SCIP_Bool negated;
2624 
2625  var = vars[v];
2626  assert( var != NULL );
2627 
2628  negated = SCIPvarIsNegated(var);
2629 
2630  /* replace and-resultant with corresponding variables */
2631  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, var, nresvars, &pos) )
2632  {
2633  int a;
2634 
2635  assert(andvars != NULL);
2636  assert(nandvars != NULL);
2637  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
2638  assert(andvars[pos][nandvars[pos] - 1] != NULL);
2639 
2640  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
2641 
2642  if( vals[v] * (*mult) > (SCIP_Real)SCIP_LONGINT_MAX )
2643  {
2644  SCIPerrorMessage("Integral coefficient to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", *mult, vals[v], vals[v] * (*mult), (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)));
2645  }
2646 
2647  /* print and-vars */
2648  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s",
2649  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "",
2650  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x") );
2651  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2652 
2653  for(a = nandvars[pos] - 2; a >= 0; --a )
2654  {
2655  negated = SCIPvarIsNegated(andvars[pos][a]);
2656 
2657  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
2658  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2659  }
2660 
2661  appendBuffer(scip, file, linebuffer, &linecnt, " ");
2662  }
2663  else
2664  {
2665  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
2666  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2667  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2668  }
2669  }
2670 
2671  /* print left hand side */
2672  if( SCIPisZero(scip, lhs) )
2673  lhs = 0.0;
2674 
2675  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
2676  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2677 
2678  writeBuffer(scip, file, linebuffer, &linecnt);
2679 
2680  return SCIP_OKAY;
2681 }
2682 
2683 
2684 /** prints given maybe non-linear constraint information in OPB format to file stream */
2685 static
2687  SCIP*const scip, /**< SCIP data structure */
2688  FILE*const file, /**< output file (or NULL for standard output) */
2689  SCIP_VAR**const vars, /**< array of variables */
2690  SCIP_Real*const vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2691  int const nvars, /**< number of variables */
2692  SCIP_Real const lhs, /**< left hand side */
2693  SCIP_Real const rhs, /**< right hand side */
2694  SCIP_VAR** const resvars, /**< array of resultant variables */
2695  int const nresvars, /**< number of resultant variables */
2696  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
2697  int const*const nandvars, /**< array of numbers of corresponding and-variables */
2698  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2699  SCIP_Bool const transformed, /**< transformed constraint? */
2700  char const*const multisymbol /**< the multiplication symbol to use between coefficient and variable */
2701  )
2702 {
2703  SCIP_VAR** activevars;
2704  SCIP_Real* activevals;
2705  SCIP_Real activeconstant;
2706  SCIP_Longint mult;
2707  SCIP_RETCODE retcode;
2708  int v;
2709  int nactivevars;
2710 
2711  assert(scip != NULL);
2712  assert(vars != NULL);
2713  assert(nvars > 0);
2714  assert(lhs <= rhs);
2715  assert(resvars != NULL);
2716  assert(nresvars > 0);
2717  assert(andvars != NULL && nandvars != NULL);
2718 
2719  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2720  return SCIP_OKAY;
2721 
2722  activeconstant = 0.0;
2723  nactivevars = nvars;
2724 
2725  /* duplicate variable and value array */
2726  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2727  if( vals != NULL )
2728  {
2729  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2730  }
2731  else
2732  {
2733  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2734 
2735  for( v = 0; v < nactivevars; ++v )
2736  activevals[v] = 1.0;
2737  }
2738 
2739  /* retransform given variables to active variables */
2740  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2741 
2742  mult = 1;
2743  retcode = SCIP_OKAY;
2744 
2745  /* print row(s) in OPB format */
2746  if( SCIPisEQ(scip, lhs, rhs) )
2747  {
2748  assert( !SCIPisInfinity(scip, rhs) );
2749 
2750  /* equality constraint */
2751  retcode = printNLRow(scip, file, "=", activevars, activevals, nactivevars, rhs - activeconstant, resvars,
2752  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2753  }
2754  else
2755  {
2756  if( !SCIPisInfinity(scip, -lhs) )
2757  {
2758  /* print inequality ">=" */
2759  retcode = printNLRow(scip, file, ">=", activevars, activevals, nactivevars, lhs - activeconstant, resvars,
2760  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2761  }
2762 
2763  if( !SCIPisInfinity(scip, rhs) )
2764  {
2765  mult *= -1;
2766 
2767  /* print inequality ">=" and multiplying all coefficients by -1 */
2768  retcode = printNLRow(scip, file, ">=", activevars, activevals, nactivevars, rhs - activeconstant, resvars,
2769  nresvars, andvars, nandvars, weight, &mult, multisymbol);
2770  }
2771  }
2772 
2773  /* free buffer arrays */
2774  SCIPfreeBufferArray(scip, &activevars);
2775  SCIPfreeBufferArray(scip, &activevals);
2776 
2777  return retcode;
2778 }
2779 
2780 
2781 /* print row in OPB format to file stream */
2782 static
2784  SCIP* scip, /**< SCIP data structure */
2785  FILE* file, /**< output file (or NULL for standard output) */
2786  const char* type, /**< row type ("=" or ">=") */
2787  SCIP_VAR** vars, /**< array of variables */
2788  SCIP_Real* vals, /**< array of values */
2789  int nvars, /**< number of variables */
2790  SCIP_Real lhs, /**< left hand side */
2791  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2792  SCIP_Longint* mult, /**< multiplier for the coefficients */
2793  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2794  )
2795 {
2796  SCIP_VAR* var;
2797  char buffer[OPB_MAX_LINELEN];
2798  char linebuffer[OPB_MAX_LINELEN + 1];
2799  int v;
2800  int linecnt;
2801 
2802  assert(scip != NULL);
2803  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2804  assert(mult != NULL);
2805 
2806  clearBuffer(linebuffer, &linecnt);
2807 
2808  /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
2809  * we can stop printing because it is an artificial constraint
2810  */
2811  if( nvars > 0 && strstr(SCIPvarGetName(vars[0]), INDICATORVARNAME) != NULL )
2812  return SCIP_OKAY;
2813 
2814  /* check if all coefficients are integral; if not commentstart multiplier */
2815  for( v = 0; v < nvars; ++v )
2816  {
2817  while( !SCIPisIntegral(scip, vals[v] * (*mult)) )
2818  {
2819  if( ABS(*mult) > ABS(*mult * 10) )
2820  return SCIP_INVALIDDATA;
2821  (*mult) *= 10;
2822  }
2823  }
2824 
2825  while( !SCIPisIntegral(scip, lhs * (*mult)) )
2826  {
2827  if( ABS(*mult) > ABS(*mult * 10) )
2828  return SCIP_INVALIDDATA;
2829  (*mult) *= 10;
2830  }
2831 
2832  /* print comment line if we have to multiply the coefficients to get integrals */
2833  if( ABS(*mult) != 1 )
2834  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
2835 
2836  /* if we have a soft constraint print the weight*/
2837  if( weight != 0 )
2838  {
2839  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+" SCIP_LONGINT_FORMAT "] ", weight);
2840  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2841  }
2842 
2843  /* print coefficients */
2844  for( v = 0; v < nvars; ++v )
2845  {
2846  SCIP_Bool negated;
2847 
2848  var = vars[v];
2849  assert( var != NULL );
2850 
2851  negated = SCIPvarIsNegated(var);
2852 
2853  if( vals[v] * (*mult) > (SCIP_Real)SCIP_LONGINT_MAX )
2854  {
2855  SCIPerrorMessage("Integral coefficient to big (mult = %" SCIP_LONGINT_FORMAT ", value = %g, mult*value = %g, printingvalue = %" SCIP_LONGINT_FORMAT ")for printing in opb format.\n", *mult, vals[v], vals[v] * (*mult), (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)));
2856  }
2857 
2858  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
2859  (SCIP_Longint) SCIPround(scip, vals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
2860  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2861  }
2862 
2863  /* print left hand side */
2864  if( SCIPisZero(scip, lhs) )
2865  lhs = 0.0;
2866 
2867  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
2868  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
2869 
2870  writeBuffer(scip, file, linebuffer, &linecnt);
2871 
2872  return SCIP_OKAY;
2873 }
2874 
2875 
2876 /** prints given linear constraint information in OPB format to file stream */
2877 static
2879  SCIP* scip, /**< SCIP data structure */
2880  FILE* file, /**< output file (or NULL for standard output) */
2881  SCIP_VAR** vars, /**< array of variables */
2882  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2883  int nvars, /**< number of variables */
2884  SCIP_Real lhs, /**< left hand side */
2885  SCIP_Real rhs, /**< right hand side */
2886  SCIP_Longint weight, /**< if we found a soft constraint this is the weight, otherwise 0 */
2887  SCIP_Bool transformed, /**< transformed constraint? */
2888  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2889  )
2890 {
2891  SCIP_VAR** activevars;
2892  SCIP_Real* activevals;
2893  int nactivevars;
2894  SCIP_Real activeconstant;
2895  SCIP_Longint mult;
2896  SCIP_RETCODE retcode;
2897  int v;
2898 
2899  assert( scip != NULL );
2900  assert( vars != NULL );
2901  assert( nvars > 0 );
2902  assert( lhs <= rhs );
2903 
2904  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
2905  return SCIP_OKAY;
2906 
2907  activeconstant = 0.0;
2908 
2909  /* duplicate variable and value array */
2910  nactivevars = nvars;
2911  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2912  if( vals != NULL )
2913  {
2914  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2915  }
2916  else
2917  {
2918  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2919 
2920  for( v = 0; v < nactivevars; ++v )
2921  activevals[v] = 1.0;
2922  }
2923 
2924  /* retransform given variables to active variables */
2925  SCIP_CALL( getActiveVariables(scip, activevars, activevals, &nactivevars, &activeconstant, transformed) );
2926 
2927  mult = 1;
2928  retcode = SCIP_OKAY;
2929 
2930  /* print row(s) in OPB format */
2931  if( SCIPisEQ(scip, lhs, rhs) )
2932  {
2933  assert( !SCIPisInfinity(scip, rhs) );
2934 
2935  /* equality constraint */
2936  retcode = printRow(scip, file, "=", activevars, activevals, nactivevars, rhs - activeconstant, weight, &mult,
2937  multisymbol);
2938  }
2939  else
2940  {
2941  if( !SCIPisInfinity(scip, -lhs) )
2942  {
2943  /* print inequality ">=" */
2944  retcode = printRow(scip, file, ">=", activevars, activevals, nactivevars, lhs - activeconstant, weight, &mult,
2945  multisymbol);
2946  }
2947 
2948  if( !SCIPisInfinity(scip, rhs) )
2949  {
2950  mult *= -1;
2951 
2952  /* print inequality ">=" and multiplying all coefficients by -1 */
2953  retcode = printRow(scip, file, ">=", activevars, activevals, nactivevars, rhs - activeconstant, weight, &mult,
2954  multisymbol);
2955  }
2956  }
2957 
2958  /* free buffer arrays */
2959  SCIPfreeBufferArray(scip, &activevars);
2960  SCIPfreeBufferArray(scip, &activevals);
2961 
2962  return retcode;
2963 }
2964 
2965 /* print row in OPB format to file stream */
2966 static
2968  SCIP*const scip, /**< SCIP data structure */
2969  FILE*const file, /**< output file (or NULL for standard output) */
2970  const char* type, /**< row type ("=" or ">=") */
2971  SCIP_VAR**const linvars, /**< array of variables */
2972  SCIP_Real*const linvals, /**< array of values */
2973  int const nlinvars, /**< number of variables */
2974  SCIP_VAR***const termvars, /**< term array with array of variables to print */
2975  int*const ntermvars, /**< array with number of variables in each term */
2976  SCIP_Real*const termvals, /**< array of coefficient values for non-linear variables */
2977  int const ntermvals, /**< number non-linear variables in the problem */
2978  SCIP_Bool**const negatedarrays, /**< array of arrays to know which variable in a non-linear part is negated */
2979  SCIP_VAR*const indvar, /**< indicator variable, or NULL */
2980  SCIP_Real lhs, /**< left hand side */
2981  SCIP_Longint* mult, /**< multiplier for the coefficients */
2982  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
2983  )
2984 {
2985  SCIP_VAR* var;
2986  char buffer[OPB_MAX_LINELEN];
2987  char linebuffer[OPB_MAX_LINELEN + 1];
2988  int v;
2989  int t;
2990  int linecnt;
2991 
2992  assert(scip != NULL);
2993  assert(strcmp(type, "=") == 0 || strcmp(type, ">=") == 0);
2994  assert(linvars != NULL || nlinvars == 0);
2995  assert(linvals != NULL || nlinvars == 0);
2996  assert(termvars != NULL || ntermvals == 0);
2997  assert(ntermvars != NULL || ntermvals == 0);
2998  assert(termvals != NULL || ntermvals == 0);
2999  assert(negatedarrays != NULL || ntermvals == 0);
3000  assert(mult != NULL);
3001 
3002  clearBuffer(linebuffer, &linecnt);
3003 
3004  /* if we found the topcost linear inequality which gives us the maximal cost which could be violated by our solution,
3005  * we can stop printing because it is an artificial constraint
3006  */
3007  if( ntermvals == 0 && nlinvars > 0 && strstr(SCIPvarGetName(linvars[0]), INDICATORVARNAME) != NULL ) /*lint !e613 */
3008  return SCIP_OKAY;
3009 
3010  /* check if all linear coefficients are internal; if not commentstart multiplier */
3011  for( v = 0; v < nlinvars; ++v )
3012  {
3013  while( !SCIPisIntegral(scip, linvals[v] * (*mult)) ) /*lint !e613 */
3014  {
3015  if( ABS(*mult) > ABS(*mult * 10) )
3016  return SCIP_INVALIDDATA;
3017  (*mult) *= 10;
3018  }
3019  }
3020 
3021  /* check if all non-linear coefficients are internal; if not commentstart multiplier */
3022  for( v = 0; v < ntermvals; ++v )
3023  {
3024  while( !SCIPisIntegral(scip, termvals[v] * (*mult)) ) /*lint !e613 */
3025  {
3026  if( ABS(*mult) > ABS(*mult * 10) )
3027  return SCIP_INVALIDDATA;
3028  (*mult) *= 10;
3029  }
3030  }
3031 
3032  while( !SCIPisIntegral(scip, lhs * (*mult)) )
3033  {
3034  if( ABS(*mult) > ABS(*mult * 10) )
3035  return SCIP_INVALIDDATA;
3036  (*mult) *= 10;
3037  }
3038 
3039  /* print comment line if we have to multiply the coefficients to get integrals */
3040  if( ABS(*mult) != 1 )
3041  SCIPinfoMessage(scip, file, "* the following constraint is multiplied by %" SCIP_LONGINT_FORMAT " to get integral coefficients\n", ABS(*mult) );
3042 
3043  /* if indicator variable exist we have a soft constraint */
3044  if( indvar != NULL )
3045  {
3046  SCIP_Real weight;
3047 
3048  weight = SCIPvarGetObj(indvar);
3049  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "[%+g] ", weight);
3050  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3051  }
3052 
3053  /* print linear part */
3054  for( v = 0; v < nlinvars; ++v )
3055  {
3056  SCIP_Bool negated;
3057 
3058  var = linvars[v]; /*lint !e613 */
3059  assert(var != NULL);
3060 
3061  negated = SCIPvarIsNegated(var);
3062 
3063  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT "%s%s%s ",
3064  (SCIP_Longint) SCIPround(scip, linvals[v] * (*mult)), multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x")); /*lint !e613 */
3065  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3066  }
3067 
3068  /* print non-linear part */
3069  for( t = 0; t < ntermvals; ++t )
3070  {
3071  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%+" SCIP_LONGINT_FORMAT, (SCIP_Longint) SCIPround(scip, termvals[t] * (*mult))); /*lint !e613 */
3072  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3073 
3074  for( v = 0; v < ntermvars[t]; ++v ) /*lint !e613 */
3075  {
3076  SCIP_Bool negated;
3077 
3078  var = termvars[t][v]; /*lint !e613 */
3079  assert(var != NULL);
3080 
3081  negated = negatedarrays[t][v]; /*lint !e613 */
3082 
3083  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(var) : var), "x"));
3084  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3085  }
3086  appendBuffer(scip, file, linebuffer, &linecnt, " ");
3087  }
3088 
3089  /* print left hand side */
3090  if( SCIPisZero(scip, lhs) )
3091  lhs = 0.0;
3092 
3093  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s %" SCIP_LONGINT_FORMAT " ;\n", type, (SCIP_Longint) (lhs * (*mult)) );
3094  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3095 
3096  writeBuffer(scip, file, linebuffer, &linecnt);
3097 
3098  return SCIP_OKAY;
3099 }
3100 
3101 
3102 /** prints given pseudo boolean constraint information in OPB format to file stream */
3103 static
3105  SCIP*const scip, /**< SCIP data structure */
3106  FILE*const file, /**< output file, or NULL if standard output should be used */
3107  SCIP_VAR**const linvars, /**< array with variables of linear part */
3108  SCIP_Real*const linvals, /**< array of coefficients values of linear part */
3109  int const nlinvars, /**< number variables in linear part of the problem */
3110  SCIP_VAR***const termvars, /**< term array with array of variables to print */
3111  int*const ntermvars, /**< array with number of variables in each term */
3112  SCIP_Real*const termvals, /**< array of coefficient values for non-linear variables */
3113  int const ntermvals, /**< number non-linear variables in the problem */
3114  SCIP_VAR*const indvar, /**< indicator variable, or NULL */
3115  SCIP_Real const lhs, /**< left hand side of constraint */
3116  SCIP_Real const rhs, /**< right hand side of constraint */
3117  SCIP_Bool transformed, /**< should the transformed problem be printed ? */
3118  const char* multisymbol /**< the multiplication symbol to use between coefficient and variable */
3119  )
3120 {
3121  SCIP_VAR*** activetermvars;
3122  SCIP_Bool** negatedarrays;
3123  SCIP_VAR** activelinvars;
3124  SCIP_Real* activelinvals;
3125  int nactivelinvars;
3126  SCIP_Real activelinconstant;
3127  SCIP_Longint mult;
3128  SCIP_RETCODE retcode;
3129  int v;
3130 
3131  assert(scip != NULL);
3132  assert(linvars != NULL || nlinvars == 0);
3133  assert(linvals != NULL || nlinvars == 0);
3134  assert(termvars != NULL || 0 == ntermvals);
3135  assert(ntermvars != NULL || 0 == ntermvals);
3136  assert(termvals != NULL || 0 == ntermvals);
3137  assert(lhs <= rhs);
3138 
3139  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
3140  return SCIP_OKAY;
3141 
3142  activelinconstant = 0.0;
3143 
3144  /* duplicate variable and value array for linear part */
3145  nactivelinvars = nlinvars;
3146  if( nactivelinvars > 0 )
3147  {
3148  SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvars, linvars, nactivelinvars ) );
3149  SCIP_CALL( SCIPduplicateBufferArray(scip, &activelinvals, linvals, nactivelinvars ) );
3150 
3151  /* retransform given variables to active variables */
3152  SCIP_CALL( getActiveVariables(scip, activelinvars, activelinvals, &nactivelinvars, &activelinconstant, transformed) );
3153  }
3154  else
3155  {
3156  activelinvars = NULL;
3157  activelinvals = NULL;
3158  }
3159 
3160  /* create non-linear information for printing */
3161  if( ntermvals > 0 )
3162  {
3163  assert(termvars != NULL);
3164  assert(ntermvars != NULL);
3165  assert(termvals != NULL);
3166 
3167  SCIP_CALL( SCIPallocBufferArray(scip, &activetermvars, ntermvals) );
3168  SCIP_CALL( SCIPallocBufferArray(scip, &negatedarrays, ntermvals) );
3169  for( v = ntermvals - 1; v >= 0; --v )
3170  {
3171  assert(ntermvars[v] > 0); /*lint !e613 */
3172 
3173  if( transformed )
3174  {
3175  SCIP_CALL( SCIPallocBufferArray(scip, &(activetermvars[v]), ntermvars[v]) ); /*lint !e866 */
3176  SCIP_CALL( SCIPallocBufferArray(scip, &(negatedarrays[v]), ntermvars[v]) ); /*lint !e866 */
3177 
3178  /* get binary representatives of binary variables in non-linear terms */
3179  SCIP_CALL( SCIPgetBinvarRepresentatives(scip, ntermvars[v], termvars[v], activetermvars[v], negatedarrays[v]) );
3180  }
3181  else
3182  {
3183  SCIP_CALL( SCIPduplicateBufferArray(scip, &(activetermvars[v]), termvars[v], ntermvars[v]) ); /*lint !e866 */
3184  SCIP_CALL( SCIPallocBufferArray(scip, &(negatedarrays[v]), ntermvars[v]) ); /*lint !e866 */
3185  BMSclearMemoryArray(negatedarrays[v], ntermvars[v]); /*lint !e866 */
3186  }
3187  }
3188  }
3189  else
3190  {
3191  activetermvars = NULL;
3192  negatedarrays = NULL;
3193  }
3194 
3195  mult = 1;
3196  retcode = SCIP_OKAY;
3197 
3198  /* print row(s) in OPB format */
3199  if( SCIPisEQ(scip, lhs, rhs) )
3200  {
3201  assert( !SCIPisInfinity(scip, rhs) );
3202 
3203  /* equality constraint */
3204  retcode = printPBRow(scip, file, "=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3205  ntermvars, termvals, ntermvals, negatedarrays, indvar, rhs - activelinconstant, &mult, multisymbol);
3206  }
3207  else
3208  {
3209  if( !SCIPisInfinity(scip, -lhs) )
3210  {
3211  /* print inequality ">=" */
3212  retcode = printPBRow(scip, file, ">=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3213  ntermvars, termvals, ntermvals, negatedarrays, indvar, lhs - activelinconstant, &mult, multisymbol);
3214  }
3215 
3216  if( !SCIPisInfinity(scip, rhs) )
3217  {
3218  mult *= -1;
3219 
3220  /* print inequality ">=" and multiplying all coefficients by -1 */
3221  /* coverity[var_deref_model] */
3222  retcode = printPBRow(scip, file, ">=", activelinvars, activelinvals, nactivelinvars, activetermvars,
3223  ntermvars, termvals, ntermvals, negatedarrays, indvar, rhs - activelinconstant, &mult, multisymbol);
3224  }
3225  }
3226 
3227  /* free buffers for non-linear arrays */
3228  if( ntermvals > 0 )
3229  {
3230  assert(negatedarrays != NULL);
3231  assert(activetermvars != NULL);
3232 
3233  for( v = 0; v < ntermvals; ++v )
3234  {
3235  assert(negatedarrays[v] != NULL);
3236  assert(activetermvars[v] != NULL);
3237  SCIPfreeBufferArray(scip, &(negatedarrays[v]));
3238  SCIPfreeBufferArray(scip, &(activetermvars[v]));
3239  }
3240  SCIPfreeBufferArray(scip, &negatedarrays);
3241  SCIPfreeBufferArray(scip, &activetermvars);
3242  }
3243 
3244  /* free buffer for linear arrays */
3245  if( nactivelinvars > 0 )
3246  {
3247  SCIPfreeBufferArray(scip, &activelinvars);
3248  SCIPfreeBufferArray(scip, &activelinvals);
3249  }
3250 
3251  return retcode;
3252 }
3253 
3254 /** determine total number of linear constraints split into lhs/rhs */
3255 static
3257  SCIP*const scip, /**< SCIP data structure */
3258  SCIP_CONS**const conss, /**< array with constraints of the problem */
3259  int const nconss, /**< number of constraints in the problem */
3260  int* nlinearconss, /**< pointer to store the total number of linear constraints */
3261  int* nsplitlinearconss /**< pointer to store the total number of linear constraints split into lhs/rhs */
3262  )
3263 {
3264  SCIP_CONSHDLR* conshdlr;
3265  const char* conshdlrname;
3266  SCIP_CONS* cons;
3267  int c;
3268 
3269  assert(scip != NULL);
3270  assert(conss != NULL || nconss == 0);
3271  assert(nlinearconss != NULL);
3272  assert(nsplitlinearconss != NULL);
3273 
3274  *nlinearconss = 0;
3275  *nsplitlinearconss = 0;
3276 
3277  /* loop over all constraints */
3278  for( c = 0; c < nconss; ++c )
3279  {
3280  cons = conss[c];
3281  assert(cons != NULL);
3282  conshdlr = SCIPconsGetHdlr(cons); /*lint !e613*/
3283  assert(conshdlr != NULL);
3284 
3285  conshdlrname = SCIPconshdlrGetName(conshdlr);
3286 
3287  if( strcmp(conshdlrname, "linear") == 0 )
3288  {
3289  if( ! SCIPisInfinity(scip, SCIPgetLhsLinear(scip, cons)) )
3290  ++(*nsplitlinearconss);
3291 
3292  if( ! SCIPisInfinity(scip, SCIPgetRhsLinear(scip, cons)) )
3293  ++(*nsplitlinearconss);
3294 
3295  ++(*nlinearconss);
3296  }
3297 
3298  if( strcmp(conshdlrname, "varbound") == 0 )
3299  {
3300  if( ! SCIPisInfinity(scip, SCIPgetLhsVarbound(scip, cons)) )
3301  ++(*nsplitlinearconss);
3302 
3303  if( ! SCIPisInfinity(scip, SCIPgetRhsVarbound(scip, cons)) )
3304  ++(*nsplitlinearconss);
3305 
3306  ++(*nlinearconss);
3307  }
3308  }
3309 }
3310 
3311 /** write constraints */
3312 static
3314  SCIP*const scip, /**< SCIP data structure */
3315  FILE*const file, /**< output file, or NULL if standard output should be used */
3316  SCIP_CONS**const conss, /**< array with constraints of the problem */
3317  int const nconss, /**< number of constraints in the problem */
3318  SCIP_VAR**const vars, /**< array with active (binary) variables */
3319  int const nvars, /**< number of active variables in the problem */
3320  SCIP_VAR** const resvars, /**< array of resultant variables */
3321  int const nresvars, /**< number of resultant variables */
3322  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
3323  int const*const nandvars, /**< array of numbers of corresponding and-variables */
3324  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3325  SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
3326  SCIP_Bool const existands, /**< does some and-constraints exist? */
3327  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3328  )
3329 {
3330  SCIP_CONSHDLR* conshdlr;
3331  const char* conshdlrname;
3332  SCIP_CONS* cons;
3333  SCIP_VAR** consvars;
3334  SCIP_Real* consvals;
3335  SCIP_RETCODE retcode;
3336  int nconsvars;
3337  int v, c;
3338  SCIP_HASHMAP* linconssofindicatorsmap = NULL;
3339  SCIP_HASHMAP* linconssofpbsmap = NULL;
3340 
3341  assert(scip != NULL);
3342  assert(file != NULL);
3343  assert(conss != NULL || nconss == 0);
3344  assert(vars != NULL || nvars == 0);
3345  assert(resvars != NULL || nresvars == 0);
3346  assert(andvars != NULL || nandvars == 0);
3347  assert(multisymbol != NULL);
3348 
3349  if( transformed )
3350  {
3351  conshdlr = SCIPfindConshdlr(scip, "indicator");
3352 
3353  /* find artificial linear constraints which correspond to indicator constraints to avoid double printing */
3354  if( conshdlr != NULL )
3355  {
3356  SCIP_CONS** indconss;
3357  int nindconss;
3358 
3359  indconss = SCIPconshdlrGetConss(conshdlr);
3360  nindconss = SCIPconshdlrGetNConss(conshdlr);
3361  assert(indconss != NULL || nindconss == 0);
3362 
3363  if( nindconss > 0 )
3364  {
3365  SCIP_CONS* lincons;
3366 
3367  /* create the linear constraint of indicator constraints hash map */
3368  SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nindconss) );
3369  assert(indconss != NULL);
3370 
3371  for( c = 0; c < nindconss; ++c )
3372  {
3373  assert(indconss[c] != NULL);
3374  lincons = SCIPgetLinearConsIndicator(indconss[c]);
3375  assert(lincons != NULL);
3376 
3377  /* insert constraint into mapping between */
3378  SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)lincons) );
3379  }
3380  }
3381  }
3382 
3383  conshdlr = SCIPfindConshdlr(scip, "pseudoboolean");
3384 
3385  /* find artifical linear constraints which correspond to indicator constraints to avoid double printing */
3386  if( conshdlr != NULL )
3387  {
3388  SCIP_CONS** pbconss;
3389  int npbconss;
3390 
3391  pbconss = SCIPconshdlrGetConss(conshdlr);
3392  npbconss = SCIPconshdlrGetNConss(conshdlr);
3393  assert(pbconss != NULL || npbconss == 0);
3394 
3395  if( npbconss > 0 )
3396  {
3397  SCIP_CONS* lincons;
3398 
3399  /* create the linear constraint of indicator constraints hash map */
3400  SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), npbconss) );
3401 
3402  for( c = 0; c < npbconss; ++c )
3403  {
3404  assert(pbconss[c] != NULL); /*lint !e613*/
3405  lincons = SCIPgetLinearConsPseudoboolean(scip, pbconss[c]); /*lint !e613*/
3406  assert(lincons != NULL);
3407 
3408  /* insert constraint into mapping between */
3409  SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)lincons) );
3410  }
3411  }
3412  }
3413  }
3414  /* in original space we cannot ask the constraint handler for its constraints, therefore we have to loop over all
3415  * original to check for artificial linear once
3416  */
3417  else
3418  {
3419  SCIP_CONS* lincons;
3420  SCIP_Bool pbhashmapcreated = FALSE;
3421  SCIP_Bool indhashmapcreated = FALSE;
3422 
3423  /* loop over all constraint for printing */
3424  for( c = 0; c < nconss; ++c )
3425  {
3426  conshdlr = SCIPconsGetHdlr(conss[c]); /*lint !e613*/
3427  assert(conshdlr != NULL);
3428 
3429  conshdlrname = SCIPconshdlrGetName(conshdlr);
3430 
3431  if( strcmp(conshdlrname, "pseudoboolean") == 0 )
3432  {
3433  if( !pbhashmapcreated )
3434  {
3435  /* create the linear constraint of indicator constraints hash map */
3436  SCIP_CALL( SCIPhashmapCreate(&linconssofpbsmap, SCIPblkmem(scip), nconss) );
3437  pbhashmapcreated = TRUE;
3438  }
3439 
3440  lincons = SCIPgetLinearConsPseudoboolean(scip, conss[c]); /*lint !e613*/
3441  assert(lincons != NULL);
3442 
3443  /* insert constraint into mapping between */
3444  SCIP_CALL( SCIPhashmapInsert(linconssofpbsmap, (void*)lincons, (void*)lincons) );
3445  }
3446  else if( strcmp(conshdlrname, "indicator") == 0 )
3447  {
3448  if( !indhashmapcreated )
3449  {
3450  /* create the linear constraint of indicator constraints hash map */
3451  SCIP_CALL( SCIPhashmapCreate(&linconssofindicatorsmap, SCIPblkmem(scip), nconss) );
3452  indhashmapcreated = TRUE;
3453  }
3454 
3455  lincons = SCIPgetLinearConsIndicator(conss[c]); /*lint !e613*/
3456  assert(lincons != NULL);
3457 
3458  /* insert constraint into mapping between */
3459  SCIP_CALL( SCIPhashmapInsert(linconssofindicatorsmap, (void*)lincons, (void*)lincons) );
3460  }
3461  }
3462  }
3463 
3464  retcode = SCIP_OKAY;
3465  cons = NULL;
3466 
3467  /* loop over all constraint for printing */
3468  for( c = 0; c < nconss && retcode == SCIP_OKAY; ++c )
3469  {
3470  SCIP_CONS* artcons;
3471 
3472  artcons = NULL;
3473 
3474  cons = conss[c]; /*lint !e613 */
3475  assert(cons != NULL);
3476 
3477  conshdlr = SCIPconsGetHdlr(cons);
3478  assert(conshdlr != NULL);
3479 
3480  conshdlrname = SCIPconshdlrGetName(conshdlr);
3481  assert(transformed == SCIPconsIsTransformed(cons));
3482 
3483  /* in case the transformed is written only constraint are posted which are enabled in the current node */
3484  assert(!transformed || SCIPconsIsEnabled(cons));
3485 
3486  if( linconssofpbsmap != NULL )
3487  artcons = (SCIP_CONS*) SCIPhashmapGetImage(linconssofpbsmap, (void*)cons);
3488  if( artcons == NULL && linconssofindicatorsmap != NULL )
3489  artcons = (SCIP_CONS*) SCIPhashmapGetImage(linconssofindicatorsmap, (void*)cons);
3490 
3491  if( artcons == NULL )
3492  {
3493  if( strcmp(conshdlrname, "linear") == 0 )
3494  {
3495  if( SCIPgetNVarsLinear(scip, cons) == 0 )
3496  {
3497  if( SCIPisGT(scip, SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons)) )
3498  {
3499  SCIPerrorMessage("Cannot print empty violated constraint %s, %g <= %g is not fulfilled\n",
3500  SCIPconsGetName(cons), SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons));
3501  }
3502  continue;
3503  }
3504 
3505  if( existands )
3506  {
3507  retcode = printNonLinearCons(scip, file,
3508  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3509  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), resvars, nresvars, andvars, nandvars,
3510  0LL, transformed, multisymbol);
3511  }
3512  else
3513  {
3514  retcode = printLinearCons(scip, file,
3515  SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons), SCIPgetNVarsLinear(scip, cons),
3516  SCIPgetLhsLinear(scip, cons), SCIPgetRhsLinear(scip, cons), 0LL, transformed, multisymbol);
3517  }
3518  }
3519  else if( strcmp(conshdlrname, "setppc") == 0 )
3520  {
3521  consvars = SCIPgetVarsSetppc(scip, cons);
3522  nconsvars = SCIPgetNVarsSetppc(scip, cons);
3523 
3524  if( nconsvars == 0 )
3525  continue;
3526 
3527  switch( SCIPgetTypeSetppc(scip, cons) )
3528  {
3530  if( existands )
3531  {
3532  retcode = printNonLinearCons(scip, file, consvars, NULL, nconsvars, 1.0, 1.0, resvars, nresvars,
3533  andvars, nandvars, 0LL, transformed, multisymbol);
3534  }
3535  else
3536  {
3537  retcode = printLinearCons(scip, file,
3538  consvars, NULL, nconsvars, 1.0, 1.0, 0LL, transformed, multisymbol);
3539  }
3540  break;
3542  if( existands )
3543  {
3544  retcode = printNonLinearCons(scip, file,
3545  consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, resvars, nresvars, andvars, nandvars,
3546  0LL, transformed, multisymbol);
3547  }
3548  else
3549  {
3550  retcode = printLinearCons(scip, file,
3551  consvars, NULL, nconsvars, -SCIPinfinity(scip), 1.0, 0LL, transformed, multisymbol);
3552  }
3553  break;
3555  if( existands )
3556  {
3557  retcode = printNonLinearCons(scip, file,
3558  consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), resvars, nresvars, andvars, nandvars,
3559  0LL, transformed, multisymbol);
3560  }
3561  else
3562  {
3563  retcode = printLinearCons(scip, file,
3564  consvars, NULL, nconsvars, 1.0, SCIPinfinity(scip), 0LL, transformed, multisymbol);
3565  }
3566  break;
3567  }
3568  }
3569  else if( strcmp(conshdlrname, "logicor") == 0 )
3570  {
3571  if( SCIPgetNVarsLogicor(scip, cons) == 0 )
3572  continue;
3573 
3574  if( existands )
3575  {
3576  retcode = printNonLinearCons(scip, file,
3577  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), 1.0, SCIPinfinity(scip),
3578  resvars, nresvars, andvars, nandvars, 0LL, transformed, multisymbol);
3579  }
3580  else
3581  {
3582  retcode = printLinearCons(scip, file,
3583  SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons),
3584  1.0, SCIPinfinity(scip), 0LL, transformed, multisymbol);
3585  }
3586  }
3587  else if( strcmp(conshdlrname, "knapsack") == 0 )
3588  {
3589  SCIP_Longint* weights;
3590 
3591  consvars = SCIPgetVarsKnapsack(scip, cons);
3592  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
3593 
3594  if( nconsvars == 0 )
3595  continue;
3596 
3597  /* copy Longint array to SCIP_Real array */
3598  weights = SCIPgetWeightsKnapsack(scip, cons);
3599  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
3600  for( v = 0; v < nconsvars; ++v )
3601  consvals[v] = (SCIP_Real)weights[v];
3602 
3603  if( existands )
3604  {
3605  retcode = printNonLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
3606  (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), resvars, nresvars, andvars, nandvars,
3607  0LL, transformed, multisymbol);
3608  }
3609  else
3610  {
3611  retcode = printLinearCons(scip, file, consvars, consvals, nconsvars, -SCIPinfinity(scip),
3612  (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), 0LL, transformed, multisymbol);
3613  }
3614 
3615  SCIPfreeBufferArray(scip, &consvals);
3616  }
3617  else if( strcmp(conshdlrname, "varbound") == 0 )
3618  {
3619  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
3620  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, 2) );
3621 
3622  consvars[0] = SCIPgetVarVarbound(scip, cons);
3623  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
3624 
3625  consvals[0] = 1.0;
3626  consvals[1] = SCIPgetVbdcoefVarbound(scip, cons);
3627 
3628  if( existands )
3629  {
3630  retcode = printNonLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
3631  SCIPgetRhsVarbound(scip, cons), resvars, nresvars, andvars, nandvars, 0LL, transformed, multisymbol);
3632  }
3633  else
3634  {
3635  retcode = printLinearCons(scip, file, consvars, consvals, 2, SCIPgetLhsVarbound(scip, cons),
3636  SCIPgetRhsVarbound(scip, cons), 0LL, transformed, multisymbol);
3637  }
3638 
3639  SCIPfreeBufferArray(scip, &consvars);
3640  SCIPfreeBufferArray(scip, &consvals);
3641  }
3642  else if( strcmp(conshdlrname, "pseudoboolean") == 0 )
3643  {
3644  SCIP_VAR*** termvars;
3645  int* ntermvars;
3646  int termvarssize;
3647  SCIP_CONS** andconss;
3648  SCIP_Real* andcoefs ;
3649  SCIP_VAR** linvars;
3650  SCIP_Real* lincoefs ;
3651  int nlinvars;
3652  int t;
3653 
3654  /* get the required array size for the variables array and for the number of variables in each variable array */
3655  termvarssize = SCIPgetNAndsPseudoboolean(scip, cons);
3656  assert(termvarssize >= 0);
3657 
3658  /* allocate temporary memory */
3659  SCIP_CALL( SCIPallocBufferArray(scip, &andconss, termvarssize) );
3660  SCIP_CALL( SCIPallocBufferArray(scip, &termvars, termvarssize) );
3661  SCIP_CALL( SCIPallocBufferArray(scip, &andcoefs, termvarssize) );
3662  SCIP_CALL( SCIPallocBufferArray(scip, &ntermvars, termvarssize) );
3663 
3664  /* get all corresponding and-constraints and therefor all variables */
3665  SCIP_CALL( SCIPgetAndDatasPseudoboolean(scip, cons, andconss, andcoefs, &termvarssize) );
3666  for( t = termvarssize - 1; t >= 0; --t )
3667  {
3668  termvars[t] = SCIPgetVarsAnd(scip, andconss[t]);
3669  ntermvars[t] = SCIPgetNVarsAnd(scip, andconss[t]);
3670  }
3671 
3672  /* gets number of linear variables without artificial terms variables of pseudoboolean constraint */
3673  nlinvars = SCIPgetNLinVarsWithoutAndPseudoboolean(scip, cons);
3674 
3675  /* allocate temporary memory */
3676  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinvars) );
3677  SCIP_CALL( SCIPallocBufferArray(scip, &lincoefs, nlinvars) );
3678 
3679  /* gets linear constraint of pseudoboolean constraint */
3680  SCIP_CALL( SCIPgetLinDatasWithoutAndPseudoboolean(scip, cons, linvars, lincoefs, &nlinvars) );
3681 
3682  retcode = printPseudobooleanCons(scip, file, linvars, lincoefs, nlinvars,
3683  termvars, ntermvars, andcoefs, termvarssize, SCIPgetIndVarPseudoboolean(scip, cons),
3684  SCIPgetLhsPseudoboolean(scip, cons), SCIPgetRhsPseudoboolean(scip, cons), transformed, multisymbol);
3685 
3686  /* free temporary memory */
3687  SCIPfreeBufferArray(scip, &lincoefs);
3688  SCIPfreeBufferArray(scip, &linvars);
3689  SCIPfreeBufferArray(scip, &ntermvars);
3690  SCIPfreeBufferArray(scip, &andcoefs);
3691  SCIPfreeBufferArray(scip, &termvars);
3692  SCIPfreeBufferArray(scip, &andconss);
3693  }
3694  else if( strcmp(conshdlrname, "indicator") == 0 )
3695  {
3696  SCIP_CONS* lincons;
3697  SCIP_VAR* indvar;
3698  SCIP_VAR* slackvar;
3699  SCIP_Longint weight;
3700 
3701  /* get artificial binary indicator variables */
3702  indvar = SCIPgetBinaryVarIndicator(cons);
3703  assert(indvar != NULL);
3704 
3705  if( SCIPvarGetStatus(indvar) == SCIP_VARSTATUS_NEGATED )
3706  {
3707  indvar = SCIPvarGetNegationVar(indvar);
3708  assert(indvar != NULL);
3710 
3711  /* get the soft cost of this constraint */
3712  weight = (SCIP_Longint) SCIPvarGetObj(indvar);
3713  }
3714  else
3715  {
3717 
3718  /* get the soft cost of this constraint */
3719  weight = -(SCIP_Longint) SCIPvarGetObj(indvar);
3720  }
3721 
3722  /* get artificial slack variable */
3723  slackvar = SCIPgetSlackVarIndicator(cons);
3724  assert(slackvar != NULL);
3725 
3726  /* only need to print indicator constraints with weights on their indicator variable */
3727  if( weight != 0 )
3728  {
3729  SCIP_VAR** scipvarslinear;
3730  SCIP_Real* scipvalslinear;
3731  SCIP_Bool cont;
3732  int nonbinarypos;
3733 
3734  lincons = SCIPgetLinearConsIndicator(cons);
3735  assert(lincons != NULL);
3736 
3737  nconsvars = SCIPgetNVarsLinear(scip, lincons);
3738  scipvarslinear = SCIPgetVarsLinear(scip, lincons);
3739  scipvalslinear = SCIPgetValsLinear(scip, lincons);
3740 
3741  /* allocate temporary memory */
3742  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, scipvarslinear, nconsvars) );
3743  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, scipvalslinear, nconsvars) );
3744 
3745  nonbinarypos = -1;
3746  cont = FALSE;
3747 
3748  /* find non-binary variable */
3749  for( v = 0; v < nconsvars; ++v )
3750  {
3751  if( SCIPvarGetType(consvars[v]) != SCIP_VARTYPE_BINARY )
3752  {
3753  if( consvars[v] == slackvar )
3754  {
3755  assert(nonbinarypos == -1);
3756  nonbinarypos = v;
3757  }
3758  else
3759  {
3760  SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has more than one non-binary variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
3761  SCIPinfoMessage(scip, file, "* ");
3762  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3763  SCIPinfoMessage(scip, file, ";\n");
3764  cont = TRUE;
3765  break;
3766  }
3767  }
3768  }
3769 
3770  /* if we have not found any non-binary variable we do not print the constraint, maybe we should ??? */
3771  if( nonbinarypos == -1 )
3772  {
3773  SCIPwarningMessage(scip, "cannot print linear constraint <%s> of indicator constraint <%s> because it has no slack variable\n", SCIPconsGetName(lincons), SCIPconsGetName(cons) );
3774  SCIPinfoMessage(scip, file, "* ");
3775  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3776  SCIPinfoMessage(scip, file, ";\n");
3777 
3778  /* free temporary memory */
3779  SCIPfreeBufferArray(scip, &consvals);
3780  SCIPfreeBufferArray(scip, &consvars);
3781  continue;
3782  }
3783 
3784  /* if the constraint has more than two non-binary variables is not printable and we go to the next */
3785  if( cont )
3786  {
3787  /* free temporary memory */
3788  SCIPfreeBufferArray(scip, &consvals);
3789  SCIPfreeBufferArray(scip, &consvars);
3790  continue;
3791  }
3792 
3793  assert(0 <= nonbinarypos && nonbinarypos < nconsvars);
3794 
3795  /* remove slackvariable in linear constraint for printing */
3796  --nconsvars;
3797  consvars[nonbinarypos] = consvars[nconsvars];
3798  consvals[nonbinarypos] = consvals[nconsvars];
3799 
3800  if( existands )
3801  {
3802  retcode = printNonLinearCons(scip, file,
3803  consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3804  resvars, nresvars, andvars, nandvars,
3805  weight, transformed, multisymbol);
3806  }
3807  else
3808  {
3809  retcode = printLinearCons(scip, file,
3810  consvars, consvals, nconsvars, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
3811  weight, transformed, multisymbol);
3812  }
3813 
3814  /* free temporary memory */
3815  SCIPfreeBufferArray(scip, &consvals);
3816  SCIPfreeBufferArray(scip, &consvars);
3817  }
3818  else
3819  {
3820  SCIPwarningMessage(scip, "indicator constraint <%s> will not be printed because the indicator variable has no objective value(= weight of this soft constraint)\n", SCIPconsGetName(cons) );
3821  SCIPinfoMessage(scip, file, "* ");
3822  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3823  SCIPinfoMessage(scip, file, ";\n");
3824  }
3825  }
3826  else if( strcmp(conshdlrname, "and") == 0 )
3827  {
3828  /* all resultants of the and constraint will be replaced by all corresponding variables of this constraint,
3829  * so no and-constraint will be printed directly */
3830  assert(existandconshdlr);
3831  }
3832  else
3833  {
3834  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
3835  SCIPinfoMessage(scip, file, "* ");
3836  SCIP_CALL( SCIPprintCons(scip, cons, file) );
3837  SCIPinfoMessage(scip, file, ";\n");
3838  }
3839  }
3840  }
3841 
3842  if( retcode == SCIP_INVALIDDATA )
3843  {
3844  assert(cons != NULL);
3845 
3846  SCIPerrorMessage("Cannot print constraint %s with non-integral coefficient or sides in opb-format\n",
3847  SCIPconsGetName(cons));
3848  SCIP_CALL( SCIPprintCons(scip, cons, stderr) );
3849  SCIPinfoMessage(scip, file, ";\n");
3850  }
3851 
3852  if( linconssofpbsmap != NULL )
3853  {
3854  /* free hash map */
3855  SCIPhashmapFree(&linconssofpbsmap);
3856  }
3857  if( linconssofindicatorsmap != NULL )
3858  {
3859  /* free hash map */
3860  SCIPhashmapFree(&linconssofindicatorsmap);
3861  }
3862 
3863  return retcode;
3864 }
3865 
3866 /* write fixed variables (unless already done because they are an and resultant or and variable) */
3867 static
3869  SCIP*const scip, /**< SCIP data structure */
3870  FILE*const file, /**< output file, or NULL if standard output should be used */
3871  SCIP_VAR** vars, /**< array with active (binary) variables */
3872  int nvars, /**< number of active variables in the problem */
3873  SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
3874  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3875  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3876  )
3877 {
3878  char linebuffer[OPB_MAX_LINELEN+1];
3879  char buffer[OPB_MAX_LINELEN];
3880  int linecnt;
3881  int v;
3882 
3883  assert(scip != NULL);
3884  assert(file != NULL);
3885  assert(vars != NULL || nvars == 0);
3886  assert(printedfixing != NULL);
3887  assert(multisymbol != NULL);
3888 
3889  clearBuffer(linebuffer, &linecnt);
3890 
3891  /* print variables which are fixed */
3892  for( v = 0; v < nvars; ++v )
3893  {
3894  SCIP_VAR* var;
3895  SCIP_Real lb;
3896  SCIP_Real ub;
3897  SCIP_Bool neg = FALSE;
3898 
3899  assert( vars != NULL );
3900  var = vars[v];
3901 
3902  if( transformed )
3903  {
3904  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3905  lb = SCIPvarGetLbLocal(var);
3906  ub = SCIPvarGetUbLocal(var);
3907  }
3908  else
3909  {
3910  lb = SCIPvarGetLbOriginal(var);
3911  ub = SCIPvarGetUbOriginal(var);
3912  }
3913  assert(lb > -0.5 && ub < 1.5);
3914  assert(SCIPisFeasIntegral(scip, lb));
3915  assert(SCIPisFeasIntegral(scip, ub));
3916 
3917  /* print fixed and-resultants */
3918  if( lb > 0.5 || ub < 0.5 )
3919  {
3920  if( transformed ) {
3921  SCIP_CALL( SCIPgetBinvarRepresentative(scip, var, &var, &neg) );
3922  }
3923 
3924  if( SCIPhashtableExists(printedfixing, (void*)var) )
3925  continue;
3926 
3927  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
3928  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
3929 
3930  /* add variable to the hashmap */
3931  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
3932  }
3933  }
3934 
3935  writeBuffer(scip, file, linebuffer, &linecnt);
3936 
3937  return SCIP_OKAY;
3938 }
3939 
3940 /* write and constraints of inactive but relevant and-resultants and and variables which are fixed to one */
3941 static
3943  SCIP*const scip, /**< SCIP data structure */
3944  FILE*const file, /**< output file, or NULL if standard output should be used */
3945  SCIP_VAR**const resvars, /**< array of resultant variables */
3946  int const nresvars, /**< number of resultant variables */
3947  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
3948  int const*const nandvars, /**< array of numbers of corresponding and-variables */
3949  SCIP_HASHTABLE*const printedfixing, /**< hashmap to store if a fixed variable was already printed */
3950  char const*const multisymbol, /**< the multiplication symbol to use between coefficient and variable */
3951  SCIP_Bool const transformed /**< TRUE iff problem is the transformed problem */
3952  )
3953 {
3954  SCIP_VAR* resvar;
3955  SCIP_Longint rhslhs;
3956  char linebuffer[OPB_MAX_LINELEN+1];
3957  char buffer[OPB_MAX_LINELEN];
3958  int linecnt;
3959  int r, v;
3960 
3961  assert(scip != NULL);
3962  assert(file != NULL);
3963  assert(resvars != NULL || nresvars == 0);
3964  assert(nandvars != NULL || nresvars == 0);
3965  assert(andvars != NULL || nandvars == NULL);
3966  assert(multisymbol != NULL);
3967 
3968  clearBuffer(linebuffer, &linecnt);
3969 
3970  /* print and-variables which are fixed */
3971  /* @todo remove this block here and the hashtable and let writeOpbFixedVars() do the job? */
3972  for( r = nresvars - 1; r >= 0; --r )
3973  {
3974  SCIP_VAR* var;
3975  SCIP_Bool neg;
3976  SCIP_Real lb;
3977  SCIP_Real ub;
3978 
3979  assert( resvars != NULL );
3980  resvar = resvars[r];
3981 
3982  if( transformed )
3983  {
3984  /* in case the transformed is written only local bounds are posted which are valid in the current node */
3985  lb = SCIPvarGetLbLocal(resvar);
3986  ub = SCIPvarGetUbLocal(resvar);
3987  }
3988  else
3989  {
3990  lb = SCIPvarGetLbOriginal(resvar);
3991  ub = SCIPvarGetUbOriginal(resvar);
3992  }
3993 
3994  /* print fixed and-resultants */
3995  if( lb > 0.5 || ub < 0.5 )
3996  {
3997  /* coverity[copy_paste_error] */
3998  SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &var, &neg) );
3999 
4000  assert(SCIPisFeasIntegral(scip, lb));
4001  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
4002  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4003 
4004  /* add variable to the hashmap */
4005  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
4006  }
4007 
4008  assert( andvars != NULL && nandvars != NULL );
4009  assert( andvars[r] != NULL || nandvars[r] == 0 );
4010 
4011  /* print fixed and-variables */
4012  for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
4013  {
4014  assert( andvars[r] != NULL );
4015  assert( andvars[r][v] != NULL );
4016 
4017  if( transformed )
4018  {
4019  /* in case the transformed is written only local bounds are posted which are valid in the current node */
4020  lb = SCIPvarGetLbLocal(andvars[r][v]);
4021  ub = SCIPvarGetUbLocal(andvars[r][v]);
4022  }
4023  else
4024  {
4025  lb = SCIPvarGetLbOriginal(andvars[r][v]);
4026  ub = SCIPvarGetUbOriginal(andvars[r][v]);
4027  }
4028 
4029  if( lb > 0.5 || ub < 0.5 )
4030  {
4031  SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
4032 
4033  assert(SCIPisFeasIntegral(scip, lb));
4034  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "+1%s%s%s = %g ;\n", multisymbol, neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"), lb);
4035  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4036 
4037  /* add variable to the hashmap */
4038  SCIP_CALL( SCIPhashtableInsert(printedfixing, (void*)var) );
4039  }
4040  }
4041  }
4042 
4043  /* print and-constraints with fixed and-resultant to zero and all and-constraints with
4044  * aggregated resultant, otherwise we would loose this information
4045  */
4046  for( r = nresvars - 1; r >= 0; --r )
4047  {
4048  assert( resvars != NULL );
4049  resvar = resvars[r];
4050  rhslhs = (SCIPvarGetUbLocal(resvar) < 0.5) ? 0 : ((SCIPvarGetLbLocal(resvar) > 0.5) ? 1 : -1);
4051 
4052  /* if and resultant is fixed to 0 and at least one and-variable is fixed to zero, we don't print this redundant constraint */
4053  if( rhslhs == 0 )
4054  {
4055  SCIP_Bool cont;
4056 
4057  cont = FALSE;
4058 
4059  assert( andvars != NULL && nandvars != NULL );
4060  assert( andvars[r] != NULL || nandvars[r] == 0 );
4061 
4062  /* if resultant variable and one other and variable is already zero, so we did not need to print this and
4063  * constraint because all other variables are free
4064  */
4065  for( v = nandvars[r] - 1; v >= 0; --v ) /*lint !e613 */
4066  {
4067  assert( andvars[r] != NULL );
4068  assert( andvars[r][v] != NULL );
4069 
4070  if( SCIPvarGetUbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
4071  {
4072  cont = TRUE;
4073  break;
4074  }
4075  }
4076 
4077  if( cont )
4078  continue;
4079  }
4080  /* if and resultant is fixed to 1 and all and-variable are fixed to 1 too, we don't print this redundant constraint */
4081  else if( rhslhs == 1 )
4082  {
4083  SCIP_Bool cont;
4084 
4085  cont = TRUE;
4086 
4087  assert( andvars != NULL && nandvars != NULL );
4088  assert( andvars[r] != NULL || nandvars[r] == 0 );
4089 
4090  /* if all variables are already fixed to one, we do not need to print this and constraint */
4091  for( v = nandvars[r] - 1; v >= 0; --v )
4092  {
4093  assert( andvars[r] != NULL );
4094  assert( andvars[r][v] != NULL );
4095 
4096  if( SCIPvarGetLbLocal(andvars[r][v]) < 0.5 ) /*lint !e613 */
4097  {
4098  cont = FALSE;
4099  break;
4100  }
4101  }
4102 
4103  if( cont )
4104  continue;
4105  }
4106 
4107  /* print and with fixed or aggregated and-resultant */
4108  /* rhslhs equals to 0 means the and constraint is relevant due to it's not clear on which values the and variables are
4109  * rhslhs equals to 1 means the and constraint is irrelevant cause all and variables have to be 1 too
4110  * rhslhs equals to -1 means the and constraint is relevant cause the variable is only aggregated */
4111  if( !SCIPvarIsActive(resvar) )
4112  {
4113  SCIP_VAR* var;
4114  SCIP_Bool neg;
4115  SCIP_Bool firstprinted;
4116 
4117  firstprinted = FALSE;
4118 
4119  assert( andvars != NULL && nandvars != NULL );
4120  assert( andvars[r] != NULL || nandvars[r] == 0 );
4121 
4122  for( v = nandvars[r] - 1; v >= 0; --v )
4123  {
4124  assert( andvars[r] != NULL );
4125  assert( andvars[r][v] != NULL );
4126 
4127  SCIP_CALL( SCIPgetBinvarRepresentative(scip, andvars[r][v], &var, &neg) ); /*lint !e613 */
4128 
4129  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", (firstprinted) ? multisymbol : "", neg ? "~" : "", strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(var) : var), "x"));
4130  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4131 
4132  firstprinted = TRUE;
4133  }
4134 
4135  /* if the resultant is aggregated we need to print his binary representation */
4136  if( rhslhs == -1 )
4137  {
4138  int pos;
4139 
4140  assert(transformed);
4141 
4142  SCIP_CALL( SCIPgetBinvarRepresentative(scip, resvar, &resvar, &neg) );
4143 
4144 #ifndef NDEBUG
4145  if( neg )
4146  assert(SCIPvarIsActive(SCIPvarGetNegationVar(resvar)));
4147  else
4148  assert(SCIPvarIsActive(resvar));
4149 #endif
4150 
4151  /* replace and-resultant with corresponding variables */
4152  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, neg ? SCIPvarGetNegationVar(resvar) : resvar, nresvars, &pos) )
4153  {
4154  SCIP_Bool negated;
4155  int a;
4156 
4157  assert(andvars != NULL);
4158  assert(nandvars != NULL);
4159  assert(pos >= 0 && nandvars[pos] > 0 && andvars[pos] != NULL);
4160  assert(andvars[pos][nandvars[pos] - 1] != NULL);
4161 
4162  negated = SCIPvarIsNegated(andvars[pos][nandvars[pos] - 1]);
4163 
4164  /* print and-vars */
4165  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, neg ? " +1%s%s%s" : " -1%s%s%s", multisymbol, negated ? "~" : "",
4166  strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][nandvars[pos] - 1]) : andvars[pos][nandvars[pos] - 1]), "x"));
4167  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4168 
4169  for(a = nandvars[pos] - 2; a >= 0; --a )
4170  {
4171  negated = SCIPvarIsNegated(andvars[pos][a]);
4172 
4173  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, "%s%s%s", multisymbol, negated ? "~" : "", strstr(SCIPvarGetName(negated ? SCIPvarGetNegationVar(andvars[pos][a]) : andvars[pos][a]), "x"));
4174  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4175  }
4176 
4177  appendBuffer(scip, file, linebuffer, &linecnt, " ");
4178 
4179  if( neg )
4180  rhslhs = 1;
4181  else
4182  rhslhs = 0;
4183  }
4184  else
4185  {
4186  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " -1%s%s%s", multisymbol, neg ? "~" : "",
4187  strstr(SCIPvarGetName(neg ? SCIPvarGetNegationVar(resvar) : resvar), "x"));
4188  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4189 
4190  rhslhs = 0;
4191  }
4192  }
4193 
4194  /* print rhslhs */
4195  (void) SCIPsnprintf(buffer, OPB_MAX_LINELEN, " = %" SCIP_LONGINT_FORMAT " ;\n", rhslhs);
4196  appendBuffer(scip, file, linebuffer, &linecnt, buffer);
4197 
4198  writeBuffer(scip, file, linebuffer, &linecnt);
4199  }
4200  }
4201 
4202  return SCIP_OKAY;
4203 }
4204 
4205 /* writes problem to file */
4206 static
4208  SCIP* scip, /**< SCIP data structure */
4209  FILE* file, /**< output file, or NULL if standard output should be used */
4210  const char* name, /**< problem name */
4211  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4212  SCIP_OBJSENSE objsense, /**< objective sense */
4213  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4214  * extobj = objsense * objscale * (intobj + objoffset) */
4215  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4216  SCIP_VAR** vars, /**< array with active (binary) variables */
4217  int nvars, /**< number of active variables in the problem */
4218  SCIP_CONS** conss, /**< array with constraints of the problem */
4219  int nconss, /**< number of constraints in the problem */
4220  SCIP_VAR** const resvars, /**< array of resultant variables */
4221  int const nresvars, /**< number of resultant variables */
4222  SCIP_VAR**const*const andvars, /**< corresponding array of and-variables */
4223  int const*const nandvars, /**< array of numbers of corresponding and-variables */
4224  SCIP_Bool const existandconshdlr, /**< does and-constrainthandler exist? */
4225  SCIP_Bool const existands, /**< does some and-constraints exist? */
4226  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
4227  )
4228 {
4229  char multisymbol[OPB_MAX_LINELEN];
4230  SCIP_HASHTABLE* printedfixing;
4231  SCIP_Bool usesymbol;
4232  SCIP_RETCODE retcode;
4233  int nlinearconss;
4234  int nsplitlinearconss;
4235 
4236  assert( scip != NULL );
4237  assert( vars != NULL || nvars == 0 );
4238  assert( conss != NULL || nconss == 0 );
4239  assert( result != NULL );
4240 
4241  /* check if should use a multipliers symbol star '*' between coefficients and variables */
4242  SCIP_CALL( SCIPgetBoolParam(scip, "reading/" READER_NAME "/multisymbol", &usesymbol) );
4243  (void) SCIPsnprintf(multisymbol, OPB_MAX_LINELEN, "%s", usesymbol ? " * " : " ");
4244 
4245  /* determine how many linear constraints are split */
4246  determineTotalNumberLinearConss(scip, conss, nconss, &nlinearconss, &nsplitlinearconss);
4247 
4248  /* print statistics as comment to file */
4249  SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4250  SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4251  SCIPinfoMessage(scip, file, "* Variables : %d (all binary)\n", nvars);
4252  SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss - nlinearconss + nsplitlinearconss);
4253 
4254  /* create a hash table */
4255  SCIP_CALL( SCIPhashtableCreate(&printedfixing, SCIPblkmem(scip), nvars,
4256  SCIPvarGetHashkey, SCIPvarIsHashkeyEq, SCIPvarGetHashkeyVal, NULL) );
4257 
4258  /* write objective function */
4259  SCIP_CALL( writeOpbObjective(scip, file, vars, nvars, resvars, nresvars, andvars, nandvars,
4260  objsense, objscale, objoffset, multisymbol, existands, transformed) );
4261 
4262  /* write constraints */
4263  retcode = writeOpbConstraints(scip, file, conss, nconss, vars, nvars, resvars, nresvars, andvars, nandvars,
4264  multisymbol, existandconshdlr, existands, transformed);
4265 
4266  if( existands && (retcode == SCIP_OKAY) )
4267  {
4268  /* write and constraints of inactive but relevant and-resultants and and-variables which are fixed to one
4269  with no fixed and resultant */
4270  SCIP_CALL( writeOpbRelevantAnds(scip, file, resvars, nresvars, andvars, nandvars, printedfixing, multisymbol, transformed) );
4271  }
4272 
4273  /* write fixed variables */
4274  SCIP_CALL( writeOpbFixedVars(scip, file, vars, nvars, printedfixing, multisymbol, transformed) );
4275 
4276  SCIPhashtableFree(&printedfixing);
4277 
4278  *result = SCIP_SUCCESS;
4279 
4280  return retcode;
4281 }
4282 
4283 
4284 /*
4285  * extern methods
4286  */
4287 
4288 /** reads problem from file */
4290  SCIP* scip, /**< SCIP data structure */
4291  SCIP_READER* reader, /**< the file reader itself */
4292  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
4293  SCIP_RESULT* result /**< pointer to store the result of the file reading call */
4294  )
4295 { /*lint --e{715}*/
4296  OPBINPUT opbinput;
4297  SCIP_RETCODE retcode;
4298  int i;
4299 
4300  assert(scip != NULL); /* for lint */
4301  assert(reader != NULL);
4302 
4303  /* initialize OPB input data */
4304  opbinput.file = NULL;
4305  opbinput.linebuf[0] = '\0';
4306  SCIP_CALL( SCIPallocBufferArray(scip, &opbinput.token, OPB_MAX_LINELEN) );
4307  opbinput.token[0] = '\0';
4308  SCIP_CALL( SCIPallocBufferArray(scip, &opbinput.tokenbuf, OPB_MAX_LINELEN) );
4309  opbinput.tokenbuf[0] = '\0';
4310  for( i = 0; i < OPB_MAX_PUSHEDTOKENS; ++i )
4311  {
4312  SCIP_CALL( SCIPallocBufferArray(scip, &(opbinput.pushedtokens[i]), OPB_MAX_LINELEN) ); /*lint !e866 */
4313  }
4314 
4315  opbinput.npushedtokens = 0;
4316  opbinput.linenumber = 1;
4317  opbinput.bufpos = 0;
4318  opbinput.linepos = 0;
4319  opbinput.objsense = SCIP_OBJSENSE_MINIMIZE;
4320  opbinput.comment = FALSE;
4321  opbinput.endline = FALSE;
4322  opbinput.eof = FALSE;
4323  opbinput.haserror = FALSE;
4324  opbinput.nproblemcoeffs = 0;
4325  opbinput.wbo = FALSE;
4326  opbinput.topcost = -SCIPinfinity(scip);
4327  opbinput.nindvars = 0;
4328 #if GENCONSNAMES == TRUE
4329  opbinput.consnumber = 0;
4330 #endif
4331 
4332  /* read the file */
4333  retcode = readOPBFile(scip, &opbinput, filename);
4334 
4335  /* free dynamically allocated memory */
4336  for( i = OPB_MAX_PUSHEDTOKENS - 1; i >= 0; --i )
4337  {
4338  SCIPfreeBufferArrayNull(scip, &(opbinput.pushedtokens[i]));
4339  }
4340  SCIPfreeBufferArrayNull(scip, &opbinput.tokenbuf);
4341  SCIPfreeBufferArrayNull(scip, &opbinput.token);
4342 
4343  if( retcode == SCIP_PLUGINNOTFOUND )
4344  retcode = SCIP_READERROR;
4345 
4346  SCIP_CALL( retcode );
4347 
4348  if( opbinput.nproblemcoeffs > 0 )
4349  {
4350  SCIPwarningMessage(scip, "there might be <%d> coefficients or weight out of range!\n", opbinput.nproblemcoeffs);
4351  }
4352 
4353  /* evaluate the result */
4354  if( opbinput.haserror )
4355  return SCIP_READERROR;
4356  else
4357  {
4358  /* set objective sense */
4359  SCIP_CALL( SCIPsetObjsense(scip, opbinput.objsense) );
4360  *result = SCIP_SUCCESS;
4361  }
4362 
4363  return SCIP_OKAY;
4364 }
4365 
4366 /** writes problem to file */
4368  SCIP* scip, /**< SCIP data structure */
4369  FILE* file, /**< output file, or NULL if standard output should be used */
4370  const char* name, /**< problem name */
4371  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
4372  SCIP_OBJSENSE objsense, /**< objective sense */
4373  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
4374  * extobj = objsense * objscale * (intobj + objoffset) */
4375  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
4376  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
4377  int nvars, /**< number of active variables in the problem */
4378  int nbinvars, /**< number of binary variables */
4379  int nintvars, /**< number of general integer variables */
4380  int nimplvars, /**< number of implicit integer variables */
4381  int ncontvars, /**< number of continuous variables */
4382  SCIP_VAR** fixedvars, /**< array with fixed variables */
4383  int nfixedvars, /**< number of fixed and aggregated variables in the problem */
4384  SCIP_CONS** conss, /**< array with constraints of the problem */
4385  int nconss, /**< number of constraints in the problem */
4386  SCIP_Bool genericnames, /**< should generic variable and constraint names be used */
4387  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
4388  )
4389 { /*lint --e{715}*/
4390  SCIP_RETCODE retcode = SCIP_OKAY;
4391 
4392  if( nvars != nbinvars && (nintvars > 0 || SCIPfindConshdlr(scip, "indicator") != NULL
4393  || ncontvars + nimplvars != SCIPconshdlrGetNConss(SCIPfindConshdlr(scip, "indicator"))) )
4394  {
4395  SCIPwarningMessage(scip, "only binary problems can be written in OPB format.\n");
4396  *result = SCIP_DIDNOTRUN;
4397  }
4398  else
4399  {
4400  SCIP_VAR*** andvars;
4401  SCIP_VAR** resvars;
4402  int* nandvars;
4403  SCIP_Bool existands;
4404  SCIP_Bool existandconshdlr;
4405  int nresvars;
4406  int v;
4407 
4408  /* computes all and-resultants and their corresponding constraint variables */
4409  /* coverity[leaked_storage] */
4410  SCIP_CALL( computeAndConstraintInfos(scip, transformed, &resvars, &nresvars, &andvars, &nandvars, &existandconshdlr, &existands) );
4411 
4412  if( genericnames )
4413  {
4414 #ifndef NDEBUG
4415  /* check for correct names for opb-format */
4416  int idx;
4417  int pos;
4418 
4419  for( v = nvars - 1; v >= 0; --v )
4420  {
4421  if( existands )
4422  {
4423  /* and variables are artificial */
4424  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4425  continue;
4426  }
4427 
4428  assert(sscanf(SCIPvarGetName(vars[v]), "x%d", &idx) == 1);
4429  }
4430 #endif
4431  retcode = writeOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4432  nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
4433  }
4434  else
4435  {
4436  SCIP_Bool printed;
4437  int idx;
4438  int pos;
4439 
4440  printed = FALSE;
4441 
4442  /* check if there are already generic names for all (not fixed variables)*/
4443  for( v = nvars - 1; v >= 0; --v )
4444  if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4445  {
4446  if( sscanf(SCIPvarGetName(vars[v]), transformed ? "t_x%d" : "x%d", &idx) != 1 && strstr(SCIPvarGetName(vars[v]), INDICATORVARNAME) == NULL && strstr(SCIPvarGetName(vars[v]), INDICATORSLACKVARNAME) == NULL )
4447  {
4448  SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
4449  SCIP_CALL( SCIPprintVar(scip, vars[v], NULL) );
4450  SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
4451 
4452  if( transformed )
4453  {
4454  SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
4455  SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
4456  }
4457  else
4458  {
4459  SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
4460  SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
4461  }
4462  printed = TRUE;
4463  break;
4464  }
4465  }
4466 
4467  if( !printed )
4468  {
4469  /* check if there are already generic names for all (fixed variables)*/
4470  for( v = nfixedvars - 1; v >= 0; --v )
4471  if( !existands || !SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4472  {
4473  /* coverity[secure_coding] */
4474  if( sscanf(SCIPvarGetName(fixedvars[v]), transformed ? "t_x%d" : "x%d", &idx) != 1 && strstr(SCIPvarGetName(fixedvars[v]), INDICATORVARNAME) == NULL && strstr(SCIPvarGetName(fixedvars[v]), INDICATORSLACKVARNAME) == NULL )
4475  {
4476  SCIPwarningMessage(scip, "At least following variable name isn't allowed in opb format.\n");
4477  SCIP_CALL( SCIPprintVar(scip, fixedvars[v], NULL) );
4478  SCIPwarningMessage(scip, "OPB format needs generic variable names!\n");
4479 
4480  if( transformed )
4481  {
4482  SCIPwarningMessage(scip, "write transformed problem with generic variable names.\n");
4483  SCIP_CALL( SCIPprintTransProblem(scip, file, "opb", TRUE) );
4484  }
4485  else
4486  {
4487  SCIPwarningMessage(scip, "write original problem with generic variable names.\n");
4488  SCIP_CALL( SCIPprintOrigProblem(scip, file, "opb", TRUE) );
4489  }
4490  printed = TRUE;
4491  break;
4492  }
4493  }
4494  }
4495 
4496  if( !printed )
4497  {
4498 #ifndef NDEBUG
4499  for( v = nvars - 1; v >= 0; --v )
4500  {
4501  if( existands )
4502  {
4503  if( SCIPsortedvecFindPtr((void**)resvars, SCIPvarComp, vars[v], nresvars, &pos) )
4504  continue;
4505  }
4506 
4507  assert(sscanf(SCIPvarGetName(vars[v]), transformed ? "t_x%d" : "x%d", &idx) == 1 || strstr(SCIPvarGetName(vars[v]), INDICATORVARNAME) != NULL || strstr(SCIPvarGetName(vars[v]), INDICATORSLACKVARNAME) != NULL );
4508  }
4509 #endif
4510  retcode = writeOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4511  nvars, conss, nconss, resvars, nresvars, andvars, nandvars, existandconshdlr, existands, result);
4512  }
4513  }
4514 
4515  if( existands )
4516  {
4517  /* free temporary buffers */
4518  assert(resvars != NULL);
4519  assert(andvars != NULL);
4520  assert(nandvars != NULL);
4521 
4522  for( v = nresvars - 1; v >= 0; --v )
4523  {
4524  assert(andvars[v] != NULL);
4525  SCIPfreeMemoryArray(scip, &andvars[v]);
4526  }
4527  SCIPfreeMemoryArray(scip, &nandvars);
4528  SCIPfreeMemoryArray(scip, &andvars);
4529  SCIPfreeMemoryArray(scip, &resvars);
4530  }
4531 
4532  *result = SCIP_SUCCESS;
4533  }
4534 
4535  if( retcode == SCIP_INVALIDDATA )
4536  return SCIP_WRITEERROR;
4537 
4538  return retcode;
4539 }
4540 
4541 /*
4542  * Callback methods of reader
4543  */
4544 
4545 /** copy method for reader plugins (called when SCIP copies plugins) */
4546 static
4547 SCIP_DECL_READERCOPY(readerCopyOpb)
4548 { /*lint --e{715}*/
4549  assert(scip != NULL);
4550  assert(reader != NULL);
4551  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
4552 
4553  /* call inclusion method of reader */
4555 
4556  return SCIP_OKAY;
4557 }
4558 
4559 
4560 /** problem reading method of reader */
4561 static
4562 SCIP_DECL_READERREAD(readerReadOpb)
4563 { /*lint --e{715}*/
4564 
4565  SCIP_CALL( SCIPreadOpb(scip, reader, filename, result) );
4566 
4567  return SCIP_OKAY;
4568 }
4569 
4570 
4571 /** problem writing method of reader */
4572 static
4573 SCIP_DECL_READERWRITE(readerWriteOpb)
4574 { /*lint --e{715}*/
4575 
4576  SCIP_CALL( SCIPwriteOpb(scip, file, name, transformed, objsense, objscale, objoffset, vars,
4577  nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, genericnames, result) );
4578 
4579  return SCIP_OKAY;
4580 }
4581 
4582 /*
4583  * reader specific interface methods
4584  */
4585 
4586 /** includes the opb file reader in SCIP */
4588  SCIP* scip /**< SCIP data structure */
4589  )
4590 {
4591  SCIP_READER* reader;
4592 
4593  /* include reader */
4595 
4596  /* set non fundamental callbacks via setter functions */
4597  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyOpb) );
4598  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadOpb) );
4599  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteOpb) );
4600 
4601  /* add opb reader parameters */
4603  "reading/" READER_NAME "/dynamicconss", "should model constraints be subject to aging?",
4604  NULL, FALSE, FALSE/*TRUE*/, NULL, NULL) ); /* have to be FALSE, otherwise an error might inccur in restart during branch and bound */
4606  "reading/" READER_NAME "/multisymbol", "use '*' between coefficients and variables by writing to problem?",
4607  NULL, TRUE, FALSE, NULL, NULL) );
4608 
4609  return SCIP_OKAY;
4610 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPcreateConsPseudoboolean(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR **linvars, int nlinvars, SCIP_Real *linvals, SCIP_VAR ***terms, int nterms, int *ntermvars, SCIP_Real *termvals, SCIP_VAR *indvar, SCIP_Real weight, SCIP_Bool issoftcons, SCIP_VAR *intvar, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_Real SCIPround(SCIP *scip, SCIP_Real val)
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
SCIP_EXPORT const char * SCIPreaderGetName(SCIP_READER *reader)
Definition: reader.c:548
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3096
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_and.c:5007
#define ARTIFICIALVARNAMEPREFIX
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8174
static void swapTokenBuffer(OPBINPUT *opbinput)
Definition: reader_opb.c:555
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2487
SCIP_EXPORT SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17172
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
public methods for SCIP parameter handling
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
#define READER_DESC
Definition: reader_opb.c:117
#define INDICATORVARNAME
Definition: reader_opb.c:126
#define SCIPduplicateMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:65
static SCIP_RETCODE printNLRow(SCIP *const scip, FILE *const file, char const *const type, SCIP_VAR **const vars, SCIP_Real const *const vals, int const nvars, SCIP_Real lhs, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Longint weight, SCIP_Longint *const mult, char const *const multisymbol)
Definition: reader_opb.c:2552
Constraint handler for variable bound constraints .
SCIP_Real SCIPgetRhsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
static SCIP_RETCODE writeOpb(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, SCIP_CONS **conss, int nconss, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Bool const existandconshdlr, SCIP_Bool const existands, SCIP_RESULT *result)
Definition: reader_opb.c:4207
public methods for memory management
static SCIP_RETCODE readCoefficients(SCIP *const scip, OPBINPUT *const opbinput, char *const name, SCIP_VAR ***linvars, SCIP_Real **lincoefs, int *const nlincoefs, SCIP_VAR ****terms, SCIP_Real **termcoefs, int **ntermvars, int *const ntermcoefs, SCIP_Bool *const newsection, SCIP_Bool *const isNonlinear, SCIP_Bool *const issoftcons, SCIP_Real *const weight)
Definition: reader_opb.c:812
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5160
#define SCIPfreeMemoryArray(scip, ptr)
Definition: scip_mem.h:69
SCIP_EXPORT SCIP_Bool SCIPsortedvecFindPtr(void **ptrarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), void *val, int len, int *pos)
SCIP_RETCODE SCIPprintVar(SCIP *scip, SCIP_VAR *var, FILE *file)
Definition: scip_var.c:9813
SCIP_VAR * SCIPgetIndVarPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2599
#define SCIP_MAXSTRLEN
Definition: def.h:279
static SCIP_Bool isDelimChar(char c)
Definition: reader_opb.c:225
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1240
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:123
#define INDICATORSLACKVARNAME
Definition: reader_opb.c:127
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition: scip_var.c:1594
#define SCIPallocMemoryArray(scip, ptr, num)
Definition: scip_mem.h:53
static SCIP_RETCODE getMaxAndConsDim(SCIP *scip, OPBINPUT *opbinput, const char *filename, SCIP_Real *objoffset)
Definition: reader_opb.c:1606
static SCIP_RETCODE getBinVarsRepresentatives(SCIP *const scip, SCIP_VAR **const vars, int const nvars, SCIP_Bool const transformed)
Definition: reader_opb.c:1806
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4582
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:241
constraint handler for indicator constraints
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:186
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3036
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1986
#define FALSE
Definition: def.h:73
int SCIPgetNLinVarsWithoutAndPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17515
SCIP_RETCODE SCIPsetReaderCopy(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERCOPY((*readercopy)))
Definition: scip_reader.c:138
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17182
#define TRUE
Definition: def.h:72
#define SCIPdebug(x)
Definition: pub_message.h:84
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
#define OPB_INIT_COEFSSIZE
Definition: reader_opb.c:135
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9273
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3201
SCIP_EXPORT SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17340
public methods for problem variables
SCIP_RETCODE SCIPincludeReaderOpb(SCIP *scip)
Definition: reader_opb.c:4587
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:48
static SCIP_RETCODE printPBRow(SCIP *const scip, FILE *const file, const char *type, SCIP_VAR **const linvars, SCIP_Real *const linvals, int const nlinvars, SCIP_VAR ***const termvars, int *const ntermvars, SCIP_Real *const termvals, int const ntermvals, SCIP_Bool **const negatedarrays, SCIP_VAR *const indvar, SCIP_Real lhs, SCIP_Longint *mult, const char *multisymbol)
Definition: reader_opb.c:2967
static void pushBufferToken(OPBINPUT *opbinput)
Definition: reader_opb.c:542
#define TOPCOSTCONSNAME
Definition: reader_opb.c:128
static SCIP_DECL_READERCOPY(readerCopyOpb)
Definition: reader_opb.c:4547
enum OpbExpType OPBEXPTYPE
Definition: reader_opb.c:144
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
Constraint handler for AND constraints, .
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:119
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
#define SCIP_LONGINT_MAX
Definition: def.h:149
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
Constraint handler for the set partitioning / packing / covering constraints .
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:93
public methods for SCIP variables
static SCIP_RETCODE writeOpbConstraints(SCIP *const scip, FILE *const file, SCIP_CONS **const conss, int const nconss, SCIP_VAR **const vars, int const nvars, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, char const *const multisymbol, SCIP_Bool const existandconshdlr, SCIP_Bool const existands, SCIP_Bool const transformed)
Definition: reader_opb.c:3313
int SCIPfseek(SCIP_FILE *stream, long offset, int whence)
Definition: fileio.c:203
#define SCIPdebugMsgPrint
Definition: scip_message.h:70
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE createVariable(SCIP *scip, SCIP_VAR **var, char *name)
Definition: reader_opb.c:704
static SCIP_DECL_READERREAD(readerReadOpb)
Definition: reader_opb.c:4562
SCIP_CONS * SCIPgetLinearConsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5185
public methods for numerical tolerances
SCIP_RETCODE SCIPreadOpb(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result)
Definition: reader_opb.c:4289
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2236
public methods for querying solving statistics
SCIP_RETCODE SCIPaddOrigObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1288
SCIP_RETCODE SCIPsetReaderWrite(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERWRITE((*readerwrite)))
Definition: scip_reader.c:210
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1524
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:144
SCIP_VAR * w
Definition: circlepacking.c:58
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
static void clearBuffer(char *linebuffer, int *linecnt)
Definition: reader_opb.c:2119
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1735
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
static SCIP_Bool isEndingSoftConstraintWeight(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:688
#define SCIPerrorMessage
Definition: pub_message.h:55
static SCIP_RETCODE getActiveVariables(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
Definition: reader_opb.c:1870
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7954
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1941
SCIP_Real SCIPgetVbdcoefVarbound(SCIP *scip, SCIP_CONS *cons)
static const char delimchars[]
Definition: reader_fzn.c:215
SCIP_VAR * SCIPgetBinaryVarIndicator(SCIP_CONS *cons)
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:124
int SCIPfeof(SCIP_FILE *stream)
Definition: fileio.c:218
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:34
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:191
OpbSense
Definition: reader_opb.c:146
#define SCIPreallocMemoryArray(scip, ptr, newnum)
Definition: scip_mem.h:59
static SCIP_Bool isEndLine(OPBINPUT *opbinput)
Definition: reader_opb.c:566
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIPInterval sign(const SCIPInterval &x)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_VAR * SCIPgetVbdvarVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
int SCIPgetNOrigConss(SCIP *scip)
Definition: scip_prob.c:3128
#define READER_EXTENSION
Definition: reader_opb.c:118
#define SCIP_CALL(x)
Definition: def.h:370
static void pushToken(OPBINPUT *opbinput)
Definition: reader_opb.c:529
static SCIP_Bool isValue(SCIP *scip, OPBINPUT *opbinput, SCIP_Real *value)
Definition: reader_opb.c:607
static SCIP_RETCODE writeOpbFixedVars(SCIP *const scip, FILE *const file, SCIP_VAR **vars, int nvars, SCIP_HASHTABLE *const printedfixing, char const *const multisymbol, SCIP_Bool const transformed)
Definition: reader_opb.c:3868
static SCIP_Bool isTokenChar(char c)
Definition: reader_opb.c:246
SCIP_RETCODE SCIPgetBinvarRepresentatives(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **repvars, SCIP_Bool *negated)
Definition: scip_var.c:1641
static SCIP_RETCODE printRow(SCIP *scip, FILE *file, const char *type, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Longint weight, SCIP_Longint *mult, const char *multisymbol)
Definition: reader_opb.c:2783
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:275
OpbExpType
Definition: reader_opb.c:138
SCIP_RETCODE SCIPwriteOpb(SCIP *scip, FILE *file, const char *name, SCIP_Bool transformed, SCIP_OBJSENSE objsense, SCIP_Real objscale, SCIP_Real objoffset, SCIP_VAR **vars, int nvars, int nbinvars, int nintvars, int nimplvars, int ncontvars, SCIP_VAR **fixedvars, int nfixedvars, SCIP_CONS **conss, int nconss, SCIP_Bool genericnames, SCIP_RESULT *result)
Definition: reader_opb.c:4367
static SCIP_Bool isSign(OPBINPUT *opbinput, int *sign)
Definition: reader_opb.c:580
public methods for constraint handler plugins and constraints
static const char commentchars[]
Definition: reader_opb.c:183
wrapper functions to map file i/o to standard or zlib file i/o
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPinfinity(SCIP *scip)
public data structures and miscellaneous methods
SCIP_EXPORT SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17493
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2286
#define SCIP_Bool
Definition: def.h:70
#define READER_NAME
Definition: reader_opb.c:116
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3014
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition: scip_prob.c:2941
static SCIP_Bool getNextLine(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:313
static void determineTotalNumberLinearConss(SCIP *const scip, SCIP_CONS **const conss, int const nconss, int *nlinearconss, int *nsplitlinearconss)
Definition: reader_opb.c:3256
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
static SCIP_Bool isValueChar(char c, char nextc, SCIP_Bool firstchar, SCIP_Bool *hasdot, OPBEXPTYPE *exptype)
Definition: reader_opb.c:269
static SCIP_RETCODE writeOpbRelevantAnds(SCIP *const scip, FILE *const file, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_HASHTABLE *const printedfixing, char const *const multisymbol, SCIP_Bool const transformed)
Definition: reader_opb.c:3942
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2473
static SCIP_RETCODE printNonLinearCons(SCIP *const scip, FILE *const file, SCIP_VAR **const vars, SCIP_Real *const vals, int const nvars, SCIP_Real const lhs, SCIP_Real const rhs, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_Longint weight, SCIP_Bool const transformed, char const *const multisymbol)
Definition: reader_opb.c:2686
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:105
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNAndsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
methods for debugging
static void swapPointers(char **pointer1, char **pointer2)
Definition: reader_opb.c:409
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8386
static SCIP_RETCODE readConstraints(SCIP *scip, OPBINPUT *opbinput, int *nNonlinearConss)
Definition: reader_opb.c:1373
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
static void appendBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt, const char *extension)
Definition: reader_opb.c:2157
SCIP_RETCODE SCIPincludeReaderBasic(SCIP *scip, SCIP_READER **readerptr, const char *name, const char *desc, const char *extension, SCIP_READERDATA *readerdata)
Definition: scip_reader.c:100
static SCIP_Bool isSense(OPBINPUT *opbinput, OPBSENSE *sense)
Definition: reader_opb.c:641
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5136
static SCIP_Bool getNextToken(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:423
SCIP_RETCODE SCIPcreateProb(SCIP *scip, const char *name, SCIP_DECL_PROBDELORIG((*probdelorig)), SCIP_DECL_PROBTRANS((*probtrans)), SCIP_DECL_PROBDELTRANS((*probdeltrans)), SCIP_DECL_PROBINITSOL((*probinitsol)), SCIP_DECL_PROBEXITSOL((*probexitsol)), SCIP_DECL_PROBCOPY((*probcopy)), SCIP_PROBDATA *probdata)
Definition: scip_prob.c:107
Constraint handler for linear constraints in their most general form, .
SCIP_EXPORT SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17613
static SCIP_RETCODE computeAndConstraintInfos(SCIP *const scip, SCIP_Bool const transformed, SCIP_VAR ***resvars, int *nresvars, SCIP_VAR ****andvars, int **nandvars, SCIP_Bool *const existandconshdlr, SCIP_Bool *const existands)
Definition: reader_opb.c:1915
static SCIP_RETCODE printPseudobooleanCons(SCIP *const scip, FILE *const file, SCIP_VAR **const linvars, SCIP_Real *const linvals, int const nlinvars, SCIP_VAR ***const termvars, int *const ntermvars, SCIP_Real *const termvals, int const ntermvals, SCIP_VAR *const indvar, SCIP_Real const lhs, SCIP_Real const rhs, SCIP_Bool transformed, const char *multisymbol)
Definition: reader_opb.c:3104
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17723
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2679
SCIP_RETCODE SCIPgetAndDatasPseudoboolean(SCIP *const scip, SCIP_CONS *const cons, SCIP_CONS **const andconss, SCIP_Real *const andcoefs, int *const nandconss)
enum OpbSense OPBSENSE
Definition: reader_opb.c:153
static SCIP_Bool hasError(OPBINPUT *opbinput)
Definition: reader_opb.c:214
SCIP_Real * r
Definition: circlepacking.c:50
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17733
methods for sorting joint arrays of various types
static void writeBuffer(SCIP *scip, FILE *file, char *linebuffer, int *linecnt)
Definition: reader_opb.c:2134
pseudo-Boolean file reader (opb format)
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4507
static const SCIP_Real scalars[]
Definition: lp.c:5731
static SCIP_RETCODE getVariableOrTerm(SCIP *scip, OPBINPUT *opbinput, SCIP_VAR ***vars, int *nvars, int *varssize)
Definition: reader_opb.c:736
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
#define OPB_MAX_PUSHEDTOKENS
Definition: reader_opb.c:134
SCIP_CONS ** SCIPgetOrigConss(SCIP *scip)
Definition: scip_prob.c:3155
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4539
public methods for message output
SCIP_VAR * a
Definition: circlepacking.c:57
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9250
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3048
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8077
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
static SCIP_RETCODE setObjective(SCIP *const scip, OPBINPUT *const opbinput, const char *sense, SCIP_VAR **const linvars, SCIP_Real *const coefs, int const ncoefs, SCIP_VAR ***const terms, SCIP_Real *const termcoefs, int *const ntermvars, int const ntermcoefs)
Definition: reader_opb.c:1165
#define SCIP_Real
Definition: def.h:163
static void syntaxError(SCIP *scip, OPBINPUT *opbinput, const char *msg)
Definition: reader_opb.c:190
public methods for input file readers
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8097
#define OPB_MAX_LINELEN
Definition: reader_opb.c:133
public methods for message handling
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_EXPORT SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12545
SCIP_RETCODE SCIPgetLinDatasWithoutAndPseudoboolean(SCIP *const scip, SCIP_CONS *const cons, SCIP_VAR **const linvars, SCIP_Real *const lincoefs, int *const nlinvars)
void SCIPprintSysError(const char *message)
Definition: misc.c:10513
#define SCIP_Longint
Definition: def.h:148
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4167
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:274
SCIP_Real SCIPgetLhsPseudoboolean(SCIP *const scip, SCIP_CONS *const cons)
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9296
constraint handler for pseudoboolean constraints
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2764
static SCIP_RETCODE writeOpbObjective(SCIP *const scip, FILE *const file, SCIP_VAR **const vars, int const nvars, SCIP_VAR **const resvars, int const nresvars, SCIP_VAR **const *const andvars, int const *const nandvars, SCIP_OBJSENSE const objsense, SCIP_Real const objscale, SCIP_Real const objoffset, char const *const multisymbol, SCIP_Bool const existands, SCIP_Bool const transformed)
Definition: reader_opb.c:2180
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
SCIP_EXPORT SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:17633
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:223
struct OpbInput OPBINPUT
Definition: reader_opb.c:181
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
static SCIP_RETCODE readOPBFile(SCIP *scip, OPBINPUT *opbinput, const char *filename)
Definition: reader_opb.c:1705
public methods for reader plugins
static SCIP_DECL_READERWRITE(readerWriteOpb)
Definition: reader_opb.c:4573
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
#define SCIPABORT()
Definition: def.h:342
public methods for global and local (sub)problems
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10488
static SCIP_RETCODE printLinearCons(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real lhs, SCIP_Real rhs, SCIP_Longint weight, SCIP_Bool transformed, const char *multisymbol)
Definition: reader_opb.c:2878
SCIP_Longint SCIPgetCapacityKnapsack(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17350
SCIP_EXPORT void SCIPsortPtrPtrInt(void **ptrarray1, void **ptrarray2, int *intarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
memory allocation routines
static SCIP_Bool isStartingSoftConstraintWeight(SCIP *scip, OPBINPUT *opbinput)
Definition: reader_opb.c:672