Scippy

SCIP

Solving Constraint Integer Programs

reader_mps.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_mps.c
26  * @ingroup DEFPLUGINS_READER
27  * @brief (extended) MPS file reader
28  * @author Thorsten Koch
29  * @author Tobias Achterberg
30  * @author Marc Pfetsch
31  * @author Stefan Heinz
32  * @author Stefan Vigerske
33  * @author Michael Winkler
34  *
35  * This reader/writer handles MPS files in extended MPS format, as it
36  * is used by CPLEX. In the extended format the limits on variable
37  * name lengths and coefficients are considerably relaxed. The columns
38  * in the format are then separated by whitespaces.
39  *
40  * @todo Check whether constructing the names for aggregated constraint yields name clashes (aggrXXX).
41  */
42 
43 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
44 
45 #include "blockmemshell/memory.h"
46 #include <ctype.h>
47 #include "scip/cons_and.h"
49 #include "scip/cons_nonlinear.h"
50 #include "scip/cons_indicator.h"
51 #include "scip/cons_knapsack.h"
52 #include "scip/cons_linear.h"
53 #include "scip/cons_logicor.h"
54 #include "scip/cons_setppc.h"
55 #include "scip/cons_sos1.h"
56 #include "scip/cons_sos2.h"
57 #include "scip/cons_varbound.h"
58 #include "scip/pub_cons.h"
59 #include "scip/pub_fileio.h"
60 #include "scip/pub_message.h"
61 #include "scip/pub_misc.h"
62 #include "scip/pub_misc_sort.h"
63 #include "scip/pub_reader.h"
64 #include "scip/pub_var.h"
65 #include "scip/reader_mps.h"
66 #include "scip/scip_cons.h"
67 #include "scip/scip_mem.h"
68 #include "scip/scip_message.h"
69 #include "scip/scip_numerics.h"
70 #include "scip/scip_param.h"
71 #include "scip/scip_prob.h"
72 #include "scip/scip_reader.h"
73 #include "scip/scip_solvingstats.h"
74 #include "scip/scip_var.h"
75 #include <stdlib.h>
76 #include <string.h>
77 
78 #define READER_NAME "mpsreader"
79 #define READER_DESC "file reader for MIQPs in IBM's Mathematical Programming System format"
80 #define READER_EXTENSION "mps"
81 
82 #define DEFAULT_LINEARIZE_ANDS TRUE /**< should possible \"and\" constraint be linearized when writing the mps file? */
83 #define DEFAULT_AGGRLINEARIZATION_ANDS TRUE /**< should an aggregated linearization for and constraints be used? */
84 
85 /*
86  * mps reader internal methods
87  */
88 
89 #define MPS_MAX_LINELEN 1024
90 #define MPS_MAX_NAMELEN 256
91 #define MPS_MAX_VALUELEN 26
92 #define MPS_MAX_FIELDLEN 20
93 
94 #define PATCH_CHAR '_'
95 #define BLANK ' '
96 
97 /** MPS reading data */
98 struct SCIP_ReaderData
99 {
100  SCIP_Bool linearizeands;
101  SCIP_Bool aggrlinearizationands;
102 };
103 
104 /** enum containing all mps sections */
106 {
123 };
124 typedef enum MpsSection MPSSECTION;
125 
126 /** mps input structure */
127 struct MpsInput
128 {
129  MPSSECTION section;
130  SCIP_FILE* fp;
131  int lineno;
132  SCIP_OBJSENSE objsense;
133  SCIP_Bool haserror;
134  char buf[MPS_MAX_LINELEN];
135  const char* f0;
136  const char* f1;
137  const char* f2;
138  const char* f3;
139  const char* f4;
140  const char* f5;
141  char probname[MPS_MAX_NAMELEN];
142  char objname [MPS_MAX_NAMELEN];
143  SCIP_Bool initialconss; /**< should model constraints be marked as initial? */
144  SCIP_Bool dynamicconss; /**< should model constraints be subject to aging? */
145  SCIP_Bool dynamiccols; /**< should columns be added and removed dynamically to the LP? */
146  SCIP_Bool dynamicrows; /**< should rows be added and removed dynamically to the LP? */
147  SCIP_Bool isinteger;
148  SCIP_Bool isnewformat;
149 };
150 typedef struct MpsInput MPSINPUT;
151 
152 /** sparse matrix representation */
153 struct SparseMatrix
154 {
155  SCIP_Real* values; /**< matrix element */
156  SCIP_VAR** columns; /**< corresponding variables */
157  const char** rows; /**< corresponding constraint names */
158  int nentries; /**< number of elements in the arrays */
159  int sentries; /**< number of slots in the arrays */
160 };
161 typedef struct SparseMatrix SPARSEMATRIX;
162 
163 /** struct for mapping cons names to numbers */
165 {
166  const char* consname; /**< name of the constraint */
167  int freq; /**< how often we have seen the name */
168 };
169 typedef struct ConsNameFreq CONSNAMEFREQ;
170 
171 /** creates the mps input structure */
172 static
174  SCIP* scip, /**< SCIP data structure */
175  MPSINPUT** mpsi, /**< mps input structure */
176  SCIP_FILE* fp /**< file object for the input file */
177  )
178 {
179  assert(mpsi != NULL);
180  assert(fp != NULL);
181 
182  SCIP_CALL( SCIPallocBlockMemory(scip, mpsi) );
183 
184  (*mpsi)->section = MPS_NAME;
185  (*mpsi)->fp = fp;
186  (*mpsi)->lineno = 0;
187  (*mpsi)->objsense = SCIP_OBJSENSE_MINIMIZE;
188  (*mpsi)->haserror = FALSE;
189  (*mpsi)->isinteger = FALSE;
190  (*mpsi)->isnewformat = FALSE;
191  (*mpsi)->buf [0] = '\0';
192  (*mpsi)->probname[0] = '\0';
193  (*mpsi)->objname [0] = '\0';
194  (*mpsi)->f0 = NULL;
195  (*mpsi)->f1 = NULL;
196  (*mpsi)->f2 = NULL;
197  (*mpsi)->f3 = NULL;
198  (*mpsi)->f4 = NULL;
199  (*mpsi)->f5 = NULL;
200 
201  SCIP_CALL( SCIPgetBoolParam(scip, "reading/initialconss", &((*mpsi)->initialconss)) );
202  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicconss", &((*mpsi)->dynamicconss)) );
203  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamiccols", &((*mpsi)->dynamiccols)) );
204  SCIP_CALL( SCIPgetBoolParam(scip, "reading/dynamicrows", &((*mpsi)->dynamicrows)) );
205 
206  return SCIP_OKAY;
207 }
208 
209 /** free the mps input structure */
210 static
212  SCIP* scip, /**< SCIP data structure */
213  MPSINPUT** mpsi /**< mps input structure */
214  )
215 {
216  SCIPfreeBlockMemory(scip, mpsi);
217 }
218 
219 /** returns the current section */
220 static
222  const MPSINPUT* mpsi /**< mps input structure */
223  )
224 {
225  assert(mpsi != NULL);
226 
227  return mpsi->section;
228 }
229 
230 /** return the current value of field 0 */
231 static
232 const char* mpsinputField0(
233  const MPSINPUT* mpsi /**< mps input structure */
234  )
235 {
236  assert(mpsi != NULL);
237 
238  return mpsi->f0;
239 }
240 
241 /** return the current value of field 1 */
242 static
243 const char* mpsinputField1(
244  const MPSINPUT* mpsi /**< mps input structure */
245  )
246 {
247  assert(mpsi != NULL);
248 
249  return mpsi->f1;
250 }
251 
252 /** return the current value of field 2 */
253 static
254 const char* mpsinputField2(
255  const MPSINPUT* mpsi /**< mps input structure */
256  )
257 {
258  assert(mpsi != NULL);
259 
260  return mpsi->f2;
261 }
262 
263 /** return the current value of field 3 */
264 static
265 const char* mpsinputField3(
266  const MPSINPUT* mpsi /**< mps input structure */
267  )
268 {
269  assert(mpsi != NULL);
270 
271  return mpsi->f3;
272 }
273 
274 /** return the current value of field 4 */
275 static
276 const char* mpsinputField4(
277  const MPSINPUT* mpsi /**< mps input structure */
278  )
279 {
280  assert(mpsi != NULL);
281 
282  return mpsi->f4;
283 }
284 
285 /** return the current value of field 5 */
286 static
287 const char* mpsinputField5(
288  const MPSINPUT* mpsi /**< mps input structure */
289  )
290 {
291  assert(mpsi != NULL);
292 
293  return mpsi->f5;
294 }
295 
296 /** returns the objective name */
297 static
298 const char* mpsinputObjname(
299  const MPSINPUT* mpsi /**< mps input structure */
300  )
301 {
302  assert(mpsi != NULL);
303 
304  return mpsi->objname;
305 }
306 
307 /** returns the objective sense */
308 static
310  const MPSINPUT* mpsi /**< mps input structure */
311  )
312 {
313  assert(mpsi != NULL);
314 
315  return mpsi->objsense;
316 }
317 
318 /** returns if an error was detected */
319 static
321  const MPSINPUT* mpsi /**< mps input structure */
322  )
323 {
324  assert(mpsi != NULL);
325 
326  return mpsi->haserror;
327 }
328 
329 /** returns the value of the Bool "is integer" in the mps input */
330 static
332  const MPSINPUT* mpsi /**< mps input structure */
333  )
334 {
335  assert(mpsi != NULL);
336 
337  return mpsi->isinteger;
338 }
339 
340 /** set the section in the mps input structure to given section */
341 static
343  MPSINPUT* mpsi, /**< mps input structure */
344  MPSSECTION section /**< section that is set */
345  )
346 {
347  assert(mpsi != NULL);
348 
349  mpsi->section = section;
350 }
351 
352 /** set the problem name in the mps input structure to given problem name */
353 static
355  MPSINPUT* mpsi, /**< mps input structure */
356  const char* probname /**< name of the problem to set */
357  )
358 {
359  assert(mpsi != NULL);
360  assert(probname != NULL);
361  assert(strlen(probname) < sizeof(mpsi->probname));
362 
363  (void)SCIPmemccpy(mpsi->probname, probname, '\0', MPS_MAX_NAMELEN - 1);
364 }
365 
366 /** set the objective name in the mps input structure to given objective name */
367 static
369  MPSINPUT* mpsi, /**< mps input structure */
370  const char* objname /**< name of the objective function to set */
371  )
372 {
373  assert(mpsi != NULL);
374  assert(objname != NULL);
375  assert(strlen(objname) < sizeof(mpsi->objname));
376 
377  (void)SCIPmemccpy(mpsi->objname, objname, '\0', MPS_MAX_NAMELEN - 1);
378 }
379 
380 /** set the objective sense in the mps input structure to given objective sense */
381 static
383  MPSINPUT* mpsi, /**< mps input structure */
384  SCIP_OBJSENSE sense /**< sense of the objective function */
385  )
386 {
387  assert(mpsi != NULL);
388 
389  mpsi->objsense = sense;
390 }
391 
392 static
394  MPSINPUT* mpsi /**< mps input structure */
395  )
396 {
397  assert(mpsi != NULL);
398 
399  SCIPerrorMessage("Syntax error in line %d\n", mpsi->lineno);
400  mpsi->section = MPS_ENDATA;
401  mpsi->haserror = TRUE;
402 }
403 
404 /** method post a ignore message */
405 static
407  SCIP* scip, /**< SCIP data structure */
408  MPSINPUT* mpsi, /**< mps input structure */
409  const char* what, /**< what get ignored */
410  const char* what_name, /**< name of that object */
411  const char* entity, /**< entity */
412  const char* entity_name, /**< entity name */
413  SCIP_VERBLEVEL verblevel /**< SCIP verblevel for this message */
414  )
415 {
416  assert(mpsi != NULL);
417  assert(what != NULL);
418  assert(what_name != NULL);
419  assert(entity != NULL);
420  assert(entity_name != NULL);
421 
422  SCIPverbMessage(scip, verblevel, NULL,
423  "Warning line %d: %s \"%s\" for %s \"%s\" ignored\n", mpsi->lineno, what, what_name, entity, entity_name);
424 }
425 
426 /** fill the line from \p pos up to column 80 with blanks. */
427 static
429  char* buf, /**< buffer to clear */
430  unsigned int pos /**< position to start the clearing process */
431  )
432 {
433  unsigned int i;
434 
435  for(i = pos; i < 80; i++)
436  buf[i] = BLANK;
437  buf[80] = '\0';
438 }
439 
440 /** change all blanks inside a field to #PATCH_CHAR. */
441 static
443  char* buf, /**< buffer to patch */
444  int beg, /**< position to begin */
445  int end /**< position to end */
446  )
447 {
448  int i;
449 
450  while( (beg <= end) && (buf[end] == BLANK) )
451  end--;
452 
453  while( (beg <= end) && (buf[beg] == BLANK) )
454  beg++;
455 
456  for( i = beg; i <= end; i++ )
457  if( buf[i] == BLANK )
458  buf[i] = PATCH_CHAR;
459 }
460 
461 /** read a mps format data line and parse the fields. */
462 static
464  MPSINPUT* mpsi /**< mps input structure */
465  )
466 {
467  unsigned int len;
468  unsigned int i;
469  int space;
470  char* s;
471  SCIP_Bool is_marker;
472  SCIP_Bool is_empty;
473  char* nexttok;
474 
475  do
476  {
477  mpsi->f0 = mpsi->f1 = mpsi->f2 = mpsi->f3 = mpsi->f4 = mpsi->f5 = 0;
478  is_marker = FALSE;
479 
480  /* Read until we have not a comment line. */
481  do
482  {
483  mpsi->buf[MPS_MAX_LINELEN-1] = '\0';
484  if( NULL == SCIPfgets(mpsi->buf, (int) sizeof(mpsi->buf), mpsi->fp) )
485  return FALSE;
486  mpsi->lineno++;
487  }
488  while( *mpsi->buf == '*' ); /* coverity[a_loop_bound] */
489 
490  /* Normalize line */
491  len = (unsigned int) strlen(mpsi->buf);
492 
493  for( i = 0; i < len; i++ )
494  if( (mpsi->buf[i] == '\t') || (mpsi->buf[i] == '\n') || (mpsi->buf[i] == '\r') )
495  mpsi->buf[i] = BLANK;
496 
497  if( len < 80 )
498  clearFrom(mpsi->buf, len);
499 
500  SCIPdebugMessage("line %d: <%s>\n", mpsi->lineno, mpsi->buf);
501 
502  assert(strlen(mpsi->buf) >= 80);
503 
504  /* Look for new section */
505  if( *mpsi->buf != BLANK )
506  {
507  mpsi->f0 = SCIPstrtok(&mpsi->buf[0], " ", &nexttok);
508 
509  assert(mpsi->f0 != 0);
510 
511  mpsi->f1 = SCIPstrtok(NULL, " ", &nexttok);
512 
513  return TRUE;
514  }
515 
516  /* If we decide to use the new format we never revert this decision */
517  if( !mpsi->isnewformat )
518  {
519  /* Test for fixed format comments */
520  if( (mpsi->buf[14] == '$') && (mpsi->buf[13] == ' ') )
521  clearFrom(mpsi->buf, 14);
522  else if( (mpsi->buf[39] == '$') && (mpsi->buf[38] == ' ') )
523  clearFrom(mpsi->buf, 39);
524 
525  /* Test for fixed format */
526  space = mpsi->buf[12] | mpsi->buf[13]
527  | mpsi->buf[22] | mpsi->buf[23]
528  | mpsi->buf[36] | mpsi->buf[37] | mpsi->buf[38]
529  | mpsi->buf[47] | mpsi->buf[48]
530  | mpsi->buf[61] | mpsi->buf[62] | mpsi->buf[63];
531 
532  if( space == BLANK )
533  {
534  /* Now we have space at the right positions.
535  * But are there also the non space where they
536  * should be ?
537  */
539 
540  number = isdigit((unsigned char)mpsi->buf[24]) || isdigit((unsigned char)mpsi->buf[25])
541  || isdigit((unsigned char)mpsi->buf[26]) || isdigit((unsigned char)mpsi->buf[27])
542  || isdigit((unsigned char)mpsi->buf[28]) || isdigit((unsigned char)mpsi->buf[29])
543  || isdigit((unsigned char)mpsi->buf[30]) || isdigit((unsigned char)mpsi->buf[31])
544  || isdigit((unsigned char)mpsi->buf[32]) || isdigit((unsigned char)mpsi->buf[33])
545  || isdigit((unsigned char)mpsi->buf[34]) || isdigit((unsigned char)mpsi->buf[35]);
546 
547  /* len < 14 is handle ROW lines with embedded spaces
548  * in the names correctly
549  */
550  if( number || len < 14 )
551  {
552  /* We assume fixed format, so we patch possible embedded spaces. */
553  patchField(mpsi->buf, 4, 12);
554  patchField(mpsi->buf, 14, 22);
555  patchField(mpsi->buf, 39, 47);
556  }
557  else
558  {
559  if( mpsi->section == MPS_COLUMNS || mpsi->section == MPS_RHS
560  || mpsi->section == MPS_RANGES || mpsi->section == MPS_BOUNDS )
561  mpsi->isnewformat = TRUE;
562  }
563  }
564  else
565  {
566  mpsi->isnewformat = TRUE;
567  }
568  }
569  s = &mpsi->buf[1];
570 
571  /* At this point it is not clear if we have a indicator field.
572  * If there is none (e.g. empty) f1 will be the first name field.
573  * If there is one, f2 will be the first name field.
574  *
575  * Initially comment marks '$' are only allowed in the beginning
576  * of the 2nd and 3rd name field. We test all fields but the first.
577  * This makes no difference, since if the $ is at the start of a value
578  * field, the line will be erroneous anyway.
579  */
580  do
581  {
582  if( NULL == (mpsi->f1 = SCIPstrtok(s, " ", &nexttok)) )
583  break;
584 
585  if( (NULL == (mpsi->f2 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f2 == '$') )
586  {
587  mpsi->f2 = 0;
588  break;
589  }
590  if( !strcmp(mpsi->f2, "'MARKER'") )
591  is_marker = TRUE;
592 
593  if( (NULL == (mpsi->f3 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f3 == '$') )
594  {
595  mpsi->f3 = 0;
596  break;
597  }
598  if( is_marker )
599  {
600  if( !strcmp(mpsi->f3, "'INTORG'") )
601  mpsi->isinteger = TRUE;
602  else if( !strcmp(mpsi->f3, "'INTEND'") )
603  mpsi->isinteger = FALSE;
604  else
605  break; /* unknown marker */
606  }
607  if( !strcmp(mpsi->f3, "'MARKER'") )
608  is_marker = TRUE;
609 
610  if( (NULL == (mpsi->f4 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f4 == '$') )
611  {
612  mpsi->f4 = 0;
613  break;
614  }
615  if( is_marker )
616  {
617  if( !strcmp(mpsi->f4, "'INTORG'") )
618  mpsi->isinteger = TRUE;
619  else if( !strcmp(mpsi->f4, "'INTEND'") )
620  mpsi->isinteger = FALSE;
621  else
622  break; /* unknown marker */
623  }
624  if( (NULL == (mpsi->f5 = SCIPstrtok(NULL, " ", &nexttok))) || (*mpsi->f5 == '$') )
625  mpsi->f5 = 0;
626  }
627  while( FALSE );
628 
629  /* check for empty lines */
630  is_empty = (mpsi->f0 == NULL && mpsi->f1 == NULL);
631  }
632  while( is_marker || is_empty );
633 
634  return TRUE;
635 }
636 
637 /** Insert \p str as field 4 and shift all other fields up. */
638 static
640  MPSINPUT* mpsi, /**< mps input structure */
641  const char* str /**< str to insert */
642  )
643 {
644  assert(mpsi != NULL);
645  assert(str != NULL);
646 
647  mpsi->f5 = mpsi->f4;
648  mpsi->f4 = str;
649 }
650 
651 /** Insert \p name as field 1 or 2 and shift all other fields up. */
652 static
654  MPSINPUT* mpsi, /**< mps input structure */
655  const char* name, /**< name to insert */
656  SCIP_Bool second /**< insert as second field? */
657  )
658 {
659  assert(mpsi != NULL);
660  assert(name != NULL);
661 
662  mpsi->f5 = mpsi->f4;
663  mpsi->f4 = mpsi->f3;
664  mpsi->f3 = mpsi->f2;
665 
666  if( second )
667  mpsi->f2 = name;
668  else
669  {
670  mpsi->f2 = mpsi->f1;
671  mpsi->f1 = name;
672  }
673 }
674 
675 /** Add variable name to storage */
676 static
678  SCIP* scip, /**< SCIP data structure */
679  const char*** varnames, /**< the variable name storage */
680  int* varnamessize, /**< the size of the variable names storage */
681  int* nvars, /**< the number of variables */
682  const char* colname /**< the name of the variable */
683  )
684 {
685  assert(scip != NULL);
686 
687  if( varnames != NULL )
688  {
689  SCIP_CALL( SCIPensureBlockMemoryArray(scip, varnames, varnamessize, (*nvars) + 1) );
690  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*varnames)[(*nvars)], colname, strlen(colname) + 1) ); /*lint !e866*/
691  (*nvars)++;
692  }
693 
694  return SCIP_OKAY;
695 }
696 
697 /** Add constraint name to storage */
698 static
700  SCIP* scip, /**< SCIP data structure */
701  const char*** consnames, /**< the constraint name storage */
702  int* consnamessize, /**< the size of the constraint names storage */
703  int* ncons, /**< the number of constraint */
704  const char* rowname /**< the name of the constraint */
705  )
706 {
707  assert(scip != NULL);
708 
709  if( consnames != NULL )
710  {
711  SCIP_CALL( SCIPensureBlockMemoryArray(scip, consnames, consnamessize, (*ncons) + 1) );
712  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consnames)[(*ncons)], rowname, strlen(rowname) + 1) ); /*lint !e866*/
713  (*ncons)++;
714  }
715 
716  return SCIP_OKAY;
717 }
718 
719 /** Process NAME section. */
720 static
722  SCIP* scip, /**< SCIP data structure */
723  MPSINPUT* mpsi /**< mps input structure */
724  )
725 {
726  assert(mpsi != NULL);
727 
728  SCIPdebugMsg(scip, "read problem name\n");
729 
730  /* This has to be the Line with the NAME section. */
731  if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL || strcmp(mpsinputField0(mpsi), "NAME") )
732  {
733  mpsinputSyntaxerror(mpsi);
734  return SCIP_OKAY;
735  }
736 
737  /* Sometimes the name is omitted. */
738  mpsinputSetProbname(mpsi, (mpsinputField1(mpsi) == 0) ? "_MPS_" : mpsinputField1(mpsi));
739 
740  /* This hat to be a new section */
741  /* coverity[tainted_data] */
742  if( !mpsinputReadLine(mpsi) || (mpsinputField0(mpsi) == NULL) )
743  {
744  mpsinputSyntaxerror(mpsi);
745  return SCIP_OKAY;
746  }
747 
748  if( !strncmp(mpsinputField0(mpsi), "ROWS", 4) )
750  else if( !strncmp(mpsinputField0(mpsi), "USERCUTS", 8) )
752  else if( !strncmp(mpsinputField0(mpsi), "LAZYCONS", 8) )
754  else if( !strncmp(mpsinputField0(mpsi), "OBJSEN", 6) )
756  else if( !strncmp(mpsinputField0(mpsi), "OBJNAME", 7) )
758  else
759  {
760  mpsinputSyntaxerror(mpsi);
761  return SCIP_OKAY;
762  }
763 
764  return SCIP_OKAY;
765 }
766 
767 /** Process OBJSEN section. This Section is a CPLEX extension. */
768 static
770  SCIP* scip, /**< SCIP data structure */
771  MPSINPUT* mpsi /**< mps input structure */
772  )
773 {
774  assert(mpsi != NULL);
775 
776  SCIPdebugMsg(scip, "read objective sense\n");
777 
778  /* Although this is not explicitly in the MPS extensions as provided by CPLEX, some other MIP solvers
779  * (in particular gurobi), put 'MIN' or 'MAX' as the input field on the same line as the section declaration */
780  if( mpsinputField1(mpsi) == NULL){
781  /* Normal Cplex extension; info should be on the next line, in field 1 */
782  /* This has to be the Line with MIN or MAX. */
783  if( !mpsinputReadLine(mpsi) || (mpsinputField1(mpsi) == NULL) )
784  {
785  mpsinputSyntaxerror(mpsi);
786  return SCIP_OKAY;
787  }
788  }
789  /* Otherwise, the input should read e.g. "OBJSENSE MAX" so that MAX is also the first field */
790 
791  if( !strncmp(mpsinputField1(mpsi), "MIN", 3) )
793  else if( !strncmp(mpsinputField1(mpsi), "MAX", 3) )
795  else
796  {
797  mpsinputSyntaxerror(mpsi);
798  return SCIP_OKAY;
799  }
800 
801  /* Look for ROWS, USERCUTS, LAZYCONS, or OBJNAME Section */
802  /* coverity[tainted_data] */
803  if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
804  {
805  mpsinputSyntaxerror(mpsi);
806  return SCIP_OKAY;
807  }
808 
809  if( !strcmp(mpsinputField0(mpsi), "ROWS") )
811  else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
813  else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
815  else if( !strcmp(mpsinputField0(mpsi), "OBJNAME") )
817  else
818  {
819  mpsinputSyntaxerror(mpsi);
820  return SCIP_OKAY;
821  }
822 
823  return SCIP_OKAY;
824 }
825 
826 /** Process OBJNAME section. This Section is a CPLEX extension. */
827 static
829  SCIP* scip, /**< SCIP data structure */
830  MPSINPUT* mpsi /**< mps input structure */
831  )
832 {
833  assert(mpsi != NULL);
834 
835  SCIPdebugMsg(scip, "read objective name\n");
836 
837  /* This has to be the Line with the name. */
838  if( !mpsinputReadLine(mpsi) || mpsinputField1(mpsi) == NULL )
839  {
840  mpsinputSyntaxerror(mpsi);
841  return SCIP_OKAY;
842  }
843 
844  mpsinputSetObjname(mpsi, mpsinputField1(mpsi));
845 
846  /* Look for ROWS, USERCUTS, or LAZYCONS Section */
847  /* coverity[tainted_data] */
848  if( !mpsinputReadLine(mpsi) || mpsinputField0(mpsi) == NULL )
849  {
850  mpsinputSyntaxerror(mpsi);
851  return SCIP_OKAY;
852  }
853  if( !strcmp(mpsinputField0(mpsi), "ROWS") )
855  else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
857  else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
859  else
860  mpsinputSyntaxerror(mpsi);
861 
862  return SCIP_OKAY;
863 }
864 
865 /** Process ROWS, USERCUTS, or LAZYCONS section. */
866 static
868  MPSINPUT* mpsi, /**< mps input structure */
869  SCIP* scip, /**< SCIP data structure */
870  const char*** consnames, /**< storage for the constraint names, or NULL */
871  int* consnamessize, /**< the size of the constraint names storage, or NULL */
872  int* nconsnames /**< the number of stored constraint names, or NULL */
873  )
874 {
875  SCIPdebugMsg(scip, "read rows\n");
876 
877  /* coverity[tainted_data] */
878  while( mpsinputReadLine(mpsi) )
879  {
880  if( mpsinputField0(mpsi) != NULL )
881  {
882  if( !strcmp(mpsinputField0(mpsi), "ROWS") )
884  else if( !strcmp(mpsinputField0(mpsi), "USERCUTS") )
886  else if( !strcmp(mpsinputField0(mpsi), "LAZYCONS") )
888  else if( !strcmp(mpsinputField0(mpsi), "COLUMNS") )
890  else
891  mpsinputSyntaxerror(mpsi);
892 
893  return SCIP_OKAY;
894  }
895 
896  if( *mpsinputField1(mpsi) == 'N' )
897  {
898  if( *mpsinputObjname(mpsi) == '\0' )
899  mpsinputSetObjname(mpsi, mpsinputField2(mpsi));
900  else
901  mpsinputEntryIgnored(scip, mpsi, "row", mpsinputField2(mpsi), "objective function", "N", SCIP_VERBLEVEL_NORMAL);
902  }
903  else
904  {
905  SCIP_CONS* cons;
906  SCIP_Bool initial;
907  SCIP_Bool separate;
908  SCIP_Bool enforce;
909  SCIP_Bool check;
910  SCIP_Bool propagate;
911  SCIP_Bool local;
912  SCIP_Bool modifiable;
913  SCIP_Bool dynamic;
914  SCIP_Bool removable;
915 
916  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
917  if( cons != NULL )
918  break;
919 
920  initial = mpsi->initialconss && (mpsinputSection(mpsi) == MPS_ROWS);
921  separate = TRUE;
922  enforce = (mpsinputSection(mpsi) != MPS_USERCUTS);
923  check = (mpsinputSection(mpsi) != MPS_USERCUTS);
924  propagate = TRUE;
925  local = FALSE;
926  modifiable = FALSE;
927  dynamic = mpsi->dynamicconss;
928  removable = mpsi->dynamicrows || (mpsinputSection(mpsi) == MPS_USERCUTS);
929 
930  switch(*mpsinputField1(mpsi))
931  {
932  case 'G' :
933  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, SCIPinfinity(scip),
934  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
935  break;
936  case 'E' :
937  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, 0.0, 0.0,
938  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
939  break;
940  case 'L' :
941  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, mpsinputField2(mpsi), 0, NULL, NULL, -SCIPinfinity(scip), 0.0,
942  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, FALSE) );
943  break;
944  default :
945  mpsinputSyntaxerror(mpsi);
946  return SCIP_OKAY;
947  }
948  SCIP_CALL( SCIPaddCons(scip, cons) );
949  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
950 
951  /* if the file is of type cor, then the constraint names must be stored */
952  SCIP_CALL( addConsNameToStorage(scip, consnames, consnamessize, nconsnames, mpsinputField2(mpsi)) );
953  }
954  }
955  mpsinputSyntaxerror(mpsi);
956 
957  return SCIP_OKAY;
958 }
959 
960 /** Process COLUMNS section. */
961 static
963  MPSINPUT* mpsi, /**< mps input structure */
964  SCIP* scip, /**< SCIP data structure */
965  const char*** varnames, /**< storage for the variable names, or NULL */
966  int* varnamessize, /**< the size of the variable names storage, or NULL */
967  int* nvarnames /**< the number of stored variable names, or NULL */
968  )
969 {
970  char colname[MPS_MAX_NAMELEN] = { '\0' };
971  SCIP_CONS* cons;
972  SCIP_VAR* var;
973  SCIP_Real val;
974  SCIP_Bool usevartable;
975 
976  SCIPdebugMsg(scip, "read columns\n");
977 
978  var = NULL;
979  SCIP_CALL( SCIPgetBoolParam(scip, "misc/usevartable", &usevartable) );
980 
981  while( mpsinputReadLine(mpsi) )
982  {
983  if( mpsinputField0(mpsi) != 0 )
984  {
985  if( strcmp(mpsinputField0(mpsi), "RHS") )
986  break;
987 
988  /* add the last variable to the problem */
989  if( var != NULL )
990  {
991  SCIP_CALL( SCIPaddVar(scip, var) );
992  SCIP_CALL( SCIPreleaseVar(scip, &var) );
993  }
994  assert(var == NULL);
995 
997  return SCIP_OKAY;
998  }
999  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1000  break;
1001 
1002  /* new column? */
1003  if( strcmp(colname, mpsinputField1(mpsi)) )
1004  {
1005  /* add the last variable to the problem */
1006  if( var != NULL )
1007  {
1008  SCIP_CALL( SCIPaddVar(scip, var) );
1009  SCIP_CALL( SCIPreleaseVar(scip, &var) );
1010  }
1011  assert(var == NULL);
1012 
1013  (void)SCIPmemccpy(colname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1014 
1015  /* check whether we have seen this variable before, this would not allowed */
1016  if( usevartable && SCIPfindVar(scip, colname) != NULL )
1017  {
1018  SCIPerrorMessage("Coeffients of column <%s> don't appear consecutively (line: %d)\n",
1019  colname, mpsi->lineno);
1020 
1021  return SCIP_READERROR;
1022  }
1023 
1024  /* if the file type is a cor file, the the variable name must be stored */
1025  SCIP_CALL( addVarNameToStorage(scip, varnames, varnamessize, nvarnames, colname) );
1026 
1027  if( mpsinputIsInteger(mpsi) )
1028  {
1029  /* for integer variables, default bounds are 0 <= x < 1(not +infinity, like it is for continuous variables), and default cost is 0 */
1030  SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
1031  !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1032  }
1033  else
1034  {
1035  /* for continuous variables, default bounds are 0 <= x, and default cost is 0 */
1036  SCIP_CALL( SCIPcreateVar(scip, &var, colname, 0.0, SCIPinfinity(scip), 0.0, SCIP_VARTYPE_CONTINUOUS,
1037  !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1038  }
1039  }
1040  assert(var != NULL);
1041 
1042  val = atof(mpsinputField3(mpsi));
1043 
1044  if( !strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) )
1045  {
1046  SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1047  }
1048  else
1049  {
1050  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1051  if( cons == NULL )
1052  mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_FULL);
1053  else if( !SCIPisZero(scip, val) )
1054  {
1055  /* warn the user in case the coefficient is infinite */
1056  if( SCIPisInfinity(scip, REALABS(val)) )
1057  {
1058  SCIPwarningMessage(scip, "Coefficient of variable <%s> in constraint <%s> contains infinite value <%e>,"
1059  " consider adjusting SCIP infinity.\n", SCIPvarGetName(var), SCIPconsGetName(cons), val);
1060  }
1061  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1062  }
1063  }
1064  if( mpsinputField5(mpsi) != NULL )
1065  {
1066  assert(mpsinputField4(mpsi) != NULL);
1067 
1068  val = atof(mpsinputField5(mpsi));
1069 
1070  if( !strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) )
1071  {
1072  SCIP_CALL( SCIPchgVarObj(scip, var, val) );
1073  }
1074  else
1075  {
1076  cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1077  if( cons == NULL )
1078  mpsinputEntryIgnored(scip, mpsi, "Column", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_FULL);
1079  else if( !SCIPisZero(scip, val) )
1080  {
1081  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
1082  }
1083  }
1084  }
1085  }
1086  mpsinputSyntaxerror(mpsi);
1087 
1088  return SCIP_OKAY;
1089 }
1090 
1091 /** Process RHS section. */
1092 static
1094  MPSINPUT* mpsi, /**< mps input structure */
1095  SCIP* scip /**< SCIP data structure */
1096  )
1097 {
1098  char rhsname[MPS_MAX_NAMELEN] = { '\0' };
1099  SCIP_CONS* cons;
1100  SCIP_Real lhs;
1101  SCIP_Real rhs;
1102  SCIP_Real val;
1103 
1104  SCIPdebugMsg(scip, "read right hand sides\n");
1105 
1106  while( mpsinputReadLine(mpsi) )
1107  {
1108  if( mpsinputField0(mpsi) != NULL )
1109  {
1110  if( !strcmp(mpsinputField0(mpsi), "RANGES") )
1112  else if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1114  else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1115  mpsinputSetSection(mpsi, MPS_SOS);
1116  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1118  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1120  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1122  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1124  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1126  else
1127  break;
1128  return SCIP_OKAY;
1129  }
1130  if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1131  || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1132  {
1133  SCIPwarningMessage(scip, "reading rhs section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1134 
1135  mpsinputInsertName(mpsi, "_RHS_", FALSE);
1136  }
1137 
1138  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1139  break;
1140 
1141  if( *rhsname == '\0' )
1142  (void)SCIPmemccpy(rhsname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1143 
1144  if( !strcmp(rhsname, mpsinputField1(mpsi)) )
1145  {
1146  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1147  if( cons == NULL )
1148  {
1149  /* the rhs of the objective row is treated as objective constant */
1150  if( strcmp(mpsinputField2(mpsi), mpsinputObjname(mpsi)) == 0 )
1151  {
1152  val = atof(mpsinputField3(mpsi));
1153  SCIP_CALL( SCIPaddOrigObjoffset(scip, -val) );
1154  }
1155  else
1156  mpsinputEntryIgnored(scip, mpsi, "RHS", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1157  }
1158  else
1159  {
1160  val = atof(mpsinputField3(mpsi));
1161 
1162  /* find out the row sense */
1163  lhs = SCIPgetLhsLinear(scip, cons);
1164  rhs = SCIPgetRhsLinear(scip, cons);
1165  if( SCIPisInfinity(scip, -lhs) )
1166  {
1167  /* lhs = -infinity -> lower or equal */
1168  assert(SCIPisZero(scip, rhs));
1169  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1170  }
1171  else if( SCIPisInfinity(scip, rhs) )
1172  {
1173  /* rhs = +infinity -> greater or equal */
1174  assert(SCIPisZero(scip, lhs));
1175  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1176  }
1177  else
1178  {
1179  /* lhs > -infinity, rhs < infinity -> equality */
1180  assert(SCIPisZero(scip, lhs));
1181  assert(SCIPisZero(scip, rhs));
1182  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1183  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1184  }
1185  SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField2(mpsi), lhs, rhs, val);
1186  }
1187  if( mpsinputField5(mpsi) != NULL )
1188  {
1189  cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1190  if( cons == NULL )
1191  {
1192  /* the rhs of the objective row is treated as objective constant */
1193  if( strcmp(mpsinputField4(mpsi), mpsinputObjname(mpsi)) == 0 )
1194  {
1195  val = atof(mpsinputField5(mpsi));
1196  SCIP_CALL( SCIPaddOrigObjoffset(scip, -val) );
1197  }
1198  else
1199  mpsinputEntryIgnored(scip, mpsi, "RHS", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1200  }
1201  else
1202  {
1203  val = atof(mpsinputField5(mpsi));
1204 
1205  /* find out the row sense */
1206  lhs = SCIPgetLhsLinear(scip, cons);
1207  rhs = SCIPgetRhsLinear(scip, cons);
1208  if( SCIPisInfinity(scip, -lhs) )
1209  {
1210  /* lhs = -infinity -> lower or equal */
1211  assert(SCIPisZero(scip, rhs));
1212  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1213  }
1214  else if( SCIPisInfinity(scip, rhs) )
1215  {
1216  /* rhs = +infinity -> greater or equal */
1217  assert(SCIPisZero(scip, lhs));
1218  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1219  }
1220  else
1221  {
1222  /* lhs > -infinity, rhs < infinity -> equality */
1223  assert(SCIPisZero(scip, lhs));
1224  assert(SCIPisZero(scip, rhs));
1225  SCIP_CALL( SCIPchgLhsLinear(scip, cons, val) );
1226  SCIP_CALL( SCIPchgRhsLinear(scip, cons, val) );
1227  }
1228  SCIPdebugMsg(scip, "RHS <%s> lhs: %g rhs: %g val: <%22.12g>\n", mpsinputField4(mpsi), lhs, rhs, val);
1229  }
1230  }
1231  }
1232  }
1233  mpsinputSyntaxerror(mpsi);
1234 
1235  return SCIP_OKAY;
1236 }
1237 
1238 /** Process RANGES section */
1239 static
1241  MPSINPUT* mpsi, /**< mps input structure */
1242  SCIP* scip /**< SCIP data structure */
1243  )
1244 {
1245  char rngname[MPS_MAX_NAMELEN] = { '\0' };
1246  SCIP_CONS* cons;
1247  SCIP_Real lhs;
1248  SCIP_Real rhs;
1249  SCIP_Real val;
1250 
1251  SCIPdebugMsg(scip, "read ranges\n");
1252 
1253  while( mpsinputReadLine(mpsi) )
1254  {
1255  if( mpsinputField0(mpsi) != NULL )
1256  {
1257  if( !strcmp(mpsinputField0(mpsi), "BOUNDS") )
1259  else if( !strcmp(mpsinputField0(mpsi), "SOS") )
1260  mpsinputSetSection(mpsi, MPS_SOS);
1261  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1263  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1265  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1267  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1269  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1271  else
1272  break;
1273  return SCIP_OKAY;
1274  }
1275  if( (mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL)
1276  || (mpsinputField4(mpsi) != NULL && mpsinputField5(mpsi) == NULL) )
1277  {
1278  SCIPwarningMessage(scip, "reading ranged section, a field is missing, assuming that the vector name is the missing one(, row identfier <%s>)\n", mpsinputField2(mpsi));
1279 
1280  mpsinputInsertName(mpsi, "_RNG_", FALSE);
1281  }
1282 
1283  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1284  break;
1285 
1286  if( *rngname == '\0' )
1287  (void)SCIPmemccpy(rngname, mpsinputField1(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1288 
1289  /* The rules are:
1290  * Row Sign LHS RHS
1291  * ----------------------------------------
1292  * G +/- rhs rhs + |range|
1293  * L +/- rhs - |range| rhs
1294  * E + rhs rhs + range
1295  * E - rhs + range rhs
1296  * ----------------------------------------
1297  */
1298  if( !strcmp(rngname, mpsinputField1(mpsi)) )
1299  {
1300  cons = SCIPfindCons(scip, mpsinputField2(mpsi));
1301  if( cons == NULL )
1302  mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField2(mpsi), SCIP_VERBLEVEL_NORMAL);
1303  else
1304  {
1305  val = atof(mpsinputField3(mpsi));
1306 
1307  /* find out the row sense */
1308  lhs = SCIPgetLhsLinear(scip, cons);
1309  rhs = SCIPgetRhsLinear(scip, cons);
1310  if( SCIPisInfinity(scip, -lhs) )
1311  {
1312  /* lhs = -infinity -> lower or equal */
1313  SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1314  }
1315  else if( SCIPisInfinity(scip, rhs) )
1316  {
1317  /* rhs = +infinity -> greater or equal */
1318  SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1319  }
1320  else
1321  {
1322  /* lhs > -infinity, rhs < infinity -> equality */
1323  assert(SCIPisEQ(scip, lhs, rhs));
1324  if( val >= 0.0 )
1325  {
1326  SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1327  }
1328  else
1329  {
1330  SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1331  }
1332  }
1333  }
1334  if( mpsinputField5(mpsi) != NULL )
1335  {
1336  cons = SCIPfindCons(scip, mpsinputField4(mpsi));
1337  if( cons == NULL )
1338  mpsinputEntryIgnored(scip, mpsi, "Range", mpsinputField1(mpsi), "row", mpsinputField4(mpsi), SCIP_VERBLEVEL_NORMAL);
1339  else
1340  {
1341  val = atof(mpsinputField5(mpsi));
1342 
1343  /* find out the row sense */
1344  lhs = SCIPgetLhsLinear(scip, cons);
1345  rhs = SCIPgetRhsLinear(scip, cons);
1346  if( SCIPisInfinity(scip, -lhs) )
1347  {
1348  /* lhs = -infinity -> lower or equal */
1349  SCIP_CALL( SCIPchgLhsLinear(scip, cons, rhs - REALABS(val)) );
1350  }
1351  else if( SCIPisInfinity(scip, rhs) )
1352  {
1353  /* rhs = +infinity -> greater or equal */
1354  SCIP_CALL( SCIPchgRhsLinear(scip, cons, lhs + REALABS(val)) );
1355  }
1356  else
1357  {
1358  /* lhs > -infinity, rhs < infinity -> equality */
1359  assert(SCIPisEQ(scip, lhs, rhs));
1360  if( val >= 0.0 )
1361  {
1362  SCIP_CALL( SCIPchgRhsLinear(scip, cons, rhs + val) );
1363  }
1364  else
1365  {
1366  SCIP_CALL( SCIPchgLhsLinear(scip, cons, lhs + val) );
1367  }
1368  }
1369  }
1370  }
1371  }
1372  }
1373  mpsinputSyntaxerror(mpsi);
1374 
1375  return SCIP_OKAY;
1376 }
1377 
1378 /** Process BOUNDS section. */
1379 static
1381  MPSINPUT* mpsi, /**< mps input structure */
1382  SCIP* scip /**< SCIP data structure */
1383  )
1384 {
1385  char bndname[MPS_MAX_NAMELEN] = { '\0' };
1386  SCIP_VAR* var;
1387  SCIP_RETCODE retcode;
1388  SCIP_Real val;
1389  SCIP_Bool shifted;
1390 
1391  SCIP_VAR** semicont;
1392  int nsemicont;
1393  int semicontsize;
1394 
1395  retcode = SCIP_OKAY;
1396 
1397  semicont = NULL;
1398  nsemicont = 0;
1399  semicontsize = 0;
1400 
1401  SCIPdebugMsg(scip, "read bounds\n");
1402 
1403  while( mpsinputReadLine(mpsi) )
1404  {
1405  if( mpsinputField0(mpsi) != 0 )
1406  {
1407  if( !strcmp(mpsinputField0(mpsi), "SOS") )
1408  mpsinputSetSection(mpsi, MPS_SOS);
1409  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1411  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1413  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1415  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1417  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1419  else
1420  break;
1421  goto READBOUNDS_FINISH;
1422  }
1423 
1424  shifted = FALSE;
1425 
1426  /* Is the value field used ? */
1427  if( !strcmp(mpsinputField1(mpsi), "LO") /* lower bound given in field 4 */
1428  || !strcmp(mpsinputField1(mpsi), "UP") /* upper bound given in field 4 */
1429  || !strcmp(mpsinputField1(mpsi), "FX") /* fixed value given in field 4 */
1430  || !strcmp(mpsinputField1(mpsi), "LI") /* CPLEX extension: lower bound of integer variable given in field 4 */
1431  || !strcmp(mpsinputField1(mpsi), "UI") /* CPLEX extension: upper bound of integer variable given in field 4 */
1432  || !strcmp(mpsinputField1(mpsi), "SC") /* CPLEX extension: semi-continuous variable, upper bound given in field 4 */
1433  || !strcmp(mpsinputField1(mpsi), "SI") )/* CPLEX extension: semi-integer variable, upper bound given in field 4 */
1434  {
1435  if( mpsinputField3(mpsi) != NULL && mpsinputField4(mpsi) == NULL )
1436  {
1437  int l;
1438 
1439  /* check what might be missing, if field 3 is a number the bound name might be missing */
1440  for( l = (int) strlen(mpsinputField3(mpsi)) - 1; l >= 0; --l )
1441  {
1442  if( mpsinputField3(mpsi)[l] != '.' && !isdigit(mpsinputField3(mpsi)[l]) )
1443  break;
1444  }
1445 
1446  /* the bound name?! is missing */
1447  if( l < 0 )
1448  {
1449  SCIPwarningMessage(scip, "in bound section a name for value <%s> might be missing\n", mpsinputField3(mpsi));
1450 
1451  mpsinputInsertName(mpsi, "_BND_", TRUE);
1452  shifted = TRUE;
1453  }
1454  /* the bound is be missing */
1455  else
1456  {
1457  SCIPwarningMessage(scip, "in bound section a value for column <%s> is missing, assuming 0.0\n", mpsinputField3(mpsi));
1458 
1459  mpsinputInsertField4(mpsi, "0.0");
1460  shifted = TRUE;
1461  }
1462  }
1463  }
1464  else if( !strcmp(mpsinputField1(mpsi), "FR") /* free variable */
1465  || !strcmp(mpsinputField1(mpsi), "MI") /* lower bound is minus infinity */
1466  || !strcmp(mpsinputField1(mpsi), "PL") /* upper bound is plus infinity */
1467  || !strcmp(mpsinputField1(mpsi), "BV") ) /* CPLEX extension: binary variable */
1468  {
1469  if( mpsinputField2(mpsi) != NULL && mpsinputField3(mpsi) == NULL )
1470  {
1471  SCIPwarningMessage(scip, "in bound section a name for a column is missing\n");
1472 
1473  mpsinputInsertName(mpsi, "_BND_", TRUE);
1474  shifted = TRUE;
1475  }
1476  }
1477  else
1478  {
1479  mpsinputSyntaxerror(mpsi);
1480  return SCIP_OKAY;
1481  }
1482 
1483  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL || mpsinputField3(mpsi) == NULL )
1484  break;
1485 
1486  if( *bndname == '\0' )
1487  (void)SCIPmemccpy(bndname, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1488 
1489  /* Only read the first Bound in section */
1490  if( !strcmp(bndname, mpsinputField2(mpsi)) )
1491  {
1492  SCIP_VARTYPE oldvartype;
1493  SCIP_Bool infeasible;
1494 
1495  var = SCIPfindVar(scip, mpsinputField3(mpsi));
1496  /* if variable did not appear in columns section before, then it may still come in later sections (QCMATRIX, QMATRIX, SOS, ...)
1497  * thus add it as continuous variables, which has default bounds 0.0 <= x, and default cost 0.0 */
1498  if( var == NULL )
1499  {
1500  SCIP_VAR* varcpy;
1501 
1502  SCIP_CALL( SCIPcreateVar(scip, &var, mpsinputField3(mpsi), 0.0, SCIPinfinity(scip), 0.0,
1503  SCIP_VARTYPE_CONTINUOUS, !mpsi->dynamiccols, mpsi->dynamiccols, NULL, NULL, NULL, NULL, NULL) );
1504 
1505  SCIP_CALL( SCIPaddVar(scip, var) );
1506  varcpy = var;
1507  SCIP_CALL( SCIPreleaseVar(scip, &varcpy) );
1508  /* mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField3(mpsi), "bound", bndname, SCIP_VERBLEVEL_NORMAL); */
1509  }
1510  assert(var != NULL);
1511 
1512  if( mpsinputField4(mpsi) == NULL )
1513  val = 0.0;
1514  else
1515  val = atof(mpsinputField4(mpsi));
1516 
1517  /* remember variable type */
1518  oldvartype = SCIPvarGetType(var);
1519 
1520  /* If a bound of a binary variable is given, the variable is converted into an integer variable
1521  * with default bounds 0 <= x <= infinity before applying the bound. Note that integer variables
1522  * are by default assumed to be binary, but an explicit lower bound of 0 turns them into integer variables.
1523  * Only if the upper bound is explicitly set to 1, we leave the variable as a binary one.
1524  */
1525  if( oldvartype == SCIP_VARTYPE_BINARY && !((mpsinputField1(mpsi)[0] == 'U' ||
1526  (mpsinputField1(mpsi)[0] == 'F' && mpsinputField1(mpsi)[1] == 'X')) && SCIPisFeasEQ(scip, val, 1.0))
1527  && !(mpsinputField1(mpsi)[0] == 'F' && mpsinputField1(mpsi)[1] == 'X'&& SCIPisFeasEQ(scip, val, 0.0)) )
1528  {
1529  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1530  assert(!infeasible);
1531 
1532  oldvartype = SCIP_VARTYPE_INTEGER;
1533  SCIP_CALL( SCIPchgVarUb(scip, var, SCIPinfinity(scip)) );
1534  }
1535 
1536  /* switch variable type to continuous before applying the bound, this is necessary for stupid non-integral
1537  * bounds on general variables, which even might lead to infeasibility
1538  */
1539  if( oldvartype != SCIP_VARTYPE_CONTINUOUS )
1540  {
1542  /* relaxing variable type */
1543  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_CONTINUOUS, &infeasible) );
1544  }
1545  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
1546 
1547  switch( mpsinputField1(mpsi)[0] )
1548  {
1549  case 'L':
1550  if( !SCIPisZero(scip, SCIPvarGetLbGlobal(var)) && SCIPisLT(scip, val, SCIPvarGetLbGlobal(var)) )
1551  {
1552  SCIPwarningMessage(scip, "Relaxing already defined lower bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetLbGlobal(var), SCIPvarGetName(var), val);
1553  }
1554 
1555  SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1556 
1557  if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1558  {
1559  if( !SCIPisFeasIntegral(scip, val) )
1560  {
1561  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1562  }
1563  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1564  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1565  }
1566  else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
1567  {
1568  if( !SCIPisFeasIntegral(scip, val) )
1569  {
1570  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral lower bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1571  }
1572  }
1573 
1574  break;
1575  case 'U':
1576  if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
1577  {
1578  SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
1579  }
1580 
1581  SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1582  if( mpsinputField1(mpsi)[1] == 'I' ) /* CPLEX extension (Integer Bound) */
1583  {
1584  if( !SCIPisFeasIntegral(scip, val) )
1585  {
1586  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1587  }
1588 
1589  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1590  /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1591  }
1592  else if( oldvartype < SCIP_VARTYPE_CONTINUOUS )
1593  {
1594  if( !SCIPisFeasIntegral(scip, val) )
1595  {
1596  SCIPwarningMessage(scip, "variable <%s> declared as integral has a non-integral upper bound (%.14g) -> if feasible, bounds will be adjusted\n", SCIPvarGetName(var), val);
1597  }
1598  }
1599  break;
1600  case 'S':
1601  assert(mpsinputField1(mpsi)[1] == 'C' || mpsinputField1(mpsi)[1] == 'I'); /* semi-continuous or semi-integer (CPLEX extension) */
1602  /* remember that variable is semi-continuous/-integer */
1603  if( semicontsize <= nsemicont )
1604  {
1605  semicontsize = SCIPcalcMemGrowSize(scip, nsemicont+1);
1606  if( semicont == NULL )
1607  {
1608  SCIP_CALL( SCIPallocBufferArray(scip, &semicont, semicontsize) );
1609  }
1610  else
1611  {
1612  SCIP_CALL( SCIPreallocBufferArray(scip, &semicont, semicontsize) );
1613  }
1614  }
1615  assert(semicont != NULL);
1616  semicont[nsemicont] = var;
1617  ++nsemicont;
1618 
1619  if( mpsinputField1(mpsi)[1] == 'I' ) /* variable is semi-integer, hence change its type to integer (the "semi" part will be handled below) */
1620  {
1621  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_INTEGER, &infeasible) );
1622  /* don't assert feasibility here because the presolver will and should detect an infeasibility */
1623  }
1624 
1625  /* if both bounds are infinite anyway, we do not need to print a warning or change the bound */
1626  if( !SCIPisInfinity(scip, val) || !SCIPisInfinity(scip, SCIPvarGetUbGlobal(var)) )
1627  {
1628  if( SCIPisGT(scip, val, SCIPvarGetUbGlobal(var)) )
1629  {
1630  SCIPwarningMessage(scip, "Relaxing already defined upper bound %g of variable <%s> to %g not allowed.\n", SCIPvarGetUbGlobal(var), SCIPvarGetName(var), val);
1631  }
1632 
1633  SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1634  }
1635  break;
1636  case 'F':
1637  if( mpsinputField1(mpsi)[1] == 'X' )
1638  {
1639  SCIP_CALL( SCIPchgVarLb(scip, var, val) );
1640  SCIP_CALL( SCIPchgVarUb(scip, var, val) );
1641  }
1642  else
1643  {
1644  SCIP_CALL( SCIPchgVarLb(scip, var, -SCIPinfinity(scip)) );
1645  SCIP_CALL( SCIPchgVarUb(scip, var, +SCIPinfinity(scip)) );
1646  }
1647  break;
1648  case 'M':
1649  SCIP_CALL( SCIPchgVarLb(scip, var, -SCIPinfinity(scip)) );
1650  break;
1651  case 'P':
1652  SCIP_CALL( SCIPchgVarUb(scip, var, +SCIPinfinity(scip)) );
1653  break;
1654  case 'B' : /* CPLEX extension (Binary) */
1655  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1656  SCIP_CALL( SCIPchgVarUb(scip, var, 1.0) );
1657  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_BINARY, &infeasible) );
1658  /* don't assert feasibility here because the presolver will and should detect a infeasibility */
1659  break;
1660  default:
1661  mpsinputSyntaxerror(mpsi);
1662  return SCIP_OKAY;
1663  }
1664 
1665  /* switch variable type back to old type if necessary */
1666  if( oldvartype < SCIPvarGetType(var) )
1667  {
1668  SCIP_CALL( SCIPchgVarType(scip, var, oldvartype, &infeasible) );
1669  }
1670  }
1671  else
1672  {
1673  /* check for syntax error */
1674  assert(*bndname != '\0');
1675  if( strcmp(bndname, mpsinputField3(mpsi)) == 0 && shifted )
1676  {
1677  mpsinputSyntaxerror(mpsi);
1678  return SCIP_OKAY;
1679  }
1680 
1681  mpsinputEntryIgnored(scip, mpsi, "bound", mpsinputField2(mpsi), "variable", mpsinputField3(mpsi), SCIP_VERBLEVEL_NORMAL);
1682  }
1683  }
1684  mpsinputSyntaxerror(mpsi);
1685 
1686  READBOUNDS_FINISH:
1687  if( nsemicont > 0 )
1688  {
1689  SCIP_CONS* cons;
1690  SCIP_VAR* vars[2];
1691  SCIP_BOUNDTYPE boundtypes[2];
1692  SCIP_Real bounds[2];
1693  char name[SCIP_MAXSTRLEN];
1694  SCIP_Real oldlb;
1695  int i;
1696 
1697  assert(semicont != NULL);
1698 
1699  /* add bound disjunction constraints for semi-continuous and semi-integer variables */
1700  for( i = 0; i < nsemicont; ++i )
1701  {
1702  var = semicont[i];
1704 
1705  oldlb = SCIPvarGetLbGlobal(var);
1706  assert(oldlb >= 0.0);
1707 
1708  /* if no bound was specified (which we assume if we see lower bound 0.0),
1709  * then the default lower bound for a semi-continuous variable is 1.0 */
1710  if( oldlb == 0.0 )
1711  oldlb = 1.0;
1712 
1713  /* change the lower bound to 0.0 */
1714  SCIP_CALL( SCIPchgVarLb(scip, var, 0.0) );
1715 
1716  /* add a bound disjunction constraint to say var <= 0.0 or var >= oldlb */
1717  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "semicont_%s", SCIPvarGetName(var));
1718 
1719  vars[0] = var;
1720  vars[1] = var;
1721  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1722  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1723  bounds[0] = 0.0;
1724  bounds[1] = oldlb;
1725 
1726  retcode = SCIPcreateConsBounddisjunction(scip, &cons, name, 2, vars, boundtypes, bounds,
1727  !mpsi->dynamiccols, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, mpsi->dynamicconss, mpsi->dynamiccols, FALSE);
1728 
1729  if( retcode != SCIP_OKAY )
1730  break;
1731 
1732  SCIP_CALL( SCIPaddCons(scip, cons) );
1733 
1734  SCIPdebugMsg(scip, "add bound disjunction constraint for semi-continuity/-integrality of <%s>:\n\t", SCIPvarGetName(var));
1735  SCIPdebugPrintCons(scip, cons, NULL);
1736 
1737  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1738  }
1739  }
1740 
1741  SCIPfreeBufferArrayNull(scip, &semicont);
1742 
1743  SCIP_CALL( retcode );
1744 
1745  return SCIP_OKAY;
1746 }
1747 
1748 
1749 /** Process SOS section.
1750  *
1751  * We read the SOS section, which is a nonstandard section introduced by CPLEX.
1752  *
1753  * @note Currently we do not support the standard way of specifying SOS constraints via markers.
1754  */
1755 static
1757  MPSINPUT* mpsi, /**< mps input structure */
1758  SCIP* scip /**< SCIP data structure */
1759  )
1760 {
1761  SCIP_Bool initial;
1762  SCIP_Bool separate;
1763  SCIP_Bool enforce;
1764  SCIP_Bool check;
1765  SCIP_Bool propagate;
1766  SCIP_Bool local;
1767  SCIP_Bool dynamic;
1768  SCIP_Bool removable;
1769  char name[MPS_MAX_NAMELEN] = { '\0' };
1770  SCIP_CONS* cons = NULL;
1771  int consType = -1;
1772  int cnt = 0;
1773 
1774  SCIPdebugMsg(scip, "read SOS constraints\n");
1775 
1776  /* standard settings for SOS constraints: */
1777  initial = mpsi->initialconss;
1778  separate = TRUE;
1779  enforce = TRUE;
1780  check = TRUE;
1781  propagate = TRUE;
1782  local = FALSE;
1783  dynamic = mpsi->dynamicconss;
1784  removable = mpsi->dynamicrows;
1785 
1786  /* loop through section */
1787  while( mpsinputReadLine(mpsi) )
1788  {
1789  int type = -1;
1790 
1791  /* check if next section is found */
1792  if( mpsinputField0(mpsi) != NULL )
1793  {
1794  if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1796  else if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
1798  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
1800  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1802  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1804  break;
1805  }
1806  if( mpsinputField1(mpsi) == NULL )
1807  {
1808  SCIPerrorMessage("empty data in a non-comment line.\n");
1809  mpsinputSyntaxerror(mpsi);
1810  return SCIP_OKAY;
1811  }
1812 
1813  /* check for new SOS set */
1814  if( strcmp(mpsinputField1(mpsi), "S1") == 0 )
1815  type = 1;
1816  if( strcmp(mpsinputField1(mpsi), "S2") == 0 )
1817  type = 2;
1818 
1819  /* add last constraint and create a new one */
1820  if( type > 0 )
1821  {
1822  assert( type == 1 || type == 2 );
1823  if( cons != NULL )
1824  {
1825  /* add last constraint */
1826  SCIP_CALL( SCIPaddCons(scip, cons) );
1827  SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1828  SCIPdebugPrintCons(scip, cons, NULL);
1829  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1830  }
1831 
1832  /* check name */
1833  if( mpsinputField2(mpsi) != NULL )
1834  (void)SCIPmemccpy(name, mpsinputField2(mpsi), '\0', MPS_MAX_NAMELEN - 1);
1835  else
1836  {
1837  /* create new name */
1838  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "SOS%d", ++cnt);
1839  }
1840 
1841  /* create new SOS constraint */
1842  if( type == 1 )
1843  {
1844  /* we do not know the name of the constraint */
1845  SCIP_CALL( SCIPcreateConsSOS1(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1846  local, dynamic, removable, FALSE) );
1847  }
1848  else
1849  {
1850  assert( type == 2 );
1851  SCIP_CALL( SCIPcreateConsSOS2(scip, &cons, name, 0, NULL, NULL, initial, separate, enforce, check, propagate,
1852  local, dynamic, removable, FALSE) );
1853  }
1854  consType = type;
1855  SCIPdebugMsg(scip, "created constraint <%s> of type %d.\n", name, type);
1856  /* note: we ignore the priorities! */
1857  }
1858  else
1859  {
1860  /* otherwise we are in the section given variables */
1861  SCIP_VAR* var;
1862  SCIP_Real weight;
1863  char* endptr;
1864 
1865  if( consType != 1 && consType != 2 )
1866  {
1867  SCIPerrorMessage("missing SOS type specification.\n");
1868  mpsinputSyntaxerror(mpsi);
1869  return SCIP_OKAY;
1870  }
1871 
1872  /* get variable */
1873  var = SCIPfindVar(scip, mpsinputField1(mpsi));
1874  if( var == NULL )
1875  {
1876  /* ignore unknown variables - we would not know the type anyway */
1877  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "SOS", name, SCIP_VERBLEVEL_NORMAL);
1878  }
1879  else
1880  {
1881  /* get weight */
1882  if( NULL == mpsinputField2(mpsi) )
1883  {
1884  SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1885  mpsinputSyntaxerror(mpsi);
1886  return SCIP_OKAY;
1887  }
1888 
1889  weight = strtod(mpsinputField2(mpsi), &endptr);
1890  if( endptr == mpsinputField2(mpsi) || *endptr != '\0' )
1891  {
1892  SCIPerrorMessage("weight for variable <%s> not specified.\n", mpsinputField1(mpsi));
1893  mpsinputSyntaxerror(mpsi);
1894  return SCIP_OKAY;
1895  }
1896 
1897  /* add variable and weight */
1898  assert( consType == 1 || consType == 2 );
1899  switch( consType )
1900  {
1901  case 1:
1902  SCIP_CALL( SCIPaddVarSOS1(scip, cons, var, weight) );
1903  break;
1904  case 2:
1905  SCIP_CALL( SCIPaddVarSOS2(scip, cons, var, weight) );
1906  break;
1907  /* coverity[dead_error_begin] */
1908  default:
1909  SCIPerrorMessage("unknown SOS type: <%d>\n", type); /* should not happen */
1910  SCIPABORT();
1911  return SCIP_INVALIDDATA; /*lint !e527*/
1912  }
1913  SCIPdebugMsg(scip, "added variable <%s> with weight %g.\n", SCIPvarGetName(var), weight);
1914  }
1915  /* check other fields */
1916  if( (mpsinputField3(mpsi) != NULL && *mpsinputField3(mpsi) != '\0' ) ||
1917  (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
1918  (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
1919  {
1920  SCIPwarningMessage(scip, "ignoring data in fields 3-5 <%s> <%s> <%s>.\n",
1921  mpsinputField3(mpsi), mpsinputField4(mpsi), mpsinputField5(mpsi));
1922  }
1923  }
1924  }
1925 
1926  if( cons != NULL )
1927  {
1928  /* add last constraint */
1929  SCIP_CALL( SCIPaddCons(scip, cons) );
1930  SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
1931  SCIPdebugPrintCons(scip, cons, NULL);
1932  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
1933  }
1934 
1935  return SCIP_OKAY;
1936 }
1937 
1938 
1939 /** Process QMATRIX or QUADOBJ section.
1940  *
1941  * - We read the QMATRIX or QUADOBJ section, which is a nonstandard section introduced by CPLEX.
1942  * - We create a quadratic constraint for this matrix and add a variable to the objective to
1943  * represent the value of the QMATRIX.
1944  * - For a QMATRIX, we expect that both lower and upper diagonal elements are given and every
1945  * coefficient has to be divided by 2.0.
1946  * - For a QUADOBJ, we expect that only the upper diagonal elements are given and thus only
1947  * coefficients on the diagonal have to be divided by 2.0.
1948  */
1949 static
1951  MPSINPUT* mpsi, /**< mps input structure */
1952  SCIP_Bool isQuadObj, /**< whether we actually read a QUADOBJ section */
1953  SCIP* scip /**< SCIP data structure */
1954  )
1955 {
1956  SCIP_VAR** quadvars1;
1957  SCIP_VAR** quadvars2;
1958  SCIP_Real* quadcoefs;
1959  SCIP_RETCODE retcode;
1960  int cnt = 0; /* number of qmatrix elements processed so far */
1961  int size; /* size of quad* arrays */
1962 
1963  SCIPdebugMsg(scip, "read %s objective\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
1964 
1965  retcode = SCIP_OKAY;
1966 
1967  size = 1;
1968  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
1969  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
1970  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
1971 
1972  /* loop through section */
1973  /* coverity[tainted_data] */
1974  while( mpsinputReadLine(mpsi) )
1975  {
1976  /* otherwise we are in the section given variables */
1977  SCIP_VAR* var1;
1978  SCIP_VAR* var2;
1979  SCIP_Real coef;
1980 
1981  /* check if next section is found */
1982  if( mpsinputField0(mpsi) != NULL )
1983  {
1984  if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
1986  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
1988  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
1990  break;
1991  }
1992  if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
1993  {
1994  SCIPerrorMessage("empty data in a non-comment line.\n");
1995  mpsinputSyntaxerror(mpsi);
1996  SCIPfreeBufferArray(scip, &quadvars1);
1997  SCIPfreeBufferArray(scip, &quadvars2);
1998  SCIPfreeBufferArray(scip, &quadcoefs);
1999  return SCIP_OKAY;
2000  }
2001 
2002  /* get first variable */
2003  var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2004  if( var1 == NULL )
2005  {
2006  /* ignore unknown variables - we would not know the type anyway */
2007  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2008  }
2009  else
2010  {
2011  int k;
2012  for( k = 1; k <= 2; ++k )
2013  {
2014  /* get second variable */
2015  var2 = SCIPfindVar(scip, k == 1 ? mpsinputField2(mpsi) : mpsinputField4(mpsi));
2016  if( var2 == NULL )
2017  {
2018  /* ignore unknown variables - we would not know the type anyway */
2019  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2020  }
2021  else
2022  {
2023  const char* field;
2024  char* endptr;
2025 
2026  /* get coefficient */
2027  field = (k == 1 ? mpsinputField3(mpsi) : mpsinputField5(mpsi));
2028  if( NULL == field )
2029  {
2030  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2031  mpsinputSyntaxerror(mpsi);
2032  SCIPfreeBufferArray(scip, &quadvars1);
2033  SCIPfreeBufferArray(scip, &quadvars2);
2034  SCIPfreeBufferArray(scip, &quadcoefs);
2035  return SCIP_OKAY;
2036  }
2037 
2038  coef = strtod(field, &endptr);
2039  if( endptr == field || *endptr != '\0' )
2040  {
2041  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", SCIPvarGetName(var1), SCIPvarGetName(var2));
2042  mpsinputSyntaxerror(mpsi);
2043  SCIPfreeBufferArray(scip, &quadvars1);
2044  SCIPfreeBufferArray(scip, &quadvars2);
2045  SCIPfreeBufferArray(scip, &quadcoefs);
2046  return SCIP_OKAY;
2047  }
2048 
2049  /* store variables and coefficient */
2050  if( cnt >= size )
2051  {
2052  int newsize = SCIPcalcMemGrowSize(scip, size+1);
2053  assert(newsize > size);
2054  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2055  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2056  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2057  size = newsize;
2058  }
2059  assert(cnt < size);
2060  quadvars1[cnt] = var1;
2061  quadvars2[cnt] = var2;
2062  quadcoefs[cnt] = coef;
2063 
2064  /* diagonal elements have to be divided by 2.0
2065  * in a QMATRIX section also off-diagonal have to be divided by 2.0, since both lower and upper diagonal elements are given
2066  */
2067  if( var1 == var2 || !isQuadObj )
2068  quadcoefs[cnt] /= 2.0;
2069  ++cnt;
2070 
2071  SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
2072  }
2073 
2074  if( mpsinputField4(mpsi) == NULL || *mpsinputField4(mpsi) == '\0' )
2075  break;
2076 
2077  if( mpsinputField5(mpsi) == NULL || *mpsinputField5(mpsi) == '\0' )
2078  {
2079  /* ignore unknown variables - we would not know the type anyway */
2080  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField4(mpsi), "QMatrix", "QMATRIX", SCIP_VERBLEVEL_NORMAL);
2081  break;
2082  }
2083  }
2084  }
2085  }
2086 
2087  /* add constraint */
2088  if( cnt )
2089  {
2090  SCIP_Bool initial, separate, enforce, check, propagate;
2091  SCIP_Bool local, modifiable, dynamic, removable;
2092  SCIP_CONS* cons = NULL;
2093  SCIP_VAR* qmatrixvar = NULL;
2094  SCIP_Real lhs, rhs;
2095  SCIP_Real minusone = -1.0;
2096 
2097  /* determine settings; note that reading/{initialconss,dynamicconss,dynamicrows,dynamiccols} apply only to model
2098  * constraints and variables, not to an auxiliary objective constraint (otherwise it can happen that an auxiliary
2099  * objective variable is loose with infinite best bound, triggering the problem that an LP that is unbounded
2100  * because of loose variables with infinite best bound cannot be solved)
2101  */
2102  initial = TRUE;
2103  separate = TRUE;
2104  enforce = TRUE;
2105  check = TRUE;
2106  propagate = TRUE;
2107  local = FALSE;
2108  modifiable = FALSE;
2109  dynamic = FALSE;
2110  removable = FALSE;
2111 
2112  SCIP_CALL( SCIPcreateVar(scip, &qmatrixvar, "qmatrixvar", -SCIPinfinity(scip), SCIPinfinity(scip), 1.0,
2114  SCIP_CALL( SCIPaddVar(scip, qmatrixvar) );
2115 
2117  {
2118  lhs = -SCIPinfinity(scip);
2119  rhs = 0.0;
2120  }
2121  else
2122  {
2123  lhs = 0.0;
2124  rhs = SCIPinfinity(scip);
2125  }
2126 
2127  retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, "qmatrix", 1, &qmatrixvar, &minusone, cnt, quadvars1, quadvars2, quadcoefs, lhs, rhs,
2128  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable);
2129 
2130  if( retcode == SCIP_OKAY )
2131  {
2132  SCIP_CALL( SCIPaddCons(scip, cons) );
2133  SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2134  SCIPdebugPrintCons(scip, cons, NULL);
2135 
2136  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2137  SCIP_CALL( SCIPreleaseVar(scip, &qmatrixvar) );
2138  }
2139  }
2140  else
2141  {
2142  SCIPwarningMessage(scip, "%s section has no entries.\n", isQuadObj ? "QUADOBJ" : "QMATRIX");
2143  }
2144 
2145  SCIPfreeBufferArray(scip, &quadvars1);
2146  SCIPfreeBufferArray(scip, &quadvars2);
2147  SCIPfreeBufferArray(scip, &quadcoefs);
2148 
2149  SCIP_CALL( retcode );
2150 
2151  return SCIP_OKAY;
2152 }
2153 
2154 
2155 /** Process QCMATRIX section.
2156  *
2157  * We read the QCMATRIX section, which is a nonstandard section introduced by CPLEX.
2158  *
2159  * We replace the corresponding linear constraint by a quadratic constraint which contains the
2160  * original linear constraint plus the quadratic part specified in the QCMATRIX.
2161  */
2162 static
2164  MPSINPUT* mpsi, /**< mps input structure */
2165  SCIP* scip /**< SCIP data structure */
2166  )
2167 {
2168  SCIP_CONS* lincons; /* the linear constraint that was added for the corresponding row */
2169  SCIP_VAR** quadvars1;
2170  SCIP_VAR** quadvars2;
2171  SCIP_Real* quadcoefs;
2172  SCIP_RETCODE retcode;
2173  int cnt = 0; /* number of qcmatrix elements processed so far */
2174  int size; /* size of quad* arrays */
2175 
2176  if( mpsinputField1(mpsi) == NULL )
2177  {
2178  SCIPerrorMessage("no row name in QCMATRIX line.\n");
2179  mpsinputSyntaxerror(mpsi);
2180  return SCIP_OKAY;
2181  }
2182 
2183  retcode = SCIP_OKAY;
2184 
2185  SCIPdebugMsg(scip, "read QCMATRIX section for row <%s>\n", mpsinputField1(mpsi));
2186 
2187  lincons = SCIPfindCons(scip, mpsinputField1(mpsi));
2188  if( lincons == NULL )
2189  {
2190  SCIPerrorMessage("no row under name <%s> processed so far.\n", mpsinputField1(mpsi));
2191  mpsinputSyntaxerror(mpsi);
2192  return SCIP_OKAY;
2193  }
2194 
2195  size = 1;
2196  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars1, size) );
2197  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars2, size) );
2198  SCIP_CALL( SCIPallocBufferArray(scip, &quadcoefs, size) );
2199 
2200  /* loop through section */
2201  /* coverity[tainted_data] */
2202  while( mpsinputReadLine(mpsi) )
2203  {
2204  /* otherwise we are in the section given variables */
2205  SCIP_VAR* var1;
2206  SCIP_VAR* var2;
2207  SCIP_Real coef;
2208 
2209  /* check if next section is found */
2210  if( mpsinputField0(mpsi) != NULL )
2211  {
2212  if( !strcmp(mpsinputField0(mpsi), "QMATRIX") )
2214  else if( !strcmp(mpsinputField0(mpsi), "QUADOBJ") )
2216  else if( !strcmp(mpsinputField0(mpsi), "QCMATRIX") )
2218  else if( !strcmp(mpsinputField0(mpsi), "INDICATORS") )
2220  else if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2222  break;
2223  }
2224  if( mpsinputField1(mpsi) == NULL && mpsinputField2(mpsi) == NULL )
2225  {
2226  SCIPerrorMessage("empty data in a non-comment line.\n");
2227  mpsinputSyntaxerror(mpsi);
2228 
2229  goto TERMINATE;
2230  }
2231 
2232  /* get first variable */
2233  var1 = SCIPfindVar(scip, mpsinputField1(mpsi));
2234  if( var1 == NULL )
2235  {
2236  /* ignore unknown variables - we would not know the type anyway */
2237  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField1(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
2238  }
2239  else
2240  {
2241  /* get second variable */
2242  var2 = SCIPfindVar(scip, mpsinputField2(mpsi));
2243  if( var2 == NULL )
2244  {
2245  /* ignore unknown variables - we would not know the type anyway */
2246  mpsinputEntryIgnored(scip, mpsi, "column", mpsinputField2(mpsi), "QCMatrix", SCIPconsGetName(lincons), SCIP_VERBLEVEL_NORMAL);
2247  }
2248  else
2249  {
2250  char* endptr;
2251  if( mpsinputField3(mpsi) == NULL )
2252  {
2253  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
2254  mpsinputSyntaxerror(mpsi);
2255 
2256  goto TERMINATE;
2257  }
2258 
2259  /* get coefficient */
2260  coef = strtod(mpsinputField3(mpsi), &endptr);
2261  if( endptr == mpsinputField3(mpsi) || *endptr != '\0' )
2262  {
2263  SCIPerrorMessage("coefficient of term <%s>*<%s> not specified.\n", mpsinputField1(mpsi), mpsinputField2(mpsi));
2264  mpsinputSyntaxerror(mpsi);
2265 
2266  goto TERMINATE;
2267  }
2268 
2269  /* store variables and coefficient */
2270  if( cnt >= size )
2271  {
2272  int newsize = SCIPcalcMemGrowSize(scip, size+1);
2273  assert(newsize > size);
2274  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars1, newsize) );
2275  SCIP_CALL( SCIPreallocBufferArray(scip, &quadvars2, newsize) );
2276  SCIP_CALL( SCIPreallocBufferArray(scip, &quadcoefs, newsize) );
2277  size = newsize;
2278  }
2279  assert(cnt < size);
2280  quadvars1[cnt] = var1;
2281  quadvars2[cnt] = var2;
2282  quadcoefs[cnt] = coef;
2283  ++cnt;
2284 
2285  SCIPdebugMsg(scip, "stored term %g*<%s>*<%s>.\n", coef, SCIPvarGetName(var1), SCIPvarGetName(var2));
2286 
2287  /* check other fields */
2288  if( (mpsinputField4(mpsi) != NULL && *mpsinputField4(mpsi) != '\0' ) ||
2289  (mpsinputField5(mpsi) != NULL && *mpsinputField5(mpsi) != '\0' ) )
2290  {
2291  SCIPwarningMessage(scip, "ignoring data in fields 4 and 5 <%s> <%s>.\n", mpsinputField4(mpsi), mpsinputField5(mpsi));
2292  }
2293  }
2294  }
2295  }
2296 
2297  /* replace linear constraint by quadratic constraint */
2298  if( cnt )
2299  {
2300  SCIP_CONS* cons = NULL;
2301 
2302  retcode = SCIPcreateConsQuadraticNonlinear(scip, &cons, SCIPconsGetName(lincons),
2303  SCIPgetNVarsLinear(scip, lincons), SCIPgetVarsLinear(scip, lincons), SCIPgetValsLinear(scip, lincons),
2304  cnt, quadvars1, quadvars2, quadcoefs, SCIPgetLhsLinear(scip, lincons), SCIPgetRhsLinear(scip, lincons),
2305  SCIPconsIsInitial(lincons), SCIPconsIsSeparated(lincons), SCIPconsIsEnforced(lincons), SCIPconsIsChecked(lincons),
2306  SCIPconsIsPropagated(lincons), SCIPconsIsLocal(lincons), SCIPconsIsModifiable(lincons), SCIPconsIsDynamic(lincons),
2307  SCIPconsIsRemovable(lincons));
2308 
2309  if( retcode != SCIP_OKAY )
2310  goto TERMINATE;
2311 
2312  SCIP_CALL( SCIPaddCons(scip, cons) );
2313  SCIPdebugMsg(scip, "(line %d) added constraint <%s>: ", mpsi->lineno, SCIPconsGetName(cons));
2314  SCIPdebugPrintCons(scip, cons, NULL);
2315 
2316  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2317 
2318  SCIP_CALL( SCIPdelCons(scip, lincons) );
2319  }
2320  else
2321  {
2322  SCIPwarningMessage(scip, "QCMATRIX section has no entries.\n");
2323  }
2324 
2325  TERMINATE:
2326  SCIPfreeBufferArray(scip, &quadcoefs);
2327  SCIPfreeBufferArray(scip, &quadvars2);
2328  SCIPfreeBufferArray(scip, &quadvars1);
2329 
2330  SCIP_CALL( retcode );
2331 
2332  return SCIP_OKAY;
2333 }
2334 
2335 
2336 /** Process INDICATORS section.
2337  *
2338  * We read the INDICATORS section, which is a nonstandard section introduced by CPLEX.
2339  * Note that CPLEX does not allow ranged rows.
2340  *
2341  * If the linear constraints are equations or ranged rows, we generate two indicator
2342  * constraints.
2343  *
2344  * The section has to come after the QMATRIX* sections.
2345  */
2346 static
2348  MPSINPUT* mpsi, /**< mps input structure */
2349  SCIP* scip /**< SCIP data structure */
2350  )
2351 {
2352  SCIP_Bool initial;
2353  SCIP_Bool separate;
2354  SCIP_Bool enforce;
2355  SCIP_Bool check;
2356  SCIP_Bool propagate;
2357  SCIP_Bool local;
2358  SCIP_Bool dynamic;
2359  SCIP_Bool removable;
2360  SCIP_Bool stickingatnode;
2361  char name[MPS_MAX_NAMELEN] = { '\0' };
2362 
2363  SCIPdebugMsg(scip, "read INDICATORS constraints\n");
2364 
2365  /* standard settings for indicator constraints: */
2366  initial = mpsi->initialconss;
2367  separate = TRUE;
2368  enforce = TRUE;
2369  check = TRUE;
2370  propagate = TRUE;
2371  local = FALSE;
2372  dynamic = mpsi->dynamicconss;
2373  removable = mpsi->dynamicrows;
2374  stickingatnode = FALSE;
2375 
2376  /* loop through section */
2377  while( mpsinputReadLine(mpsi) )
2378  {
2379  SCIP_CONSHDLR* conshdlr;
2380  SCIP_CONS* cons;
2381  SCIP_CONS* lincons;
2382  SCIP_VAR* binvar;
2383  SCIP_Real lhs;
2384  SCIP_Real rhs;
2385 
2386  /* check if next section is found */
2387  if( mpsinputField0(mpsi) != NULL )
2388  {
2389  if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2391  break;
2392  }
2393 
2394  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
2395  {
2396  SCIPerrorMessage("empty data in a non-comment line.\n");
2397  mpsinputSyntaxerror(mpsi);
2398  return SCIP_OKAY;
2399  }
2400 
2401  /* check for new indicator constraint */
2402  if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
2403  {
2404  SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
2405  mpsinputSyntaxerror(mpsi);
2406  return SCIP_OKAY;
2407  }
2408 
2409  /* get linear constraint (row) */
2410  lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
2411  if( lincons == NULL )
2412  {
2413  SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
2414  mpsinputSyntaxerror(mpsi);
2415  return SCIP_OKAY;
2416  }
2417 
2418  /* check whether constraint is really linear */
2419  conshdlr = SCIPconsGetHdlr(lincons);
2420  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
2421  {
2422  SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
2423  mpsinputSyntaxerror(mpsi);
2424  return SCIP_OKAY;
2425  }
2426 
2427  /* get binary variable */
2428  binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
2429  if( binvar == NULL )
2430  {
2431  SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
2432  mpsinputSyntaxerror(mpsi);
2433  return SCIP_OKAY;
2434  }
2435 
2436  /* check type */
2437  if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
2438  {
2439  SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
2440  mpsinputSyntaxerror(mpsi);
2441  return SCIP_OKAY;
2442  }
2443 
2444  /* check whether we need the negated variable */
2445  if( mpsinputField4(mpsi) != NULL )
2446  {
2447  if( *mpsinputField4(mpsi) == '0' )
2448  {
2449  SCIP_VAR* var;
2450  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
2451  binvar = var;
2452  assert( binvar != NULL );
2453  }
2454  else
2455  {
2456  if( *mpsinputField4(mpsi) != '1' )
2457  {
2458  SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
2459  mpsinputSyntaxerror(mpsi);
2460  return SCIP_OKAY;
2461  }
2462  }
2463  }
2464 
2465  /* get lhs/rhs */
2466  lhs = SCIPgetLhsLinear(scip, lincons);
2467  rhs = SCIPgetRhsLinear(scip, lincons);
2468 
2469  if( !SCIPisInfinity(scip, -lhs) )
2470  {
2471  if( ! SCIPisInfinity(scip, rhs) )
2472  {
2473  /* create second indicator constraint */
2474  SCIP_VAR** vars;
2475  SCIP_Real* vals;
2476  SCIP_RETCODE retcode;
2477  SCIP_VAR** linvars;
2478  SCIP_Real* linvals;
2479  int nlinvars;
2480  int i;
2481 
2482  nlinvars = SCIPgetNVarsLinear(scip, lincons);
2483  linvars = SCIPgetVarsLinear(scip, lincons);
2484  linvals = SCIPgetValsLinear(scip, lincons);
2485 
2486  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
2487  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
2488  for( i = 0; i < nlinvars; ++i )
2489  {
2490  vars[i] = linvars[i];
2491  vals[i] = -linvals[i];
2492  }
2493 
2494  /* create new name */
2495  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
2496 
2497  /* create indicator constraint */
2498  retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
2499  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
2500 
2501  if( retcode == SCIP_OKAY )
2502  {
2503  SCIP_CALL( SCIPaddCons(scip, cons) );
2504  SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
2505  SCIPdebugPrintCons(scip, cons, NULL);
2506  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2507  }
2508 
2509  SCIPfreeBufferArray(scip, &vals);
2510  SCIPfreeBufferArray(scip, &vars);
2511 
2512  SCIP_CALL( retcode );
2513  }
2514  }
2515 
2516  /* correct linear constraint and create new name */
2517  if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
2518  {
2519  /* we have added lhs above and only need the rhs */
2520  SCIP_CALL( SCIPchgLhsLinear(scip, lincons, -SCIPinfinity(scip) ) );
2521  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
2522  }
2523  else
2524  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
2525 
2526  /* create indicator constraint */
2527  SCIP_CALL( SCIPcreateConsIndicatorLinConsPure(scip, &cons, name, binvar, lincons,
2528  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
2529 
2530  SCIP_CALL( SCIPaddCons(scip, cons) );
2531  SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
2532  SCIPdebugPrintCons(scip, cons, NULL);
2533  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2534  }
2535 
2536  return SCIP_OKAY;
2537 }
2538 
2539 
2540 /** Read LP in "MPS File Format".
2541  *
2542  * A specification of the MPS format can be found at
2543  *
2544  * http://plato.asu.edu/ftp/mps_format.txt,
2545  * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
2546  *
2547  * and in the
2548  *
2549  * CPLEX Reference Manual
2550  *
2551  * This routine should read all valid MPS format files.
2552  * What it will not do, is to find all cases where a file is ill formed.
2553  * If this happens it may complain and read nothing or read "something".
2554  */
2555 static
2557  SCIP* scip, /**< SCIP data structure */
2558  const char* filename, /**< name of the input file */
2559  const char*** varnames, /**< storage for the variable names, or NULL */
2560  const char*** consnames, /**< storage for the constraint names, or NULL */
2561  int* varnamessize, /**< the size of the variable names storage, or NULL */
2562  int* consnamessize, /**< the size of the constraint names storage, or NULL */
2563  int* nvarnames, /**< the number of stored variable names, or NULL */
2564  int* nconsnames /**< the number of stored constraint names, or NULL */
2565  )
2566 {
2567  SCIP_FILE* fp;
2568  MPSINPUT* mpsi;
2569  SCIP_RETCODE retcode;
2570  SCIP_Bool error = TRUE;
2571 
2572  assert(scip != NULL);
2573  assert(filename != NULL);
2574 
2575  fp = SCIPfopen(filename, "r");
2576  if( fp == NULL )
2577  {
2578  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2579  SCIPprintSysError(filename);
2580  return SCIP_NOFILE;
2581  }
2582 
2583  SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
2584 
2585  SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
2586 
2587  SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
2588 
2589  if( mpsinputSection(mpsi) == MPS_OBJSEN )
2590  {
2591  SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
2592  }
2593  if( mpsinputSection(mpsi) == MPS_OBJNAME )
2594  {
2595  SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
2596  }
2597  while( mpsinputSection(mpsi) == MPS_ROWS
2598  || mpsinputSection(mpsi) == MPS_USERCUTS
2599  || mpsinputSection(mpsi) == MPS_LAZYCONS )
2600  {
2601  SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
2602  }
2603  if( mpsinputSection(mpsi) == MPS_COLUMNS )
2604  {
2605  SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
2606  }
2607  if( mpsinputSection(mpsi) == MPS_RHS )
2608  {
2609  SCIP_CALL_TERMINATE( retcode, readRhs(mpsi, scip), TERMINATE );
2610  }
2611  if( mpsinputSection(mpsi) == MPS_RANGES )
2612  {
2613  SCIP_CALL_TERMINATE( retcode, readRanges(mpsi, scip), TERMINATE );
2614  }
2615  if( mpsinputSection(mpsi) == MPS_BOUNDS )
2616  {
2617  SCIP_CALL_TERMINATE( retcode, readBounds(mpsi, scip), TERMINATE );
2618  }
2619  if( mpsinputSection(mpsi) == MPS_SOS )
2620  {
2621  SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
2622  }
2623  while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2624  {
2625  SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2626  }
2627  if( mpsinputSection(mpsi) == MPS_QMATRIX )
2628  {
2629  SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
2630  }
2631  if( mpsinputSection(mpsi) == MPS_QUADOBJ )
2632  {
2633  SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
2634  }
2635  while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2636  {
2637  SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2638  }
2639  if( mpsinputSection(mpsi) == MPS_INDICATORS )
2640  {
2641  SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
2642  }
2643  if( mpsinputSection(mpsi) != MPS_ENDATA )
2644  mpsinputSyntaxerror(mpsi);
2645 
2646  SCIPfclose(fp);
2647 
2648  error = mpsinputHasError(mpsi);
2649 
2650  if( !error )
2651  {
2652  SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
2653  }
2654 
2655  TERMINATE:
2656  mpsinputFree(scip, &mpsi);
2657 
2658  if( error )
2659  return SCIP_READERROR;
2660  else
2661  return SCIP_OKAY;
2662 }
2663 
2664 /*
2665  * local methods for writing problem
2666  */
2667 
2668 /** gets the key (i.e. the name) of the given namefreq */
2669 static
2670 SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
2671 { /*lint --e{715}*/
2672  CONSNAMEFREQ* consnamefreq = (CONSNAMEFREQ*)elem;
2673 
2674  assert(consnamefreq != NULL);
2675  assert(consnamefreq->consname != NULL);
2676 
2677  return (void*)consnamefreq->consname;
2678 }
2679 
2680 /** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
2681 static
2682 SCIP_DECL_HASHKEYEQ(hashKeyEqString)
2683 { /*lint --e{715}*/
2684  const char* string1 = (const char*)key1;
2685  const char* string2 = (const char*)key2;
2686 
2687  return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
2688 }
2689 
2690 /** hash key retrieval function for variables */
2691 static
2692 SCIP_DECL_HASHGETKEY(hashGetKeyVar)
2693 { /*lint --e{715}*/
2694  return elem;
2695 }
2696 
2697 /** returns TRUE iff the indices of both variables are equal */
2698 static
2699 SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
2700 { /*lint --e{715}*/
2701  if( key1 == key2 )
2702  return TRUE;
2703  return FALSE;
2704 }
2705 
2706 /** returns the hash value of the key */
2707 static
2708 SCIP_DECL_HASHKEYVAL(hashKeyValVar)
2709 { /*lint --e{715}*/
2710  assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2711  return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2712 }
2713 
2714 
2715 /** computes the field width such that the output file is nicely arranged */
2716 static
2717 unsigned int computeFieldWidth(
2718  unsigned int width /**< required width */
2719  )
2720 {
2721  width = MAX(8u, width);
2722  return MIN(MPS_MAX_FIELDLEN, width);
2723 }
2724 
2725 
2726 /** output two strings in columns 1 and 2 with computed widths */
2727 static
2729  SCIP* scip, /**< SCIP data structure */
2730  FILE* file, /**< output file (or NULL for standard output) */
2731  const char* col1, /**< column 1 */
2732  const char* col2, /**< column 2 */
2733  unsigned int maxnamelen /**< maximum name length */
2734  )
2735 {
2736  unsigned int fieldwidth;
2737  char format[32];
2738 
2739  assert( scip != NULL );
2740  assert( col1 != NULL );
2741  assert( col2 != NULL );
2742  assert( strlen(col1) < MPS_MAX_NAMELEN );
2743  assert( strlen(col2) < MPS_MAX_VALUELEN );
2744  assert( maxnamelen > 0 );
2745 
2746  fieldwidth = computeFieldWidth(maxnamelen);
2747  (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
2748 
2749  SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
2750 }
2751 
2752 /** output two strings in columns 1 (width 2) and 2 (width 8) */
2753 static
2755  SCIP* scip, /**< SCIP data structure */
2756  FILE* file, /**< output file (or NULL for standard output) */
2757  const char* col1, /**< column 1 */
2758  const char* col2, /**< column 2 */
2759  int maxnamelen /**< maximum name length (-1 if irrelevant) */
2760  )
2761 {
2762  unsigned int fieldwidth;
2763  char format[32];
2764 
2765  assert( scip != NULL );
2766  assert( col1 != NULL );
2767  assert( col2 != NULL );
2768  assert( strlen(col1) <= 2 );
2769  assert( strlen(col2) < MPS_MAX_NAMELEN );
2770  assert( maxnamelen == -1 || maxnamelen > 0 );
2771 
2772  if( maxnamelen < 0 )
2773  {
2774  /* format does not matter */
2775  (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
2776  }
2777  else
2778  {
2779  fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
2780  (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
2781  }
2782 
2783  SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
2784 }
2785 
2786 /** prints the given data as column entry */
2787 static
2789  SCIP* scip, /**< SCIP data structure */
2790  FILE* file, /**< output file (or NULL for standard output) */
2791  const char* varname, /**< variable name */
2792  const char* consname, /**< constraint name */
2793  SCIP_Real value, /**< value to display */
2794  int* recordcnt, /**< pointer to store the number of records per line */
2795  unsigned int maxnamelen /**< maximum name length */
2796  )
2797 {
2798  char valuestr[MPS_MAX_VALUELEN] = { '\0' };
2799 
2800  assert( scip != NULL );
2801  assert( recordcnt != NULL );
2802  assert( *recordcnt >= 0 && *recordcnt < 2 );
2803 
2804  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
2805 
2806  if( *recordcnt == 0 )
2807  {
2808  /* start new line with an empty first column and the variable name in the second column */
2809  printStart(scip, file, "", varname, (int) maxnamelen);
2810  *recordcnt = 0;
2811  }
2812 
2813  printRecord(scip, file, consname, valuestr, maxnamelen);
2814  (*recordcnt)++;
2815 
2816  if( *recordcnt == 2 )
2817  {
2818  /* each line can have at most two records */
2819  SCIPinfoMessage(scip, file, "\n");
2820  *recordcnt = 0;
2821  }
2822 }
2823 
2824 /** prints the constraint type to file stream */
2825 static
2827  SCIP* scip, /**< SCIP data structure */
2828  FILE* file, /**< output file (or NULL for standard output) */
2829  SCIP_Real lhs, /**< left hand side */
2830  SCIP_Real rhs, /**< right hand side */
2831  const char* name /**< constraint name */
2832  )
2833 {
2834  char rowtype[2];
2835 
2836  assert( scip != NULL );
2837  assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
2838  assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
2839  assert( name != NULL );
2840 
2841  if( SCIPisEQ(scip, lhs, rhs) )
2842  (void) SCIPsnprintf(rowtype, 2, "%s", "E");
2843  else
2844  {
2845  /* in case the right hand side and the left hand side are not infinity we print a
2846  * less or equal constraint and put the right hand side in the RHS section and the
2847  * left hand side (hidden) in the RANGE section */
2848  if( !SCIPisInfinity(scip, rhs) )
2849  (void) SCIPsnprintf(rowtype, 2, "%s", "L");
2850  else
2851  {
2852  assert( !SCIPisInfinity(scip, -lhs) );
2853  (void) SCIPsnprintf(rowtype, 2, "%s", "G");
2854  }
2855  }
2856 
2857  printStart(scip, file, rowtype, name, -1);
2858  SCIPinfoMessage(scip, file, "\n");
2859 }
2860 
2861 
2862 /** initializes the sparse matrix */
2863 static
2865  SCIP* scip, /**< SCIP data structure */
2866  SPARSEMATRIX** matrix, /**< pointer to sparse matrix containing the entries */
2867  int slots /**< number of slots */
2868  )
2869 {
2870  SCIP_CALL( SCIPallocBuffer(scip, matrix) );
2871  (*matrix)->nentries = 0;
2872  (*matrix)->sentries = slots;
2873  SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
2874  SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
2875  SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
2876 
2877  return SCIP_OKAY;
2878 }
2879 
2880 /** this method takes care that the required capacity is available in the sparse matrix */
2881 static
2883  SCIP* scip, /**< SCIP data structure */
2884  SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2885  int capacity /**< needed capacity */
2886  )
2887 {
2888  if( matrix->nentries + capacity >= matrix->sentries )
2889  {
2890  matrix->sentries = matrix->sentries * 2 + capacity;
2891  SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
2892  SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
2893  SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
2894  }
2895  return SCIP_OKAY;
2896 }
2897 
2898 /** frees the sparse matrix */
2899 static
2901  SCIP* scip, /**< SCIP data structure */
2902  SPARSEMATRIX* matrix /**< sparse matrix to free */
2903  )
2904 {
2905  SCIPfreeBufferArray(scip, &matrix->rows);
2906  SCIPfreeBufferArray(scip, &matrix->columns);
2907  SCIPfreeBufferArray(scip, &matrix->values);
2908 
2909  SCIPfreeBuffer(scip, &matrix);
2910 }
2911 
2912 
2913 /** computes the coefficient for the given variables and linear constraint information */
2914 static
2916  SCIP* scip, /**< SCIP data structure */
2917  const char* consname, /**< name of the constraint */
2918  SCIP_VAR** vars, /**< array of variables */
2919  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2920  int nvars, /**< number of variables */
2921  SCIP_Bool transformed, /**< transformed constraint? */
2922  SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2923  SCIP_Real* rhs /**< pointer to right hand side */
2924  )
2925 {
2926  SCIP_VAR** activevars;
2927  SCIP_Real* activevals;
2928  SCIP_Real activeconstant = 0.0;
2929 
2930  int nactivevars;
2931  int requiredsize;
2932  int v;
2933 
2934  assert( scip != NULL );
2935  assert( nvars == 0 || vars != NULL );
2936  assert( !SCIPisInfinity(scip, *rhs) );
2937  assert( matrix != NULL );
2938 
2939  /* if the variables array contains no variables, then return without
2940  * doing any thing; The MPS format and LP format do not forbid this
2941  * situation */
2942  if( nvars == 0 )
2943  return SCIP_OKAY;
2944 
2945  /* duplicate variable and value array */
2946  nactivevars = nvars;
2947  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2948 
2949  if( vals != NULL )
2950  {
2951  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2952  }
2953  else
2954  {
2955  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2956 
2957  for( v = 0; v < nactivevars; ++v )
2958  activevals[v] = 1.0;
2959  }
2960 
2961  /* retransform given variables to active variables */
2962  if( transformed )
2963  {
2964  SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, nactivevars, &activeconstant, &requiredsize, TRUE) );
2965 
2966  if( requiredsize > nactivevars )
2967  {
2968  SCIP_CALL( SCIPreallocBufferArray(scip, &activevars, requiredsize) );
2969  SCIP_CALL( SCIPreallocBufferArray(scip, &activevals, requiredsize) );
2970 
2971  SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, requiredsize, &activeconstant, &requiredsize, TRUE) );
2972  assert( requiredsize <= nactivevars );
2973  }
2974  }
2975  else
2976  {
2977  for( v = 0; v < nactivevars; ++v )
2978  {
2979  SCIP_CALL( SCIPvarGetOrigvarSum(&activevars[v], &activevals[v], &activeconstant) );
2980 
2981  /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
2982  * make sure we get the original variable in that case
2983  */
2984  if( SCIPvarGetStatus(activevars[v]) == SCIP_VARSTATUS_NEGATED )
2985  {
2986  activevars[v] = SCIPvarGetNegatedVar(activevars[v]);
2987  activeconstant += activevals[v];
2988  activevals[v] *= -1.0;
2989  }
2990  }
2991  }
2992 
2993  /* copy the (matrix) row into the sparse matrix */
2994  SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, nactivevars) );
2995  assert( matrix->nentries + nactivevars < matrix->sentries );
2996 
2997  for( v = 0; v < nactivevars; ++v )
2998  {
2999  matrix->values[matrix->nentries] = activevals[v];
3000  matrix->columns[matrix->nentries] = activevars[v];
3001  matrix->rows[matrix->nentries] = consname;
3002  matrix->nentries++;
3003  }
3004 
3005  /* adjust right hand side */
3006  (*rhs) -= activeconstant;
3007 
3008  /* free buffer arrays */
3009  SCIPfreeBufferArray(scip, &activevals);
3010  SCIPfreeBufferArray(scip, &activevars);
3011 
3012  return SCIP_OKAY;
3013 }
3014 
3015 
3016 /** check whether given variables are aggregated and put them into an array without duplication */
3017 static
3019  SCIP* scip, /**< SCIP data structure */
3020  SCIP_VAR** vars, /**< variable array */
3021  int nvars, /**< number of active variables in the problem */
3022  SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
3023  int* naggvars, /**< pointer to number of aggregated variables on output */
3024  int* saggvars, /**< pointer to number of slots in aggvars array */
3025  SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
3026  )
3027 {
3028  int v;
3029 
3030  assert( scip != NULL );
3031  assert( aggvars != NULL );
3032  assert( naggvars != NULL );
3033  assert( saggvars != NULL );
3034 
3035  /* check variables */
3036  for( v = 0; v < nvars; ++v )
3037  {
3038  SCIP_VARSTATUS status;
3039  SCIP_VAR* var;
3040 
3041  var = vars[v];
3042  status = SCIPvarGetStatus(var);
3043 
3044  /* collect aggregated variables in a list */
3045  if( status >= SCIP_VARSTATUS_AGGREGATED )
3046  {
3047  assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
3048  assert( varAggregated != NULL );
3049 
3050  if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3051  {
3052  /* possibly enlarge array */
3053  if ( *saggvars <= *naggvars )
3054  {
3055  int newsize;
3056  newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
3057  assert( newsize > *saggvars );
3058  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
3059  *saggvars = newsize;
3060  }
3061 
3062  (*aggvars)[*naggvars] = var;
3063  (*naggvars)++;
3064  SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
3065  assert( *naggvars <= *saggvars );
3066  }
3067  }
3068  }
3069  return SCIP_OKAY;
3070 }
3071 
3072 
3073 /** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
3074 static
3076  SCIP* scip, /**< SCIP data structure */
3077  SCIP_VAR** vars, /**< array of variables */
3078  int nvars, /**< number of variables */
3079  unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3080  const char*** varnames, /**< pointer to array of variable names */
3081  SCIP_HASHMAP** varnameHashmap /**< pointer to hash map storing variable, variable name mapping */
3082  )
3083 {
3084  int v;
3085  int faulty;
3086  char* varname;
3087  SCIP_VAR* var;
3088 
3089  assert( scip != NULL );
3090  assert( vars != NULL );
3091  assert( maxnamelen != NULL );
3092 
3093  faulty = 0;
3094 
3095  /* allocate memory */
3096  SCIP_CALL( SCIPhashmapCreate(varnameHashmap, SCIPblkmem(scip), nvars) );
3097  SCIP_CALL( SCIPallocBufferArray(scip, varnames, nvars) );
3098 
3099  /* check if the variable names are not to long */
3100  for( v = 0; v < nvars; ++v )
3101  {
3102  size_t l;
3103 
3104  var = vars[v];
3105  assert( var != NULL );
3106 
3107  l = strlen(SCIPvarGetName(var));
3108 
3109  if( l >= MPS_MAX_NAMELEN )
3110  {
3111  faulty++;
3112  (*maxnamelen) = MPS_MAX_NAMELEN - 1;
3113  }
3114  else
3115  {
3116  (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3117  }
3118 
3119  SCIP_CALL( SCIPallocBufferArray(scip, &varname, (int) *maxnamelen + 1) );
3120  (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
3121 
3122  /* insert variable with variable name into hash map */
3123  assert( !SCIPhashmapExists(*varnameHashmap, var) );
3124  SCIP_CALL( SCIPhashmapInsert(*varnameHashmap, var, (void*) varname) );
3125 
3126  (*varnames)[v] = varname;
3127  }
3128 
3129  if( faulty > 0 )
3130  {
3131  SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
3132  faulty, MPS_MAX_NAMELEN - 1);
3133  }
3134  return SCIP_OKAY;
3135 }
3136 
3137 /** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
3138 static
3140  SCIP* scip, /**< SCIP data structure */
3141  SCIP_CONS** conss, /**< array of all constraints */
3142  int nconss, /**< number of all constraints */
3143  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3144  unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3145  const char*** consnames, /**< pointer to array of constraint names */
3146  SCIP_Bool* error /**< pointer to store whether all constraint names exist */
3147  )
3148 {
3149  SCIP_HASHTABLE* consfreq;
3150  CONSNAMEFREQ* consnamefreqs;
3151  SCIP_CONS* cons;
3152  char* consname;
3153  int i;
3154 
3155  assert(scip != NULL);
3156  assert(maxnamelen != NULL);
3157 
3158  *error = FALSE;
3159 
3160  /* allocate memory */
3161  SCIP_CALL( SCIPallocBufferArray(scip, &consnamefreqs, nconss) );
3162  SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
3164  hashGetKeyNamefreq, hashKeyEqString, SCIPhashKeyValString, NULL) );
3165 
3166  for( i = 0; i < nconss; ++i )
3167  {
3168  CONSNAMEFREQ* consnamefreq;
3169  size_t l;
3170  int freq;
3171 
3172  cons = conss[i];
3173  assert( cons != NULL );
3174 
3175  /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
3176  assert(!transformed || SCIPconsIsEnabled(cons));
3177 
3178  l = strlen(SCIPconsGetName(cons));
3179 
3180  if( l == 0 )
3181  {
3182  SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
3183  *error = TRUE;
3184 
3185  goto TERMINATE;
3186  }
3187 
3188  consnamefreqs[i].consname = SCIPconsGetName(cons);
3189  consnamefreqs[i].freq = 0;
3190  freq = 0;
3191 
3192  /* check for duplicate names */
3193  if( NULL != (consnamefreq = (CONSNAMEFREQ *)SCIPhashtableRetrieve(consfreq, (void*)SCIPconsGetName(cons))) )
3194  {
3195  consnamefreq->freq += 1;
3196  consnamefreqs[i] = *consnamefreq;
3197  freq = consnamefreq->freq;
3198  }
3199  SCIP_CALL( SCIPhashtableInsert(consfreq, (void*)(&consnamefreqs[i])) );
3200 
3201  /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
3202  if( freq > 0 )
3203  l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
3204 
3205  if( l >= MPS_MAX_NAMELEN )
3206  {
3207  SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
3208  *error = TRUE;
3209 
3210  goto TERMINATE;
3211  }
3212 
3213  (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3214 
3215  SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
3216  if( freq > 0 )
3217  (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
3218  else
3219  (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
3220 
3221  (*consnames)[i] = consname;
3222  }
3223 
3224 TERMINATE:
3225  SCIPfreeBufferArray(scip, &consnamefreqs);
3226 
3227  if( *error )
3228  {
3229  --i; /*lint !e445*/
3230  for( ; i >= 0; --i) /*lint !e445*/
3231  {
3232  SCIPfreeBufferArray(scip, &((*consnames)[i]));
3233  }
3234  SCIPfreeBufferArray(scip, consnames);
3235  }
3236 
3237  SCIPhashtableFree(&consfreq);
3238 
3239  return SCIP_OKAY;
3240 }
3241 
3242 
3243 /** outputs the COLUMNS section of the MPS format */
3244 static
3246  SCIP* scip, /**< SCIP data structure */
3247  FILE* file, /**< output file, or NULL if standard output should be used */
3248  SPARSEMATRIX* matrix, /**< sparse matrix containing the entries */
3249  SCIP_HASHMAP* varnameHashmap, /**< map from SCIP_VAR* to variable name */
3250  SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3251  unsigned int maxnamelen /**< maximum name length */
3252  )
3253 {
3254  SCIP_Bool intSection;
3255  SCIP_VAR* var;
3256  const char* varname;
3257  SCIP_Real value;
3258  int v;
3259  int recordcnt;
3260 
3261  /* sort sparse matrix w.r.t. the variable indices */
3262  SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, SCIPvarComp, matrix->nentries);
3263 
3264  /* print COLUMNS section */
3265  SCIPinfoMessage(scip, file, "COLUMNS\n");
3266 
3267  intSection = FALSE;
3268 
3269  for( v = 0; v < matrix->nentries; )
3270  {
3271  var = matrix->columns[v];
3272  assert( var != NULL );
3273 
3274  /* skip slack variables in output */
3275  if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3276  {
3277  ++v;
3278  continue;
3279  }
3280 
3281  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && intSection )
3282  {
3283  /* end integer section in MPS format */
3284  printStart(scip, file, "", "INTEND", (int) maxnamelen);
3285  printRecord(scip, file, "'MARKER'", "", maxnamelen);
3286  printRecord(scip, file, "'INTEND'", "", maxnamelen);
3287  SCIPinfoMessage(scip, file, "\n");
3288  intSection = FALSE;
3289  }
3290  else if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !intSection )
3291  {
3292  /* start integer section in MPS format */
3293  printStart(scip, file, "", "INTSTART", (int) maxnamelen);
3294  printRecord(scip, file, "'MARKER'", "", maxnamelen);
3295  printRecord(scip, file, "'INTORG'", "", maxnamelen);
3296  SCIPinfoMessage(scip, file, "\n");
3297  intSection = TRUE;
3298  }
3299 
3300  SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
3301 
3302  /* record count; there are at most two records per line */
3303  recordcnt = 0;
3304 
3305  /* get variable name */
3306  assert ( SCIPhashmapExists(varnameHashmap, var) );
3307  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var);
3308 
3309  /* output all entries of the same variable */
3310  do
3311  {
3312  value = matrix->values[v];
3313 
3314  /* print record to file */
3315  printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
3316  v++;
3317  }
3318  while( v < matrix->nentries && var == matrix->columns[v] );
3319 
3320  if( recordcnt == 1 )
3321  SCIPinfoMessage(scip, file, "\n");
3322  }
3323  /* end integer section, if the columns sections ends with integer variables */
3324  if( intSection )
3325  {
3326  /* end integer section in MPS format */
3327  printStart(scip, file, "", "INTEND", (int) maxnamelen);
3328  printRecord(scip, file, "'MARKER'", "", maxnamelen);
3329  printRecord(scip, file, "'INTEND'", "", maxnamelen);
3330  SCIPinfoMessage(scip, file, "\n");
3331  }
3332 }
3333 
3334 
3335 /** outputs the right hand side section */
3336 static
3338  SCIP* scip, /**< SCIP data structure */
3339  FILE* file, /**< output file, or NULL if standard output should be used */
3340  int nconss, /**< number of constraints */
3341  const char** consnames, /**< constraint names */
3342  SCIP_Real* rhss, /**< right hand side array */
3343  unsigned int maxnamelen, /**< maximum name length */
3344  SCIP_Real objoffset /**< objective offset */
3345  )
3346 {
3347  int recordcnt = 0;
3348  int c;
3349 
3350  assert( rhss != NULL );
3351 
3352  SCIPinfoMessage(scip, file, "RHS\n");
3353  SCIPdebugMsg(scip, "start printing RHS section\n");
3354 
3355  /* take care of the linear constraints */
3356  for( c = 0; c < nconss; ++c )
3357  {
3358  /* skip all constraints which have a right hand side of infinity */
3359  if( SCIPisInfinity(scip, rhss[c]) )
3360  continue;
3361 
3362  assert(consnames[c] != NULL);
3363 
3364  printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
3365  }
3366 
3367  if( ! SCIPisZero(scip, objoffset) )
3368  {
3369  /* write objective offset (-1 because it is moved to the rhs) */
3370  printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
3371  }
3372 
3373  if( recordcnt == 1 )
3374  SCIPinfoMessage(scip, file, "\n");
3375 }
3376 
3377 
3378 /** outputs the range section */
3379 static
3381  SCIP* scip, /**< SCIP data structure */
3382  FILE* file, /**< output file, or NULL if standard output should be used */
3383  SCIP_CONS** conss, /**< constraint array */
3384  int nconss, /**< number of constraints */
3385  const char** consnames, /**< constraint names */
3386  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3387  unsigned int maxnamelen /**< maximum name length */
3388  )
3389 {
3390  int c;
3391  int recordcnt = 0;
3392 
3393  SCIP_CONSHDLR* conshdlr;
3394  const char* conshdlrname;
3395 
3396  SCIP_CONS* cons;
3397  SCIP_Real lhs;
3398  SCIP_Real rhs;
3399 
3400  SCIPinfoMessage(scip, file, "RANGES\n");
3401  SCIPdebugMsg(scip, "start printing RANGES section\n");
3402 
3403  for( c = 0; c < nconss; ++c )
3404  {
3405  cons = conss[c];
3406  assert( cons != NULL);
3407 
3408  /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
3409  * the conss array should only contain relevant constraints
3410  */
3411  assert( !transformed || SCIPconsIsEnabled(cons) );
3412 
3413  assert( consnames[c] != NULL );
3414 
3415  conshdlr = SCIPconsGetHdlr(cons);
3416  assert( conshdlr != NULL );
3417 
3418  conshdlrname = SCIPconshdlrGetName(conshdlr);
3419 
3420  if( strcmp(conshdlrname, "linear") == 0 )
3421  {
3422  lhs = SCIPgetLhsLinear(scip, cons);
3423  rhs = SCIPgetRhsLinear(scip, cons);
3424  }
3425  else if( strcmp(conshdlrname, "varbound") == 0 )
3426  {
3427  lhs = SCIPgetLhsVarbound(scip, cons);
3428  rhs = SCIPgetRhsVarbound(scip, cons);
3429  }
3430  else
3431  continue;
3432 
3433  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
3434  {
3435  assert( SCIPisGT(scip, rhs, lhs) );
3436  printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
3437  }
3438  }
3439  if(recordcnt == 1 )
3440  SCIPinfoMessage(scip, file, "\n");
3441 }
3442 
3443 /** print bound section name */
3444 static
3446  SCIP* scip, /**< SCIP data structure */
3447  FILE* file /**< output file, or NULL if standard output should be used */
3448  )
3449 {
3450  SCIPinfoMessage(scip, file, "BOUNDS\n");
3451  SCIPdebugMsg(scip, "start printing BOUNDS section\n");
3452 }
3453 
3454 /** output bound section */
3455 static
3457  SCIP* scip, /**< SCIP data structure */
3458  FILE* file, /**< output file, or NULL if standard output should be used */
3459  SCIP_VAR** vars, /**< active variables */
3460  int nvars, /**< number of active variables */
3461  SCIP_VAR** aggvars, /**< needed aggregated variables */
3462  int naggvars, /**< number of aggregated variables */
3463  SCIP_VAR** fixvars, /**< all fixed variables (or NULL if nfixvars is 0) */
3464  int nfixvars, /**< number of fixed variables */
3465  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3466  const char** varnames, /**< array with variable names */
3467  SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3468  unsigned int maxnamelen /**< maximum name length */
3469  )
3470 {
3471  int v;
3472  SCIP_VAR* var;
3473  SCIP_Real lb;
3474  SCIP_Real ub;
3475  SCIP_Bool sectionName;
3476  const char* varname;
3477  char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3478 
3479  assert(scip != NULL);
3480  assert(vars != NULL);
3481  assert(nfixvars == 0 || fixvars != NULL);
3482 
3483  sectionName = FALSE;
3484 
3485  /* output the active variables */
3486  for( v = 0; v < nvars; ++v )
3487  {
3488  var = vars[v];
3489  assert( var != NULL );
3490 
3491  /* skip slack variables in output */
3492  if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3493  continue;
3494 
3495  /* get variable name */
3496  varname = varnames[v];
3497  assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3498 
3499  if( transformed )
3500  {
3501  /* in case the transformed is written only local bounds are posted
3502  * which are valid in the current node */
3503  lb = SCIPvarGetLbLocal(var);
3504  ub = SCIPvarGetUbLocal(var);
3505  }
3506  else
3507  {
3508  lb = SCIPvarGetLbOriginal(var);
3509  ub = SCIPvarGetUbOriginal(var);
3510  }
3511 
3512  /* take care of binary variables */
3513  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3514  {
3515  if( !sectionName )
3516  {
3517  printBoundSectionName(scip, file);
3518  sectionName = TRUE;
3519  }
3520 
3521  if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
3522  {
3523  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3524  printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3525  printRecord(scip, file, varname, valuestr, maxnamelen);
3526  SCIPinfoMessage(scip, file, "\n");
3527 
3528  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3529  printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3530  printRecord(scip, file, varname, valuestr, maxnamelen);
3531  }
3532  else
3533  {
3534  printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3535  printRecord(scip, file, varname, "", maxnamelen);
3536  }
3537  SCIPinfoMessage(scip, file, "\n");
3538 
3539  continue;
3540  }
3541 
3542  /* take care of free variables */
3543  if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3544  {
3545  if( !sectionName )
3546  {
3547  printBoundSectionName(scip, file);
3548  sectionName = TRUE;
3549  }
3550 
3551  /* variable is free */
3552  printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3553  printRecord(scip, file, varname, "", maxnamelen);
3554  SCIPinfoMessage(scip, file, "\n");
3555  continue;
3556  }
3557 
3558  /* take care of fixed variables */
3559  if( SCIPisEQ(scip, lb, ub) )
3560  {
3561  if( !sectionName )
3562  {
3563  printBoundSectionName(scip, file);
3564  sectionName = TRUE;
3565  }
3566 
3567  /* variable is fixed */
3568  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3569  printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3570  printRecord(scip, file, varname, valuestr, maxnamelen);
3571  SCIPinfoMessage(scip, file, "\n");
3572  continue;
3573  }
3574 
3575  /* print lower bound */
3576  if( SCIPisInfinity(scip, -lb) )
3577  {
3578  if( !sectionName )
3579  {
3580  printBoundSectionName(scip, file);
3581  sectionName = TRUE;
3582  }
3583 
3584  /* the free variables are processed above */
3585  assert( !SCIPisInfinity(scip, ub) );
3586  printStart(scip, file, "MI", "Bound", (int) maxnamelen);
3587  printRecord(scip, file, varname, "", maxnamelen);
3588  SCIPinfoMessage(scip, file, "\n");
3589  }
3590  else
3591  {
3592  if( SCIPisZero(scip, lb) )
3593  {
3594  lb = 0.0;
3595  }
3596  else
3597  {
3598  if( !sectionName )
3599  {
3600  printBoundSectionName(scip, file);
3601  sectionName = TRUE;
3602  }
3603 
3604  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3605  printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3606  printRecord(scip, file, varname, valuestr, maxnamelen);
3607  SCIPinfoMessage(scip, file, "\n");
3608  }
3609  }
3610 
3611  /* print upper bound, infinity has to be printed for integer (!) variables, because during
3612  * reading an mps file no upper bound of an integer variable means that the upper bound will
3613  * be set to 1 instead of +infinity (like it is for continuous variables) */
3614  if( SCIPisInfinity(scip, ub) )
3615  {
3616  if( !sectionName )
3617  {
3618  printBoundSectionName(scip, file);
3619  sectionName = TRUE;
3620  }
3621 
3622  /* the free variables are processed above */
3623  assert( !SCIPisInfinity(scip, -lb) );
3624  printStart(scip, file, "PL", "Bound", (int) maxnamelen);
3625  printRecord(scip, file, varname, "", maxnamelen);
3626  SCIPinfoMessage(scip, file, "\n");
3627  }
3628  else
3629  {
3630  if( !sectionName )
3631  {
3632  printBoundSectionName(scip, file);
3633  sectionName = TRUE;
3634  }
3635 
3636  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3637  printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3638  printRecord(scip, file, varname, valuestr, maxnamelen);
3639  SCIPinfoMessage(scip, file, "\n");
3640  }
3641  }
3642 
3643  /* output aggregated variables as 'free', except if they are binary */
3644  for( v = 0; v < naggvars; ++v )
3645  {
3646  if( !sectionName )
3647  {
3648  printBoundSectionName(scip, file);
3649  sectionName = TRUE;
3650  }
3651 
3652  var = aggvars[v];
3653  assert( var != NULL );
3654 
3655  /* get variable name */
3656  varname = varnames[nvars + v];
3657  assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3658 
3659  /* take care of binary variables */
3660  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3661  {
3662  printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3663  printRecord(scip, file, varname, "", maxnamelen);
3664  SCIPinfoMessage(scip, file, "\n");
3665  }
3666  else
3667  {
3668  /* variable is free */
3669  printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3670  printRecord(scip, file, varname, "", maxnamelen);
3671  SCIPinfoMessage(scip, file, "\n");
3672  }
3673  }
3674 
3675  /* output all fixed variables */
3676  for( v = 0; v < nfixvars; ++v )
3677  {
3678  /* we should print the transformed problem, otherwise no fixed variable should exists */
3679  assert(transformed);
3680  assert(fixvars != NULL && fixvars[v] != NULL);
3681 
3682  /* cppcheck-suppress nullPointer */
3683  var = fixvars[v];
3684 
3685  assert(var != NULL);
3686  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED);
3687 
3688  /* get variable name */
3689  varname = varnames[nvars + naggvars + v];
3690  assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3691 
3692  /* only local bounds are posted which are valid in the current node */
3693  lb = SCIPvarGetLbLocal(var);
3694  ub = SCIPvarGetUbLocal(var);
3695  assert(SCIPisEQ(scip, lb, ub));
3696 
3697  if( !sectionName )
3698  {
3699  printBoundSectionName(scip, file);
3700  sectionName = TRUE;
3701  }
3702 
3703  /* print fixed variable */
3704  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3705  printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3706  printRecord(scip, file, varname, valuestr, maxnamelen);
3707  SCIPinfoMessage(scip, file, "\n");
3708  }
3709 }
3710 
3711 
3712 /*
3713  * Callback methods of reader
3714  */
3715 
3716 /** copy method for reader plugins (called when SCIP copies plugins) */
3717 /**! [SnippetReaderCopyMps] */
3718 static
3719 SCIP_DECL_READERCOPY(readerCopyMps)
3720 { /*lint --e{715}*/
3721  assert(scip != NULL);
3722  assert(reader != NULL);
3723  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3724 
3725  /* call inclusion method of reader */
3727 
3728  return SCIP_OKAY;
3729 }
3730 /**! [SnippetReaderCopyMps] */
3731 
3732 /** destructor of reader to free user data (called when SCIP is exiting) */
3733 /**! [SnippetReaderFreeMps] */
3734 static
3735 SCIP_DECL_READERFREE(readerFreeMps)
3736 {
3737  SCIP_READERDATA* readerdata;
3738 
3739  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3740  readerdata = SCIPreaderGetData(reader);
3741  assert(readerdata != NULL);
3742  SCIPfreeBlockMemory(scip, &readerdata);
3743 
3744  return SCIP_OKAY;
3745 }
3746 /**! [SnippetReaderFreeMps] */
3747 
3748 /** problem reading method of reader */
3749 static
3750 SCIP_DECL_READERREAD(readerReadMps)
3751 { /*lint --e{715}*/
3752  assert(reader != NULL);
3753  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3754 
3755  SCIP_CALL( SCIPreadMps(scip, reader, filename, result, NULL, NULL, NULL, NULL, NULL, NULL) );
3756 
3757  return SCIP_OKAY;
3758 }
3759 
3760 
3761 /** problem writing method of reader */
3762 static
3763 SCIP_DECL_READERWRITE(readerWriteMps)
3764 { /*lint --e{715}*/
3765  assert(reader != NULL);
3766  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3767 
3768  SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objscale, objoffset, vars,
3769  nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
3770 
3771  return SCIP_OKAY;
3772 }
3773 
3774 
3775 /*
3776  * mps file reader specific interface methods
3777  */
3778 
3779 /** includes the mps file reader in SCIP */
3781  SCIP* scip /**< SCIP data structure */
3782  )
3783 {
3784  SCIP_READERDATA* readerdata;
3785  SCIP_READER* reader;
3786 
3787  /* create reader data */
3788  SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
3789 
3790  /* include reader */
3791  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
3792 
3793  /* set non fundamental callbacks via setter functions */
3794  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyMps) );
3795  SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeMps) );
3796  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadMps) );
3797  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteMps) );
3798 
3799  /* add lp-reader parameters */
3801  "reading/" READER_NAME "/linearize-and-constraints",
3802  "should possible \"and\" constraint be linearized when writing the mps file?",
3803  &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3805  "reading/" READER_NAME "/aggrlinearization-ands",
3806  "should an aggregated linearization for and constraints be used?",
3807  &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3808 
3809  return SCIP_OKAY;
3810 }
3811 
3812 
3813 /** reads problem from file */
3815  SCIP* scip, /**< SCIP data structure */
3816  SCIP_READER* reader, /**< the file reader itself */
3817  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3818  SCIP_RESULT* result, /**< pointer to store the result of the file reading call */
3819  const char*** varnames, /**< storage for the variable names, or NULL */
3820  const char*** consnames, /**< storage for the constraint names, or NULL */
3821  int* varnamessize, /**< the size of the variable names storage, or NULL */
3822  int* consnamessize, /**< the size of the constraint names storage, or NULL */
3823  int* nvarnames, /**< the number of stored variable names, or NULL */
3824  int* nconsnames /**< the number of stored constraint names, or NULL */
3825  )
3826 {
3827  SCIP_RETCODE retcode;
3828 
3829  assert(reader != NULL);
3830  assert(scip != NULL);
3831  assert(result != NULL);
3832 
3833  retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
3834 
3835  if( retcode == SCIP_PLUGINNOTFOUND )
3836  retcode = SCIP_READERROR;
3837 
3838  if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
3839  return retcode;
3840 
3841  SCIP_CALL( retcode );
3842 
3843  *result = SCIP_SUCCESS;
3844 
3845  return SCIP_OKAY;
3846 }
3847 
3848 
3849 /** writes problem to file */
3851  SCIP* scip, /**< SCIP data structure */
3852  SCIP_READER* reader, /**< the file reader itself */
3853  FILE* file, /**< output file, or NULL if standard output should be used */
3854  const char* name, /**< problem name */
3855  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3856  SCIP_OBJSENSE objsense, /**< objective sense */
3857  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
3858  * extobj = objsense * objscale * (intobj + objoffset) */
3859  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
3860  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
3861  int nvars, /**< number of active variables in the problem */
3862  int nbinvars, /**< number of binary variables */
3863  int nintvars, /**< number of general integer variables */
3864  int nimplvars, /**< number of implicit integer variables */
3865  int ncontvars, /**< number of continuous variables */
3866  SCIP_VAR** fixedvars, /**< array with fixed and aggregated variables */
3867  int nfixedvars, /**< number of fixed and aggregated variables in the problem */
3868  SCIP_CONS** conss, /**< array with constraints of the problem */
3869  int nconss, /**< number of constraints in the problem */
3870  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
3871  )
3872 {
3873  SCIP_READERDATA* readerdata;
3874  int naddrows;
3875  int faulty = 0;
3876  int c;
3877  int v;
3878  int k;
3879  char* namestr;
3880 
3881  SCIP_CONS* cons = NULL;
3882  const char* consname;
3883  const char** consnames;
3884 
3885  SCIP_CONSHDLR* conshdlr;
3886  const char* conshdlrname;
3887 
3888  SCIP_Real lhs;
3889  SCIP_Real rhs;
3890  SCIP_Real* rhss;
3891  SCIP_Real value;
3892 
3893  SCIP_VAR* var = NULL;
3894  const char* varname;
3895  const char** varnames;
3896 
3897  char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3898 
3899  SCIP_CONS** consIndicator;
3900  SCIP_CONS** consSOS1;
3901  SCIP_CONS** consSOS2;
3902  SCIP_CONS** consQuadratic;
3903  int nConsIndicator;
3904  int nConsSOS1;
3905  int nConsSOS2;
3906  int nConsQuadratic;
3907 
3908  SCIP_HASHMAP* varnameHashmap; /* hash map from SCIP_VAR* to variable name */
3909  SPARSEMATRIX* matrix;
3910 
3911  SCIP_VAR** aggvars;
3912  int naggvars = 0;
3913  int saggvars;
3914  SCIP_HASHTABLE* varFixedHash;
3915  SCIP_HASHTABLE* indicatorSlackHash;
3916 
3917  SCIP_VAR** fixvars = NULL;
3918  int nfixvars = 0;
3919 
3920  SCIP_VAR** consvars;
3921  int nconsvars;
3922  SCIP_Real* vals;
3923  SCIP_Longint* weights;
3924 
3925  SCIP_Bool needRANGES;
3926  unsigned int maxnamelen;
3927 
3928  SCIP_Bool error;
3929 
3930  assert(reader != NULL);
3931  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3932  assert(scip != NULL);
3933  assert(result != NULL);
3934 
3935  needRANGES = FALSE;
3936  maxnamelen = 0;
3937  nConsSOS1 = 0;
3938  nConsSOS2 = 0;
3939  nConsQuadratic = 0;
3940  nConsIndicator = 0;
3941 
3942  /* check if the constraint names are too long and build the constraint names */
3943  SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
3944  if( error )
3945  {
3946  /* call writing with generic names */
3947  if( transformed )
3948  {
3949  SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
3950  SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
3951  }
3952  else
3953  {
3954  SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
3955  SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
3956  }
3957  *result = SCIP_SUCCESS;
3958 
3959  return SCIP_OKAY;
3960  }
3961 
3962  /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
3963  SCIP_CALL( checkVarnames(scip, vars, nvars, &maxnamelen, &varnames, &varnameHashmap) );
3964 
3965  /* collect SOS, quadratic, and indicator constraints in array for later output */
3966  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
3967  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
3968  SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
3969  SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
3970 
3971  /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
3972  saggvars = nfixedvars;
3973  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
3974 
3975  /* create hashtable for storing aggregated variables */
3976  if( nfixedvars > 0 )
3977  {
3978  SCIP_CALL( SCIPhashtableCreate(&varFixedHash, SCIPblkmem(scip), nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3979  }
3980  else
3981  varFixedHash = NULL;
3982 
3983  if( nvars > 0 )
3984  {
3985  SCIP_CALL( SCIPhashtableCreate(&indicatorSlackHash, SCIPblkmem(scip), nvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
3986  }
3987  else
3988  indicatorSlackHash = NULL;
3989 
3990  /* initialize sparse matrix */
3991  SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
3992  assert( matrix->sentries >= nvars );
3993 
3994  readerdata = SCIPreaderGetData(reader);
3995  assert(readerdata != NULL);
3996 
3997  naddrows = 0;
3998 
3999  /* determine and-constraints and printing format to resize necessary arrays */
4000  if( readerdata->linearizeands )
4001  {
4002  SCIP_CONSHDLR* andconshdlr = SCIPfindConshdlr(scip, "and");
4003 
4004  if( andconshdlr != NULL )
4005  {
4006  /* need to check for and-constraints, note that in the original problem you cannot get the number of
4007  * and-constraints by one call */
4008  for( c = nconss - 1; c >= 0; --c )
4009  {
4010  conshdlr = SCIPconsGetHdlr(conss[c]);
4011  assert(conshdlr != NULL);
4012 
4013  conshdlrname = SCIPconshdlrGetName(conshdlr);
4014 
4015  if( strcmp(conshdlrname, "and") == 0 )
4016  {
4017  if( readerdata->aggrlinearizationands )
4018  ++naddrows;
4019  else
4020  naddrows += SCIPgetNVarsAnd(scip, conss[c]);
4021  }
4022  }
4023  assert(naddrows >= 0);
4024 
4025  if( naddrows > 0 )
4026  {
4027  /* resize consnames vector */
4028  SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
4029  }
4030  }
4031  }
4032 
4033  /* initialize rhs vector */
4034  SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nconss + naddrows) );
4035 
4036  /* print statistics as comment to file stream */
4037  SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4038  SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4039  SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
4040  nvars, nbinvars, nintvars, nimplvars, ncontvars);
4041  SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss);
4042 
4043  /* print NAME of the problem */
4044  SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
4045 
4046  /* print OBJSENSE of the problem */
4047  SCIPinfoMessage(scip, file, "OBJSENSE\n");
4048  SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? " MAX" : " MIN");
4049 
4050  /* start ROWS section */
4051  SCIPinfoMessage(scip, file, "ROWS\n");
4052 
4053  /* print row type for the objective function */
4054  printStart(scip, file, "N", "Obj", -1);
4055  SCIPinfoMessage(scip, file, "\n");
4056 
4057  /* first fill the matrix with the objective coefficients */
4058  for( v = 0; v < nvars; ++v )
4059  {
4060  /* take care of the objective entry */
4061  var = vars[v];
4062  value = SCIPvarGetObj(var);
4063 
4064  /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
4065  * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
4066  * and therefore do not mark the variable as an integer
4067  */
4068  if( !SCIPisZero(scip, value) || SCIPvarGetType(var) < SCIP_VARTYPE_IMPLINT
4070  && (SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0)) )
4071  {
4072  assert( matrix->nentries < matrix->sentries );
4073 
4074  matrix->values[matrix->nentries] = objscale * value;
4075  matrix->columns[matrix->nentries] = var;
4076  matrix->rows[matrix->nentries] = "Obj";
4077  matrix->nentries++;
4078  }
4079  }
4080 
4081  /* loop over all constraints */
4082  k = nconss;
4083  for( c = 0; c < nconss; ++c )
4084  {
4085  cons = conss[c];
4086  assert( cons != NULL);
4087 
4088  /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
4089  * the conss array should only contain relevant constraints
4090  */
4091  assert( !transformed || SCIPconsIsEnabled(cons) );
4092 
4093  conshdlr = SCIPconsGetHdlr(cons);
4094  assert( conshdlr != NULL );
4095 
4096  conshdlrname = SCIPconshdlrGetName(conshdlr);
4097 
4098  /* construct constraint name */
4099  consname = consnames[c];
4100 
4101  /* init rhs value to infinity (would then ignored) */
4102  rhss[c] = SCIPinfinity(scip);
4103 
4104  if( strcmp(conshdlrname, "linear") == 0 )
4105  {
4106  lhs = SCIPgetLhsLinear(scip, cons);
4107  rhs = SCIPgetRhsLinear(scip, cons);
4108 
4109  /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4110  if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4111  {
4112  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4113  needRANGES = TRUE;
4114 
4115  /* print row entry */
4116  printRowType(scip, file, lhs, rhs, consname);
4117 
4118  if( SCIPisInfinity(scip, rhs) )
4119  rhss[c] = lhs;
4120  else
4121  rhss[c] = rhs;
4122 
4123  assert( !SCIPisInfinity(scip, rhss[c]) );
4124 
4125  /* compute column entries */
4126  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
4127  SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
4128  }
4129  }
4130  else if( strcmp(conshdlrname, "setppc") == 0 )
4131  {
4132  /* print row entry */
4133  switch( SCIPgetTypeSetppc(scip, cons) )
4134  {
4136  printRowType(scip, file, 1.0, 1.0, consname);
4137  break;
4139  printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
4140  break;
4142  printRowType(scip, file, 1.0, SCIPinfinity(scip), consname);
4143  break;
4144  }
4145 
4146  rhss[c] = 1.0;
4147 
4148  /* compute column entries */
4149  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
4150  }
4151  else if( strcmp(conshdlrname, "logicor") == 0 )
4152  {
4153  /* print row entry */
4154  printRowType(scip, file, 1.0, SCIPinfinity(scip), consname);
4155 
4156  rhss[c] = 1.0;
4157 
4158  /* compute column entries */
4159  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
4160  }
4161  else if( strcmp(conshdlrname, "knapsack") == 0 )
4162  {
4163  int i;
4164 
4165  /* print row entry */
4166  printRowType(scip, file, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), consname);
4167 
4168  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
4169  weights = SCIPgetWeightsKnapsack(scip, cons);
4170 
4171  /* copy Longint array to SCIP_Real array */
4172  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
4173  for( i = 0; i < nconsvars; ++i )
4174  vals[i] = (SCIP_Real)weights[i];
4175 
4176  rhss[c] = (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons);
4177 
4178  /* compute column entries */
4179  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
4180 
4181  SCIPfreeBufferArray(scip, &vals);
4182  }
4183  else if( strcmp(conshdlrname, "varbound") == 0 )
4184  {
4185  lhs = SCIPgetLhsVarbound(scip, cons);
4186  rhs = SCIPgetRhsVarbound(scip, cons);
4187 
4188  /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4189  if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4190  {
4191  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4192  needRANGES = TRUE;
4193 
4194  /* print row entry */
4195  printRowType(scip, file, lhs, rhs, consname);
4196 
4197  /* allocate memory */
4198  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
4199  SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
4200 
4201  consvars[0] = SCIPgetVarVarbound(scip, cons);
4202  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
4203 
4204  vals[0] = 1.0;
4205  vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
4206 
4207  if( SCIPisInfinity(scip, rhs) )
4208  rhss[c] = lhs;
4209  else
4210  rhss[c] = rhs;
4211 
4212  assert( !SCIPisInfinity(scip, rhss[c]) );
4213 
4214  /* compute column entries */
4215  SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
4216 
4217  SCIPfreeBufferArray(scip, &vals);
4218  SCIPfreeBufferArray(scip, &consvars);
4219  }
4220  }
4221  else if( strcmp(conshdlrname, "indicator") == 0 )
4222  {
4223  SCIP_VAR* slackvar;
4224  SCIP_VAR* binvar;
4225 
4226  /* store slack variable in hash */
4227  slackvar = SCIPgetSlackVarIndicator(cons);
4228  assert( slackvar != NULL );
4229  assert( indicatorSlackHash != NULL );
4230  assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
4231  SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
4232 
4233  /* if slackvariable is aggregated, we store it in the list of aggregated variables */
4234  if ( SCIPvarGetStatus(slackvar) == SCIP_VARSTATUS_AGGREGATED )
4235  {
4236  SCIP_CALL( collectAggregatedVars(scip, &slackvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4237  }
4238 
4239  /* store aggregated variables */
4240  binvar = SCIPgetBinaryVarIndicator(cons);
4241  if( SCIPvarIsNegated(binvar) )
4242  binvar = SCIPvarGetNegatedVar(binvar);
4243  assert( binvar != NULL );
4244  SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4245 
4246  /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4247  rhss[c] = SCIPinfinity(scip);
4248 
4249  /* store constraint */
4250  consIndicator[nConsIndicator++] = cons;
4251  continue;
4252  }
4253  else if( strcmp(conshdlrname, "SOS1") == 0 )
4254  {
4255  /* store constraint */
4256  consSOS1[nConsSOS1++] = cons;
4257 
4258  /* check for aggregated variables in SOS1 constraints for later output
4259  * of aggregations as linear constraints */
4260  consvars = SCIPgetVarsSOS1(scip, cons);
4261  nconsvars = SCIPgetNVarsSOS1(scip, cons);
4262 
4263  /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4264  rhss[c] = SCIPinfinity(scip);
4265 
4266  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4267  }
4268  else if( strcmp(conshdlrname, "SOS2") == 0 )
4269  {
4270  /* store constraint */
4271  consSOS2[nConsSOS2++] = cons;
4272 
4273  /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
4274  consvars = SCIPgetVarsSOS2(scip, cons);
4275  nconsvars = SCIPgetNVarsSOS2(scip, cons);
4276 
4277  /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4278  rhss[c] = SCIPinfinity(scip);
4279 
4280  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4281  }
4282  else if( strcmp(conshdlrname, "nonlinear") == 0 )
4283  {
4284  SCIP_EXPR* expr;
4285  SCIP_VAR** quadvars;
4286  SCIP_Real* quadvarlincoefs;
4287  SCIP_Real* lincoefs;
4288  SCIP_Real constant;
4289  SCIP_EXPR** linexprs;
4290  SCIP_Bool isquadratic;
4291  int nquadexprs;
4292  int nlinexprs;
4293  int j;
4294 
4295  /* check if it is a quadratic constraint */
4296  SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
4297  if( !isquadratic )
4298  {
4299  /* unknown constraint type; mark this with SCIPinfinity(scip) */
4300  rhss[c] = SCIPinfinity(scip);
4301 
4302  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4303  continue;
4304  }
4305 
4306  /* store constraint */
4307  consQuadratic[nConsQuadratic++] = cons;
4308 
4309  expr = SCIPgetExprNonlinear(cons);
4310 
4311  /* collect linear coefficients of quadratic part */
4312  SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
4313  NULL);
4314 
4315  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
4316  SCIP_CALL( SCIPallocBufferArray(scip, &quadvarlincoefs, nquadexprs) );
4317  for( j = 0; j < nquadexprs; ++j )
4318  {
4319  SCIP_EXPR* qexpr;
4320 
4321  SCIPexprGetQuadraticQuadTerm(expr, j, &qexpr, &quadvarlincoefs[j], NULL, NULL, NULL, NULL);
4322 
4323  assert(SCIPisExprVar(scip, qexpr));
4324  quadvars[j] = SCIPgetVarExprVar(qexpr);
4325  }
4326 
4327  lhs = SCIPgetLhsNonlinear(cons);
4328  rhs = SCIPgetRhsNonlinear(cons);
4329 
4330  /* correct side by constant */
4331  lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
4332  rhs -= SCIPisInfinity(scip, rhs) ? 0.0 : constant;
4333 
4334  /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4335  if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4336  {
4337  SCIP_VAR** linvars;
4338 
4339  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4340  needRANGES = TRUE;
4341 
4342  /* print row entry */
4343  printRowType(scip, file, lhs, rhs, consname);
4344 
4345  if( SCIPisInfinity(scip, rhs) )
4346  rhss[c] = lhs;
4347  else
4348  rhss[c] = rhs;
4349 
4350  assert( !SCIPisInfinity(scip, rhss[c]) );
4351 
4352  /* get linear vars */
4353  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
4354  for( j = 0; j < nlinexprs; ++j )
4355  linvars[j] = SCIPgetVarExprVar(linexprs[j]);
4356 
4357  /* compute column entries for linear part */
4358  SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
4359 
4360  /* compute column entries for linear part in quadratic part */
4361  SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
4362  &rhss[c]) );
4363 
4364  SCIPfreeBufferArray(scip, &linvars);
4365  }
4366 
4367  /* check for aggregated variables in quadratic part of quadratic constraints for later output of
4368  * aggregations as linear constraints */
4369  consvars = quadvars;
4370  nconsvars = nquadexprs;
4371 
4372  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4373 
4374  SCIPfreeBufferArray(scip, &quadvars);
4375  SCIPfreeBufferArray(scip, &quadvarlincoefs);
4376  }
4377  else if( strcmp(conshdlrname, "and") == 0 )
4378  {
4379  if( readerdata->linearizeands )
4380  {
4381  SCIP_VAR** rowvars;
4382  SCIP_VAR** operands;
4383  SCIP_VAR* resultant;
4384  SCIP_Real* rowvals;
4385  char* rowname;
4386  int nrowvars;
4387  int l;
4388  int n;
4389 
4390  nrowvars = SCIPgetNVarsAnd(scip, cons);
4391  operands = SCIPgetVarsAnd(scip, cons);
4392  resultant = SCIPgetResultantAnd(scip, cons);
4393 
4394  /* allocate buffer array */
4395  SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, nrowvars + 1) );
4396  SCIP_CALL( SCIPallocBufferArray(scip, &rowvals, nrowvars + 1) );
4397 
4398  /* get length of constraint name */
4399  l = (int) strlen(consname);
4400 
4401  /* the tight relaxtion, number of and-constraint operands rows */
4402  if( !readerdata->aggrlinearizationands )
4403  {
4404  rowvars[0] = resultant;
4405  rowvals[0] = 1.0;
4406  rowvals[1] = -1.0;
4407 
4408  /* compute maximal length for rowname */
4409  /* coverity[negative_returns] */
4410  n = (int) log10((double)nrowvars) + 1 + l;
4411 
4412  /* assure maximal allowed value */
4413  if( n >= MPS_MAX_NAMELEN )
4414  n = MPS_MAX_NAMELEN - 1;
4415 
4416  /* update maxnamelen */
4417  maxnamelen = MAX(maxnamelen, (unsigned int) n);
4418 
4419  /* print operator rows */
4420  for( v = 0; v < nrowvars; ++v )
4421  {
4422  /* compute maximal length for rowname */
4423  if( v == 0 )
4424  n = 2;
4425  else
4426  n = (int) log10((double)v) + 2;
4427  n += l;
4428 
4429  /* assure maximal allowed value */
4430  if( n >= MPS_MAX_NAMELEN )
4431  {
4432  n = MPS_MAX_NAMELEN - 1;
4433  ++faulty;
4434  }
4435 
4436  /* need memory for additional row */
4437  SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4438 
4439  assert(k < nconss + naddrows);
4440  consnames[k] = rowname;
4441 
4442  (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
4443  rowvars[1] = operands[v];
4444 
4445  /* print row entry */
4446  printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4447 
4448  rhss[k] = 0.0;
4449 
4450  /* compute column entries */
4451  SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
4452  ++k;
4453  }
4454  }
4455 
4456  /* prepare for next row */
4457  for( v = nrowvars - 1; v >= 0; --v )
4458  {
4459  rowvars[v] = operands[v];
4460  rowvals[v] = -1.0;
4461  }
4462 
4463  rowvars[nrowvars] = resultant;
4464 
4465  /* the weak relaxtion, only one constraint */
4466  if( readerdata->aggrlinearizationands )
4467  {
4468  /* compute maximal length for rowname */
4469  n = l + 3;
4470 
4471  /* assure maximal allowed value */
4472  if( n >= MPS_MAX_NAMELEN )
4473  {
4474  n = MPS_MAX_NAMELEN - 1;
4475  ++faulty;
4476  }
4477 
4478  /* update maxnamelen */
4479  maxnamelen = MAX(maxnamelen, (unsigned int) n);
4480 
4481  /* need memory for additional row */
4482  SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4483 
4484  assert(k < nconss + naddrows);
4485  consnames[k] = rowname;
4486 
4487  /* adjust rowname of constraint */
4488  (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
4489 
4490  rowvals[nrowvars] = (SCIP_Real) nrowvars;
4491 
4492  /* print row entry */
4493  printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4494 
4495  rhss[k] = 0.0;
4496 
4497  /* compute column entries */
4498  SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
4499 
4500  SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
4501  ++k;
4502  }
4503 
4504  rowvals[nrowvars] = 1.0;
4505 
4506  /* print row entry */
4507  printRowType(scip, file, -nrowvars + 1.0, SCIPinfinity(scip), consname);
4508 
4509  rhss[c] = -nrowvars + 1.0;
4510 
4511  /* compute column entries */
4512  SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
4513 
4514  /* free buffer array */
4515  SCIPfreeBufferArray(scip, &rowvals);
4516  SCIPfreeBufferArray(scip, &rowvars);
4517  }
4518  else
4519  {
4520  /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
4521  rhss[c] = SCIPinfinity(scip);
4522 
4523  SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
4524  }
4525  }
4526  else
4527  {
4528  /* unknown constraint type; mark this with SCIPinfinity(scip) */
4529  rhss[c] = SCIPinfinity(scip);
4530 
4531  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4532  }
4533  }
4534 
4535  if( faulty > 0 )
4536  {
4537  SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
4538  faulty, MPS_MAX_NAMELEN - 1);
4539  }
4540 
4541  /* free hash table */
4542  if( varFixedHash != NULL )
4543  SCIPhashtableFree(&varFixedHash);
4544 
4545  if( indicatorSlackHash != NULL && nConsIndicator == 0 )
4546  {
4547  SCIPhashtableFree(&indicatorSlackHash);
4548  assert( indicatorSlackHash == NULL );
4549  }
4550 
4551  if( naggvars > 0 )
4552  {
4553  /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
4554 
4555  /* realloc memory */
4556  SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
4557  SCIP_CALL( SCIPreallocBufferArray(scip, &rhss, nconss + naddrows + naggvars) );
4558  SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, nvars + naggvars) );
4559 
4560  for( c = 0; c < naggvars; ++c )
4561  {
4562  size_t l;
4563 
4564  /* create variable name */
4565  var = aggvars[c];
4566 
4567  l = strlen(SCIPvarGetName(var));
4568  if( l >= MPS_MAX_NAMELEN )
4569  maxnamelen = MPS_MAX_NAMELEN - 1;
4570  else
4571  maxnamelen = MAX(maxnamelen, (unsigned int) l);
4572 
4573  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4574  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4575 
4576  /* insert variable with variable name into hash map */
4577  varnames[nvars + c] = namestr;
4578  assert( !SCIPhashmapExists(varnameHashmap, var) );
4579  SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4580 
4581  /* output row type (it is an equation) */
4582  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
4583  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(var));
4584  printRowType(scip, file, 1.0, 1.0, namestr);
4585 
4586  l = strlen(namestr);
4587  maxnamelen = MAX(maxnamelen, (unsigned int) l);
4588  consnames[nconss + naddrows + c] = namestr;
4589  rhss[nconss + naddrows + c] = 0.0;
4590 
4591  /* compute column entries */
4592  SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
4593 
4594  /* add the aggregated variables to the sparse matrix */
4595  SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, 1) );
4596  matrix->values[matrix->nentries] = -1.0;
4597  matrix->columns[matrix->nentries] = aggvars[c];
4598  matrix->rows[matrix->nentries] = namestr;
4599  matrix->nentries++;
4600  }
4601  }
4602 
4603  /* collect also fixed variables, because they might not be removed from all constraints */
4604  /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
4605  if( nfixedvars > 0 )
4606  {
4607  int startpos = nvars + naggvars;
4608  /* construct variables name of fixed variables */
4609 
4610  /* realloc memory */
4611  SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
4612 
4613  /* allocate memory for fixed variables */
4614  SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
4615 
4616  for( v = nfixedvars - 1; v >= 0; --v )
4617  {
4618  /* create variable name */
4619  var = fixedvars[v];
4620 
4622  {
4623  size_t l;
4624  l = strlen(SCIPvarGetName(var));
4625  if( l >= MPS_MAX_NAMELEN )
4626  maxnamelen = MPS_MAX_NAMELEN - 1;
4627  else
4628  maxnamelen = MAX(maxnamelen, (unsigned int) l);
4629 
4630  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4631  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4632 
4633  varnames[startpos + nfixvars] = namestr;
4634  fixvars[nfixvars] = var;
4635  ++nfixvars;
4636 
4637  /* insert variable with variable name into hash map */
4638  assert(!SCIPhashmapExists(varnameHashmap, var));
4639  SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4640 
4641  /* add the fixed variables to the sparse matrix, needed for columns section */
4642  SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, 1) );
4643  matrix->values[matrix->nentries] = 0.0;
4644  matrix->columns[matrix->nentries] = var;
4645  matrix->rows[matrix->nentries] = "Obj";
4646  matrix->nentries++;
4647  }
4648  }
4649  }
4650 
4651  /* output COLUMNS section */
4652  printColumnSection(scip, file, matrix, varnameHashmap, indicatorSlackHash, maxnamelen);
4653 
4654  /* output RHS section */
4655  printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
4656 
4657  /* output RANGES section */
4658  if( needRANGES )
4659  printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
4660 
4661  /* output BOUNDS section */
4662  printBoundSection(scip, file, vars, nvars, aggvars, naggvars, fixvars, nfixvars, transformed, varnames, indicatorSlackHash, maxnamelen);
4663 
4664  if( nfixedvars > 0 )
4665  {
4666  SCIPfreeBufferArray(scip, &fixvars);
4667  }
4668 
4669  /* print SOS section */
4670  if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4671  {
4672  SCIP_Real* sosweights;
4673 
4674  SCIPinfoMessage(scip, file, "SOS\n");
4675  SCIPdebugMsg(scip, "start printing SOS section\n");
4676 
4677  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4678 
4679  /* first output SOS1 constraints */
4680  for( c = 0; c < nConsSOS1; ++c )
4681  {
4682  cons = consSOS1[c];
4683  consvars = SCIPgetVarsSOS1(scip, cons);
4684  nconsvars = SCIPgetNVarsSOS1(scip, cons);
4685  sosweights = SCIPgetWeightsSOS1(scip, cons);
4686  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4687 
4688  printStart(scip, file, "S1", namestr, -1);
4689  SCIPinfoMessage(scip, file, "\n");
4690 
4691  for( v = 0; v < nconsvars; ++v )
4692  {
4693  /* get variable name */
4694  assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4695  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4696 
4697  printStart(scip, file, "", varname, (int) maxnamelen);
4698 
4699  if( sosweights != NULL )
4700  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4701  else
4702  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4703 
4704  SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4705  }
4706  }
4707 
4708  /* next output SOS2 constraints */
4709  for( c = 0; c < nConsSOS2; ++c )
4710  {
4711  cons = consSOS2[c];
4712  consvars = SCIPgetVarsSOS2(scip, cons);
4713  nconsvars = SCIPgetNVarsSOS2(scip, cons);
4714  sosweights = SCIPgetWeightsSOS2(scip, cons);
4715  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4716 
4717  printStart(scip, file, "S2", namestr, -1);
4718  SCIPinfoMessage(scip, file, "\n");
4719 
4720  for( v = 0; v < nconsvars; ++v )
4721  {
4722  /* get variable name */
4723  assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4724  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4725 
4726  printStart(scip, file, "", varname, (int) maxnamelen);
4727 
4728  if( sosweights != NULL )
4729  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4730  else
4731  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4732 
4733  SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4734  }
4735  }
4736  SCIPfreeBufferArray(scip, &namestr);
4737  }
4738 
4739  /* print QCMATRIX sections for quadratic constraints
4740  * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
4741  */
4742  if( nConsQuadratic > 0 )
4743  {
4744  const char* varname2;
4745  int nbilin;
4746 
4747  SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
4748  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4749 
4750  for( c = 0; c < nConsQuadratic; ++c )
4751  {
4752  SCIP_EXPR* expr;
4753 
4754  cons = consQuadratic[c];
4755  expr = SCIPgetExprNonlinear(cons);
4756 
4757  SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
4758 
4759  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4760 
4761  SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
4762 
4763  /* print x^2 terms */
4764  for( v = 0; v < nconsvars; ++v )
4765  {
4766  SCIP_EXPR* qexpr;
4767  SCIP_VAR* qvar;
4768  SCIP_Real sqrcoef;
4769 
4770  SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
4771  if( sqrcoef == 0.0 )
4772  continue;
4773 
4774  assert(SCIPisExprVar(scip, qexpr));
4775  qvar = SCIPgetVarExprVar(qexpr);
4776 
4777  /* get variable name */
4778  assert(SCIPhashmapExists(varnameHashmap, qvar));
4779  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, qvar);
4780 
4781  /* get coefficient as string */
4782  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
4783 
4784  /* print "x x coeff" line */
4785  printStart(scip, file, "", varname, (int) maxnamelen);
4786  printRecord(scip, file, varname, valuestr, maxnamelen);
4787  SCIPinfoMessage(scip, file, "\n");
4788  }
4789 
4790  /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
4791  * i.e., we have to split bilinear coefficients into two off diagonal elements */
4792  for( v = 0; v < nbilin; ++v )
4793  {
4794  SCIP_EXPR* expr1;
4795  SCIP_EXPR* expr2;
4796  SCIP_VAR* var1;
4797  SCIP_VAR* var2;
4798  SCIP_Real coef;
4799 
4800  SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
4801  assert(SCIPisExprVar(scip, expr1));
4802  assert(SCIPisExprVar(scip, expr2));
4803 
4804  if( coef == 0.0 )
4805  continue;
4806 
4807  var1 = SCIPgetVarExprVar(expr1);
4808  var2 = SCIPgetVarExprVar(expr2);
4809 
4810  /* get name of first variable */
4811  assert ( SCIPhashmapExists(varnameHashmap, var1) );
4812  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var1);
4813 
4814  /* get name of second variable */
4815  assert ( SCIPhashmapExists(varnameHashmap, var2) );
4816  varname2 = (const char*) SCIPhashmapGetImage(varnameHashmap, var2);
4817 
4818  /* get coefficient as string */
4819  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
4820 
4821  /* print "x y coeff/2" line */
4822  printStart(scip, file, "", varname, (int) maxnamelen);
4823  printRecord(scip, file, varname2, valuestr, maxnamelen);
4824  SCIPinfoMessage(scip, file, "\n");
4825 
4826  /* print "y x coeff/2" line */
4827  printStart(scip, file, "", varname2, (int) maxnamelen);
4828  printRecord(scip, file, varname, valuestr, maxnamelen);
4829  SCIPinfoMessage(scip, file, "\n");
4830  }
4831  }
4832 
4833  SCIPfreeBufferArray(scip, &namestr);
4834  }
4835 
4836  /* print indicator section */
4837  if( nConsIndicator > 0 )
4838  {
4839  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4840 
4841  SCIPinfoMessage(scip, file, "INDICATORS\n");
4842  SCIPdebugMsg(scip, "start printing INDICATOR section\n");
4843 
4844  /* output each indicator constraint */
4845  for( c = 0; c < nConsIndicator; ++c )
4846  {
4847  SCIP_CONS* lincons;
4848  SCIP_VAR* slackvar;
4849  SCIP_VAR* binvar;
4850 
4851  cons = consIndicator[c];
4852  binvar = SCIPgetBinaryVarIndicator(cons);
4853  lincons = SCIPgetLinearConsIndicator(cons);
4854  slackvar = SCIPgetSlackVarIndicator(cons);
4855 
4856  /* linvars always contains slack variable, thus nlinvars >= 1 */
4857  if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
4858  continue;
4859 
4860  /* create variable and value strings */
4861  if( SCIPvarIsNegated(binvar) )
4862  {
4863  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 0);
4864  assert( SCIPvarGetNegatedVar(binvar) != NULL );
4865  assert( SCIPhashmapExists(varnameHashmap, SCIPvarGetNegatedVar(binvar)) );
4866  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, SCIPvarGetNegatedVar(binvar));
4867  }
4868  else
4869  {
4870  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 1);
4871  assert ( SCIPhashmapExists(varnameHashmap, binvar) );
4872  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
4873  }
4874 
4875  /* write records */
4876  if ( SCIPvarGetStatus(slackvar) == SCIP_VARSTATUS_AGGREGATED )
4877  {
4878  /* for aggregated variables output name of aggregating constraint */
4879  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
4880  printStart(scip, file, "IF", namestr, (int) maxnamelen);
4881  printRecord(scip, file, varname, valuestr, maxnamelen);
4882  SCIPinfoMessage(scip, file, "\n");
4883  }
4884  else
4885  {
4886  printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
4887  printRecord(scip, file, varname, valuestr, maxnamelen);
4888  SCIPinfoMessage(scip, file, "\n");
4889  }
4890  }
4891  SCIPfreeBufferArray(scip, &namestr);
4892  }
4893 
4894  /* free matrix data structure */
4895  freeMatrix(scip, matrix);
4896 
4897  /* free slackvar hashtable */
4898  if( indicatorSlackHash != NULL )
4899  SCIPhashtableFree(&indicatorSlackHash);
4900 
4901  /* free variable hashmap */
4902  SCIPhashmapFree(&varnameHashmap);
4903 
4904  SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
4905  SCIPfreeBufferArray(scip, &rhss);
4906 
4907  /* free buffer arrays for SOS1, SOS2, and quadratic */
4908  SCIPfreeBufferArray(scip, &consIndicator);
4909  SCIPfreeBufferArray(scip, &consQuadratic);
4910  SCIPfreeBufferArray(scip, &consSOS2);
4911  SCIPfreeBufferArray(scip, &consSOS1);
4912 
4913  /* free variable and constraint name array */
4914  for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
4915  SCIPfreeBufferArray(scip, &varnames[v]);
4916  SCIPfreeBufferArray(scip, &varnames);
4917 
4918  for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
4919  SCIPfreeBufferArray(scip, &consnames[c]);
4920  SCIPfreeBufferArray(scip, &consnames);
4921 
4922  /* print end of data line */
4923  SCIPinfoMessage(scip, file, "ENDATA");
4924 
4925  *result = SCIP_SUCCESS;
4926 
4927  return SCIP_OKAY;
4928 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
#define BLANK
Definition: reader_mps.c:95
static SCIP_RETCODE collectAggregatedVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR ***aggvars, int *naggvars, int *saggvars, SCIP_HASHTABLE *varAggregated)
Definition: reader_mps.c:3018
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
static void mpsinputSetObjsense(MPSINPUT *mpsi, SCIP_OBJSENSE sense)
Definition: reader_mps.c:382
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
void SCIPexprGetQuadraticData(SCIP_EXPR *expr, SCIP_Real *constant, int *nlinexprs, SCIP_EXPR ***linexprs, SCIP_Real **lincoefs, int *nquadexprs, int *nbilinexprs, SCIP_Real **eigenvalues, SCIP_Real **eigenvectors)
Definition: expr.c:4113
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define READER_DESC
Definition: reader_mps.c:79
#define NULL
Definition: def.h:267
static SCIP_DECL_READERCOPY(readerCopyMps)
Definition: reader_mps.c:3719
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8313
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
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3296
static SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
Definition: reader_mps.c:2670
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8475
static void printRangeSection(SCIP *scip, FILE *file, SCIP_CONS **conss, int nconss, const char **consnames, SCIP_Bool transformed, unsigned int maxnamelen)
Definition: reader_mps.c:3380
SCIP_RETCODE SCIPcreateConsIndicatorLinConsPure(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, 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)
Constraint handler for variable bound constraints .
static void mpsinputSyntaxerror(MPSINPUT *mpsi)
Definition: reader_mps.c:393
SCIP_VAR ** SCIPgetVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10808
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2547
static SCIP_RETCODE readQMatrix(MPSINPUT *mpsi, SCIP_Bool isQuadObj, SCIP *scip)
Definition: reader_mps.c:1950
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
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9553
#define READER_NAME
Definition: reader_mps.c:78
SCIP_Real SCIPgetLhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18079
static SCIP_RETCODE readRows(MPSINPUT *mpsi, SCIP *scip, const char ***consnames, int *consnamessize, int *nconsnames)
Definition: reader_mps.c:867
int SCIPgetNVarsLogicor(SCIP *scip, SCIP_CONS *cons)
static void printBoundSection(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_VAR **aggvars, int naggvars, SCIP_VAR **fixvars, int nfixvars, SCIP_Bool transformed, const char **varnames, SCIP_HASHTABLE *indicatorSlackHash, unsigned int maxnamelen)
Definition: reader_mps.c:3456
#define SCIP_MAXSTRLEN
Definition: def.h:288
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3354
void SCIPsortPtrPtrReal(void **ptrarray1, void **ptrarray2, SCIP_Real *realarray, SCIP_DECL_SORTPTRCOMP((*ptrcomp)), int len)
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
static void mpsinputSetObjname(MPSINPUT *mpsi, const char *objname)
Definition: reader_mps.c:368
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2843
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
#define MPS_MAX_LINELEN
Definition: reader_mps.c:89
SCIP_RETCODE SCIPaddVarSOS2(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos2.c:2670
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18135
static SCIP_RETCODE checkSparseMatrixCapacity(SCIP *scip, SPARSEMATRIX *matrix, int capacity)
Definition: reader_mps.c:2882
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10833
static SCIP_DECL_READERFREE(readerFreeMps)
Definition: reader_mps.c:3735
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
SCIP_RETCODE SCIPprintTransProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
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
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_mps.c:2708
static void printColumnSection(SCIP *scip, FILE *file, SPARSEMATRIX *matrix, SCIP_HASHMAP *varnameHashmap, SCIP_HASHTABLE *indicatorSlackHash, unsigned int maxnamelen)
Definition: reader_mps.c:3245
#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
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
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: reader_mps.c:406
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57
static void mpsinputInsertName(MPSINPUT *mpsi, const char *name, SCIP_Bool second)
Definition: reader_mps.c:653
enum SCIP_VerbLevel SCIP_VERBLEVEL
Definition: type_message.h:59
static void mpsinputInsertField4(MPSINPUT *mpsi, const char *str)
Definition: reader_mps.c:639
public methods for problem variables
SCIP_RETCODE SCIPwriteMps(SCIP *scip, SCIP_READER *reader, 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_RESULT *result)
Definition: reader_mps.c:3850
static const char * mpsinputField4(const MPSINPUT *mpsi)
Definition: reader_mps.c:276
SCIP_VAR ** SCIPgetVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPdebugMessage
Definition: pub_message.h:96
Constraint handler for AND constraints, .
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
int SCIPgetNVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2721
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4678
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3261
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
SCIP_VAR * SCIPgetVarVarbound(SCIP *scip, SCIP_CONS *cons)
Constraint handler for the set partitioning / packing / covering constraints .
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:102
public methods for SCIP variables
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8485
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
const char * consname
Definition: reader_mps.c:166
static SCIP_RETCODE readCols(MPSINPUT *mpsi, SCIP *scip, const char ***varnames, int *varnamessize, int *nvarnames)
Definition: reader_mps.c:962
public methods for numerical tolerances
static SCIP_Bool mpsinputReadLine(MPSINPUT *mpsi)
Definition: reader_mps.c:463
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
public methods for querying solving statistics
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17895
static SCIP_RETCODE addVarNameToStorage(SCIP *scip, const char ***varnames, int *varnamessize, int *nvars, const char *colname)
Definition: reader_mps.c:677
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3423
SCIP_VAR * SCIPgetSlackVarIndicator(SCIP_CONS *cons)
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2685
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8178
SCIP_FILE * SCIPfopen(const char *path, const char *mode)
Definition: fileio.c:153
SCIP_READERDATA * SCIPreaderGetData(SCIP_READER *reader)
Definition: reader.c:492
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18089
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
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 .
SCIP_Real SCIPgetRhsVarbound(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5230
#define MPS_MAX_VALUELEN
Definition: reader_mps.c:91
static void printEntry(SCIP *scip, FILE *file, const char *varname, const char *consname, SCIP_Real value, int *recordcnt, unsigned int maxnamelen)
Definition: reader_mps.c:2788
static const char * mpsinputObjname(const MPSINPUT *mpsi)
Definition: reader_mps.c:298
#define SCIPerrorMessage
Definition: pub_message.h:64
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4199
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
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_Bool mpsinputIsInteger(const MPSINPUT *mpsi)
Definition: reader_mps.c:331
static SCIP_OBJSENSE mpsinputObjsense(const MPSINPUT *mpsi)
Definition: reader_mps.c:309
static SCIP_RETCODE readRhs(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1093
SCIP_VAR ** SCIPgetVarsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2746
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10716
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:416
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
#define SCIPallocBuffer(scip, ptr)
Definition: scip_mem.h:122
SCIP_Real SCIPvarGetUbOriginal(SCIP_VAR *var)
Definition: var.c:18045
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
static SCIP_RETCODE readBounds(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1380
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_RETCODE SCIPcreateConsQuadraticNonlinear(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)
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8216
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4768
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_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8435
SCIP_VAR ** SCIPgetVarsLogicor(SCIP *scip, SCIP_CONS *cons)
struct SparseMatrix SPARSEMATRIX
Definition: reader_mps.c:161
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17420
#define DEFAULT_LINEARIZE_ANDS
Definition: reader_mps.c:82
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3108
SCIP_RETCODE SCIPgetBoolParam(SCIP *scip, const char *name, SCIP_Bool *value)
Definition: scip_param.c:250
static void printRhsSection(SCIP *scip, FILE *file, int nconss, const char **consnames, SCIP_Real *rhss, unsigned int maxnamelen, SCIP_Real objoffset)
Definition: reader_mps.c:3337
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
SCIP_CONS * SCIPfindCons(SCIP *scip, const char *name)
Definition: scip_prob.c:2947
void SCIPexprGetQuadraticQuadTerm(SCIP_EXPR *quadexpr, int termidx, SCIP_EXPR **expr, SCIP_Real *lincoef, SCIP_Real *sqrcoef, int *nadjbilin, int **adjbilin, SCIP_EXPR **sqrexpr)
Definition: expr.c:4158
SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
#define REALABS(x)
Definition: def.h:197
#define SCIP_CALL(x)
Definition: def.h:380
static void patchField(char *buf, int beg, int end)
Definition: reader_mps.c:442
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip_mem.h:107
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
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8455
public methods for constraint handler plugins and constraints
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
struct SCIP_ReaderData SCIP_READERDATA
Definition: type_reader.h:53
public data structures and miscellaneous methods
SCIP_RETCODE SCIPcheckQuadraticNonlinear(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *isquadratic)
static SCIP_RETCODE addConsNameToStorage(SCIP *scip, const char ***consnames, int *consnamessize, int *ncons, const char *rowname)
Definition: reader_mps.c:699
#define SCIP_Bool
Definition: def.h:91
static SCIP_RETCODE readSOS(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1756
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
void SCIPprintSysError(const char *message)
Definition: misc.c:10769
enum SCIP_Objsense SCIP_OBJSENSE
Definition: type_prob.h:50
static void printRecord(SCIP *scip, FILE *file, const char *col1, const char *col2, unsigned int maxnamelen)
Definition: reader_mps.c:2728
static const char * mpsinputField5(const MPSINPUT *mpsi)
Definition: reader_mps.c:287
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9599
constraint handler for nonlinear constraints specified by algebraic expressions
SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2771
static MPSSECTION mpsinputSection(const MPSINPUT *mpsi)
Definition: reader_mps.c:221
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8236
#define MIN(x, y)
Definition: def.h:243
#define MPS_MAX_NAMELEN
Definition: reader_mps.c:90
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8345
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8415
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8385
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17927
static SCIP_RETCODE readObjsen(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:769
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10783
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
SCIP_RETCODE SCIPreadMps(SCIP *scip, SCIP_READER *reader, const char *filename, SCIP_RESULT *result, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
Definition: reader_mps.c:3814
static const char * mpsinputField1(const MPSINPUT *mpsi)
Definition: reader_mps.c:243
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 void printRowType(SCIP *scip, FILE *file, SCIP_Real lhs, SCIP_Real rhs, const char *name)
Definition: reader_mps.c:2826
static SCIP_RETCODE readIndicators(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:2347
Constraint handler for linear constraints in their most general form, .
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2608
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
static long * number
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_Bool mpsinputHasError(const MPSINPUT *mpsi)
Definition: reader_mps.c:320
#define MPS_MAX_FIELDLEN
Definition: reader_mps.c:92
SCIP_VAR ** SCIPgetVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9576
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2346
#define SCIP_HASHSIZE_NAMES
Definition: def.h:299
static unsigned int computeFieldWidth(unsigned int width)
Definition: reader_mps.c:2717
static const char * mpsinputField0(const MPSINPUT *mpsi)
Definition: reader_mps.c:232
methods for sorting joint arrays of various types
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)
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)
static void mpsinputSetSection(MPSINPUT *mpsi, MPSSECTION section)
Definition: reader_mps.c:342
static void clearFrom(char *buf, unsigned int pos)
Definition: reader_mps.c:428
#define SCIPfreeBuffer(scip, ptr)
Definition: scip_mem.h:134
#define MAX(x, y)
Definition: def.h:239
static void mpsinputSetProbname(MPSINPUT *mpsi, const char *probname)
Definition: reader_mps.c:354
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE checkVarnames(SCIP *scip, SCIP_VAR **vars, int nvars, unsigned int *maxnamelen, const char ***varnames, SCIP_HASHMAP **varnameHashmap)
Definition: reader_mps.c:3075
static const char * mpsinputField3(const MPSINPUT *mpsi)
Definition: reader_mps.c:265
struct MpsInput MPSINPUT
Definition: reader_mps.c:150
static SCIP_DECL_READERWRITE(readerWriteMps)
Definition: reader_mps.c:3763
static void freeMatrix(SCIP *scip, SPARSEMATRIX *matrix)
Definition: reader_mps.c:2900
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
public methods for message output
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1431
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition: expr.c:4198
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17539
static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
Definition: reader_mps.c:173
#define SCIP_Real
Definition: def.h:173
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8465
static void mpsinputFree(SCIP *scip, MPSINPUT **mpsi)
Definition: reader_mps.c:211
public methods for input file readers
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition: def.h:401
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5206
constraint handler for SOS type 1 constraints
int SCIPgetNVarsKnapsack(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE initializeMatrix(SCIP *scip, SPARSEMATRIX **matrix, int slots)
Definition: reader_mps.c:2864
public methods for message handling
static SCIP_RETCODE readRanges(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:1240
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8405
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8395
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
static void printBoundSectionName(SCIP *scip, FILE *file)
Definition: reader_mps.c:3445
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17585
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2659
enum MpsSection MPSSECTION
Definition: reader_mps.c:124
static SCIP_RETCODE checkConsnames(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool transformed, unsigned int *maxnamelen, const char ***consnames, SCIP_Bool *error)
Definition: reader_mps.c:3139
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
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:10579
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:73
constraint handler for SOS type 2 constraints
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:2571
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
static const char * mpsinputField2(const MPSINPUT *mpsi)
Definition: reader_mps.c:254
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18145
static SCIP_DECL_HASHKEYEQ(hashKeyEqString)
Definition: reader_mps.c:2682
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
MpsSection
Definition: reader_mps.c:105
#define DEFAULT_AGGRLINEARIZATION_ANDS
Definition: reader_mps.c:83
#define READER_EXTENSION
Definition: reader_mps.c:80
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3156
int SCIPfclose(SCIP_FILE *fp)
Definition: fileio.c:232
static SCIP_RETCODE readObjname(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:828
constraint handler for bound disjunction constraints
static void printStart(SCIP *scip, FILE *file, const char *col1, const char *col2, int maxnamelen)
Definition: reader_mps.c:2754
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for reader plugins
#define SCIPABORT()
Definition: def.h:352
public methods for global and local (sub)problems
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10818
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
#define PATCH_CHAR
Definition: reader_mps.c:94
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetReaderFree(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERFREE((*readerfree)))
Definition: scip_reader.c:171
static SCIP_DECL_READERREAD(readerReadMps)
Definition: reader_mps.c:3750
SCIP_RETCODE SCIPincludeReaderMps(SCIP *scip)
Definition: reader_mps.c:3780
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1529
static SCIP_RETCODE getLinearCoeffs(SCIP *scip, const char *consname, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool transformed, SPARSEMATRIX *matrix, SCIP_Real *rhs)
Definition: reader_mps.c:2915
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
static SCIP_RETCODE readMps(SCIP *scip, const char *filename, const char ***varnames, const char ***consnames, int *varnamessize, int *consnamessize, int *nvarnames, int *nconsnames)
Definition: reader_mps.c:2556
(extended) MPS file reader
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17575
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
static SCIP_RETCODE readQCMatrix(MPSINPUT *mpsi, SCIP *scip)
Definition: reader_mps.c:2163
static SCIP_RETCODE readName(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:721
memory allocation routines