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