Scippy

SCIP

Solving Constraint Integer Programs

ReaderMOP.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program PolySCIP */
4 /* */
5 /* Copyright (C) 2012-2021 Konrad-Zuse-Zentrum */
6 /* fuer Informationstechnik Berlin */
7 /* */
8 /* PolySCIP is distributed under the terms of the ZIB Academic License. */
9 /* */
10 /* You should have received a copy of the ZIB Academic License */
11 /* along with PolySCIP; see the file LICENCE. */
12 /* */
13 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
14 
15 /**
16  * @file ReaderMOP.cpp
17  * @brief Class implementing .mop file reader
18  * @author Sebastian Schenker
19  * @author Timo Strunk
20  *
21  * Adaption of SCIP MPS reader towards MOP format with multiple objectives.
22  * The input file has to follow some simple conventions
23  * - It has to contain a problem in
24  * <a href="http://en.wikipedia.org/wiki/MPS_%28format%29">MPS</a> format
25  * - The file extension must be <code>.mop</code>
26  * - Every row marked <code>N</code> is treated as an objective
27  */
28 
29 #include "ReaderMOP.h"
30 
31 #include <iostream>
32 #include <assert.h>
33 #include <string.h>
34 #include <ctype.h>
35 
36 #include "objscip/objscip.h"
37 #include "prob_data_objectives.h"
38 #include "scip/cons_knapsack.h"
39 #include "scip/cons_indicator.h"
40 #include "scip/cons_linear.h"
41 #include "scip/cons_logicor.h"
42 #include "scip/cons_setppc.h"
43 #include "scip/cons_varbound.h"
44 #include "scip/cons_sos1.h"
45 #include "scip/cons_sos2.h"
46 #include "scip/cons_quadratic.h"
47 #include "scip/cons_soc.h"
49 #include "scip/pub_misc.h"
50 
51 #define MPS_MAX_LINELEN 1024 ///< global define
52 #define MPS_MAX_NAMELEN 256 ///< global define
53 #define MPS_MAX_VALUELEN 26 ///< global define
54 #define MPS_MAX_FIELDLEN 20 ///< global define
55 
56 #define PATCH_CHAR '_' ///< global define
57 #define BLANK ' ' ///< global define
58 
59 /** enum containing all mps sections */
61 {
78 };
79 typedef enum MpsSection MPSSECTION; ///< typedef
80 
81 /** mps input structure */
82 struct MpsInput
83 {
84  MPSSECTION section; ///< MpsSection enum
85  SCIP_FILE* fp; ///< SCIP file pointer
86  int lineno; ///< line number
87  SCIP_OBJSENSE objsense; ///< Objective sense
88  SCIP_Bool haserror; ///< Indicates error
89  char buf[MPS_MAX_LINELEN]; ///< character
90  const char* f0; ///< @todo
91  const char* f1; ///< @todo
92  const char* f2; ///< @todo
93  const char* f3; ///< @todo
94  const char* f4; ///< @todo
95  const char* f5; ///< @todo
96  char probname[MPS_MAX_NAMELEN]; ///< problem name
97  char objname [MPS_MAX_NAMELEN]; ///< objective identifier
98  SCIP_Bool isinteger; ///< Indicates integer
99  SCIP_Bool isnewformat; ///< Indicates new MPS format
100 };
101 typedef struct MpsInput MPSINPUT; ///< typedef
102 
103 /** sparse matrix representation */
104 struct SparseMatrix
105 {
106  SCIP_Real* values; /**< matrix element */
107  SCIP_VAR** columns; /**< corresponding variables */
108  const char** rows; /**< corresponding constraint names */
109  int nentries; /**< number of elements in the arrays */
110  int sentries; /**< number of slots in the arrays */
111 };
112 typedef struct SparseMatrix SPARSEMATRIX; ///< typedef
113 
114 /** creates the mps input structure */
115 static
117  SCIP* scip, /**< SCIP data structure */
118  MPSINPUT** mpsi, /**< mps input structure */
119  SCIP_FILE* fp /**< file object for the input file */
120  )
121 {
122  assert(mpsi != NULL);
123  assert(fp != NULL);
124 
125  SCIP_CALL( SCIPallocBlockMemory(scip, mpsi) );
126 
127  (*mpsi)->section = MPS_NAME;
128  (*mpsi)->fp = fp;
129  (*mpsi)->lineno = 0;
130  (*mpsi)->objsense = SCIP_OBJSENSE_MINIMIZE;
131  (*mpsi)->haserror = FALSE;
132  (*mpsi)->isinteger = FALSE;
133  (*mpsi)->isnewformat = FALSE;
134  (*mpsi)->buf [0] = '\0';
135  (*mpsi)->probname[0] = '\0';
136  (*mpsi)->objname [0] = '\0';
137  (*mpsi)->f0 = NULL;
138  (*mpsi)->f1 = NULL;
139  (*mpsi)->f2 = NULL;
140  (*mpsi)->f3 = NULL;
141  (*mpsi)->f4 = NULL;
142  (*mpsi)->f5 = NULL;
143 
144  return SCIP_OKAY;
145 }
146 
147 /** free the mps input structure */
148 static
150  SCIP* scip, /**< SCIP data structure */
151  MPSINPUT** mpsi /**< mps input structure */
152  )
153 {
154  SCIPfreeBlockMemory(scip, mpsi);
155 }
156 
157 /** returns the current section */
158 static
160  const MPSINPUT* mpsi /**< mps input structure */
161  )
162 {
163  assert(mpsi != NULL);
164 
165  return mpsi->section;
166 }
167 
168 /** return the current value of field 0 */
169 static
170 const char* mpsinputField0(
171  const MPSINPUT* mpsi /**< mps input structure */
172  )
173 {
174  assert(mpsi != NULL);
175 
176  return mpsi->f0;
177 }
178 
179 /** return the current value of field 1 */
180 static
181 const char* mpsinputField1(
182  const MPSINPUT* mpsi /**< mps input structure */
183  )
184 {
185  assert(mpsi != NULL);
186 
187  return mpsi->f1;
188 }
189 
190 /** return the current value of field 2 */
191 static
192 const char* mpsinputField2(
193  const MPSINPUT* mpsi /**< mps input structure */
194  )
195 {
196  assert(mpsi != NULL);
197 
198  return mpsi->f2;
199 }
200 
201 /** return the current value of field 3 */
202 static
203 const char* mpsinputField3(
204  const MPSINPUT* mpsi /**< mps input structure */
205  )
206 {
207  assert(mpsi != NULL);
208 
209  return mpsi->f3;
210 }
211 
212 /** return the current value of field 4 */
213 static
214 const char* mpsinputField4(
215  const MPSINPUT* mpsi /**< mps input structure */
216  )
217 {
218  assert(mpsi != NULL);
219 
220  return mpsi->f4;
221 }
222 
223 /** return the current value of field 5 */
224 static
225 const char* mpsinputField5(
226  const MPSINPUT* mpsi /**< mps input structure */
227  )
228 {
229  assert(mpsi != NULL);
230 
231  return mpsi->f5;
232 }
233 
234 /** returns the objective sense */
235 static
237  const MPSINPUT* mpsi /**< mps input structure */
238  )
239 {
240  assert(mpsi != NULL);
241 
242  return mpsi->objsense;
243 }
244 
245 /** returns if an error was detected */
246 static
248  const MPSINPUT* mpsi /**< mps input structure */
249  )
250 {
251  assert(mpsi != NULL);
252 
253  return mpsi->haserror;
254 }
255 
256 /** returns the value of the Bool "is integer" in the mps input */
257 static
259  const MPSINPUT* mpsi /**< mps input structure */
260  )
261 {
262  assert(mpsi != NULL);
263 
264  return mpsi->isinteger;
265 }
266 
267 /** set the section in the mps input structure to given section */
268 static
270  MPSINPUT* mpsi, /**< mps input structure */
271  MPSSECTION section /**< section that is set */
272  )
273 {
274  assert(mpsi != NULL);
275 
276  mpsi->section = section;
277 }
278 
279 /** set the problem name in the mps input structure to given problem name */
280 static
282  MPSINPUT* mpsi, /**< mps input structure */
283  const char* probname /**< name of the problem to set */
284  )
285 {
286  assert(mpsi != NULL);
287  assert(probname != NULL);
288  assert(strlen(probname) < sizeof(mpsi->probname));
289 
290  (void)SCIPmemccpy(mpsi->probname, probname, '\0', MPS_MAX_NAMELEN - 1);
291 }
292 
293 /** set the objective name in the mps input structure to given objective name */
294 static
296  MPSINPUT* mpsi, /**< mps input structure */
297  const char* objname /**< name of the objective function to set */
298  )
299 {
300  assert(mpsi != NULL);
301  assert(objname != NULL);
302  assert(strlen(objname) < sizeof(mpsi->objname));
303 
304  (void)SCIPmemccpy(mpsi->objname, objname, '\0', MPS_MAX_NAMELEN - 1);
305 }
306 
307 /** set the objective sense in the mps input structure to given objective sense */
308 static
310  MPSINPUT* mpsi, /**< mps input structure */
311  SCIP_OBJSENSE sense /**< sense of the objective function */
312  )
313 {
314  assert(mpsi != NULL);
315 
316  mpsi->objsense = sense;
317 }
318 
319 static
321  MPSINPUT* mpsi /**< mps input structure */
322  )
323 {
324  assert(mpsi != NULL);
325 
326  SCIPerrorMessage("Syntax error in line %d\n", mpsi->lineno);
327  mpsi->section = MPS_ENDATA;
328  mpsi->haserror = TRUE;
329 }
330 
331 /** method post a ignore message */
332 static
334  SCIP* scip, /**< SCIP data structure */
335  MPSINPUT* mpsi, /**< mps input structure */
336  const char* what, /**< what get ignored */
337  const char* what_name, /**< name of that object */
338  const char* entity, /**< entity */
339  const char* entity_name, /**< entity name */
340  SCIP_VERBLEVEL verblevel /**< SCIP verblevel for this message */
341  )
342 {
343  assert(mpsi != NULL);
344  assert(what != NULL);
345  assert(what_name != NULL);
346  assert(entity != NULL);
347  assert(entity_name != NULL);
348 
349  SCIPverbMessage(scip, verblevel, NULL,
350  "Warning line %d: %s \"%s\" for %s \"%s\" ignored\n", mpsi->lineno, what, what_name, entity, entity_name);
351 }
352 
353 /** fill the line from \p pos up to column 80 with blanks. */
354 static
356  char* buf, /**< buffer to clear */
357  unsigned int pos /**< position to start the clearing process */
358  )
359 {
360  unsigned int i;
361 
362  for(i = pos; i < 80; i++)
363  buf[i] = BLANK;
364  buf[80] = '\0';
365 }
366 
367 /** change all blanks inside a field to #PATCH_CHAR. */
368 static
370  char* buf, /**< buffer to patch */
371  int beg, /**< position to begin */
372  int end /**< position to end */
373  )
374 {
375  int i;
376 
377  while( (beg <= end) && (buf[end] == BLANK) )
378  end--;
379 
380  while( (beg <= end) && (buf[beg] == BLANK) )
381  beg++;
382 
383  for( i = beg; i <= end; i++ )
384  if( buf[i] == BLANK )
385  buf[i] = PATCH_CHAR;
386 }
387 
388 /** read a mps format data line and parse the fields. */
389 static
391  MPSINPUT* mpsi /**< mps input structure */
392  )
393 {
394  unsigned int len;
395  unsigned int i;
396  int space;
397  char* s;
398  SCIP_Bool is_marker;
399  SCIP_Bool is_empty;
400  char* nexttok;
401 
402  do
403  {
404  mpsi->f0 = mpsi->f1 = mpsi->f2 = mpsi->f3 = mpsi->f4 = mpsi->f5 = 0;
405  is_marker = FALSE;
406 
407  /* Read until we have not a comment line. */
408  do
409  {
410  mpsi->buf[MPS_MAX_LINELEN-1] = '\0';
411  if( NULL == SCIPfgets(mpsi->buf, sizeof(mpsi->buf), mpsi->fp) )
412  return FALSE;
413  mpsi->lineno++;
414  }
415  while( *mpsi->buf == '*' );
416 
417  /* Normalize line */
418  len = strlen(mpsi->buf);
419 
420  for( i = 0; i < len; i++ )
421  if( (mpsi->buf[i] == '\t') || (mpsi->buf[i] == '\n') || (mpsi->buf[i] == '\r') )
422  mpsi->buf[i] = BLANK;
423 
424  if( len < 80 )
425  clearFrom(mpsi->buf, len);
426 
427  SCIPdebugMessage("line %d: <%s>\n", mpsi->lineno, mpsi->buf);
428 
429  assert(strlen(mpsi->buf) >= 80);
430 
431  /* Look for new section */
432  if( *mpsi->buf != BLANK )
433  {
434  mpsi->f0 = SCIPstrtok(&mpsi->buf[0], " ", &nexttok);
435 
436  assert(mpsi->f0 != 0);
437 
438  mpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
439 
440  return TRUE;
441  }
442 
443  /* If we decide to use the new format we never revert this decision */
444  if( !mpsi->isnewformat )
445  {
446  /* Test for fixed format comments */
447  if( (mpsi->buf[14] == '$') && (mpsi->buf[13] == ' ') )
448  clearFrom(mpsi->buf, 14);
449  else if( (mpsi->buf[39] == '$') && (mpsi->buf[38] == ' ') )
450  clearFrom(mpsi->buf, 39);
451 
452  /* Test for fixed format */
453  space = mpsi->buf[12] | mpsi->buf[13]
454  | mpsi->buf[22] | mpsi->buf[23]
455  | mpsi->buf[36] | mpsi->buf[37] | mpsi->buf[38]
456  | mpsi->buf[47] | mpsi->buf[48]
457  | mpsi->buf[61] | mpsi->buf[62] | mpsi->buf[63];
458 
459  if( space == BLANK )
460  {
461  /* Now we have space at the right positions.
462  * But are there also the non space where they
463  * should be ?
464  */
466 
467  number = isdigit((unsigned char)mpsi->buf[24]) || isdigit((unsigned char)mpsi->buf[25])
468  || isdigit((unsigned char)mpsi->buf[26]) || isdigit((unsigned char)mpsi->buf[27])
469  || isdigit((unsigned char)mpsi->buf[28]) || isdigit((unsigned char)mpsi->buf[29])
470  || isdigit((unsigned char)mpsi->buf[30]) || isdigit((unsigned char)mpsi->buf[31])
471  || isdigit((unsigned char)mpsi->buf[32]) || isdigit((unsigned char)mpsi->buf[33])
472  || isdigit((unsigned char)mpsi->buf[34]) || isdigit((unsigned char)mpsi->buf[35]);
473 
474  /* len < 14 is handle ROW lines with embedded spaces
475  * in the names correctly
476  */
477  if( number || len < 14 )
478  {
479  /* We assume fixed format, so we patch possible embedded spaces. */
480  patchField(mpsi->buf, 4, 12);
481  patchField(mpsi->buf, 14, 22);
482  patchField(mpsi->buf, 39, 47);
483  }
484  else
485  {
486  if( mpsi->section == MPS_COLUMNS || mpsi->section == MPS_RHS
487  || mpsi->section == MPS_RANGES || mpsi->section == MPS_BOUNDS )
488  mpsi->isnewformat = TRUE;
489  }
490  }
491  else
492  {
493  mpsi->isnewformat = TRUE;
494  }
495  }
496  s = &mpsi->buf[1];
497 
498  /* At this point it is not clear if we have a indicator field.
499  * If there is none (e.g. empty) f1 will be the first name field.
500  * If there is one, f2 will be the first name field.
501  *
502  * Initially comment marks '$' are only allowed in the beginning
503  * of the 2nd and 3rd name field. We test all fields but the first.
504  * This makes no difference, since if the $ is at the start of a value
505  * field, the line will be erroneous anyway.
506  */
507  do
508  {
509  if( NULL == (mpsi->f1 = SCIPstrtok(s, " ", &nexttok)) )
510  break;
511 
512  if( (NULL == (mpsi->f2 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f2 == '$') )
513  {
514  mpsi->f2 = 0;
515  break;
516  }
517  if( !strcmp(mpsi->f2, "'MARKER'") )
518  is_marker = TRUE;
519 
520  if( (NULL == (mpsi->f3 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f3 == '$') )
521  {
522  mpsi->f3 = 0;
523  break;
524  }
525  if( is_marker )
526  {
527  if( !strcmp(mpsi->f3, "'INTORG'") )
528  mpsi->isinteger = TRUE;
529  else if( !strcmp(mpsi->f3, "'INTEND'") )
530  mpsi->isinteger = FALSE;
531  else
532  break; /* unknown marker */
533  }
534  if( !strcmp(mpsi->f3, "'MARKER'") )
535  is_marker = TRUE;
536 
537  if( (NULL == (mpsi->f4 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f4 == '$') )
538  {
539  mpsi->f4 = 0;
540  break;
541  }
542  if( is_marker )
543  {
544  if( !strcmp(mpsi->f4, "'INTORG'") )
545  mpsi->isinteger = TRUE;
546  else if( !strcmp(mpsi->f4, "'INTEND'") )
547  mpsi->isinteger = FALSE;
548  else
549  break; /* unknown marker */
550  }
551  if( (NULL == (mpsi->f5 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f5 == '$') )
552  mpsi->f5 = 0;
553  }
554  while( FALSE );
555 
556  /* check for empty lines */
557  is_empty = (mpsi->f0 == NULL && mpsi->f1 == NULL);
558  }
559  while( is_marker || is_empty );
560 
561  return TRUE;
562 }
563 
564 /** Insert \p name as field 1 or 2 and shift all other fields up. */
565 static
567  MPSINPUT* mpsi, /**< mps input structure */
568  const char* name, /**< name to insert */
569  SCIP_Bool second /**< insert as second field? */
570  )
571 {
572  assert(mpsi != NULL);
573  assert(name != NULL);
574 
575  mpsi->f5 = mpsi->f4;
576  mpsi->f4 = mpsi->f3;
577  mpsi->f3 = mpsi->f2;
578 
579  if( second )
580  mpsi->f2 = name;
581  else
582  {
583  mpsi->f2 = mpsi->f1;
584  mpsi->f1 = name;
585  }
586 }
587 
588 /** Process NAME section. */
589 static
591  SCIP* scip, /**< SCIP data structure */
592  MPSINPUT* mpsi /**< mps input structure */
593  )
594 {
595  assert(mpsi != NULL);
596 
597  SCIPdebugMessage("read problem name\n");
598 
599  /* This has to be the Line with the NAME section. */
600  if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL || strcmp(mpsinputField0(mpsi), "NAME") )
601  {
602  mpsinputSyntaxerror(mpsi);
603  return SCIP_OKAY;
604  }
605 
606  /* Sometimes the name is omitted. */
607  mpsinputSetProbname(mpsi, (mpsinputField1(mpsi) == 0) ? "_MOP_" : mpsinputField1(mpsi));
608 
609  /* This hat to be a new section */
610  if( !mpsinputReadLine(mpsi) || (mpsinputField0(mpsi) == NULL) )
611  {
612  mpsinputSyntaxerror(mpsi);
613  return SCIP_OKAY;
614  }
615 
616  if( !strncmp(mpsinputField0(mpsi), "ROWS", 4) )
618  else if( !strncmp(mpsinputField0(mpsi), "USERCUTS", 8) )
620  else if( !strncmp(mpsinputField0(mpsi), "LAZYCONS", 8) )
622  else if( !strncmp(mpsinputField0(mpsi), "OBJSEN", 6) )
624  else if( !strncmp(mpsinputField0(mpsi), "OBJNAME", 7) )
626  else
627  {
628  mpsinputSyntaxerror(mpsi);
629  return SCIP_OKAY;
630  }
631 
632  return SCIP_OKAY;
633 }
634 
635 /** Process OBJSEN section. This Section is a CPLEX extension. */
636 static
638  SCIP* scip, /**< SCIP data structure */
639  MPSINPUT* mpsi /**< mps input structure */
640  )
641 {
642  assert(mpsi != NULL);
643 
644  SCIPdebugMessage("read objective sense\n");
645 
646  /* This has to be the Line with MIN or MAX. */
647  if( !mpsinputReadLine(mpsi) || (mpsinputField1(mpsi) == NULL) )
648  {
649  mpsinputSyntaxerror(mpsi);
650  return SCIP_OKAY;
651  }
652 
653  if( !strncmp(mpsinputField1(mpsi), "MIN", 3) )
655  else if( !strncmp(mpsinputField1(mpsi), "MAX", 3) )
657  else
658  {
659  mpsinputSyntaxerror(mpsi);
660  return SCIP_OKAY;
661  }
662 
663  /* Look for ROWS, USERCUTS, LAZYCONS, or OBJNAME Section */
664  if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
665  {
666  mpsinputSyntaxerror(mpsi);
667  return SCIP_OKAY;
668  }
669 
670  if( !strcmp(mpsinputField0(mpsi), "ROWS") )
672  else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
674  else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
676  else if( !strcmp(mpsinputField0(mpsi), "OBJNAME") )
678  else
679  {
680  mpsinputSyntaxerror(mpsi);
681  return SCIP_OKAY;
682  }
683 
684  return SCIP_OKAY;
685 }
686 
687 /** Process OBJNAME section. This Section is a CPLEX extension. */
688 static
690  SCIP* scip, /**< SCIP data structure */
691  MPSINPUT* mpsi /**< mps input structure */
692  )
693 {
694  assert(mpsi != NULL);
695 
696  SCIPdebugMessage("read objective name\n");
697 
698  /* This has to be the Line with the name. */
699  if( !mpsinputReadLine(mpsi) || mpsinputField1(mpsi) == NULL )
700  {
701  mpsinputSyntaxerror(mpsi);
702  return SCIP_OKAY;
703  }
704 
705  mpsinputSetObjname(mpsi, mpsinputField1(mpsi));
706 
707  /* Look for ROWS, USERCUTS, or LAZYCONS Section */
708  if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
709  {
710  mpsinputSyntaxerror(mpsi);
711  return SCIP_OKAY;
712  }
713  if( !strcmp(mpsinputField0(mpsi), "ROWS") )
715  else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
717  else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
719  else
720  mpsinputSyntaxerror(mpsi);
721 
722  return SCIP_OKAY;
723 }
724 
725 /** Process RHS section. */
726 static
728  MPSINPUT* mpsi, /**< mps input structure */
729  SCIP* scip /**< SCIP data structure */
730  )
731 {
732  char rhsname[MPS_MAX_NAMELEN] = { '\0' };
733  SCIP_CONS* cons;
734  SCIP_Real lhs;
735  SCIP_Real rhs;
736  SCIP_Real val;
737 
738  SCIPdebugMessage("read right hand sides\n");
739 
740  while( mpsinputReadLine(mpsi) )
741  {
742  if( mpsinputField0(mpsi) != NULL )
743  {
744  if( !strcmp(mpsinputField0(mpsi), "RANGES") )
746  else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
748  else if( !strcmp(mpsinputField0(mpsi), "SOS") )
750  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
752  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
754  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
756  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
758  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
760  else
761  break;
762  return SCIP_OKAY;
763  }
764  if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
765  || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
766  mpsinputInsertName(mpsi, "_RHS_", FALSE);
767 
768  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
769  break;
770 
771  if( *rhsname == '\0' )
772  (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
773 
774  if( !strcmp(rhsname, mpsinputField1(mpsi)) )
775  {
776  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
777  if( cons == NULL )
778  mpsinputEntryIgnored(scip, mpsi, "RHS", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
779  else
780  {
781  val = atof(mpsinputField3(mpsi));
782 
783  /* find out the row sense */
784  lhs = SCIPgetLhsLinear(scip, cons);
785  rhs = SCIPgetRhsLinear(scip, cons);
786  if( SCIPisInfinity(scip, -lhs) )
787  {
788  /* lhs = -infinity -> lower or equal */
789  assert(SCIPisZero(scip, rhs));
790  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
791  }
792  else if( SCIPisInfinity(scip, rhs) )
793  {
794  /* rhs = +infinity -> greater or equal */
795  assert(SCIPisZero(scip, lhs));
796  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
797  }
798  else
799  {
800  /* lhs > -infinity, rhs < infinity -> equality */
801  assert(SCIPisZero(scip, lhs));
802  assert(SCIPisZero(scip, rhs));
803  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
804  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
805  }
806  SCIPdebugMessage("RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField2(mpsi), lhs, rhs, val);
807  }
808  if( mpsinputField5(mpsi) != NULL )
809  {
810  cons = SCIPfindCons(scip, mpsinputField4(mpsi));
811  if( cons == NULL )
812  mpsinputEntryIgnored(scip, mpsi, "RHS", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
813  else
814  {
815  val = atof(mpsinputField5(mpsi));
816 
817  /* find out the row sense */
818  lhs = SCIPgetLhsLinear(scip, cons);
819  rhs = SCIPgetRhsLinear(scip, cons);
820  if( SCIPisInfinity(scip, -lhs) )
821  {
822  /* lhs = -infinity -> lower or equal */
823  assert(SCIPisZero(scip, rhs));
824  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
825  }
826  else if( SCIPisInfinity(scip, rhs) )
827  {
828  /* rhs = +infinity -> greater or equal */
829  assert(SCIPisZero(scip, lhs));
830  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
831  }
832  else
833  {
834  /* lhs > -infinity, rhs < infinity -> equality */
835  assert(SCIPisZero(scip, lhs));
836  assert(SCIPisZero(scip, rhs));
837  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
838  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
839  }
840  SCIPdebugMessage("RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField4(mpsi), lhs, rhs, val);
841  }
842  }
843  }
844  }
845  mpsinputSyntaxerror(mpsi);
846 
847  return SCIP_OKAY;
848 }
849 
850 /** Process RANGES section */
851 static
853  MPSINPUT* mpsi, /**< mps input structure */
854  SCIP* scip /**< SCIP data structure */
855  )
856 {
857  char rngname[MPS_MAX_NAMELEN] = { '\0' };
858  SCIP_CONS* cons;
859  SCIP_Real lhs;
860  SCIP_Real rhs;
861  SCIP_Real val;
862 
863  SCIPdebugMessage("read ranges\n");
864 
865  while( mpsinputReadLine(mpsi) )
866  {
867  if( mpsinputField0(mpsi) != NULL )
868  {
869  if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
871  else if( !strcmp(mpsinputField0(mpsi), "SOS") )
873  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
875  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
877  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
879  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
881  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
883  else
884  break;
885  return SCIP_OKAY;
886  }
887  if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
888  || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
889  mpsinputInsertName(mpsi, "_RNG_", FALSE);
890 
891  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
892  break;
893 
894  if( *rngname == '\0' )
895  (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
896 
897  /* The rules are:
898  * Row Sign LHS RHS
899  * ----------------------------------------
900  * G +/- rhs rhs + |range|
901  * L +/- rhs - |range| rhs
902  * E + rhs rhs + range
903  * E - rhs + range rhs
904  * ----------------------------------------
905  */
906  if( !strcmp(rngname, mpsinputField1(mpsi)) )
907  {
908  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
909  if( cons == NULL )
910  mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
911  else
912  {
913  val = atof(mpsinputField3(mpsi));
914 
915  /* find out the row sense */
916  lhs = SCIPgetLhsLinear(scip, cons);
917  rhs = SCIPgetRhsLinear(scip, cons);
918  if( SCIPisInfinity(scip, -lhs) )
919  {
920  /* lhs = -infinity -> lower or equal */
921  SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
922  }
923  else if( SCIPisInfinity(scip, rhs) )
924  {
925  /* rhs = +infinity -> greater or equal */
926  SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
927  }
928  else
929  {
930  /* lhs > -infinity, rhs < infinity -> equality */
931  assert(SCIPisEQ(scip, lhs, rhs));
932  if( val >= 0.0 )
933  {
934  SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
935  }
936  else
937  {
938  SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
939  }
940  }
941  }
942  if( mpsinputField5(mpsi) != NULL )
943  {
944  cons = SCIPfindCons(scip, mpsinputField4(mpsi));
945  if( cons == NULL )
946  mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
947  else
948  {
949  val = atof(mpsinputField5(mpsi));
950 
951  /* find out the row sense */
952  lhs = SCIPgetLhsLinear(scip, cons);
953  rhs = SCIPgetRhsLinear(scip, cons);
954  if( SCIPisInfinity(scip, -lhs) )
955  {
956  /* lhs = -infinity -> lower or equal */
957  SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
958  }
959  else if( SCIPisInfinity(scip, rhs) )
960  {
961  /* rhs = +infinity -> greater or equal */
962  SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
963  }
964  else
965  {
966  /* lhs > -infinity, rhs < infinity -> equality */
967  assert(SCIPisEQ(scip, lhs, rhs));
968  if( val >= 0.0 )
969  {
970  SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
971  }
972  else
973  {
974  SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
975  }
976  }
977  }
978  }
979  }
980  }
981  mpsinputSyntaxerror(mpsi);
982 
983  return SCIP_OKAY;
984 }
985 
986 /** Process BOUNDS section. */
987 static
989  MPSINPUT* mpsi, /**< mps input structure */
990  SCIP* scip /**< SCIP data structure */
991  )
992 {
993  char bndname[MPS_MAX_NAMELEN] = { '\0' };
994  SCIP_VAR* var;
995  SCIP_Real val;
996  SCIP_Bool shifted;
997 
998  SCIP_VAR** semicont;
999  int nsemicont;
1000  int semicontsize;
1001  SCIP_Bool dynamiccols;
1002  SCIP_Bool dynamicconss;
1003 
1004  semicont = NULL;
1005  nsemicont = 0;
1006  semicontsize = 0;
1007 
1008  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols) );
1009  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss) );
1010 
1011  SCIPdebugMessage("read bounds\n");
1012 
1013  while( mpsinputReadLine(mpsi) )
1014  {
1015  if( mpsinputField0(mpsi) != 0 )
1016  {
1017  if( !strcmp(mpsinputField0(mpsi), "SOS") )
1018  mpsinputSetSection(mpsi, MPS_SOS);
1019  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1021  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1023  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1025  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1027  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1029  else
1030  break;
1031  goto READBOUNDS_FINISH;
1032  }
1033 
1034  shifted = FALSE;
1035 
1036  /* Is the value field used ? */
1037  if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
1038  || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
1039  || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
1040  || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
1041  || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
1042  || !strcmp(mpsinputField1(mpsi), "SC") )/* CPLEX extension: semi continuous variable, upper bound given in field 4 */
1043  {
1044  if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
1045  {
1046  mpsinputInsertName(mpsi, "_BND_", TRUE);
1047  shifted = TRUE;
1048  }
1049  }
1050  else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
1051  || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
1052  || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
1053  || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
1054  {
1055  if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
1056  {
1057  mpsinputInsertName(mpsi, "_BND_", TRUE);
1058  shifted = TRUE;
1059  }
1060  }
1061  else
1062  {
1063  mpsinputSyntaxerror(mpsi);
1064  return SCIP_OKAY;
1065  }
1066 
1067  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1068  break;
1069 
1070  if( *bndname == '\0' )
1071  (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1072 
1073  /* Only read the first Bound in section */
1074  if( !strcmp(bndname, mpsinputField2(mpsi)) )
1075  {
1076  SCIP_Bool infeasible;
1077 
1078  var = SCIPfindVar(scip, mpsinputField3(mpsi));
1079  /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
1080  * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
1081  if( var == NULL )
1082  {
1083  SCIP_VAR* varcpy;
1084 
1085  SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
1086  SCIP_VARTYPE_CONTINUOUS, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1087 
1088  SCIP_CALL( SCIPaddVar(scip, var) );
1089  varcpy = var;
1090  SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
1091  /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
1092  }
1093  assert(var != NULL);
1094 
1095  if( mpsinputField4(mpsi) == NULL )
1096  val = 0.0;
1097  else
1098  val = atof(mpsinputField4(mpsi));
1099 
1100  /* if a bound of a binary variable is given, the variable is converted into an integer variable
1101  * with default bounds 0 <= x <= infinity
1102  */
1103  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
1104  {
1105  if( (mpsinputField1(mpsi)[1] == 'I') /* CPLEX extension (Integer Bound) */
1106  || (!(mpsinputField1(mpsi)[0] == 'L' && SCIPisFeasEQ(scip, val, 0.0))
1107  && !(mpsinputField1(mpsi)[0] == 'U' && SCIPisFeasEQ(scip, val, 1.0))) )
1108  {
1109  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), 0.0));
1110  assert(SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(var), 1.0));
1111  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1112  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1113  SCIP_CALL( SCIPchgVarUb(scip, var, SCIPinfinity(scip)) );
1114  }
1115  }
1116 
1117  switch( mpsinputField1(mpsi)[0] )
1118  {
1119  case 'L':
1120  if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1121  {
1122  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1123  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1124  }
1125  SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1126  break;
1127  case 'U':
1128  if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1129  {
1130  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1131  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1132  }
1133  SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1134  break;
1135  case 'S':
1136  assert(mpsinputField1(mpsi)[1] == 'C'); /* CPLEX extension (Semi-Continuous) */
1137  /* remember that variable is semi-continuous */
1138  if( semicontsize <= nsemicont )
1139  {
1140  semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
1141  if( semicont == NULL )
1142  {
1143  SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
1144  }
1145  else
1146  {
1147  SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
1148  }
1149  }
1150  assert(semicont != NULL);
1151  semicont[nsemicont] = var;
1152  ++nsemicont;
1153 
1154  SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1155  break;
1156  case 'F':
1157  if( mpsinputField1(mpsi)[1] == 'X' )
1158  {
1159  SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1160  SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1161  }
1162  else
1163  {
1164  SCIP_CALL( SCIPchgVarLb(scip, var, -SCIPinfinity(scip)) );
1165  SCIP_CALL( SCIPchgVarUb(scip, var, +SCIPinfinity(scip)) );
1166  }
1167  break;
1168  case 'M':
1169  SCIP_CALL( SCIPchgVarLb(scip, var, -SCIPinfinity(scip)) );
1170  break;
1171  case 'P':
1172  SCIP_CALL( SCIPchgVarUb(scip, var, +SCIPinfinity(scip)) );
1173  break;
1174  case 'B' : /* CPLEX extension (Binary) */
1175  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1176  SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1177  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
1178  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1179  break;
1180  default:
1181  mpsinputSyntaxerror(mpsi);
1182  return SCIP_OKAY;
1183  }
1184  }
1185  else
1186  {
1187  /* check for syntax error */
1188  assert(*bndname != '\0');
1189  if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
1190  {
1191  mpsinputSyntaxerror(mpsi);
1192  return SCIP_OKAY;
1193  }
1194 
1195  mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
1196  }
1197  }
1198  mpsinputSyntaxerror(mpsi);
1199 
1200 
1201  READBOUNDS_FINISH:
1202  if( nsemicont > 0 )
1203  {
1204  int i;
1205  SCIP_Real oldlb;
1206  char name[SCIP_MAXSTRLEN];
1207  SCIP_CONS* cons;
1208 
1209  SCIP_VAR* vars[2];
1210  SCIP_BOUNDTYPE boundtypes[2];
1211  SCIP_Real bounds[2];
1212 
1213  assert(semicont != NULL);
1214 
1215  /* add bound disjunction constraints for semi-continuous variables */
1216  for( i = 0; i < nsemicont; ++i )
1217  {
1218  var = semicont[i];
1219 
1220  oldlb = SCIPvarGetLbGlobal(var);
1221  /* if no bound was specified (which we assume if we see lower bound 0.0),
1222  * then the default lower bound for a semi-continuous variable is 1.0 */
1223  if( oldlb == 0.0 )
1224  oldlb = 1.0;
1225 
1226  /* change the lower bound to 0.0 */
1227  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1228 
1229  /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
1230  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
1231 
1232  vars[0] = var;
1233  vars[1] = var;
1234  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1235  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1236  bounds[0] = 0.0;
1237  bounds[1] = oldlb;
1238 
1239  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
1240  !dynamiccols, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, dynamicconss, dynamiccols, FALSE) );
1241  SCIP_CALL( SCIPaddCons(scip, cons) );
1242 
1243  SCIPdebugMessage("add bound disjunction constraint for semi-continuity of <%s>:\n\t", SCIPvarGetName(var));
1244  SCIPdebugPrintCons(scip, cons, NULL);
1245 
1246  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1247  }
1248  }
1249 
1250  SCIPfreeBufferArrayNull(scip, &semicont);
1251 
1252  return SCIP_OKAY;
1253 }
1254 
1255 
1256 /** Process SOS section.
1257  *
1258  * We read the SOS section, which is a nonstandard section introduced by CPLEX.
1259  *
1260  * @note Currently we do not support the standard way of specifying SOS constraints via markers.
1261  */
1262 static
1264  MPSINPUT* mpsi, /**< mps input structure */
1265  SCIP* scip /**< SCIP data structure */
1266  )
1267 {
1268  SCIP_Bool initial;
1269  SCIP_Bool separate;
1270  SCIP_Bool enforce;
1271  SCIP_Bool check;
1272  SCIP_Bool propagate;
1273  SCIP_Bool local;
1274  SCIP_Bool modifiable;
1275  SCIP_Bool dynamic;
1276  SCIP_Bool removable;
1277  char name[MPS_MAX_NAMELEN] = { '\0' };
1278  SCIP_CONS* cons = NULL;
1279  int consType = -1;
1280  int cnt = 0;
1281 
1282  SCIPdebugMessage("read SOS constraints\n");
1283 
1284  /* standard settings for SOS constraints: */
1285  initial = TRUE;
1286  separate = FALSE;
1287  enforce = TRUE;
1288  check = TRUE;
1289  propagate = TRUE;
1290  local = FALSE;
1291  modifiable = FALSE;
1292  dynamic = FALSE;
1293  removable = FALSE;
1294 
1295  /* loop through section */
1296  while( mpsinputReadLine(mpsi) )
1297  {
1298  int type = -1;
1299 
1300  /* check if next section is found */
1301  if( mpsinputField0(mpsi) != NULL )
1302  {
1303  if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1305  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1307  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1309  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1311  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1313  break;
1314  }
1315  if( mpsinputField1(mpsi) == NULL )
1316  {
1317  SCIPerrorMessage("empty data in a non-comment line.\n");
1318  mpsinputSyntaxerror(mpsi);
1319  return SCIP_OKAY;
1320  }
1321 
1322  /* check for new SOS set */
1323  if( strcmp(mpsinputField1(mpsi), "S1") == 0 )
1324  type = 1;
1325  if( strcmp(mpsinputField1(mpsi), "S2") == 0 )
1326  type = 2;
1327 
1328  /* add last constraint and create a new one */
1329  if( type > 0 )
1330  {
1331  assert( type == 1 || type == 2 );
1332  if( cons != NULL )
1333  {
1334  /* add last constraint */
1335  SCIP_CALL( SCIPaddCons(scip, cons) );
1336  SCIPdebugMessage("(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1337  SCIPdebugPrintCons(scip, cons, NULL);
1338  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1339  }
1340 
1341  /* check name */
1342  if( mpsinputField2(mpsi) != NULL )
1343  (void)SCIPmemccpy(name, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1344  else
1345  {
1346  /* create new name */
1347  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "SOS%d", ++cnt);
1348  }
1349 
1350  /* create new SOS constraint */
1351  if( type == 1 )
1352  {
1353  /* we do not know the name of the constraint */
1354  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1355  local, modifiable, dynamic, removable) );
1356  }
1357  else
1358  {
1359  assert( type == 2 );
1360  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1361  local, modifiable, dynamic, removable) );
1362  }
1363  consType = type;
1364  SCIPdebugMessage("created constraint <%s> of type %d.\n", name, type);
1365  /* note: we ignore the priorities! */
1366  }
1367  else
1368  {
1369  /* otherwise we are in the section given variables */
1370  SCIP_VAR* var;
1371  SCIP_Real weight;
1372  char* endptr;
1373 
1374  if( consType != 1 && consType != 2 )
1375  {
1376  SCIPerrorMessage("missing SOS type specification.\n");
1377  mpsinputSyntaxerror(mpsi);
1378  return SCIP_OKAY;
1379  }
1380 
1381  /* get variable */
1382  var = SCIPfindVar(scip, mpsinputField1(mpsi));
1383  if( var == NULL )
1384  {
1385  /* ignore unknown variables - we would not know the type anyway */
1386  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "SOS", name, SCIP_VERBLEVEL_NORMAL);
1387  }
1388  else
1389  {
1390  /* get weight */
1391  weight = strtod(mpsinputField2(mpsi), &endptr);
1392  if( endptr == mpsinputField2(mpsi) || *endptr != '\0' )
1393  {
1394  SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1395  mpsinputSyntaxerror(mpsi);
1396  return SCIP_OKAY;
1397  }
1398 
1399  /* add variable and weight */
1400  assert( consType == 1 || consType == 2 );
1401  switch( consType )
1402  {
1403  case 1:
1404  SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
1405  break;
1406  case 2:
1407  SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
1408  break;
1409  default:
1410  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
1411  SCIPABORT();
1412  }
1413  SCIPdebugMessage("added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
1414  }
1415  /* check other fields */
1416  if( (mpsinputField3(mpsi) != NULL && *mpsinputField3(mpsi) != '\0' ) ||
1417  (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
1418  (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
1419  {
1420  SCIPwarningMessage(scip, "ignoring data in fields 3-5 <%s> <%s> <%s>.\n",
1421  mpsinputField3(mpsi), mpsinputField4(mpsi), mpsinputField5(mpsi));
1422  }
1423  }
1424  }
1425 
1426  if( cons != NULL )
1427  {
1428  /* add last constraint */
1429  SCIP_CALL( SCIPaddCons(scip, cons) );
1430  SCIPdebugMessage("(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1431  SCIPdebugPrintCons(scip, cons, NULL);
1432  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1433  }
1434 
1435  return SCIP_OKAY;
1436 }
1437 
1438 
1439 /** Process QMATRIX or QUADOBJ section.
1440  *
1441  * - We read the QMATRIX or QUADOBJ section, which is a nonstandard section introduced by CPLEX.
1442  * - We create a quadratic constraint for this matrix and add a variable to the objective to
1443  * represent the value of the QMATRIX.
1444  * - For a QMATRIX, we expect that both lower and upper diagonal elements are given and every
1445  * coefficient has to be divided by 2.0.
1446  * - For a QUADOBJ, we expect that only the upper diagonal elements are given and thus only
1447  * coefficients on the diagonal have to be divided by 2.0.
1448  */
1449 static
1451  MPSINPUT* mpsi, /**< mps input structure */
1452  SCIP_Bool isQuadObj, /**< whether we actually read a QUADOBJ section */
1453  SCIP* scip /**< SCIP data structure */
1454  )
1455 {
1456  SCIP_VAR** quadvars1;
1457  SCIP_VAR** quadvars2;
1458  SCIP_Real* quadcoefs;
1459  int cnt = 0; /* number of qmatrix elements processed so far */
1460  int size; /* size of quad* arrays */
1461 
1462  SCIPdebugMessage("read %s objective\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
1463 
1464  size = 1;
1465  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
1466  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
1467  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
1468 
1469  /* loop through section */
1470  while( mpsinputReadLine(mpsi) )
1471  {
1472  /* otherwise we are in the section given variables */
1473  SCIP_VAR* var1;
1474  SCIP_VAR* var2;
1475  SCIP_Real coef;
1476 
1477  /* check if next section is found */
1478  if( mpsinputField0(mpsi) != NULL )
1479  {
1480  if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1482  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1484  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1486  break;
1487  }
1488  if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
1489  {
1490  SCIPerrorMessage("empty data in a non-comment line.\n");
1491  mpsinputSyntaxerror(mpsi);
1492  SCIPfreeBufferArray(scip, &quadvars1);
1493  SCIPfreeBufferArray(scip, &quadvars2);
1494  SCIPfreeBufferArray(scip, &quadcoefs);
1495  return SCIP_OKAY;
1496  }
1497 
1498  /* get first variable */
1499  var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
1500  if( var1 == NULL )
1501  {
1502  /* ignore unknown variables - we would not know the type anyway */
1503  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
1504  }
1505  else
1506  {
1507  /* get second variable */
1508  var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
1509  if( var2 == NULL )
1510  {
1511  /* ignore unknown variables - we would not know the type anyway */
1512  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
1513  }
1514  else
1515  {
1516  char* endptr;
1517  /* get coefficient */
1518  coef = strtod(mpsinputField3(mpsi), &endptr);
1519  if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
1520  {
1521  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
1522  mpsinputSyntaxerror(mpsi);
1523  SCIPfreeBufferArray(scip, &quadvars1);
1524  SCIPfreeBufferArray(scip, &quadvars2);
1525  SCIPfreeBufferArray(scip, &quadcoefs);
1526  return SCIP_OKAY;
1527  }
1528 
1529  /* store variables and coefficient */
1530  if( cnt >= size )
1531  {
1532  int newsize = SCIPcalcMemGrowSize(scip, size+1);
1533  assert(newsize > size);
1534  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
1535  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
1536  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
1537  size = newsize;
1538  }
1539  assert(cnt < size);
1540  quadvars1[cnt] = var1;
1541  quadvars2[cnt] = var2;
1542  quadcoefs[cnt] = coef;
1543  /* diagonal elements have to be divided by 2.0
1544  * in a QMATRIX section also off-diagonal have to be divided by 2.0, since both lower and upper diagonal elements are given
1545  */
1546  if( var1 == var2 || !isQuadObj )
1547  quadcoefs[cnt] /= 2.0;
1548  ++cnt;
1549 
1550  SCIPdebugMessage("stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
1551 
1552  /* check other fields */
1553  if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
1554  (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
1555  {
1556  SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
1557  }
1558  }
1559  }
1560  }
1561 
1562  /* add constraint */
1563  if( cnt )
1564  {
1565  SCIP_Bool initial, separate, enforce, check, propagate;
1566  SCIP_Bool local, modifiable, dynamic, removable;
1567  SCIP_CONS* cons = NULL;
1568  SCIP_VAR* qmatrixvar = NULL;
1569  SCIP_Real lhs, rhs;
1570  SCIP_Real minusone = -1.0;
1571 
1572  /* standard settings for quadratic constraints: */
1573  initial = TRUE;
1574  separate = TRUE;
1575  enforce = TRUE;
1576  check = TRUE;
1577  propagate = TRUE;
1578  local = FALSE;
1579  modifiable = FALSE;
1580  dynamic = FALSE;
1581  removable = FALSE;
1582 
1583  SCIP_CALL( SCIPcreateVar(scip, &qmatrixvar, "qmatrixvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
1584  SCIP_VARTYPE_CONTINUOUS, initial, removable, NULL, NULL, NULL, NULL, NULL) );
1585  SCIP_CALL( SCIPaddVar(scip, qmatrixvar) );
1586 
1588  {
1589  lhs = -SCIPinfinity(scip);
1590  rhs = 0.0;
1591  }
1592  else
1593  {
1594  lhs = 0.0;
1595  rhs = SCIPinfinity(scip);
1596  }
1597 
1598  SCIP_CALL( SCIPcreateConsQuadratic(scip, &cons, "qmatrix", 1, &qmatrixvar, &minusone, cnt, quadvars1, quadvars2, quadcoefs, lhs, rhs,
1599  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable) );
1600 
1601  SCIP_CALL( SCIPaddCons(scip, cons) );
1602  SCIPdebugMessage("(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1603  SCIPdebugPrintCons(scip, cons, NULL);
1604 
1605  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1606  SCIP_CALL( SCIPreleaseVar(scip, &qmatrixvar) );
1607  }
1608  else
1609  {
1610  SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
1611  }
1612 
1613  SCIPfreeBufferArray(scip, &quadvars1);
1614  SCIPfreeBufferArray(scip, &quadvars2);
1615  SCIPfreeBufferArray(scip, &quadcoefs);
1616 
1617  return SCIP_OKAY;
1618 }
1619 
1620 
1621 /** Process QCMATRIX section.
1622  *
1623  * We read the QCMATRIX section, which is a nonstandard section introduced by CPLEX.
1624  *
1625  * We replace the corresponding linear constraint by a quadratic constraint which contains the
1626  * original linear constraint plus the quadratic part specified in the QCMATRIX.
1627  */
1628 static
1630  MPSINPUT* mpsi, /**< mps input structure */
1631  SCIP* scip /**< SCIP data structure */
1632  )
1633 {
1634  SCIP_CONS* lincons; /* the linear constraint that was added for the corresponding row */
1635  SCIP_VAR** quadvars1;
1636  SCIP_VAR** quadvars2;
1637  SCIP_Real* quadcoefs;
1638  int cnt = 0; /* number of qcmatrix elements processed so far */
1639  int size; /* size of quad* arrays */
1640 
1641  if( mpsinputField1(mpsi) == NULL )
1642  {
1643  SCIPerrorMessage("no row name in QCMATRIX line.\n");
1644  mpsinputSyntaxerror(mpsi);
1645  return SCIP_OKAY;
1646  }
1647 
1648  SCIPdebugMessage("read QCMATRIX section for row <%s>\n", mpsinputField1(mpsi));
1649 
1650  lincons = SCIPfindCons(scip, mpsinputField1(mpsi));
1651  if( lincons == NULL )
1652  {
1653  SCIPerrorMessage("no row under name <%s> processed so far.\n", mpsinputField1(mpsi));
1654  mpsinputSyntaxerror(mpsi);
1655  return SCIP_OKAY;
1656  }
1657 
1658  size = 1;
1659  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
1660  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
1661  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
1662 
1663  /* loop through section */
1664  while( mpsinputReadLine(mpsi) )
1665  {
1666  /* otherwise we are in the section given variables */
1667  SCIP_VAR* var1;
1668  SCIP_VAR* var2;
1669  SCIP_Real coef;
1670 
1671  /* check if next section is found */
1672  if( mpsinputField0(mpsi) != NULL )
1673  {
1674  if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1676  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1678  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1680  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1682  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1684  break;
1685  }
1686  if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
1687  {
1688  SCIPerrorMessage("empty data in a non-comment line.\n");
1689  mpsinputSyntaxerror(mpsi);
1690  SCIPfreeBufferArray(scip, &quadvars1);
1691  SCIPfreeBufferArray(scip, &quadvars2);
1692  SCIPfreeBufferArray(scip, &quadcoefs);
1693  return SCIP_OKAY;
1694  }
1695 
1696  /* get first variable */
1697  var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
1698  if( var1 == NULL )
1699  {
1700  /* ignore unknown variables - we would not know the type anyway */
1701  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
1702  }
1703  else
1704  {
1705  /* get second variable */
1706  var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
1707  if( var2 == NULL )
1708  {
1709  /* ignore unknown variables - we would not know the type anyway */
1710  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
1711  }
1712  else
1713  {
1714  char* endptr;
1715  /* get coefficient */
1716  coef = strtod(mpsinputField3(mpsi), &endptr);
1717  if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
1718  {
1719  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
1720  mpsinputSyntaxerror(mpsi);
1721  SCIPfreeBufferArray(scip, &quadvars1);
1722  SCIPfreeBufferArray(scip, &quadvars2);
1723  SCIPfreeBufferArray(scip, &quadcoefs);
1724  return SCIP_OKAY;
1725  }
1726 
1727  /* store variables and coefficient */
1728  if( cnt >= size )
1729  {
1730  int newsize = SCIPcalcMemGrowSize(scip, size+1);
1731  assert(newsize > size);
1732  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
1733  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
1734  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
1735  size = newsize;
1736  }
1737  assert(cnt < size);
1738  quadvars1[cnt] = var1;
1739  quadvars2[cnt] = var2;
1740  quadcoefs[cnt] = coef;
1741  ++cnt;
1742 
1743  SCIPdebugMessage("stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
1744 
1745  /* check other fields */
1746  if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
1747  (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
1748  {
1749  SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
1750  }
1751  }
1752  }
1753  }
1754 
1755  /* replace linear constraint by quadratic constraint */
1756  if( cnt )
1757  {
1758  SCIP_CONS* cons = NULL;
1759 
1760  SCIP_CALL( SCIPcreateConsQuadratic(scip, &cons, SCIPconsGetName(lincons),
1761  SCIPgetNVarsLinear(scip, lincons), SCIPgetVarsLinear(scip, lincons), SCIPgetValsLinear(scip, lincons),
1762  cnt, quadvars1, quadvars2, quadcoefs, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
1763  SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
1764  SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons), SCIPconsIsDynamic(lincons),
1765  SCIPconsIsRemovable(lincons)) );
1766 
1767  SCIP_CALL( SCIPaddCons(scip, cons) );
1768  SCIPdebugMessage("(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1769  SCIPdebugPrintCons(scip, cons, NULL);
1770 
1771  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1772 
1773  SCIP_CALL( SCIPdelCons(scip, lincons) );
1774  }
1775  else
1776  {
1777  SCIPwarningMessage(scip, "QCMATRIX section has no entries.\n");
1778  }
1779 
1780  SCIPfreeBufferArray(scip, &quadvars1);
1781  SCIPfreeBufferArray(scip, &quadvars2);
1782  SCIPfreeBufferArray(scip, &quadcoefs);
1783 
1784  return SCIP_OKAY;
1785 }
1786 
1787 
1788 /** Process INDICATORS section.
1789  *
1790  * We read the INDICATORS section, which is a nonstandard section introduced by CPLEX.
1791  *
1792  * The section has to come after the QMATRIX* sections.
1793  */
1794 static
1796  MPSINPUT* mpsi, /**< mps input structure */
1797  SCIP* scip /**< SCIP data structure */
1798  )
1799 {
1800  SCIP_Bool initial;
1801  SCIP_Bool separate;
1802  SCIP_Bool enforce;
1803  SCIP_Bool check;
1804  SCIP_Bool propagate;
1805  SCIP_Bool local;
1806  SCIP_Bool dynamic;
1807  SCIP_Bool removable;
1808  SCIP_Bool stickingatnode;
1809  char name[MPS_MAX_NAMELEN] = { '\0' };
1810 
1811  SCIPdebugMessage("read INDICATORS constraints\n");
1812 
1813  /* standard settings for indicator constraints: */
1814  initial = TRUE;
1815  separate = TRUE;
1816  enforce = TRUE;
1817  check = TRUE;
1818  propagate = TRUE;
1819  local = FALSE;
1820  dynamic = FALSE;
1821  removable = FALSE;
1822  stickingatnode = FALSE;
1823 
1824  /* loop through section */
1825  while( mpsinputReadLine(mpsi) )
1826  {
1827  SCIP_CONSHDLR* conshdlr;
1828  SCIP_VARTYPE slackvartype;
1829  SCIP_CONS* cons;
1830  SCIP_CONS* lincons;
1831  SCIP_VAR* binvar;
1832  SCIP_VAR* slackvar;
1833  SCIP_Real lhs;
1834  SCIP_Real rhs;
1835  SCIP_Real sign;
1836  SCIP_VAR** linvars;
1837  SCIP_Real* linvals;
1838  int nlinvars;
1839  int i;
1840 
1841  /* check if next section is found */
1842  if( mpsinputField0(mpsi) != NULL )
1843  {
1844  if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1846  break;
1847  }
1848  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
1849  {
1850  SCIPerrorMessage("empty data in a non-comment line.\n");
1851  mpsinputSyntaxerror(mpsi);
1852  return SCIP_OKAY;
1853  }
1854 
1855  /* check for new indicator constraint */
1856  if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
1857  {
1858  SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
1859  mpsinputSyntaxerror(mpsi);
1860  return SCIP_OKAY;
1861  }
1862 
1863  /* get linear constraint (row) */
1864  lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
1865  if( lincons == NULL )
1866  {
1867  SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
1868  mpsinputSyntaxerror(mpsi);
1869  return SCIP_OKAY;
1870  }
1871 
1872  /* check whether constraint is really linear */
1873  conshdlr = SCIPconsGetHdlr(lincons);
1874  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
1875  {
1876  SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
1877  mpsinputSyntaxerror(mpsi);
1878  return SCIP_OKAY;
1879  }
1880 
1881  /* get binary variable */
1882  binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
1883  if( binvar == NULL )
1884  {
1885  SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
1886  mpsinputSyntaxerror(mpsi);
1887  return SCIP_OKAY;
1888  }
1889 
1890  /* check type */
1891  if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
1892  {
1893  SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
1894  mpsinputSyntaxerror(mpsi);
1895  return SCIP_OKAY;
1896  }
1897 
1898  /* check whether we need the negated variable */
1899  if( mpsinputField4(mpsi) != NULL )
1900  {
1901  if( *mpsinputField4(mpsi) == '0' )
1902  {
1903  SCIP_VAR* var;
1904  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
1905  binvar = var;
1906  assert( binvar != NULL );
1907  }
1908  else
1909  {
1910  if( *mpsinputField4(mpsi) != '1' )
1911  {
1912  SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
1913  mpsinputSyntaxerror(mpsi);
1914  return SCIP_OKAY;
1915  }
1916  }
1917  }
1918 
1919  /* check lhs/rhs */
1920  lhs = SCIPgetLhsLinear(scip, lincons);
1921  rhs = SCIPgetLhsLinear(scip, lincons);
1922  nlinvars = SCIPgetNVarsLinear(scip, lincons);
1923  linvars = SCIPgetVarsLinear(scip, lincons);
1924  linvals = SCIPgetValsLinear(scip, lincons);
1925 
1926  sign = -1.0;
1927  if( !SCIPisInfinity(scip, -lhs) )
1928  {
1929  if( SCIPisInfinity(scip, rhs) )
1930  sign = 1.0;
1931  else
1932  {
1933  if( !SCIPisEQ(scip, lhs, rhs) )
1934  {
1935  SCIPerrorMessage("ranged row <%s> is not allowed in indicator constraints.\n", mpsinputField2(mpsi));
1936  mpsinputSyntaxerror(mpsi);
1937  return SCIP_OKAY;
1938  }
1939  else
1940  {
1941  /* create second indicator constraint */
1942  SCIP_VAR** vars;
1943  SCIP_Real* vals;
1944 
1945  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars+1) );
1946  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars+1) );
1947  for( i = 0; i < nlinvars; ++i )
1948  {
1949  vars[i] = linvars[i];
1950  vals[i] = -linvals[i];
1951  }
1952 
1953  /* create new name */
1954  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
1955 
1956  /* create indicator constraint */
1957  SCIP_CALL( SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars+1, vars, vals, -lhs,
1958  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1959  SCIP_CALL( SCIPaddCons(scip, cons) );
1960  SCIPdebugMessage("created indicator constraint <%s>\n", mpsinputField2(mpsi));
1961  SCIPdebugPrintCons(scip, cons, NULL);
1962  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1963 
1964  SCIPfreeBufferArray(scip, &vals);
1965  SCIPfreeBufferArray(scip, &vars);
1966  }
1967  }
1968  }
1969 
1970  /* check if slack variable can be made implicitly integer */
1971  slackvartype = SCIP_VARTYPE_IMPLINT;
1972  for( i = 0; i < nlinvars; ++i )
1973  {
1974  if( !SCIPvarIsIntegral(linvars[i]) || ! SCIPisIntegral(scip, linvals[i]) )
1975  {
1976  slackvartype = SCIP_VARTYPE_CONTINUOUS;
1977  break;
1978  }
1979  }
1980 
1981  /* create slack variable */
1982  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indslack_%s", SCIPconsGetName(lincons));
1983  SCIP_CALL( SCIPcreateVar(scip, &slackvar, name, 0.0, SCIPinfinity(scip), 0.0, slackvartype, TRUE, FALSE,
1984  NULL, NULL, NULL, NULL, NULL) );
1985 
1986  /* add slack variable */
1987  SCIP_CALL( SCIPaddVar(scip, slackvar) );
1988  SCIP_CALL( SCIPaddCoefLinear(scip, lincons, slackvar, sign) );
1989 
1990  /* create new name */
1991  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
1992 
1993  /* create indicator constraint */
1994  SCIP_CALL( SCIPcreateConsIndicatorLinCons(scip, &cons, name, binvar, lincons, slackvar,
1995  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1996 
1997  SCIP_CALL( SCIPaddCons(scip, cons) );
1998  SCIPdebugMessage("created indicator constraint <%s>", mpsinputField2(mpsi));
1999  SCIPdebugPrintCons(scip, cons, NULL);
2000  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2001  }
2002 
2003  return SCIP_OKAY;
2004 }
2005 
2006 /*
2007  * Local methods
2008  */
2009 
2010 /** Process ROWS, USERCUTS, or LAZYCONS section. */
2011 static
2013  MPSINPUT* mpsi, /**< mps input structure */
2014  SCIP* scip /**< SCIP data structure */
2015  )
2016 {
2017  ProbDataObjectives* probdata;
2018  SCIP_Bool dynamicrows;
2019  SCIP_Bool dynamicconss;
2020 
2021  SCIPdebugMessage("read rows\n");
2022 
2023  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &dynamicconss) );
2024  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &dynamicrows) );
2025 
2026  while( mpsinputReadLine(mpsi) )
2027  {
2028  if( mpsinputField0(mpsi) != NULL )
2029  {
2030  if( !strcmp(mpsinputField0(mpsi), "ROWS") )
2032  else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
2034  else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
2036  else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
2038  else
2039  mpsinputSyntaxerror(mpsi);
2040 
2041  return SCIP_OKAY;
2042  }
2043 
2044  if( *mpsinputField1(mpsi) == 'N' )
2045  {
2046  probdata = dynamic_cast<ProbDataObjectives *>(SCIPgetObjProbData(scip));
2047  probdata->addObjName(mpsinputField2(mpsi));
2048  }
2049  else
2050  {
2051  SCIP_CONS* cons;
2052  SCIP_Bool initial;
2053  SCIP_Bool separate;
2054  SCIP_Bool enforce;
2055  SCIP_Bool check;
2056  SCIP_Bool propagate;
2057  SCIP_Bool local;
2058  SCIP_Bool modifiable;
2059  SCIP_Bool dynamic;
2060  SCIP_Bool removable;
2061 
2062  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
2063  if( cons != NULL )
2064  break;
2065 
2066  initial = !dynamicrows && (mpsinputSection(mpsi) == MPS_ROWS);
2067  separate = TRUE;
2068  enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
2069  check = (mpsinputSection(mpsi) != MPS_USERCUTS);
2070  propagate = TRUE;
2071  local = FALSE;
2072  modifiable = FALSE;
2073  dynamic = dynamicconss;
2074  removable = dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
2075 
2076  switch(*mpsinputField1(mpsi))
2077  {
2078  case 'G' :
2079  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, SCIPinfinity(scip),
2080  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
2081  break;
2082  case 'E' :
2083  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, 0.0,
2084  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
2085  break;
2086  case 'L' :
2087  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, -SCIPinfinity(scip), 0.0,
2088  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
2089  break;
2090  default :
2091  mpsinputSyntaxerror(mpsi);
2092  return SCIP_OKAY;
2093  }
2094  SCIP_CALL( SCIPaddCons(scip, cons) );
2095  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2096  }
2097  }
2098  mpsinputSyntaxerror(mpsi);
2099 
2100  return SCIP_OKAY;
2101 }
2102 
2103 /** Process COLUMNS section. */
2104 static SCIP_RETCODE readColsMop(MPSINPUT* mpsi, /**< mps input structure */
2105 SCIP* scip /**< SCIP data structure */
2106 )
2107 {
2108  ProbDataObjectives* probdata;
2109  char colname[MPS_MAX_NAMELEN] = { '\0' };
2110  SCIP_CONS* cons;
2111  SCIP_VAR* var;
2112  SCIP_Real val;
2113  SCIP_Bool dynamiccols;
2114 
2115  probdata = dynamic_cast<ProbDataObjectives *>(SCIPgetObjProbData(scip));
2116 
2117  SCIPdebugMessage("read columns\n");
2118 
2119  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &dynamiccols));
2120  var = NULL;
2121  while( mpsinputReadLine(mpsi) )
2122  {
2123  if( mpsinputField0(mpsi) != 0 )
2124  {
2125  if( strcmp(mpsinputField0(mpsi), "RHS") )
2126  break;
2127 
2128  /* add the last variable to the problem */
2129  if( var != NULL )
2130  {
2131  SCIP_CALL( SCIPaddVar(scip, var));
2132  SCIP_CALL( SCIPreleaseVar(scip, &var));
2133  }
2134  assert(var == NULL);
2135 
2136  mpsinputSetSection(mpsi, MPS_RHS);
2137  return SCIP_OKAY;
2138  }
2139  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
2140  break;
2141 
2142  /* new column? */
2143  if( strcmp(colname, mpsinputField1(mpsi)) )
2144  {
2145  /* add the last variable to the problem */
2146  if( var != NULL )
2147  {
2148  SCIP_CALL( SCIPaddVar(scip, var));
2149  SCIP_CALL( SCIPreleaseVar(scip, &var));
2150  }
2151  assert(var == NULL);
2152 
2153  (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
2154  if( mpsinputIsInteger(mpsi) )
2155  {
2156  /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
2157  SCIP_CALL(
2158  SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL));
2159  }
2160  else
2161  {
2162  /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
2163  SCIP_CALL(
2164  SCIPcreateVar(scip, &var, colname, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS, !dynamiccols, dynamiccols, NULL, NULL, NULL, NULL, NULL));
2165  }
2166  }
2167  assert(var != NULL);
2168 
2169  val = atof(mpsinputField3(mpsi));
2170 
2171  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
2172  if( cons == NULL )
2173  {
2174  /* row is objective */
2175  probdata->addObjCoeff(var, mpsinputField2(mpsi), val);
2176  //std::cout << "obj : " << mpsinputField2(mpsi) << " val : " << val << "\n";
2177 
2178  }
2179  else if( !SCIPisZero(scip, val) )
2180  {
2181  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val));
2182  }
2183 
2184  if( mpsinputField5(mpsi) != NULL )
2185  {
2186  assert(mpsinputField4(mpsi) != NULL);
2187 
2188  val = atof(mpsinputField5(mpsi));
2189 
2190  cons = SCIPfindCons(scip, mpsinputField4(mpsi));
2191  if( cons == NULL )
2192  {
2193  /* row is objective */
2194  probdata->addObjCoeff(var, mpsinputField4(mpsi), val);
2195  //std::cout << "obj : " << mpsinputField4(mpsi) << " val : " << val << "\n";
2196  }
2197  else if( !SCIPisZero(scip, val) )
2198  {
2199  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val));
2200  }
2201 
2202  }
2203  }
2204  mpsinputSyntaxerror(mpsi);
2205 
2206  return SCIP_OKAY;
2207 }
2208 
2209 static
2211  SCIP* scip, /**< SCIP data structure */
2212  const char* filename /**< name of the input file */
2213  )
2214 {
2215  SCIP_FILE *fp;
2216 
2217  MPSINPUT* mpsi;
2218  SCIP_Bool error;
2219 
2220  fp = SCIPfopen(filename, "r");
2221 
2222  if( fp == NULL )
2223  {
2224  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2225  SCIPprintSysError(filename);
2226  return SCIP_NOFILE;
2227  }
2228 
2229  SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
2230 
2231  SCIP_CALL( readName(scip, mpsi) );
2232 
2233  SCIP_CALL( SCIPcreateObjProb(scip, mpsi->probname, new ProbDataObjectives(), TRUE) );
2234 
2235  if( mpsinputSection(mpsi) == MPS_OBJSEN )
2236  {
2237  SCIP_CALL( readObjsen(scip, mpsi) );
2238  }
2239  if( mpsinputSection(mpsi) == MPS_OBJNAME )
2240  {
2241  SCIP_CALL( readObjname(scip, mpsi) );
2242  }
2243  while( mpsinputSection(mpsi) == MPS_ROWS
2244  || mpsinputSection(mpsi) == MPS_USERCUTS
2245  || mpsinputSection(mpsi) == MPS_LAZYCONS )
2246  {
2247  SCIP_CALL( readRowsMop(mpsi, scip) );
2248  }
2249  if( mpsinputSection(mpsi) == MPS_COLUMNS )
2250  {
2251  SCIP_CALL( readColsMop(mpsi, scip) );
2252  }
2253  if( mpsinputSection(mpsi) == MPS_RHS )
2254  {
2255  SCIP_CALL( readRhs(mpsi, scip) );
2256  }
2257  if( mpsinputSection(mpsi) == MPS_RANGES )
2258  {
2259  SCIP_CALL( readRanges(mpsi, scip) );
2260  }
2261  if( mpsinputSection(mpsi) == MPS_BOUNDS )
2262  {
2263  SCIP_CALL( readBounds(mpsi, scip) );
2264  }
2265  if( mpsinputSection(mpsi) == MPS_SOS )
2266  {
2267  SCIP_CALL( readSOS(mpsi, scip) );
2268  }
2269  while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2270  {
2271  SCIP_CALL( readQCMatrix(mpsi, scip) );
2272  }
2273  if( mpsinputSection(mpsi) == MPS_QMATRIX )
2274  {
2275  SCIP_CALL( readQMatrix(mpsi, FALSE, scip) );
2276  }
2277  if( mpsinputSection(mpsi) == MPS_QUADOBJ )
2278  {
2279  SCIP_CALL( readQMatrix(mpsi, TRUE, scip) );
2280  }
2281  while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2282  {
2283  SCIP_CALL( readQCMatrix(mpsi, scip) );
2284  }
2285  if( mpsinputSection(mpsi) == MPS_INDICATORS )
2286  {
2287  SCIP_CALL( readIndicators(mpsi, scip) );
2288  }
2289  if( mpsinputSection(mpsi) != MPS_ENDATA )
2290  mpsinputSyntaxerror(mpsi);
2291 
2292  SCIPfclose(fp);
2293 
2294  error = mpsinputHasError(mpsi);
2295 
2296  if( !error )
2297  {
2298  SCIP_CALL( SCIPsetObjsense(scip, mpsinputObjsense(mpsi)) );
2299  }
2300  mpsinputFree(scip, &mpsi);
2301 
2302  if( error )
2303  return SCIP_READERROR;
2304  else
2305  return SCIP_OKAY;
2306 }
2307 
2308 
2309 /** destructor of file reader to free user data (called when SCIP is exiting) */
2310 SCIP_DECL_READERFREE(ReaderMOP::scip_free) {
2311  return SCIP_OKAY;
2312 }
2313 
2314 /** problem reading method of reader */
2315 SCIP_DECL_READERREAD(ReaderMOP::scip_read) {
2316  assert(reader != NULL);
2317  assert(scip != NULL);
2318  assert(result != NULL);
2319  assert(filename != NULL);
2320 
2321  SCIP_RETCODE retcode;
2322  retcode = readMOP(scip, filename);
2323 
2324  if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
2325  return retcode;
2326 
2327  SCIP_CALL( retcode );
2328 
2329  *result = SCIP_SUCCESS;
2330 
2331  return SCIP_OKAY;
2332 }
2333 
2334 
2335 
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_RETCODE readRanges(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:852
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsIndicatorLinCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, SCIP_VAR *slackvar, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
#define MPS_MAX_NAMELEN
global define
Definition: ReaderMOP.cpp:52
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
Constraint handler for variable bound constraints .
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8316
Class storing multiple objectives of given problem instance.
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8276
#define SCIP_MAXSTRLEN
Definition: def.h:279
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1240
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:123
static SCIP_RETCODE readRowsMop(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:2012
static void mpsinputSetProbname(MPSINPUT *mpsi, const char *probname)
Definition: ReaderMOP.cpp:281
static SCIP_Bool mpsinputReadLine(MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:390
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
static void mpsinputSetSection(MPSINPUT *mpsi, MPSSECTION section)
Definition: ReaderMOP.cpp:269
void addObjCoeff(SCIP_VAR *var, const char *obj_name, polyscip::ValueType val)
static SCIP_RETCODE readObjname(SCIP *scip, MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:689
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:241
static void patchField(char *buf, int beg, int end)
Definition: ReaderMOP.cpp:369
constraint handler for indicator constraints
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:216
#define FALSE
Definition: def.h:73
SCIP_RETCODE SCIPcreateConsSOS1(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos1.c:10376
static SCIP_RETCODE readColsMop(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:2104
static const char * mpsinputField2(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:192
void addObjName(const char *name)
SCIP_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17182
#define TRUE
Definition: def.h:72
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8246
static SCIP_OBJSENSE mpsinputObjsense(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:236
SCIP_RETCODE SCIPcreateConsSOS2(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *weights, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: cons_sos2.c:2351
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:48
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:95
#define SCIPdebugMessage
Definition: pub_message.h:87
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10562
constraint handler for second order cone constraints
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:123
Constraint handler for the set partitioning / packing / covering constraints .
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:78
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:93
static const char * mpsinputField4(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:214
static const char * mpsinputField0(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:170
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE readObjsen(SCIP *scip, MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:637
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2837
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1524
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:144
Constraint handler for knapsack constraints of the form , x binary and .
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4670
SCIP_EXPORT SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17208
#define SCIPerrorMessage
Definition: pub_message.h:55
static const char * mpsinputField5(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:225
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
static SCIP_Bool mpsinputIsInteger(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:258
static MPSSECTION mpsinputSection(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:159
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:124
struct SCIP_File SCIP_FILE
Definition: pub_fileio.h:34
char * SCIPfgets(char *s, int size, SCIP_FILE *stream)
Definition: fileio.c:191
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIPInterval sign(const SCIPInterval &x)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
struct SparseMatrix SPARSEMATRIX
Definition: reader_mps.c:153
constraint handler for quadratic constraints
#define NULL
Definition: lpi_spx1.cpp:155
C++ wrapper classes for SCIP.
#define REALABS(x)
Definition: def.h:187
static SCIP_RETCODE readSOS(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:1263
#define SCIP_CALL(x)
Definition: def.h:370
static SCIP_RETCODE readQCMatrix(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:1629
static void mpsinputSetObjname(MPSINPUT *mpsi, const char *objname)
Definition: ReaderMOP.cpp:295
SCIP_DECL_READERREAD(ReaderMOP::scip_read)
Definition: ReaderMOP.cpp:2315
static SCIP_RETCODE readBounds(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:988
static SCIP_RETCODE readIndicators(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:1795
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10513
static SCIP_RETCODE readQMatrix(MPSINPUT *mpsi, SCIP_Bool isQuadObj, SCIP *scip)
Definition: ReaderMOP.cpp:1450
static const char * mpsinputField1(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:181
SCIP_DECL_READERFREE(ReaderMOP::scip_free)
Definition: ReaderMOP.cpp:2310
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8346
enum MpsSection MPSSECTION
typedef
Definition: ReaderMOP.cpp:79
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPinfinity(SCIP *scip)
public data structures and miscellaneous methods
#define SCIP_Bool
Definition: def.h:70
.mop file format reader
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition: scip_prob.c:2941
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:41
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2450
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17677
static SCIP_RETCODE readMOP(SCIP *scip, const char *filename)
Definition: ReaderMOP.cpp:2210
static void mpsinputInsertName(MPSINPUT *mpsi, const char *name, SCIP_Bool second)
Definition: ReaderMOP.cpp:566
static SCIP_RETCODE readName(SCIP *scip, MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:590
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:105
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define BLANK
global define
Definition: ReaderMOP.cpp:57
static void mpsinputSetObjsense(MPSINPUT *mpsi, SCIP_OBJSENSE sense)
Definition: ReaderMOP.cpp:309
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8256
Constraint handler for linear constraints in their most general form, .
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
static long * number
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4760
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8336
scip::ObjProbData * SCIPgetObjProbData(SCIP *scip)
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2679
#define PATCH_CHAR
global define
Definition: ReaderMOP.cpp:56
Stores coefficients and basic methods for objectives of given multi-objective problem.
static SCIP_RETCODE readRhs(MPSINPUT *mpsi, SCIP *scip)
Definition: ReaderMOP.cpp:727
struct MpsInput MPSINPUT
Definition: reader_mps.c:142
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8266
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17667
static void mpsinputFree(SCIP *scip, MPSINPUT **mpsi)
Definition: ReaderMOP.cpp:149
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8077
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
#define SCIP_Real
Definition: def.h:163
SCIP_RETCODE SCIPcreateObjProb(SCIP *scip, const char *name, scip::ObjProbData *objprobdata, SCIP_Bool deleteobject)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8097
constraint handler for SOS type 1 constraints
static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
Definition: ReaderMOP.cpp:116
void SCIPprintSysError(const char *message)
Definition: misc.c:10513
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4167
static void mpsinputEntryIgnored(SCIP *scip, MPSINPUT *mpsi, const char *what, const char *what_name, const char *entity, const char *entity_name, SCIP_VERBLEVEL verblevel)
Definition: ReaderMOP.cpp:333
enum MpsSection MPSSECTION
Definition: reader_mps.c:116
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2764
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
constraint handler for SOS type 2 constraints
MpsSection
Definition: reader_mps.c:97
SCIP_RETCODE SCIPcreateConsQuadratic(SCIP *scip, SCIP_CONS **cons, const char *name, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, int nquadterms, SCIP_VAR **quadvars1, SCIP_VAR **quadvars2, SCIP_Real *quadcoefs, 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)
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:223
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
static SCIP_Bool mpsinputHasError(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:247
static void clearFrom(char *buf, unsigned int pos)
Definition: ReaderMOP.cpp:355
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8150
constraint handler for bound disjunction constraints
#define SCIPABORT()
Definition: def.h:342
#define MPS_MAX_LINELEN
global define
Definition: ReaderMOP.cpp:51
static void mpsinputSyntaxerror(MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:320
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10488
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8296
SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
static const char * mpsinputField3(const MPSINPUT *mpsi)
Definition: ReaderMOP.cpp:203
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8326
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115