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-2023 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_VARTYPE slackvartype;
2381  SCIP_CONS* cons;
2382  SCIP_CONS* lincons;
2383  SCIP_VAR* binvar;
2384  SCIP_VAR* slackvar;
2385  SCIP_Real lhs;
2386  SCIP_Real rhs;
2387  SCIP_Real sign;
2388  SCIP_VAR** linvars;
2389  SCIP_Real* linvals;
2390  int nlinvars;
2391  int i;
2392 
2393  /* check if next section is found */
2394  if( mpsinputField0(mpsi) != NULL )
2395  {
2396  if( !strcmp(mpsinputField0(mpsi), "ENDATA") )
2398  break;
2399  }
2400  if( mpsinputField1(mpsi) == NULL || mpsinputField2(mpsi) == NULL )
2401  {
2402  SCIPerrorMessage("empty data in a non-comment line.\n");
2403  mpsinputSyntaxerror(mpsi);
2404  return SCIP_OKAY;
2405  }
2406 
2407  /* check for new indicator constraint */
2408  if( strcmp(mpsinputField1(mpsi), "IF") != 0 )
2409  {
2410  SCIPerrorMessage("Indicator constraints need to be introduced by 'IF' in column 1.\n");
2411  mpsinputSyntaxerror(mpsi);
2412  return SCIP_OKAY;
2413  }
2414 
2415  /* get linear constraint (row) */
2416  lincons = SCIPfindCons(scip, mpsinputField2(mpsi));
2417  if( lincons == NULL )
2418  {
2419  SCIPerrorMessage("row <%s> does not exist.\n", mpsinputField2(mpsi));
2420  mpsinputSyntaxerror(mpsi);
2421  return SCIP_OKAY;
2422  }
2423 
2424  /* check whether constraint is really linear */
2425  conshdlr = SCIPconsGetHdlr(lincons);
2426  if( strcmp(SCIPconshdlrGetName(conshdlr), "linear") != 0 )
2427  {
2428  SCIPerrorMessage("constraint <%s> is not linear.\n", mpsinputField2(mpsi));
2429  mpsinputSyntaxerror(mpsi);
2430  return SCIP_OKAY;
2431  }
2432 
2433  /* get binary variable */
2434  binvar = SCIPfindVar(scip, mpsinputField3(mpsi));
2435  if( binvar == NULL )
2436  {
2437  SCIPerrorMessage("binary variable <%s> does not exist.\n", mpsinputField3(mpsi));
2438  mpsinputSyntaxerror(mpsi);
2439  return SCIP_OKAY;
2440  }
2441 
2442  /* check type */
2443  if( SCIPvarGetType(binvar) != SCIP_VARTYPE_BINARY )
2444  {
2445  SCIPerrorMessage("variable <%s> is not binary.\n", mpsinputField3(mpsi));
2446  mpsinputSyntaxerror(mpsi);
2447  return SCIP_OKAY;
2448  }
2449 
2450  /* check whether we need the negated variable */
2451  if( mpsinputField4(mpsi) != NULL )
2452  {
2453  if( *mpsinputField4(mpsi) == '0' )
2454  {
2455  SCIP_VAR* var;
2456  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &var) );
2457  binvar = var;
2458  assert( binvar != NULL );
2459  }
2460  else
2461  {
2462  if( *mpsinputField4(mpsi) != '1' )
2463  {
2464  SCIPerrorMessage("binary variable <%s> can only take values 0/1 (%s).\n", mpsinputField3(mpsi), mpsinputField4(mpsi));
2465  mpsinputSyntaxerror(mpsi);
2466  return SCIP_OKAY;
2467  }
2468  }
2469  }
2470 
2471  /* check lhs/rhs */
2472  lhs = SCIPgetLhsLinear(scip, lincons);
2473  rhs = SCIPgetRhsLinear(scip, lincons);
2474  nlinvars = SCIPgetNVarsLinear(scip, lincons);
2475  linvars = SCIPgetVarsLinear(scip, lincons);
2476  linvals = SCIPgetValsLinear(scip, lincons);
2477 
2478  sign = -1.0;
2479  if( !SCIPisInfinity(scip, -lhs) )
2480  {
2481  if( SCIPisInfinity(scip, rhs) )
2482  sign = 1.0;
2483  else
2484  {
2485  /* create second indicator constraint */
2486  SCIP_VAR** vars;
2487  SCIP_Real* vals;
2488  SCIP_RETCODE retcode;
2489 
2490  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nlinvars) );
2491  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nlinvars) );
2492  for( i = 0; i < nlinvars; ++i )
2493  {
2494  vars[i] = linvars[i];
2495  vals[i] = -linvals[i];
2496  }
2497 
2498  /* create new name */
2499  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indlhs_%s", SCIPconsGetName(lincons));
2500 
2501  /* create indicator constraint */
2502  retcode = SCIPcreateConsIndicator(scip, &cons, name, binvar, nlinvars, vars, vals, -lhs,
2503  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode);
2504 
2505  if( retcode == SCIP_OKAY )
2506  {
2507  SCIP_CALL( SCIPaddCons(scip, cons) );
2508  SCIPdebugMsg(scip, "created indicator constraint <%s>\n", mpsinputField2(mpsi));
2509  SCIPdebugPrintCons(scip, cons, NULL);
2510  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2511  }
2512 
2513  SCIPfreeBufferArray(scip, &vals);
2514  SCIPfreeBufferArray(scip, &vars);
2515 
2516  SCIP_CALL( retcode );
2517  }
2518  }
2519 
2520  /* check if slack variable can be made implicitly integer */
2521  slackvartype = SCIP_VARTYPE_IMPLINT;
2522  for (i = 0; i < nlinvars; ++i)
2523  {
2524  if( ! SCIPvarIsIntegral(linvars[i]) || ! SCIPisIntegral(scip, linvals[i]) )
2525  {
2526  slackvartype = SCIP_VARTYPE_CONTINUOUS;
2527  break;
2528  }
2529  }
2530 
2531  /* create slack variable */
2532  if ( ! SCIPisInfinity(scip, -lhs) )
2533  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indslack_indrhs_%s", SCIPconsGetName(lincons));
2534  else
2535  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indslack_%s", SCIPconsGetName(lincons));
2536  SCIP_CALL( SCIPcreateVar(scip, &slackvar, name, 0.0, SCIPinfinity(scip), 0.0, slackvartype, TRUE, FALSE,
2537  NULL, NULL, NULL, NULL, NULL) );
2538 
2539  /* add slack variable */
2540  SCIP_CALL( SCIPaddVar(scip, slackvar) );
2541  SCIP_CALL( SCIPaddCoefLinear(scip, lincons, slackvar, sign) );
2542 
2543  /* correct linear constraint and create new name */
2544  if ( ! SCIPisInfinity(scip, -lhs) && ! SCIPisInfinity(scip, rhs) )
2545  {
2546  /* we have added lhs above and only need the rhs */
2547  SCIP_CALL( SCIPchgLhsLinear(scip, lincons, -SCIPinfinity(scip) ) );
2548  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "indrhs_%s", SCIPconsGetName(lincons));
2549  }
2550  else
2551  (void) SCIPsnprintf(name, MPS_MAX_NAMELEN, "ind_%s", SCIPconsGetName(lincons));
2552 
2553  /* create indicator constraint */
2554  SCIP_CALL( SCIPcreateConsIndicatorLinCons(scip, &cons, name, binvar, lincons, slackvar,
2555  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
2556 
2557  SCIP_CALL( SCIPaddCons(scip, cons) );
2558  SCIPdebugMsg(scip, "created indicator constraint <%s>", mpsinputField2(mpsi));
2559  SCIPdebugPrintCons(scip, cons, NULL);
2560  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
2561  SCIP_CALL( SCIPreleaseVar(scip, &slackvar) );
2562  }
2563 
2564  return SCIP_OKAY;
2565 }
2566 
2567 
2568 /** Read LP in "MPS File Format".
2569  *
2570  * A specification of the MPS format can be found at
2571  *
2572  * http://plato.asu.edu/ftp/mps_format.txt,
2573  * ftp://ftp.caam.rice.edu/pub/people/bixby/miplib/mps_format,
2574  *
2575  * and in the
2576  *
2577  * CPLEX Reference Manual
2578  *
2579  * This routine should read all valid MPS format files.
2580  * What it will not do, is to find all cases where a file is ill formed.
2581  * If this happens it may complain and read nothing or read "something".
2582  */
2583 static
2585  SCIP* scip, /**< SCIP data structure */
2586  const char* filename, /**< name of the input file */
2587  const char*** varnames, /**< storage for the variable names, or NULL */
2588  const char*** consnames, /**< storage for the constraint names, or NULL */
2589  int* varnamessize, /**< the size of the variable names storage, or NULL */
2590  int* consnamessize, /**< the size of the constraint names storage, or NULL */
2591  int* nvarnames, /**< the number of stored variable names, or NULL */
2592  int* nconsnames /**< the number of stored constraint names, or NULL */
2593  )
2594 {
2595  SCIP_FILE* fp;
2596  MPSINPUT* mpsi;
2597  SCIP_RETCODE retcode;
2598  SCIP_Bool error = TRUE;
2599 
2600  assert(scip != NULL);
2601  assert(filename != NULL);
2602 
2603  fp = SCIPfopen(filename, "r");
2604  if( fp == NULL )
2605  {
2606  SCIPerrorMessage("cannot open file <%s> for reading\n", filename);
2607  SCIPprintSysError(filename);
2608  return SCIP_NOFILE;
2609  }
2610 
2611  SCIP_CALL( mpsinputCreate(scip, &mpsi, fp) );
2612 
2613  SCIP_CALL_TERMINATE( retcode, readName(scip, mpsi), TERMINATE );
2614 
2615  SCIP_CALL_TERMINATE( retcode, SCIPcreateProb(scip, mpsi->probname, NULL, NULL, NULL, NULL, NULL, NULL, NULL), TERMINATE );
2616 
2617  if( mpsinputSection(mpsi) == MPS_OBJSEN )
2618  {
2619  SCIP_CALL_TERMINATE( retcode, readObjsen(scip, mpsi), TERMINATE );
2620  }
2621  if( mpsinputSection(mpsi) == MPS_OBJNAME )
2622  {
2623  SCIP_CALL_TERMINATE( retcode, readObjname(scip, mpsi), TERMINATE );
2624  }
2625  while( mpsinputSection(mpsi) == MPS_ROWS
2626  || mpsinputSection(mpsi) == MPS_USERCUTS
2627  || mpsinputSection(mpsi) == MPS_LAZYCONS )
2628  {
2629  SCIP_CALL_TERMINATE( retcode, readRows(mpsi, scip, consnames, consnamessize, nconsnames), TERMINATE );
2630  }
2631  if( mpsinputSection(mpsi) == MPS_COLUMNS )
2632  {
2633  SCIP_CALL_TERMINATE( retcode, readCols(mpsi, scip, varnames, varnamessize, nvarnames), TERMINATE );
2634  }
2635  if( mpsinputSection(mpsi) == MPS_RHS )
2636  {
2637  SCIP_CALL_TERMINATE( retcode, readRhs(mpsi, scip), TERMINATE );
2638  }
2639  if( mpsinputSection(mpsi) == MPS_RANGES )
2640  {
2641  SCIP_CALL_TERMINATE( retcode, readRanges(mpsi, scip), TERMINATE );
2642  }
2643  if( mpsinputSection(mpsi) == MPS_BOUNDS )
2644  {
2645  SCIP_CALL_TERMINATE( retcode, readBounds(mpsi, scip), TERMINATE );
2646  }
2647  if( mpsinputSection(mpsi) == MPS_SOS )
2648  {
2649  SCIP_CALL_TERMINATE( retcode, readSOS(mpsi, scip), TERMINATE );
2650  }
2651  while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2652  {
2653  SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2654  }
2655  if( mpsinputSection(mpsi) == MPS_QMATRIX )
2656  {
2657  SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, FALSE, scip), TERMINATE );
2658  }
2659  if( mpsinputSection(mpsi) == MPS_QUADOBJ )
2660  {
2661  SCIP_CALL_TERMINATE( retcode, readQMatrix(mpsi, TRUE, scip), TERMINATE );
2662  }
2663  while( mpsinputSection(mpsi) == MPS_QCMATRIX )
2664  {
2665  SCIP_CALL_TERMINATE( retcode, readQCMatrix(mpsi, scip), TERMINATE );
2666  }
2667  if( mpsinputSection(mpsi) == MPS_INDICATORS )
2668  {
2669  SCIP_CALL_TERMINATE( retcode, readIndicators(mpsi, scip), TERMINATE );
2670  }
2671  if( mpsinputSection(mpsi) != MPS_ENDATA )
2672  mpsinputSyntaxerror(mpsi);
2673 
2674  SCIPfclose(fp);
2675 
2676  error = mpsinputHasError(mpsi);
2677 
2678  if( !error )
2679  {
2680  SCIP_CALL_TERMINATE( retcode, SCIPsetObjsense(scip, mpsinputObjsense(mpsi)), TERMINATE );
2681  }
2682 
2683  TERMINATE:
2684  mpsinputFree(scip, &mpsi);
2685 
2686  if( error )
2687  return SCIP_READERROR;
2688  else
2689  return SCIP_OKAY;
2690 }
2691 
2692 /*
2693  * local methods for writing problem
2694  */
2695 
2696 /** gets the key (i.e. the name) of the given namefreq */
2697 static
2698 SCIP_DECL_HASHGETKEY(hashGetKeyNamefreq)
2699 { /*lint --e{715}*/
2700  CONSNAMEFREQ* consnamefreq = (CONSNAMEFREQ*)elem;
2701 
2702  assert(consnamefreq != NULL);
2703  assert(consnamefreq->consname != NULL);
2704 
2705  return (void*)consnamefreq->consname;
2706 }
2707 
2708 /** returns TRUE iff both keys (i.e. strings) are equal up to max length*/
2709 static
2710 SCIP_DECL_HASHKEYEQ(hashKeyEqString)
2711 { /*lint --e{715}*/
2712  const char* string1 = (const char*)key1;
2713  const char* string2 = (const char*)key2;
2714 
2715  return (strncmp(string1, string2, MPS_MAX_NAMELEN - 1) == 0);
2716 }
2717 
2718 /** hash key retrieval function for variables */
2719 static
2720 SCIP_DECL_HASHGETKEY(hashGetKeyVar)
2721 { /*lint --e{715}*/
2722  return elem;
2723 }
2724 
2725 /** returns TRUE iff the indices of both variables are equal */
2726 static
2727 SCIP_DECL_HASHKEYEQ(hashKeyEqVar)
2728 { /*lint --e{715}*/
2729  if( key1 == key2 )
2730  return TRUE;
2731  return FALSE;
2732 }
2733 
2734 /** returns the hash value of the key */
2735 static
2736 SCIP_DECL_HASHKEYVAL(hashKeyValVar)
2737 { /*lint --e{715}*/
2738  assert( SCIPvarGetIndex((SCIP_VAR*) key) >= 0 );
2739  return (unsigned int) SCIPvarGetIndex((SCIP_VAR*) key);
2740 }
2741 
2742 
2743 /** computes the field width such that the output file is nicely arranged */
2744 static
2745 unsigned int computeFieldWidth(
2746  unsigned int width /**< required width */
2747  )
2748 {
2749  width = MAX(8u, width);
2750  return MIN(MPS_MAX_FIELDLEN, width);
2751 }
2752 
2753 
2754 /** output two strings in columns 1 and 2 with computed widths */
2755 static
2757  SCIP* scip, /**< SCIP data structure */
2758  FILE* file, /**< output file (or NULL for standard output) */
2759  const char* col1, /**< column 1 */
2760  const char* col2, /**< column 2 */
2761  unsigned int maxnamelen /**< maximum name length */
2762  )
2763 {
2764  unsigned int fieldwidth;
2765  char format[32];
2766 
2767  assert( scip != NULL );
2768  assert( col1 != NULL );
2769  assert( col2 != NULL );
2770  assert( strlen(col1) < MPS_MAX_NAMELEN );
2771  assert( strlen(col2) < MPS_MAX_VALUELEN );
2772  assert( maxnamelen > 0 );
2773 
2774  fieldwidth = computeFieldWidth(maxnamelen);
2775  (void) SCIPsnprintf(format, 32," %%-%ds %%%ds ", fieldwidth, MPS_MAX_VALUELEN - 1);
2776 
2777  SCIPinfoMessage(scip, file, (const char *)format, col1, col2);
2778 }
2779 
2780 /** output two strings in columns 1 (width 2) and 2 (width 8) */
2781 static
2783  SCIP* scip, /**< SCIP data structure */
2784  FILE* file, /**< output file (or NULL for standard output) */
2785  const char* col1, /**< column 1 */
2786  const char* col2, /**< column 2 */
2787  int maxnamelen /**< maximum name length (-1 if irrelevant) */
2788  )
2789 {
2790  unsigned int fieldwidth;
2791  char format[32];
2792 
2793  assert( scip != NULL );
2794  assert( col1 != NULL );
2795  assert( col2 != NULL );
2796  assert( strlen(col1) <= 2 );
2797  assert( strlen(col2) < MPS_MAX_NAMELEN );
2798  assert( maxnamelen == -1 || maxnamelen > 0 );
2799 
2800  if( maxnamelen < 0 )
2801  {
2802  /* format does not matter */
2803  (void) SCIPsnprintf(format, 32, " %%-2.2s %%-s ");
2804  }
2805  else
2806  {
2807  fieldwidth = computeFieldWidth((unsigned int) maxnamelen);
2808  (void) SCIPsnprintf(format, 32, " %%-2.2s %%-%ds ", fieldwidth);
2809  }
2810 
2811  SCIPinfoMessage(scip, file, (const char*)format, col1, col2);
2812 }
2813 
2814 /** prints the given data as column entry */
2815 static
2817  SCIP* scip, /**< SCIP data structure */
2818  FILE* file, /**< output file (or NULL for standard output) */
2819  const char* varname, /**< variable name */
2820  const char* consname, /**< constraint name */
2821  SCIP_Real value, /**< value to display */
2822  int* recordcnt, /**< pointer to store the number of records per line */
2823  unsigned int maxnamelen /**< maximum name length */
2824  )
2825 {
2826  char valuestr[MPS_MAX_VALUELEN] = { '\0' };
2827 
2828  assert( scip != NULL );
2829  assert( recordcnt != NULL );
2830  assert( *recordcnt >= 0 && *recordcnt < 2 );
2831 
2832  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", value);
2833 
2834  if( *recordcnt == 0 )
2835  {
2836  /* start new line with an empty first column and the variable name in the second column */
2837  printStart(scip, file, "", varname, (int) maxnamelen);
2838  *recordcnt = 0;
2839  }
2840 
2841  printRecord(scip, file, consname, valuestr, maxnamelen);
2842  (*recordcnt)++;
2843 
2844  if( *recordcnt == 2 )
2845  {
2846  /* each line can have at most two records */
2847  SCIPinfoMessage(scip, file, "\n");
2848  *recordcnt = 0;
2849  }
2850 }
2851 
2852 /** prints the constraint type to file stream */
2853 static
2855  SCIP* scip, /**< SCIP data structure */
2856  FILE* file, /**< output file (or NULL for standard output) */
2857  SCIP_Real lhs, /**< left hand side */
2858  SCIP_Real rhs, /**< right hand side */
2859  const char* name /**< constraint name */
2860  )
2861 {
2862  char rowtype[2];
2863 
2864  assert( scip != NULL );
2865  assert( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) );
2866  assert( SCIPisGT(scip, rhs, lhs) || SCIPisEQ(scip, lhs, rhs) );
2867  assert( name != NULL );
2868 
2869  if( SCIPisEQ(scip, lhs, rhs) )
2870  (void) SCIPsnprintf(rowtype, 2, "%s", "E");
2871  else
2872  {
2873  /* in case the right hand side and the left hand side are not infinity we print a
2874  * less or equal constraint and put the right hand side in the RHS section and the
2875  * left hand side (hidden) in the RANGE section */
2876  if( !SCIPisInfinity(scip, rhs) )
2877  (void) SCIPsnprintf(rowtype, 2, "%s", "L");
2878  else
2879  {
2880  assert( !SCIPisInfinity(scip, -lhs) );
2881  (void) SCIPsnprintf(rowtype, 2, "%s", "G");
2882  }
2883  }
2884 
2885  printStart(scip, file, rowtype, name, -1);
2886  SCIPinfoMessage(scip, file, "\n");
2887 }
2888 
2889 
2890 /** initializes the sparse matrix */
2891 static
2893  SCIP* scip, /**< SCIP data structure */
2894  SPARSEMATRIX** matrix, /**< pointer to sparse matrix containing the entries */
2895  int slots /**< number of slots */
2896  )
2897 {
2898  SCIP_CALL( SCIPallocBuffer(scip, matrix) );
2899  (*matrix)->nentries = 0;
2900  (*matrix)->sentries = slots;
2901  SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->values, (*matrix)->sentries) );
2902  SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->columns, (*matrix)->sentries) );
2903  SCIP_CALL( SCIPallocBufferArray(scip, &(*matrix)->rows, (*matrix)->sentries) );
2904 
2905  return SCIP_OKAY;
2906 }
2907 
2908 /** this method takes care that the required capacity is available in the sparse matrix */
2909 static
2911  SCIP* scip, /**< SCIP data structure */
2912  SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2913  int capacity /**< needed capacity */
2914  )
2915 {
2916  if( matrix->nentries + capacity >= matrix->sentries )
2917  {
2918  matrix->sentries = matrix->sentries * 2 + capacity;
2919  SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->values, matrix->sentries) );
2920  SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->columns, matrix->sentries) );
2921  SCIP_CALL( SCIPreallocBufferArray(scip, &matrix->rows, matrix->sentries) );
2922  }
2923  return SCIP_OKAY;
2924 }
2925 
2926 /** frees the sparse matrix */
2927 static
2929  SCIP* scip, /**< SCIP data structure */
2930  SPARSEMATRIX* matrix /**< sparse matrix to free */
2931  )
2932 {
2933  SCIPfreeBufferArray(scip, &matrix->rows);
2934  SCIPfreeBufferArray(scip, &matrix->columns);
2935  SCIPfreeBufferArray(scip, &matrix->values);
2936 
2937  SCIPfreeBuffer(scip, &matrix);
2938 }
2939 
2940 
2941 /** computes the coefficient for the given variables and linear constraint information */
2942 static
2944  SCIP* scip, /**< SCIP data structure */
2945  const char* consname, /**< name of the constraint */
2946  SCIP_VAR** vars, /**< array of variables */
2947  SCIP_Real* vals, /**< array of coefficients values (or NULL if all coefficient values are 1) */
2948  int nvars, /**< number of variables */
2949  SCIP_Bool transformed, /**< transformed constraint? */
2950  SPARSEMATRIX* matrix, /**< sparse matrix for storing the coefficient */
2951  SCIP_Real* rhs /**< pointer to right hand side */
2952  )
2953 {
2954  SCIP_VAR** activevars;
2955  SCIP_Real* activevals;
2956  SCIP_Real activeconstant = 0.0;
2957 
2958  int nactivevars;
2959  int requiredsize;
2960  int v;
2961 
2962  assert( scip != NULL );
2963  assert( nvars == 0 || vars != NULL );
2964  assert( !SCIPisInfinity(scip, *rhs) );
2965  assert( matrix != NULL );
2966 
2967  /* if the variables array contains no variables, then return without
2968  * doing any thing; The MPS format and LP format do not forbid this
2969  * situation */
2970  if( nvars == 0 )
2971  return SCIP_OKAY;
2972 
2973  /* duplicate variable and value array */
2974  nactivevars = nvars;
2975  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevars, vars, nactivevars ) );
2976 
2977  if( vals != NULL )
2978  {
2979  SCIP_CALL( SCIPduplicateBufferArray(scip, &activevals, vals, nactivevars ) );
2980  }
2981  else
2982  {
2983  SCIP_CALL( SCIPallocBufferArray(scip, &activevals, nactivevars) );
2984 
2985  for( v = 0; v < nactivevars; ++v )
2986  activevals[v] = 1.0;
2987  }
2988 
2989  /* retransform given variables to active variables */
2990  if( transformed )
2991  {
2992  SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, nactivevars, &activeconstant, &requiredsize, TRUE) );
2993 
2994  if( requiredsize > nactivevars )
2995  {
2996  SCIP_CALL( SCIPreallocBufferArray(scip, &activevars, requiredsize) );
2997  SCIP_CALL( SCIPreallocBufferArray(scip, &activevals, requiredsize) );
2998 
2999  SCIP_CALL( SCIPgetProbvarLinearSum(scip, activevars, activevals, &nactivevars, requiredsize, &activeconstant, &requiredsize, TRUE) );
3000  assert( requiredsize <= nactivevars );
3001  }
3002  }
3003  else
3004  {
3005  for( v = 0; v < nactivevars; ++v )
3006  {
3007  SCIP_CALL( SCIPvarGetOrigvarSum(&activevars[v], &activevals[v], &activeconstant) );
3008 
3009  /* negated variables with an original counterpart may also be returned by SCIPvarGetOrigvarSum();
3010  * make sure we get the original variable in that case
3011  */
3012  if( SCIPvarGetStatus(activevars[v]) == SCIP_VARSTATUS_NEGATED )
3013  {
3014  activevars[v] = SCIPvarGetNegatedVar(activevars[v]);
3015  activeconstant += activevals[v];
3016  activevals[v] *= -1.0;
3017  }
3018  }
3019  }
3020 
3021  /* copy the (matrix) row into the sparse matrix */
3022  SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, nactivevars) );
3023  assert( matrix->nentries + nactivevars < matrix->sentries );
3024 
3025  for( v = 0; v < nactivevars; ++v )
3026  {
3027  matrix->values[matrix->nentries] = activevals[v];
3028  matrix->columns[matrix->nentries] = activevars[v];
3029  matrix->rows[matrix->nentries] = consname;
3030  matrix->nentries++;
3031  }
3032 
3033  /* adjust right hand side */
3034  (*rhs) -= activeconstant;
3035 
3036  /* free buffer arrays */
3037  SCIPfreeBufferArray(scip, &activevals);
3038  SCIPfreeBufferArray(scip, &activevars);
3039 
3040  return SCIP_OKAY;
3041 }
3042 
3043 
3044 /** check whether given variables are aggregated and put them into an array without duplication */
3045 static
3047  SCIP* scip, /**< SCIP data structure */
3048  SCIP_VAR** vars, /**< variable array */
3049  int nvars, /**< number of active variables in the problem */
3050  SCIP_VAR*** aggvars, /**< pointer to array storing the aggregated variables on output */
3051  int* naggvars, /**< pointer to number of aggregated variables on output */
3052  int* saggvars, /**< pointer to number of slots in aggvars array */
3053  SCIP_HASHTABLE* varAggregated /**< hashtable for checking duplicates */
3054  )
3055 {
3056  int v;
3057 
3058  assert( scip != NULL );
3059  assert( aggvars != NULL );
3060  assert( naggvars != NULL );
3061  assert( saggvars != NULL );
3062 
3063  /* check variables */
3064  for( v = 0; v < nvars; ++v )
3065  {
3066  SCIP_VARSTATUS status;
3067  SCIP_VAR* var;
3068 
3069  var = vars[v];
3070  status = SCIPvarGetStatus(var);
3071 
3072  /* collect aggregated variables in a list */
3073  if( status >= SCIP_VARSTATUS_AGGREGATED )
3074  {
3075  assert( status == SCIP_VARSTATUS_AGGREGATED || status == SCIP_VARSTATUS_MULTAGGR || status == SCIP_VARSTATUS_NEGATED );
3076  assert( varAggregated != NULL );
3077 
3078  if( ! SCIPhashtableExists(varAggregated, (void*) var) )
3079  {
3080  /* possibly enlarge array */
3081  if ( *saggvars <= *naggvars )
3082  {
3083  int newsize;
3084  newsize = SCIPcalcMemGrowSize(scip, *naggvars + 1);
3085  assert( newsize > *saggvars );
3086  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &aggvars, *saggvars, newsize) );
3087  *saggvars = newsize;
3088  }
3089 
3090  (*aggvars)[*naggvars] = var;
3091  (*naggvars)++;
3092  SCIP_CALL( SCIPhashtableInsert(varAggregated, (void*) var) );
3093  assert( *naggvars <= *saggvars );
3094  }
3095  }
3096  }
3097  return SCIP_OKAY;
3098 }
3099 
3100 
3101 /** method check if the variable names are not longer than MPS_MAX_NAMELEN - 1*/
3102 static
3104  SCIP* scip, /**< SCIP data structure */
3105  SCIP_VAR** vars, /**< array of variables */
3106  int nvars, /**< number of variables */
3107  unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3108  const char*** varnames, /**< pointer to array of variable names */
3109  SCIP_HASHMAP** varnameHashmap /**< pointer to hash map storing variable, variable name mapping */
3110  )
3111 {
3112  int v;
3113  int faulty;
3114  char* varname;
3115  SCIP_VAR* var;
3116 
3117  assert( scip != NULL );
3118  assert( vars != NULL );
3119  assert( maxnamelen != NULL );
3120 
3121  faulty = 0;
3122 
3123  /* allocate memory */
3124  SCIP_CALL( SCIPhashmapCreate(varnameHashmap, SCIPblkmem(scip), nvars) );
3125  SCIP_CALL( SCIPallocBufferArray(scip, varnames, nvars) );
3126 
3127  /* check if the variable names are not to long */
3128  for( v = 0; v < nvars; ++v )
3129  {
3130  size_t l;
3131 
3132  var = vars[v];
3133  assert( var != NULL );
3134 
3135  l = strlen(SCIPvarGetName(var));
3136 
3137  if( l >= MPS_MAX_NAMELEN )
3138  {
3139  faulty++;
3140  (*maxnamelen) = MPS_MAX_NAMELEN - 1;
3141  }
3142  else
3143  {
3144  (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3145  }
3146 
3147  SCIP_CALL( SCIPallocBufferArray(scip, &varname, (int) *maxnamelen + 1) );
3148  (void) SCIPsnprintf(varname, (int)(*maxnamelen) + 1, "%s", SCIPvarGetName(var) );
3149 
3150  /* insert variable with variable name into hash map */
3151  assert( !SCIPhashmapExists(*varnameHashmap, var) );
3152  SCIP_CALL( SCIPhashmapInsert(*varnameHashmap, var, (void*) varname) );
3153 
3154  (*varnames)[v] = varname;
3155  }
3156 
3157  if( faulty > 0 )
3158  {
3159  SCIPwarningMessage(scip, "there are %d variable names which have to be cut down to %d characters; LP might be corrupted\n",
3160  faulty, MPS_MAX_NAMELEN - 1);
3161  }
3162  return SCIP_OKAY;
3163 }
3164 
3165 /** method check if the constraint names are not longer than MPS_MAX_NAMELEN - 1 */
3166 static
3168  SCIP* scip, /**< SCIP data structure */
3169  SCIP_CONS** conss, /**< array of all constraints */
3170  int nconss, /**< number of all constraints */
3171  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3172  unsigned int* maxnamelen, /**< pointer to store the maximum name length */
3173  const char*** consnames, /**< pointer to array of constraint names */
3174  SCIP_Bool* error /**< pointer to store whether all constraint names exist */
3175  )
3176 {
3177  SCIP_HASHTABLE* consfreq;
3178  CONSNAMEFREQ* consnamefreqs;
3179  SCIP_CONS* cons;
3180  char* consname;
3181  int i;
3182 
3183  assert(scip != NULL);
3184  assert(maxnamelen != NULL);
3185 
3186  *error = FALSE;
3187 
3188  /* allocate memory */
3189  SCIP_CALL( SCIPallocBufferArray(scip, &consnamefreqs, nconss) );
3190  SCIP_CALL( SCIPallocBufferArray(scip, consnames, nconss) );
3192  hashGetKeyNamefreq, hashKeyEqString, SCIPhashKeyValString, NULL) );
3193 
3194  for( i = 0; i < nconss; ++i )
3195  {
3196  CONSNAMEFREQ* consnamefreq;
3197  size_t l;
3198  int freq;
3199 
3200  cons = conss[i];
3201  assert( cons != NULL );
3202 
3203  /* in case the transformed problem is written, only constraints are posted which are enabled in the current node */
3204  assert(!transformed || SCIPconsIsEnabled(cons));
3205 
3206  l = strlen(SCIPconsGetName(cons));
3207 
3208  if( l == 0 )
3209  {
3210  SCIPwarningMessage(scip, "At least one name of a constraint is empty, so file will be written with generic names.\n");
3211  *error = TRUE;
3212 
3213  goto TERMINATE;
3214  }
3215 
3216  consnamefreqs[i].consname = SCIPconsGetName(cons);
3217  consnamefreqs[i].freq = 0;
3218  freq = 0;
3219 
3220  /* check for duplicate names */
3221  if( NULL != (consnamefreq = (CONSNAMEFREQ *)SCIPhashtableRetrieve(consfreq, (void*)SCIPconsGetName(cons))) )
3222  {
3223  consnamefreq->freq += 1;
3224  consnamefreqs[i] = *consnamefreq;
3225  freq = consnamefreq->freq;
3226  }
3227  SCIP_CALL( SCIPhashtableInsert(consfreq, (void*)(&consnamefreqs[i])) );
3228 
3229  /* the new length is the length of the old name + a '_' and the freq number which has floor(log10(freq)) + 1 characters */
3230  if( freq > 0 )
3231  l = l + 1 + (size_t)log10((SCIP_Real) freq) + 1;
3232 
3233  if( l >= MPS_MAX_NAMELEN )
3234  {
3235  SCIPwarningMessage(scip, "Constraints have duplicate name and are too long to fix, so file will be written with generic names.\n");
3236  *error = TRUE;
3237 
3238  goto TERMINATE;
3239  }
3240 
3241  (*maxnamelen) = MAX(*maxnamelen, (unsigned int) l);
3242 
3243  SCIP_CALL( SCIPallocBufferArray(scip, &consname, (int) l + 1) );
3244  if( freq > 0 )
3245  (void) SCIPsnprintf(consname, (int)l + 1, "%s_%d", SCIPconsGetName(cons), freq);
3246  else
3247  (void) SCIPsnprintf(consname, (int)l + 1, "%s", SCIPconsGetName(cons));
3248 
3249  (*consnames)[i] = consname;
3250  }
3251 
3252 TERMINATE:
3253  SCIPfreeBufferArray(scip, &consnamefreqs);
3254 
3255  if( *error )
3256  {
3257  --i; /*lint !e445*/
3258  for( ; i >= 0; --i) /*lint !e445*/
3259  {
3260  SCIPfreeBufferArray(scip, &((*consnames)[i]));
3261  }
3262  SCIPfreeBufferArray(scip, consnames);
3263  }
3264 
3265  SCIPhashtableFree(&consfreq);
3266 
3267  return SCIP_OKAY;
3268 }
3269 
3270 
3271 /** outputs the COLUMNS section of the MPS format */
3272 static
3274  SCIP* scip, /**< SCIP data structure */
3275  FILE* file, /**< output file, or NULL if standard output should be used */
3276  SPARSEMATRIX* matrix, /**< sparse matrix containing the entries */
3277  SCIP_HASHMAP* varnameHashmap, /**< map from SCIP_VAR* to variable name */
3278  SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3279  unsigned int maxnamelen /**< maximum name length */
3280  )
3281 {
3282  SCIP_Bool intSection;
3283  SCIP_VAR* var;
3284  const char* varname;
3285  SCIP_Real value;
3286  int v;
3287  int recordcnt;
3288 
3289  /* sort sparse matrix w.r.t. the variable indices */
3290  SCIPsortPtrPtrReal((void**) matrix->columns, (void**) matrix->rows, matrix->values, SCIPvarComp, matrix->nentries);
3291 
3292  /* print COLUMNS section */
3293  SCIPinfoMessage(scip, file, "COLUMNS\n");
3294 
3295  intSection = FALSE;
3296 
3297  for( v = 0; v < matrix->nentries; )
3298  {
3299  var = matrix->columns[v];
3300  assert( var != NULL );
3301 
3302  /* skip slack variables in output */
3303  if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3304  {
3305  ++v;
3306  continue;
3307  }
3308 
3309  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && intSection )
3310  {
3311  /* end integer section in MPS format */
3312  printStart(scip, file, "", "INTEND", (int) maxnamelen);
3313  printRecord(scip, file, "'MARKER'", "", maxnamelen);
3314  printRecord(scip, file, "'INTEND'", "", maxnamelen);
3315  SCIPinfoMessage(scip, file, "\n");
3316  intSection = FALSE;
3317  }
3318  else if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !intSection )
3319  {
3320  /* start integer section in MPS format */
3321  printStart(scip, file, "", "INTSTART", (int) maxnamelen);
3322  printRecord(scip, file, "'MARKER'", "", maxnamelen);
3323  printRecord(scip, file, "'INTORG'", "", maxnamelen);
3324  SCIPinfoMessage(scip, file, "\n");
3325  intSection = TRUE;
3326  }
3327 
3328  SCIPdebugMsg(scip, "create entries for variable <%s>\n", SCIPvarGetName(var));
3329 
3330  /* record count; there are at most two records per line */
3331  recordcnt = 0;
3332 
3333  /* get variable name */
3334  assert ( SCIPhashmapExists(varnameHashmap, var) );
3335  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var);
3336 
3337  /* output all entries of the same variable */
3338  do
3339  {
3340  value = matrix->values[v];
3341 
3342  /* print record to file */
3343  printEntry(scip, file, varname, matrix->rows[v], value, &recordcnt, maxnamelen);
3344  v++;
3345  }
3346  while( v < matrix->nentries && var == matrix->columns[v] );
3347 
3348  if( recordcnt == 1 )
3349  SCIPinfoMessage(scip, file, "\n");
3350  }
3351  /* end integer section, if the columns sections ends with integer variables */
3352  if( intSection )
3353  {
3354  /* end integer section in MPS format */
3355  printStart(scip, file, "", "INTEND", (int) maxnamelen);
3356  printRecord(scip, file, "'MARKER'", "", maxnamelen);
3357  printRecord(scip, file, "'INTEND'", "", maxnamelen);
3358  SCIPinfoMessage(scip, file, "\n");
3359  }
3360 }
3361 
3362 
3363 /** outputs the right hand side section */
3364 static
3366  SCIP* scip, /**< SCIP data structure */
3367  FILE* file, /**< output file, or NULL if standard output should be used */
3368  int nconss, /**< number of constraints */
3369  const char** consnames, /**< constraint names */
3370  SCIP_Real* rhss, /**< right hand side array */
3371  unsigned int maxnamelen, /**< maximum name length */
3372  SCIP_Real objoffset /**< objective offset */
3373  )
3374 {
3375  int recordcnt = 0;
3376  int c;
3377 
3378  assert( rhss != NULL );
3379 
3380  SCIPinfoMessage(scip, file, "RHS\n");
3381  SCIPdebugMsg(scip, "start printing RHS section\n");
3382 
3383  /* take care of the linear constraints */
3384  for( c = 0; c < nconss; ++c )
3385  {
3386  /* skip all constraints which have a right hand side of infinity */
3387  if( SCIPisInfinity(scip, rhss[c]) )
3388  continue;
3389 
3390  assert(consnames[c] != NULL);
3391 
3392  printEntry(scip, file, "RHS", consnames[c], rhss[c], &recordcnt, maxnamelen);
3393  }
3394 
3395  if( ! SCIPisZero(scip, objoffset) )
3396  {
3397  /* write objective offset (-1 because it is moved to the rhs) */
3398  printEntry(scip, file, "RHS", "Obj", -objoffset, &recordcnt, maxnamelen);
3399  }
3400 
3401  if( recordcnt == 1 )
3402  SCIPinfoMessage(scip, file, "\n");
3403 }
3404 
3405 
3406 /** outputs the range section */
3407 static
3409  SCIP* scip, /**< SCIP data structure */
3410  FILE* file, /**< output file, or NULL if standard output should be used */
3411  SCIP_CONS** conss, /**< constraint array */
3412  int nconss, /**< number of constraints */
3413  const char** consnames, /**< constraint names */
3414  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3415  unsigned int maxnamelen /**< maximum name length */
3416  )
3417 {
3418  int c;
3419  int recordcnt = 0;
3420 
3421  SCIP_CONSHDLR* conshdlr;
3422  const char* conshdlrname;
3423 
3424  SCIP_CONS* cons;
3425  SCIP_Real lhs;
3426  SCIP_Real rhs;
3427 
3428  SCIPinfoMessage(scip, file, "RANGES\n");
3429  SCIPdebugMsg(scip, "start printing RANGES section\n");
3430 
3431  for( c = 0; c < nconss; ++c )
3432  {
3433  cons = conss[c];
3434  assert( cons != NULL);
3435 
3436  /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
3437  * the conss array should only contain relevant constraints
3438  */
3439  assert( !transformed || SCIPconsIsEnabled(cons) );
3440 
3441  assert( consnames[c] != NULL );
3442 
3443  conshdlr = SCIPconsGetHdlr(cons);
3444  assert( conshdlr != NULL );
3445 
3446  conshdlrname = SCIPconshdlrGetName(conshdlr);
3447 
3448  if( strcmp(conshdlrname, "linear") == 0 )
3449  {
3450  lhs = SCIPgetLhsLinear(scip, cons);
3451  rhs = SCIPgetRhsLinear(scip, cons);
3452  }
3453  else if( strcmp(conshdlrname, "varbound") == 0 )
3454  {
3455  lhs = SCIPgetLhsVarbound(scip, cons);
3456  rhs = SCIPgetRhsVarbound(scip, cons);
3457  }
3458  else
3459  continue;
3460 
3461  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, rhs, lhs) )
3462  {
3463  assert( SCIPisGT(scip, rhs, lhs) );
3464  printEntry(scip, file, "RANGE", consnames[c], rhs - lhs, &recordcnt, maxnamelen);
3465  }
3466  }
3467  if(recordcnt == 1 )
3468  SCIPinfoMessage(scip, file, "\n");
3469 }
3470 
3471 /** print bound section name */
3472 static
3474  SCIP* scip, /**< SCIP data structure */
3475  FILE* file /**< output file, or NULL if standard output should be used */
3476  )
3477 {
3478  SCIPinfoMessage(scip, file, "BOUNDS\n");
3479  SCIPdebugMsg(scip, "start printing BOUNDS section\n");
3480 }
3481 
3482 /** output bound section */
3483 static
3485  SCIP* scip, /**< SCIP data structure */
3486  FILE* file, /**< output file, or NULL if standard output should be used */
3487  SCIP_VAR** vars, /**< active variables */
3488  int nvars, /**< number of active variables */
3489  SCIP_VAR** aggvars, /**< needed aggregated variables */
3490  int naggvars, /**< number of aggregated variables */
3491  SCIP_VAR** fixvars, /**< all fixed variables (or NULL if nfixvars is 0) */
3492  int nfixvars, /**< number of fixed variables */
3493  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3494  const char** varnames, /**< array with variable names */
3495  SCIP_HASHTABLE* indicatorSlackHash, /**< hashtable containing slack variables from indicators (or NULL) */
3496  unsigned int maxnamelen /**< maximum name length */
3497  )
3498 {
3499  int v;
3500  SCIP_VAR* var;
3501  SCIP_Real lb;
3502  SCIP_Real ub;
3503  SCIP_Bool sectionName;
3504  const char* varname;
3505  char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3506 
3507  assert(scip != NULL);
3508  assert(vars != NULL);
3509  assert(nfixvars == 0 || fixvars != NULL);
3510 
3511  sectionName = FALSE;
3512 
3513  /* output the active variables */
3514  for( v = 0; v < nvars; ++v )
3515  {
3516  var = vars[v];
3517  assert( var != NULL );
3518 
3519  /* skip slack variables in output */
3520  if( indicatorSlackHash != NULL && SCIPhashtableExists(indicatorSlackHash, var) )
3521  continue;
3522 
3523  /* get variable name */
3524  varname = varnames[v];
3525  assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3526 
3527  if( transformed )
3528  {
3529  /* in case the transformed is written only local bounds are posted
3530  * which are valid in the current node */
3531  lb = SCIPvarGetLbLocal(var);
3532  ub = SCIPvarGetUbLocal(var);
3533  }
3534  else
3535  {
3536  lb = SCIPvarGetLbOriginal(var);
3537  ub = SCIPvarGetUbOriginal(var);
3538  }
3539 
3540  /* take care of binary variables */
3541  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3542  {
3543  if( !sectionName )
3544  {
3545  printBoundSectionName(scip, file);
3546  sectionName = TRUE;
3547  }
3548 
3549  if( !SCIPisFeasZero(scip, lb) || !SCIPisFeasEQ(scip, ub, 1.0) )
3550  {
3551  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3552  printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3553  printRecord(scip, file, varname, valuestr, maxnamelen);
3554  SCIPinfoMessage(scip, file, "\n");
3555 
3556  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3557  printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3558  printRecord(scip, file, varname, valuestr, maxnamelen);
3559  }
3560  else
3561  {
3562  printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3563  printRecord(scip, file, varname, "", maxnamelen);
3564  }
3565  SCIPinfoMessage(scip, file, "\n");
3566 
3567  continue;
3568  }
3569 
3570  /* take care of free variables */
3571  if( SCIPisInfinity(scip, -lb) && SCIPisInfinity(scip, ub) )
3572  {
3573  if( !sectionName )
3574  {
3575  printBoundSectionName(scip, file);
3576  sectionName = TRUE;
3577  }
3578 
3579  /* variable is free */
3580  printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3581  printRecord(scip, file, varname, "", maxnamelen);
3582  SCIPinfoMessage(scip, file, "\n");
3583  continue;
3584  }
3585 
3586  /* take care of fixed variables */
3587  if( SCIPisEQ(scip, lb, ub) )
3588  {
3589  if( !sectionName )
3590  {
3591  printBoundSectionName(scip, file);
3592  sectionName = TRUE;
3593  }
3594 
3595  /* variable is fixed */
3596  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3597  printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3598  printRecord(scip, file, varname, valuestr, maxnamelen);
3599  SCIPinfoMessage(scip, file, "\n");
3600  continue;
3601  }
3602 
3603  /* print lower bound */
3604  if( SCIPisInfinity(scip, -lb) )
3605  {
3606  if( !sectionName )
3607  {
3608  printBoundSectionName(scip, file);
3609  sectionName = TRUE;
3610  }
3611 
3612  /* the free variables are processed above */
3613  assert( !SCIPisInfinity(scip, ub) );
3614  printStart(scip, file, "MI", "Bound", (int) maxnamelen);
3615  printRecord(scip, file, varname, "", maxnamelen);
3616  SCIPinfoMessage(scip, file, "\n");
3617  }
3618  else
3619  {
3620  if( SCIPisZero(scip, lb) )
3621  {
3622  lb = 0.0;
3623  }
3624  else
3625  {
3626  if( !sectionName )
3627  {
3628  printBoundSectionName(scip, file);
3629  sectionName = TRUE;
3630  }
3631 
3632  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3633  printStart(scip, file, "LO", "Bound", (int) maxnamelen);
3634  printRecord(scip, file, varname, valuestr, maxnamelen);
3635  SCIPinfoMessage(scip, file, "\n");
3636  }
3637  }
3638 
3639  /* print upper bound, infinity has to be printed for integer (!) variables, because during
3640  * reading an mps file no upper bound of an integer variable means that the upper bound will
3641  * be set to 1 instead of +infinity (like it is for continuous variables) */
3642  if( SCIPisInfinity(scip, ub) )
3643  {
3644  if( !sectionName )
3645  {
3646  printBoundSectionName(scip, file);
3647  sectionName = TRUE;
3648  }
3649 
3650  /* the free variables are processed above */
3651  assert( !SCIPisInfinity(scip, -lb) );
3652  printStart(scip, file, "PL", "Bound", (int) maxnamelen);
3653  printRecord(scip, file, varname, "", maxnamelen);
3654  SCIPinfoMessage(scip, file, "\n");
3655  }
3656  else
3657  {
3658  if( !sectionName )
3659  {
3660  printBoundSectionName(scip, file);
3661  sectionName = TRUE;
3662  }
3663 
3664  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", ub);
3665  printStart(scip, file, "UP", "Bound", (int) maxnamelen);
3666  printRecord(scip, file, varname, valuestr, maxnamelen);
3667  SCIPinfoMessage(scip, file, "\n");
3668  }
3669  }
3670 
3671  /* output aggregated variables as 'free', except if they are binary */
3672  for( v = 0; v < naggvars; ++v )
3673  {
3674  if( !sectionName )
3675  {
3676  printBoundSectionName(scip, file);
3677  sectionName = TRUE;
3678  }
3679 
3680  var = aggvars[v];
3681  assert( var != NULL );
3682 
3683  /* get variable name */
3684  varname = varnames[nvars + v];
3685  assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3686 
3687  /* take care of binary variables */
3688  if( SCIPvarGetType(var) == SCIP_VARTYPE_BINARY )
3689  {
3690  printStart(scip, file, "BV", "Bound", (int) maxnamelen);
3691  printRecord(scip, file, varname, "", maxnamelen);
3692  SCIPinfoMessage(scip, file, "\n");
3693  }
3694  else
3695  {
3696  /* variable is free */
3697  printStart(scip, file, "FR", "Bound", (int) maxnamelen);
3698  printRecord(scip, file, varname, "", maxnamelen);
3699  SCIPinfoMessage(scip, file, "\n");
3700  }
3701  }
3702 
3703  /* output all fixed variables */
3704  for( v = 0; v < nfixvars; ++v )
3705  {
3706  /* we should print the transformed problem, otherwise no fixed variable should exists */
3707  assert(transformed);
3708  assert(fixvars != NULL && fixvars[v] != NULL);
3709 
3710  /* cppcheck-suppress nullPointer */
3711  var = fixvars[v];
3712 
3713  assert(var != NULL);
3714  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED);
3715 
3716  /* get variable name */
3717  varname = varnames[nvars + naggvars + v];
3718  assert(strncmp(varname, SCIPvarGetName(var), maxnamelen) == 0);
3719 
3720  /* only local bounds are posted which are valid in the current node */
3721  lb = SCIPvarGetLbLocal(var);
3722  ub = SCIPvarGetUbLocal(var);
3723  assert(SCIPisEQ(scip, lb, ub));
3724 
3725  if( !sectionName )
3726  {
3727  printBoundSectionName(scip, file);
3728  sectionName = TRUE;
3729  }
3730 
3731  /* print fixed variable */
3732  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", lb);
3733  printStart(scip, file, "FX", "Bound", (int) maxnamelen);
3734  printRecord(scip, file, varname, valuestr, maxnamelen);
3735  SCIPinfoMessage(scip, file, "\n");
3736  }
3737 }
3738 
3739 
3740 /*
3741  * Callback methods of reader
3742  */
3743 
3744 /** copy method for reader plugins (called when SCIP copies plugins) */
3745 /**! [SnippetReaderCopyMps] */
3746 static
3747 SCIP_DECL_READERCOPY(readerCopyMps)
3748 { /*lint --e{715}*/
3749  assert(scip != NULL);
3750  assert(reader != NULL);
3751  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3752 
3753  /* call inclusion method of reader */
3755 
3756  return SCIP_OKAY;
3757 }
3758 /**! [SnippetReaderCopyMps] */
3759 
3760 /** destructor of reader to free user data (called when SCIP is exiting) */
3761 /**! [SnippetReaderFreeMps] */
3762 static
3763 SCIP_DECL_READERFREE(readerFreeMps)
3764 {
3765  SCIP_READERDATA* readerdata;
3766 
3767  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3768  readerdata = SCIPreaderGetData(reader);
3769  assert(readerdata != NULL);
3770  SCIPfreeBlockMemory(scip, &readerdata);
3771 
3772  return SCIP_OKAY;
3773 }
3774 /**! [SnippetReaderFreeMps] */
3775 
3776 /** problem reading method of reader */
3777 static
3778 SCIP_DECL_READERREAD(readerReadMps)
3779 { /*lint --e{715}*/
3780  assert(reader != NULL);
3781  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3782 
3783  SCIP_CALL( SCIPreadMps(scip, reader, filename, result, NULL, NULL, NULL, NULL, NULL, NULL) );
3784 
3785  return SCIP_OKAY;
3786 }
3787 
3788 
3789 /** problem writing method of reader */
3790 static
3791 SCIP_DECL_READERWRITE(readerWriteMps)
3792 { /*lint --e{715}*/
3793  assert(reader != NULL);
3794  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3795 
3796  SCIP_CALL( SCIPwriteMps(scip, reader, file, name, transformed, objsense, objscale, objoffset, vars,
3797  nvars, nbinvars, nintvars, nimplvars, ncontvars, fixedvars, nfixedvars, conss, nconss, result) );
3798 
3799  return SCIP_OKAY;
3800 }
3801 
3802 
3803 /*
3804  * mps file reader specific interface methods
3805  */
3806 
3807 /** includes the mps file reader in SCIP */
3809  SCIP* scip /**< SCIP data structure */
3810  )
3811 {
3812  SCIP_READERDATA* readerdata;
3813  SCIP_READER* reader;
3814 
3815  /* create reader data */
3816  SCIP_CALL( SCIPallocBlockMemory(scip, &readerdata) );
3817 
3818  /* include reader */
3819  SCIP_CALL( SCIPincludeReaderBasic(scip, &reader, READER_NAME, READER_DESC, READER_EXTENSION, readerdata) );
3820 
3821  /* set non fundamental callbacks via setter functions */
3822  SCIP_CALL( SCIPsetReaderCopy(scip, reader, readerCopyMps) );
3823  SCIP_CALL( SCIPsetReaderFree(scip, reader, readerFreeMps) );
3824  SCIP_CALL( SCIPsetReaderRead(scip, reader, readerReadMps) );
3825  SCIP_CALL( SCIPsetReaderWrite(scip, reader, readerWriteMps) );
3826 
3827  /* add lp-reader parameters */
3829  "reading/" READER_NAME "/linearize-and-constraints",
3830  "should possible \"and\" constraint be linearized when writing the mps file?",
3831  &readerdata->linearizeands, TRUE, DEFAULT_LINEARIZE_ANDS, NULL, NULL) );
3833  "reading/" READER_NAME "/aggrlinearization-ands",
3834  "should an aggregated linearization for and constraints be used?",
3835  &readerdata->aggrlinearizationands, TRUE, DEFAULT_AGGRLINEARIZATION_ANDS, NULL, NULL) );
3836 
3837  return SCIP_OKAY;
3838 }
3839 
3840 
3841 /** reads problem from file */
3843  SCIP* scip, /**< SCIP data structure */
3844  SCIP_READER* reader, /**< the file reader itself */
3845  const char* filename, /**< full path and name of file to read, or NULL if stdin should be used */
3846  SCIP_RESULT* result, /**< pointer to store the result of the file reading call */
3847  const char*** varnames, /**< storage for the variable names, or NULL */
3848  const char*** consnames, /**< storage for the constraint names, or NULL */
3849  int* varnamessize, /**< the size of the variable names storage, or NULL */
3850  int* consnamessize, /**< the size of the constraint names storage, or NULL */
3851  int* nvarnames, /**< the number of stored variable names, or NULL */
3852  int* nconsnames /**< the number of stored constraint names, or NULL */
3853  )
3854 {
3855  SCIP_RETCODE retcode;
3856 
3857  assert(reader != NULL);
3858  assert(scip != NULL);
3859  assert(result != NULL);
3860 
3861  retcode = readMps(scip, filename, varnames, consnames, varnamessize, consnamessize, nvarnames, nconsnames);
3862 
3863  if( retcode == SCIP_PLUGINNOTFOUND )
3864  retcode = SCIP_READERROR;
3865 
3866  if( retcode == SCIP_NOFILE || retcode == SCIP_READERROR )
3867  return retcode;
3868 
3869  SCIP_CALL( retcode );
3870 
3871  *result = SCIP_SUCCESS;
3872 
3873  return SCIP_OKAY;
3874 }
3875 
3876 
3877 /** writes problem to file */
3879  SCIP* scip, /**< SCIP data structure */
3880  SCIP_READER* reader, /**< the file reader itself */
3881  FILE* file, /**< output file, or NULL if standard output should be used */
3882  const char* name, /**< problem name */
3883  SCIP_Bool transformed, /**< TRUE iff problem is the transformed problem */
3884  SCIP_OBJSENSE objsense, /**< objective sense */
3885  SCIP_Real objscale, /**< scalar applied to objective function; external objective value is
3886  * extobj = objsense * objscale * (intobj + objoffset) */
3887  SCIP_Real objoffset, /**< objective offset from bound shifting and fixing */
3888  SCIP_VAR** vars, /**< array with active variables ordered binary, integer, implicit, continuous */
3889  int nvars, /**< number of active variables in the problem */
3890  int nbinvars, /**< number of binary variables */
3891  int nintvars, /**< number of general integer variables */
3892  int nimplvars, /**< number of implicit integer variables */
3893  int ncontvars, /**< number of continuous variables */
3894  SCIP_VAR** fixedvars, /**< array with fixed and aggregated variables */
3895  int nfixedvars, /**< number of fixed and aggregated variables in the problem */
3896  SCIP_CONS** conss, /**< array with constraints of the problem */
3897  int nconss, /**< number of constraints in the problem */
3898  SCIP_RESULT* result /**< pointer to store the result of the file writing call */
3899  )
3900 {
3901  SCIP_READERDATA* readerdata;
3902  int naddrows;
3903  int faulty = 0;
3904  int c;
3905  int v;
3906  int k;
3907  char* namestr;
3908 
3909  SCIP_CONS* cons = NULL;
3910  const char* consname;
3911  const char** consnames;
3912 
3913  SCIP_CONSHDLR* conshdlr;
3914  const char* conshdlrname;
3915 
3916  SCIP_Real lhs;
3917  SCIP_Real rhs;
3918  SCIP_Real* rhss;
3919  SCIP_Real value;
3920 
3921  SCIP_VAR* var = NULL;
3922  const char* varname;
3923  const char** varnames;
3924 
3925  char valuestr[MPS_MAX_VALUELEN] = { '\0' };
3926 
3927  SCIP_CONS** consIndicator;
3928  SCIP_CONS** consSOS1;
3929  SCIP_CONS** consSOS2;
3930  SCIP_CONS** consQuadratic;
3931  int nConsIndicator;
3932  int nConsSOS1;
3933  int nConsSOS2;
3934  int nConsQuadratic;
3935 
3936  SCIP_HASHMAP* varnameHashmap; /* hash map from SCIP_VAR* to variable name */
3937  SPARSEMATRIX* matrix;
3938 
3939  SCIP_VAR** aggvars;
3940  int naggvars = 0;
3941  int saggvars;
3942  SCIP_HASHTABLE* varFixedHash;
3943  SCIP_HASHTABLE* indicatorSlackHash;
3944 
3945  SCIP_VAR** fixvars = NULL;
3946  int nfixvars = 0;
3947 
3948  SCIP_VAR** consvars;
3949  int nconsvars;
3950  SCIP_Real* vals;
3951  SCIP_Longint* weights;
3952 
3953  SCIP_Bool needRANGES;
3954  unsigned int maxnamelen;
3955 
3956  SCIP_Bool error;
3957 
3958  assert(reader != NULL);
3959  assert(strcmp(SCIPreaderGetName(reader), READER_NAME) == 0);
3960  assert(scip != NULL);
3961  assert(result != NULL);
3962 
3963  needRANGES = FALSE;
3964  maxnamelen = 0;
3965  nConsSOS1 = 0;
3966  nConsSOS2 = 0;
3967  nConsQuadratic = 0;
3968  nConsIndicator = 0;
3969 
3970  /* check if the constraint names are too long and build the constraint names */
3971  SCIP_CALL( checkConsnames(scip, conss, nconss, transformed, &maxnamelen, &consnames, &error) );
3972  if( error )
3973  {
3974  /* call writing with generic names */
3975  if( transformed )
3976  {
3977  SCIPwarningMessage(scip, "write transformed problem with generic variable and constraint names\n");
3978  SCIP_CALL( SCIPprintTransProblem(scip, file, "mps", TRUE) );
3979  }
3980  else
3981  {
3982  SCIPwarningMessage(scip, "write original problem with generic variable and constraint names\n");
3983  SCIP_CALL( SCIPprintOrigProblem(scip, file, "mps", TRUE) );
3984  }
3985  *result = SCIP_SUCCESS;
3986 
3987  return SCIP_OKAY;
3988  }
3989 
3990  /* check if the variable names are not too long and build the "variable" -> "variable name" hash map */
3991  SCIP_CALL( checkVarnames(scip, vars, nvars, &maxnamelen, &varnames, &varnameHashmap) );
3992 
3993  /* collect SOS, quadratic, and indicator constraints in array for later output */
3994  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS1, nconss) );
3995  SCIP_CALL( SCIPallocBufferArray(scip, &consSOS2, nconss) );
3996  SCIP_CALL( SCIPallocBufferArray(scip, &consQuadratic, nconss) );
3997  SCIP_CALL( SCIPallocBufferArray(scip, &consIndicator, nconss) );
3998 
3999  /* nfixedvars counts all variables with status SCIP_VARSTATUS_FIXED, SCIP_VARSTATUS_AGGREGATED, SCIP_VARSTATUS_MULTAGGR, but not SCIP_VARSTATUS_NEGATED */
4000  saggvars = nfixedvars;
4001  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &aggvars, saggvars) );
4002 
4003  /* create hashtable for storing aggregated variables */
4004  if( nfixedvars > 0 )
4005  {
4006  SCIP_CALL( SCIPhashtableCreate(&varFixedHash, SCIPblkmem(scip), nfixedvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
4007  }
4008  else
4009  varFixedHash = NULL;
4010 
4011  if( nvars > 0 )
4012  {
4013  SCIP_CALL( SCIPhashtableCreate(&indicatorSlackHash, SCIPblkmem(scip), nvars, hashGetKeyVar, hashKeyEqVar, hashKeyValVar, NULL) );
4014  }
4015  else
4016  indicatorSlackHash = NULL;
4017 
4018  /* initialize sparse matrix */
4019  SCIP_CALL( initializeMatrix(scip, &matrix, (nvars * 2 + nfixedvars)) );
4020  assert( matrix->sentries >= nvars );
4021 
4022  readerdata = SCIPreaderGetData(reader);
4023  assert(readerdata != NULL);
4024 
4025  naddrows = 0;
4026 
4027  /* determine and-constraints and printing format to resize necessary arrays */
4028  if( readerdata->linearizeands )
4029  {
4030  SCIP_CONSHDLR* andconshdlr = SCIPfindConshdlr(scip, "and");
4031 
4032  if( andconshdlr != NULL )
4033  {
4034  /* need to check for and-constraints, note that in the original problem you cannot get the number of
4035  * and-constraints by one call */
4036  for( c = nconss - 1; c >= 0; --c )
4037  {
4038  conshdlr = SCIPconsGetHdlr(conss[c]);
4039  assert(conshdlr != NULL);
4040 
4041  conshdlrname = SCIPconshdlrGetName(conshdlr);
4042 
4043  if( strcmp(conshdlrname, "and") == 0 )
4044  {
4045  if( readerdata->aggrlinearizationands )
4046  ++naddrows;
4047  else
4048  naddrows += SCIPgetNVarsAnd(scip, conss[c]);
4049  }
4050  }
4051  assert(naddrows >= 0);
4052 
4053  if( naddrows > 0 )
4054  {
4055  /* resize consnames vector */
4056  SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows) );
4057  }
4058  }
4059  }
4060 
4061  /* initialize rhs vector */
4062  SCIP_CALL( SCIPallocBufferArray(scip, &rhss, nconss + naddrows) );
4063 
4064  /* print statistics as comment to file stream */
4065  SCIPinfoMessage(scip, file, "* SCIP STATISTICS\n");
4066  SCIPinfoMessage(scip, file, "* Problem name : %s\n", name);
4067  SCIPinfoMessage(scip, file, "* Variables : %d (%d binary, %d integer, %d implicit integer, %d continuous)\n",
4068  nvars, nbinvars, nintvars, nimplvars, ncontvars);
4069  SCIPinfoMessage(scip, file, "* Constraints : %d\n", nconss);
4070 
4071  /* print NAME of the problem */
4072  SCIPinfoMessage(scip, file, "%-14s%s\n", "NAME", name);
4073 
4074  /* print OBJSENSE of the problem */
4075  SCIPinfoMessage(scip, file, "OBJSENSE\n");
4076  SCIPinfoMessage(scip, file, "%s\n", objsense == SCIP_OBJSENSE_MAXIMIZE ? " MAX" : " MIN");
4077 
4078  /* start ROWS section */
4079  SCIPinfoMessage(scip, file, "ROWS\n");
4080 
4081  /* print row type for the objective function */
4082  printStart(scip, file, "N", "Obj", -1);
4083  SCIPinfoMessage(scip, file, "\n");
4084 
4085  /* first fill the matrix with the objective coefficients */
4086  for( v = 0; v < nvars; ++v )
4087  {
4088  /* take care of the objective entry */
4089  var = vars[v];
4090  value = SCIPvarGetObj(var);
4091 
4092  /* we also want to add integer variables to the columns section, even if the objective value is 0, because it
4093  * might happen that they only exist in non-linear constraints, which leads to no other line in the column section
4094  * and therefore do not mark the variable as an integer
4095  */
4096  if( !SCIPisZero(scip, value) || SCIPvarGetType(var) < SCIP_VARTYPE_IMPLINT
4098  && (SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0)) )
4099  {
4100  assert( matrix->nentries < matrix->sentries );
4101 
4102  matrix->values[matrix->nentries] = objscale * value;
4103  matrix->columns[matrix->nentries] = var;
4104  matrix->rows[matrix->nentries] = "Obj";
4105  matrix->nentries++;
4106  }
4107  }
4108 
4109  /* loop over all constraints */
4110  k = nconss;
4111  for( c = 0; c < nconss; ++c )
4112  {
4113  cons = conss[c];
4114  assert( cons != NULL);
4115 
4116  /* in case the transformed problems is written only constraint are posted which are enabled in the current node;
4117  * the conss array should only contain relevant constraints
4118  */
4119  assert( !transformed || SCIPconsIsEnabled(cons) );
4120 
4121  conshdlr = SCIPconsGetHdlr(cons);
4122  assert( conshdlr != NULL );
4123 
4124  conshdlrname = SCIPconshdlrGetName(conshdlr);
4125 
4126  /* construct constraint name */
4127  consname = consnames[c];
4128 
4129  /* init rhs value to infinity (would then ignored) */
4130  rhss[c] = SCIPinfinity(scip);
4131 
4132  if( strcmp(conshdlrname, "linear") == 0 )
4133  {
4134  lhs = SCIPgetLhsLinear(scip, cons);
4135  rhs = SCIPgetRhsLinear(scip, cons);
4136 
4137  /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4138  if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4139  {
4140  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4141  needRANGES = TRUE;
4142 
4143  /* print row entry */
4144  printRowType(scip, file, lhs, rhs, consname);
4145 
4146  if( SCIPisInfinity(scip, rhs) )
4147  rhss[c] = lhs;
4148  else
4149  rhss[c] = rhs;
4150 
4151  assert( !SCIPisInfinity(scip, rhss[c]) );
4152 
4153  /* compute column entries */
4154  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLinear(scip, cons), SCIPgetValsLinear(scip, cons),
4155  SCIPgetNVarsLinear(scip, cons), transformed, matrix, &rhss[c]) );
4156  }
4157  }
4158  else if( strcmp(conshdlrname, "setppc") == 0 )
4159  {
4160  /* print row entry */
4161  switch( SCIPgetTypeSetppc(scip, cons) )
4162  {
4164  printRowType(scip, file, 1.0, 1.0, consname);
4165  break;
4167  printRowType(scip, file, -SCIPinfinity(scip), 1.0, consname);
4168  break;
4170  printRowType(scip, file, 1.0, SCIPinfinity(scip), consname);
4171  break;
4172  }
4173 
4174  rhss[c] = 1.0;
4175 
4176  /* compute column entries */
4177  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsSetppc(scip, cons), NULL, SCIPgetNVarsSetppc(scip, cons), transformed, matrix, &rhss[c]) );
4178  }
4179  else if( strcmp(conshdlrname, "logicor") == 0 )
4180  {
4181  /* print row entry */
4182  printRowType(scip, file, 1.0, SCIPinfinity(scip), consname);
4183 
4184  rhss[c] = 1.0;
4185 
4186  /* compute column entries */
4187  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsLogicor(scip, cons), NULL, SCIPgetNVarsLogicor(scip, cons), transformed, matrix, &rhss[c]) );
4188  }
4189  else if( strcmp(conshdlrname, "knapsack") == 0 )
4190  {
4191  int i;
4192 
4193  /* print row entry */
4194  printRowType(scip, file, -SCIPinfinity(scip), (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons), consname);
4195 
4196  nconsvars = SCIPgetNVarsKnapsack(scip, cons);
4197  weights = SCIPgetWeightsKnapsack(scip, cons);
4198 
4199  /* copy Longint array to SCIP_Real array */
4200  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nconsvars ) );
4201  for( i = 0; i < nconsvars; ++i )
4202  vals[i] = (SCIP_Real)weights[i];
4203 
4204  rhss[c] = (SCIP_Real) SCIPgetCapacityKnapsack(scip, cons);
4205 
4206  /* compute column entries */
4207  SCIP_CALL( getLinearCoeffs(scip, consname, SCIPgetVarsKnapsack(scip, cons), vals, nconsvars, transformed, matrix, &rhss[c]) );
4208 
4209  SCIPfreeBufferArray(scip, &vals);
4210  }
4211  else if( strcmp(conshdlrname, "varbound") == 0 )
4212  {
4213  lhs = SCIPgetLhsVarbound(scip, cons);
4214  rhs = SCIPgetRhsVarbound(scip, cons);
4215 
4216  /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4217  if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4218  {
4219  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4220  needRANGES = TRUE;
4221 
4222  /* print row entry */
4223  printRowType(scip, file, lhs, rhs, consname);
4224 
4225  /* allocate memory */
4226  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, 2) );
4227  SCIP_CALL( SCIPallocBufferArray(scip, &vals, 2) );
4228 
4229  consvars[0] = SCIPgetVarVarbound(scip, cons);
4230  consvars[1] = SCIPgetVbdvarVarbound(scip, cons);
4231 
4232  vals[0] = 1.0;
4233  vals[1] = SCIPgetVbdcoefVarbound(scip, cons);
4234 
4235  if( SCIPisInfinity(scip, rhs) )
4236  rhss[c] = lhs;
4237  else
4238  rhss[c] = rhs;
4239 
4240  assert( !SCIPisInfinity(scip, rhss[c]) );
4241 
4242  /* compute column entries */
4243  SCIP_CALL( getLinearCoeffs(scip, consname, consvars, vals, 2, transformed, matrix, &rhss[c]) );
4244 
4245  SCIPfreeBufferArray(scip, &vals);
4246  SCIPfreeBufferArray(scip, &consvars);
4247  }
4248  }
4249  else if( strcmp(conshdlrname, "indicator") == 0 )
4250  {
4251  SCIP_VAR* slackvar;
4252  SCIP_VAR* binvar;
4253 
4254  /* store slack variable in hash */
4255  slackvar = SCIPgetSlackVarIndicator(cons);
4256  assert( slackvar != NULL );
4257  assert( indicatorSlackHash != NULL );
4258  assert( !SCIPhashtableExists(indicatorSlackHash, (void*) slackvar) );
4259  SCIP_CALL( SCIPhashtableInsert(indicatorSlackHash, (void*) slackvar) );
4260 
4261  /* if slackvariable is aggregated, we store it in the list of aggregated variables */
4262  if ( SCIPvarGetStatus(slackvar) == SCIP_VARSTATUS_AGGREGATED )
4263  {
4264  SCIP_CALL( collectAggregatedVars(scip, &slackvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4265  }
4266 
4267  /* store aggregated variables */
4268  binvar = SCIPgetBinaryVarIndicator(cons);
4269  if( SCIPvarIsNegated(binvar) )
4270  binvar = SCIPvarGetNegatedVar(binvar);
4271  assert( binvar != NULL );
4272  SCIP_CALL( collectAggregatedVars(scip, &binvar, 1, &aggvars, &naggvars, &saggvars, varFixedHash) );
4273 
4274  /* indicator constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4275  rhss[c] = SCIPinfinity(scip);
4276 
4277  /* store constraint */
4278  consIndicator[nConsIndicator++] = cons;
4279  continue;
4280  }
4281  else if( strcmp(conshdlrname, "SOS1") == 0 )
4282  {
4283  /* store constraint */
4284  consSOS1[nConsSOS1++] = cons;
4285 
4286  /* check for aggregated variables in SOS1 constraints for later output
4287  * of aggregations as linear constraints */
4288  consvars = SCIPgetVarsSOS1(scip, cons);
4289  nconsvars = SCIPgetNVarsSOS1(scip, cons);
4290 
4291  /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4292  rhss[c] = SCIPinfinity(scip);
4293 
4294  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4295  }
4296  else if( strcmp(conshdlrname, "SOS2") == 0 )
4297  {
4298  /* store constraint */
4299  consSOS2[nConsSOS2++] = cons;
4300 
4301  /* check for aggregated variables in SOS2 constraints for later output aggregations as linear constraints */
4302  consvars = SCIPgetVarsSOS2(scip, cons);
4303  nconsvars = SCIPgetNVarsSOS2(scip, cons);
4304 
4305  /* SOS constraint do not have a right hand side; mark this with SCIPinfinity(scip) */
4306  rhss[c] = SCIPinfinity(scip);
4307 
4308  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4309  }
4310  else if( strcmp(conshdlrname, "nonlinear") == 0 )
4311  {
4312  SCIP_EXPR* expr;
4313  SCIP_VAR** quadvars;
4314  SCIP_Real* quadvarlincoefs;
4315  SCIP_Real* lincoefs;
4316  SCIP_Real constant;
4317  SCIP_EXPR** linexprs;
4318  SCIP_Bool isquadratic;
4319  int nquadexprs;
4320  int nlinexprs;
4321  int j;
4322 
4323  /* check if it is a quadratic constraint */
4324  SCIP_CALL( SCIPcheckQuadraticNonlinear(scip, cons, &isquadratic) );
4325  if( !isquadratic )
4326  {
4327  /* unknown constraint type; mark this with SCIPinfinity(scip) */
4328  rhss[c] = SCIPinfinity(scip);
4329 
4330  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4331  continue;
4332  }
4333 
4334  /* store constraint */
4335  consQuadratic[nConsQuadratic++] = cons;
4336 
4337  expr = SCIPgetExprNonlinear(cons);
4338 
4339  /* collect linear coefficients of quadratic part */
4340  SCIPexprGetQuadraticData(expr, &constant, &nlinexprs, &linexprs, &lincoefs, &nquadexprs, NULL, NULL,
4341  NULL);
4342 
4343  SCIP_CALL( SCIPallocBufferArray(scip, &quadvars, nquadexprs) );
4344  SCIP_CALL( SCIPallocBufferArray(scip, &quadvarlincoefs, nquadexprs) );
4345  for( j = 0; j < nquadexprs; ++j )
4346  {
4347  SCIP_EXPR* qexpr;
4348 
4349  SCIPexprGetQuadraticQuadTerm(expr, j, &qexpr, &quadvarlincoefs[j], NULL, NULL, NULL, NULL);
4350 
4351  assert(SCIPisExprVar(scip, qexpr));
4352  quadvars[j] = SCIPgetVarExprVar(qexpr);
4353  }
4354 
4355  lhs = SCIPgetLhsNonlinear(cons);
4356  rhs = SCIPgetRhsNonlinear(cons);
4357 
4358  /* correct side by constant */
4359  lhs -= SCIPisInfinity(scip, -lhs) ? 0.0 : constant;
4360  rhs -= SCIPisInfinity(scip, rhs) ? 0.0 : constant;
4361 
4362  /* there is nothing to do if the left hand side is minus infinity and the right side is infinity */
4363  if( !SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs) )
4364  {
4365  SCIP_VAR** linvars;
4366 
4367  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
4368  needRANGES = TRUE;
4369 
4370  /* print row entry */
4371  printRowType(scip, file, lhs, rhs, consname);
4372 
4373  if( SCIPisInfinity(scip, rhs) )
4374  rhss[c] = lhs;
4375  else
4376  rhss[c] = rhs;
4377 
4378  assert( !SCIPisInfinity(scip, rhss[c]) );
4379 
4380  /* get linear vars */
4381  SCIP_CALL( SCIPallocBufferArray(scip, &linvars, nlinexprs) );
4382  for( j = 0; j < nlinexprs; ++j )
4383  linvars[j] = SCIPgetVarExprVar(linexprs[j]);
4384 
4385  /* compute column entries for linear part */
4386  SCIP_CALL( getLinearCoeffs(scip, consname, linvars, lincoefs, nlinexprs, transformed, matrix, &rhss[c]) );
4387 
4388  /* compute column entries for linear part in quadratic part */
4389  SCIP_CALL( getLinearCoeffs(scip, consname, quadvars, quadvarlincoefs, nquadexprs, transformed, matrix,
4390  &rhss[c]) );
4391 
4392  SCIPfreeBufferArray(scip, &linvars);
4393  }
4394 
4395  /* check for aggregated variables in quadratic part of quadratic constraints for later output of
4396  * aggregations as linear constraints */
4397  consvars = quadvars;
4398  nconsvars = nquadexprs;
4399 
4400  SCIP_CALL( collectAggregatedVars(scip, consvars, nconsvars, &aggvars, &naggvars, &saggvars, varFixedHash) );
4401 
4402  SCIPfreeBufferArray(scip, &quadvars);
4403  SCIPfreeBufferArray(scip, &quadvarlincoefs);
4404  }
4405  else if( strcmp(conshdlrname, "and") == 0 )
4406  {
4407  if( readerdata->linearizeands )
4408  {
4409  SCIP_VAR** rowvars;
4410  SCIP_VAR** operands;
4411  SCIP_VAR* resultant;
4412  SCIP_Real* rowvals;
4413  char* rowname;
4414  int nrowvars;
4415  int l;
4416  int n;
4417 
4418  nrowvars = SCIPgetNVarsAnd(scip, cons);
4419  operands = SCIPgetVarsAnd(scip, cons);
4420  resultant = SCIPgetResultantAnd(scip, cons);
4421 
4422  /* allocate buffer array */
4423  SCIP_CALL( SCIPallocBufferArray(scip, &rowvars, nrowvars + 1) );
4424  SCIP_CALL( SCIPallocBufferArray(scip, &rowvals, nrowvars + 1) );
4425 
4426  /* get length of constraint name */
4427  l = (int) strlen(consname);
4428 
4429  /* the tight relaxtion, number of and-constraint operands rows */
4430  if( !readerdata->aggrlinearizationands )
4431  {
4432  rowvars[0] = resultant;
4433  rowvals[0] = 1.0;
4434  rowvals[1] = -1.0;
4435 
4436  /* compute maximal length for rowname */
4437  /* coverity[negative_returns] */
4438  n = (int) log10((double)nrowvars) + 1 + l;
4439 
4440  /* assure maximal allowed value */
4441  if( n >= MPS_MAX_NAMELEN )
4442  n = MPS_MAX_NAMELEN - 1;
4443 
4444  /* update maxnamelen */
4445  maxnamelen = MAX(maxnamelen, (unsigned int) n);
4446 
4447  /* print operator rows */
4448  for( v = 0; v < nrowvars; ++v )
4449  {
4450  /* compute maximal length for rowname */
4451  if( v == 0 )
4452  n = 2;
4453  else
4454  n = (int) log10((double)v) + 2;
4455  n += l;
4456 
4457  /* assure maximal allowed value */
4458  if( n >= MPS_MAX_NAMELEN )
4459  {
4460  n = MPS_MAX_NAMELEN - 1;
4461  ++faulty;
4462  }
4463 
4464  /* need memory for additional row */
4465  SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4466 
4467  assert(k < nconss + naddrows);
4468  consnames[k] = rowname;
4469 
4470  (void) SCIPsnprintf(rowname, n + 1, "%s_%d", consname, v);
4471  rowvars[1] = operands[v];
4472 
4473  /* print row entry */
4474  printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4475 
4476  rhss[k] = 0.0;
4477 
4478  /* compute column entries */
4479  SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, 2, transformed, matrix, &rhss[k]) );
4480  ++k;
4481  }
4482  }
4483 
4484  /* prepare for next row */
4485  for( v = nrowvars - 1; v >= 0; --v )
4486  {
4487  rowvars[v] = operands[v];
4488  rowvals[v] = -1.0;
4489  }
4490 
4491  rowvars[nrowvars] = resultant;
4492 
4493  /* the weak relaxtion, only one constraint */
4494  if( readerdata->aggrlinearizationands )
4495  {
4496  /* compute maximal length for rowname */
4497  n = l + 3;
4498 
4499  /* assure maximal allowed value */
4500  if( n >= MPS_MAX_NAMELEN )
4501  {
4502  n = MPS_MAX_NAMELEN - 1;
4503  ++faulty;
4504  }
4505 
4506  /* update maxnamelen */
4507  maxnamelen = MAX(maxnamelen, (unsigned int) n);
4508 
4509  /* need memory for additional row */
4510  SCIP_CALL( SCIPallocBufferArray(scip, &rowname, n + 1) );
4511 
4512  assert(k < nconss + naddrows);
4513  consnames[k] = rowname;
4514 
4515  /* adjust rowname of constraint */
4516  (void) SCIPsnprintf(rowname, n + 1, "%s_op", consname);
4517 
4518  rowvals[nrowvars] = (SCIP_Real) nrowvars;
4519 
4520  /* print row entry */
4521  printRowType(scip, file, -SCIPinfinity(scip), 0.0, rowname);
4522 
4523  rhss[k] = 0.0;
4524 
4525  /* compute column entries */
4526  SCIP_CALL( getLinearCoeffs(scip, rowname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[k]) );
4527 
4528  SCIPdebugMsg(scip, "%g, %g\n", rowvals[1], rhss[k]);
4529  ++k;
4530  }
4531 
4532  rowvals[nrowvars] = 1.0;
4533 
4534  /* print row entry */
4535  printRowType(scip, file, -nrowvars + 1.0, SCIPinfinity(scip), consname);
4536 
4537  rhss[c] = -nrowvars + 1.0;
4538 
4539  /* compute column entries */
4540  SCIP_CALL( getLinearCoeffs(scip, consname, rowvars, rowvals, nrowvars + 1, transformed, matrix, &rhss[c]) );
4541 
4542  /* free buffer array */
4543  SCIPfreeBufferArray(scip, &rowvals);
4544  SCIPfreeBufferArray(scip, &rowvars);
4545  }
4546  else
4547  {
4548  /* and constraint printing not enabled; mark this with SCIPinfinity(scip) */
4549  rhss[c] = SCIPinfinity(scip);
4550 
4551  SCIPwarningMessage(scip, "change parameter \"reading/" READER_NAME "/linearize-and-constraints\" to TRUE to print and-constraints\n");
4552  }
4553  }
4554  else
4555  {
4556  /* unknown constraint type; mark this with SCIPinfinity(scip) */
4557  rhss[c] = SCIPinfinity(scip);
4558 
4559  SCIPwarningMessage(scip, "constraint handler <%s> cannot print requested format\n", conshdlrname );
4560  }
4561  }
4562 
4563  if( faulty > 0 )
4564  {
4565  SCIPwarningMessage(scip, "there are %d and-constraint-rownames which have to be cut down to %d characters; MPS file might be corrupted\n",
4566  faulty, MPS_MAX_NAMELEN - 1);
4567  }
4568 
4569  /* free hash table */
4570  if( varFixedHash != NULL )
4571  SCIPhashtableFree(&varFixedHash);
4572 
4573  if( indicatorSlackHash != NULL && nConsIndicator == 0 )
4574  {
4575  SCIPhashtableFree(&indicatorSlackHash);
4576  assert( indicatorSlackHash == NULL );
4577  }
4578 
4579  if( naggvars > 0 )
4580  {
4581  /* construct variables name of the needed aggregated variables and the constraint names for the aggregation constraints */
4582 
4583  /* realloc memory */
4584  SCIP_CALL( SCIPreallocBufferArray(scip, &consnames, nconss + naddrows + naggvars) );
4585  SCIP_CALL( SCIPreallocBufferArray(scip, &rhss, nconss + naddrows + naggvars) );
4586  SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, nvars + naggvars) );
4587 
4588  for( c = 0; c < naggvars; ++c )
4589  {
4590  size_t l;
4591 
4592  /* create variable name */
4593  var = aggvars[c];
4594 
4595  l = strlen(SCIPvarGetName(var));
4596  if( l >= MPS_MAX_NAMELEN )
4597  maxnamelen = MPS_MAX_NAMELEN - 1;
4598  else
4599  maxnamelen = MAX(maxnamelen, (unsigned int) l);
4600 
4601  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4602  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4603 
4604  /* insert variable with variable name into hash map */
4605  varnames[nvars + c] = namestr;
4606  assert( !SCIPhashmapExists(varnameHashmap, var) );
4607  SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4608 
4609  /* output row type (it is an equation) */
4610  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) ); /* note that namestr above is freed via varnames */
4611  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(var));
4612  printRowType(scip, file, 1.0, 1.0, namestr);
4613 
4614  l = strlen(namestr);
4615  maxnamelen = MAX(maxnamelen, (unsigned int) l);
4616  consnames[nconss + naddrows + c] = namestr;
4617  rhss[nconss + naddrows + c] = 0.0;
4618 
4619  /* compute column entries */
4620  SCIP_CALL( getLinearCoeffs(scip, namestr, &(aggvars[c]), NULL, 1, transformed, matrix, &rhss[nconss + naddrows + c]) );
4621 
4622  /* add the aggregated variables to the sparse matrix */
4623  SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, 1) );
4624  matrix->values[matrix->nentries] = -1.0;
4625  matrix->columns[matrix->nentries] = aggvars[c];
4626  matrix->rows[matrix->nentries] = namestr;
4627  matrix->nentries++;
4628  }
4629  }
4630 
4631  /* collect also fixed variables, because they might not be removed from all constraints */
4632  /* @todo only collect fixed variables in the non-linear constraint types, where they (could not be)/(were not) removed */
4633  if( nfixedvars > 0 )
4634  {
4635  int startpos = nvars + naggvars;
4636  /* construct variables name of fixed variables */
4637 
4638  /* realloc memory */
4639  SCIP_CALL( SCIPreallocBufferArray(scip, &varnames, startpos + nfixedvars) );
4640 
4641  /* allocate memory for fixed variables */
4642  SCIP_CALL( SCIPallocBufferArray(scip, &fixvars, nfixedvars) );
4643 
4644  for( v = nfixedvars - 1; v >= 0; --v )
4645  {
4646  /* create variable name */
4647  var = fixedvars[v];
4648 
4650  {
4651  size_t l;
4652  l = strlen(SCIPvarGetName(var));
4653  if( l >= MPS_MAX_NAMELEN )
4654  maxnamelen = MPS_MAX_NAMELEN - 1;
4655  else
4656  maxnamelen = MAX(maxnamelen, (unsigned int) l);
4657 
4658  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4659  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPvarGetName(var) );
4660 
4661  varnames[startpos + nfixvars] = namestr;
4662  fixvars[nfixvars] = var;
4663  ++nfixvars;
4664 
4665  /* insert variable with variable name into hash map */
4666  assert(!SCIPhashmapExists(varnameHashmap, var));
4667  SCIP_CALL( SCIPhashmapInsert(varnameHashmap, var, (void*) namestr) );
4668 
4669  /* add the fixed variables to the sparse matrix, needed for columns section */
4670  SCIP_CALL( checkSparseMatrixCapacity(scip, matrix, 1) );
4671  matrix->values[matrix->nentries] = 0.0;
4672  matrix->columns[matrix->nentries] = var;
4673  matrix->rows[matrix->nentries] = "Obj";
4674  matrix->nentries++;
4675  }
4676  }
4677  }
4678 
4679  /* output COLUMNS section */
4680  printColumnSection(scip, file, matrix, varnameHashmap, indicatorSlackHash, maxnamelen);
4681 
4682  /* output RHS section */
4683  printRhsSection(scip, file, nconss + naddrows +naggvars, consnames, rhss, maxnamelen, objscale * objoffset);
4684 
4685  /* output RANGES section */
4686  if( needRANGES )
4687  printRangeSection(scip, file, conss, nconss, consnames, transformed, maxnamelen);
4688 
4689  /* output BOUNDS section */
4690  printBoundSection(scip, file, vars, nvars, aggvars, naggvars, fixvars, nfixvars, transformed, varnames, indicatorSlackHash, maxnamelen);
4691 
4692  if( nfixedvars > 0 )
4693  {
4694  SCIPfreeBufferArray(scip, &fixvars);
4695  }
4696 
4697  /* print SOS section */
4698  if( nConsSOS1 > 0 || nConsSOS2 > 0 )
4699  {
4700  SCIP_Real* sosweights;
4701 
4702  SCIPinfoMessage(scip, file, "SOS\n");
4703  SCIPdebugMsg(scip, "start printing SOS section\n");
4704 
4705  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4706 
4707  /* first output SOS1 constraints */
4708  for( c = 0; c < nConsSOS1; ++c )
4709  {
4710  cons = consSOS1[c];
4711  consvars = SCIPgetVarsSOS1(scip, cons);
4712  nconsvars = SCIPgetNVarsSOS1(scip, cons);
4713  sosweights = SCIPgetWeightsSOS1(scip, cons);
4714  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4715 
4716  printStart(scip, file, "S1", namestr, -1);
4717  SCIPinfoMessage(scip, file, "\n");
4718 
4719  for( v = 0; v < nconsvars; ++v )
4720  {
4721  /* get variable name */
4722  assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4723  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4724 
4725  printStart(scip, file, "", varname, (int) maxnamelen);
4726 
4727  if( sosweights != NULL )
4728  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4729  else
4730  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4731 
4732  SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4733  }
4734  }
4735 
4736  /* next output SOS2 constraints */
4737  for( c = 0; c < nConsSOS2; ++c )
4738  {
4739  cons = consSOS2[c];
4740  consvars = SCIPgetVarsSOS2(scip, cons);
4741  nconsvars = SCIPgetNVarsSOS2(scip, cons);
4742  sosweights = SCIPgetWeightsSOS2(scip, cons);
4743  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4744 
4745  printStart(scip, file, "S2", namestr, -1);
4746  SCIPinfoMessage(scip, file, "\n");
4747 
4748  for( v = 0; v < nconsvars; ++v )
4749  {
4750  /* get variable name */
4751  assert ( SCIPhashmapExists(varnameHashmap, consvars[v]) );
4752  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, consvars[v]);
4753 
4754  printStart(scip, file, "", varname, (int) maxnamelen);
4755 
4756  if( sosweights != NULL )
4757  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sosweights[v]);
4758  else
4759  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d ", v);
4760 
4761  SCIPinfoMessage(scip, file, "%25s\n", valuestr);
4762  }
4763  }
4764  SCIPfreeBufferArray(scip, &namestr);
4765  }
4766 
4767  /* print QCMATRIX sections for quadratic constraints
4768  * in difference to a quadratic term in the objective function, the quadratic part is not divided by 2 here
4769  */
4770  if( nConsQuadratic > 0 )
4771  {
4772  const char* varname2;
4773  int nbilin;
4774 
4775  SCIPdebugMsg(scip, "start printing QCMATRIX sections for quadratic constraints\n");
4776  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4777 
4778  for( c = 0; c < nConsQuadratic; ++c )
4779  {
4780  SCIP_EXPR* expr;
4781 
4782  cons = consQuadratic[c];
4783  expr = SCIPgetExprNonlinear(cons);
4784 
4785  SCIPexprGetQuadraticData(expr, NULL, NULL, NULL, NULL, &nconsvars, &nbilin, NULL, NULL);
4786 
4787  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "%s", SCIPconsGetName(cons) );
4788 
4789  SCIPinfoMessage(scip, file, "QCMATRIX %s\n", namestr);
4790 
4791  /* print x^2 terms */
4792  for( v = 0; v < nconsvars; ++v )
4793  {
4794  SCIP_EXPR* qexpr;
4795  SCIP_VAR* qvar;
4796  SCIP_Real sqrcoef;
4797 
4798  SCIPexprGetQuadraticQuadTerm(expr, v, &qexpr, NULL, &sqrcoef, NULL, NULL, NULL);
4799  if( sqrcoef == 0.0 )
4800  continue;
4801 
4802  assert(SCIPisExprVar(scip, qexpr));
4803  qvar = SCIPgetVarExprVar(qexpr);
4804 
4805  /* get variable name */
4806  assert(SCIPhashmapExists(varnameHashmap, qvar));
4807  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, qvar);
4808 
4809  /* get coefficient as string */
4810  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", sqrcoef);
4811 
4812  /* print "x x coeff" line */
4813  printStart(scip, file, "", varname, (int) maxnamelen);
4814  printRecord(scip, file, varname, valuestr, maxnamelen);
4815  SCIPinfoMessage(scip, file, "\n");
4816  }
4817 
4818  /* print bilinear terms; CPLEX format expects a symmetric matrix with all coefficients specified,
4819  * i.e., we have to split bilinear coefficients into two off diagonal elements */
4820  for( v = 0; v < nbilin; ++v )
4821  {
4822  SCIP_EXPR* expr1;
4823  SCIP_EXPR* expr2;
4824  SCIP_VAR* var1;
4825  SCIP_VAR* var2;
4826  SCIP_Real coef;
4827 
4828  SCIPexprGetQuadraticBilinTerm(expr, v, &expr1, &expr2, &coef, NULL, NULL);
4829  assert(SCIPisExprVar(scip, expr1));
4830  assert(SCIPisExprVar(scip, expr2));
4831 
4832  if( coef == 0.0 )
4833  continue;
4834 
4835  var1 = SCIPgetVarExprVar(expr1);
4836  var2 = SCIPgetVarExprVar(expr2);
4837 
4838  /* get name of first variable */
4839  assert ( SCIPhashmapExists(varnameHashmap, var1) );
4840  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, var1);
4841 
4842  /* get name of second variable */
4843  assert ( SCIPhashmapExists(varnameHashmap, var2) );
4844  varname2 = (const char*) SCIPhashmapGetImage(varnameHashmap, var2);
4845 
4846  /* get coefficient as string */
4847  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25.15g", 0.5*coef);
4848 
4849  /* print "x y coeff/2" line */
4850  printStart(scip, file, "", varname, (int) maxnamelen);
4851  printRecord(scip, file, varname2, valuestr, maxnamelen);
4852  SCIPinfoMessage(scip, file, "\n");
4853 
4854  /* print "y x coeff/2" line */
4855  printStart(scip, file, "", varname2, (int) maxnamelen);
4856  printRecord(scip, file, varname, valuestr, maxnamelen);
4857  SCIPinfoMessage(scip, file, "\n");
4858  }
4859  }
4860 
4861  SCIPfreeBufferArray(scip, &namestr);
4862  }
4863 
4864  /* print indicator section */
4865  if( nConsIndicator > 0 )
4866  {
4867  SCIP_CALL( SCIPallocBufferArray(scip, &namestr, MPS_MAX_NAMELEN) );
4868 
4869  SCIPinfoMessage(scip, file, "INDICATORS\n");
4870  SCIPdebugMsg(scip, "start printing INDICATOR section\n");
4871 
4872  /* output each indicator constraint */
4873  for( c = 0; c < nConsIndicator; ++c )
4874  {
4875  SCIP_CONS* lincons;
4876  SCIP_VAR* slackvar;
4877  SCIP_VAR* binvar;
4878 
4879  cons = consIndicator[c];
4880  binvar = SCIPgetBinaryVarIndicator(cons);
4881  lincons = SCIPgetLinearConsIndicator(cons);
4882  slackvar = SCIPgetSlackVarIndicator(cons);
4883 
4884  /* linvars always contains slack variable, thus nlinvars >= 1 */
4885  if( SCIPgetNVarsLinear(scip, lincons) <= 1 || SCIPconsIsDeleted(lincons) )
4886  continue;
4887 
4888  /* create variable and value strings */
4889  if( SCIPvarIsNegated(binvar) )
4890  {
4891  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 0);
4892  assert( SCIPvarGetNegatedVar(binvar) != NULL );
4893  assert( SCIPhashmapExists(varnameHashmap, SCIPvarGetNegatedVar(binvar)) );
4894  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, SCIPvarGetNegatedVar(binvar));
4895  }
4896  else
4897  {
4898  (void) SCIPsnprintf(valuestr, MPS_MAX_VALUELEN, "%25d", 1);
4899  assert ( SCIPhashmapExists(varnameHashmap, binvar) );
4900  varname = (const char*) SCIPhashmapGetImage(varnameHashmap, binvar);
4901  }
4902 
4903  /* write records */
4904  if ( SCIPvarGetStatus(slackvar) == SCIP_VARSTATUS_AGGREGATED )
4905  {
4906  /* for aggregated variables output name of aggregating constraint */
4907  (void) SCIPsnprintf(namestr, MPS_MAX_NAMELEN, "aggr_%s", SCIPvarGetName(slackvar));
4908  printStart(scip, file, "IF", namestr, (int) maxnamelen);
4909  printRecord(scip, file, varname, valuestr, maxnamelen);
4910  SCIPinfoMessage(scip, file, "\n");
4911  }
4912  else
4913  {
4914  printStart(scip, file, "IF", SCIPconsGetName(lincons), (int) maxnamelen);
4915  printRecord(scip, file, varname, valuestr, maxnamelen);
4916  SCIPinfoMessage(scip, file, "\n");
4917  }
4918  }
4919  SCIPfreeBufferArray(scip, &namestr);
4920  }
4921 
4922  /* free matrix data structure */
4923  freeMatrix(scip, matrix);
4924 
4925  /* free slackvar hashtable */
4926  if( indicatorSlackHash != NULL )
4927  SCIPhashtableFree(&indicatorSlackHash);
4928 
4929  /* free variable hashmap */
4930  SCIPhashmapFree(&varnameHashmap);
4931 
4932  SCIPfreeBlockMemoryArray(scip, &aggvars, saggvars);
4933  SCIPfreeBufferArray(scip, &rhss);
4934 
4935  /* free buffer arrays for SOS1, SOS2, and quadratic */
4936  SCIPfreeBufferArray(scip, &consIndicator);
4937  SCIPfreeBufferArray(scip, &consQuadratic);
4938  SCIPfreeBufferArray(scip, &consSOS2);
4939  SCIPfreeBufferArray(scip, &consSOS1);
4940 
4941  /* free variable and constraint name array */
4942  for( v = nvars + naggvars + nfixvars - 1; v >= 0; --v )
4943  SCIPfreeBufferArray(scip, &varnames[v]);
4944  SCIPfreeBufferArray(scip, &varnames);
4945 
4946  for( c = nconss + naddrows + naggvars - 1; c >= 0; --c )
4947  SCIPfreeBufferArray(scip, &consnames[c]);
4948  SCIPfreeBufferArray(scip, &consnames);
4949 
4950  /* print end of data line */
4951  SCIPinfoMessage(scip, file, "ENDATA");
4952 
4953  *result = SCIP_SUCCESS;
4954 
4955  return SCIP_OKAY;
4956 }
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:3046
#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:4060
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
#define READER_DESC
Definition: reader_mps.c:79
static SCIP_DECL_READERCOPY(readerCopyMps)
Definition: reader_mps.c:3747
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8187
int SCIPmemccpy(char *dest, const char *src, char stop, unsigned int cnt)
Definition: misc.c:10655
#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:2698
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8349
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:3408
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:10639
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2497
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:886
int SCIPgetNVarsSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9415
#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:17901
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:3484
#define SCIP_MAXSTRLEN
Definition: def.h:302
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:2482
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17957
static SCIP_RETCODE checkSparseMatrixCapacity(SCIP *scip, SPARSEMATRIX *matrix, int capacity)
Definition: reader_mps.c:2910
SCIP_Real * SCIPgetWeightsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10664
static SCIP_DECL_READERFREE(readerFreeMps)
Definition: reader_mps.c:3763
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:1248
constraint handler for indicator constraints
static SCIP_DECL_HASHKEYVAL(hashKeyValVar)
Definition: reader_mps.c:2736
static void printColumnSection(SCIP *scip, FILE *file, SPARSEMATRIX *matrix, SCIP_HASHMAP *varnameHashmap, SCIP_HASHTABLE *indicatorSlackHash, unsigned int maxnamelen)
Definition: reader_mps.c:3273
#define FALSE
Definition: def.h:96
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3024
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10788
#define TRUE
Definition: def.h:95
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:57
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:3878
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:2533
SCIP_RETCODE SCIPchgVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4676
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3211
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:8359
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:2246
public methods for querying solving statistics
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17717
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:3373
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:8176
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:17911
#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:5151
#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:2816
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:4182
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_Real SCIPvarGetLbOriginal(SCIP_VAR *var)
Definition: var.c:17847
SCIP_VAR * SCIPgetResultantAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5176
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:2558
SCIP_RETCODE SCIPaddVarSOS1(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real weight)
Definition: cons_sos1.c:10547
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:17867
#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:8090
SCIP_RETCODE SCIPchgVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip_var.c:4766
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:8309
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:17242
#define DEFAULT_LINEARIZE_ANDS
Definition: reader_mps.c:82
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3058
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:3365
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:4105
SCIP_RETCODE SCIPprintOrigProblem(SCIP *scip, FILE *file, const char *extension, SCIP_Bool genericnames)
#define NULL
Definition: lpi_spx1.cpp:164
#define REALABS(x)
Definition: def.h:210
#define SCIP_CALL(x)
Definition: def.h:394
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:1738
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:8329
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:4513
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:93
SCIP_RETCODE SCIPcreateConsIndicatorLinCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *lincons, SCIP_VAR *slackvar, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
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:10680
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:2756
static const char * mpsinputField5(const MPSINPUT *mpsi)
Definition: reader_mps.c:287
SCIP_SETPPCTYPE SCIPgetTypeSetppc(SCIP *scip, SCIP_CONS *cons)
Definition: cons_setppc.c:9461
constraint handler for nonlinear constraints specified by algebraic expressions
SCIP_Real * SCIPgetWeightsSOS2(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos2.c:2583
static MPSSECTION mpsinputSection(const MPSINPUT *mpsi)
Definition: reader_mps.c:221
#define MAX(x, y)
Definition: tclique_def.h:92
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8110
#define MPS_MAX_NAMELEN
Definition: reader_mps.c:90
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8219
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8289
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8259
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17749
static SCIP_RETCODE readObjsen(SCIP *scip, MPSINPUT *mpsi)
Definition: reader_mps.c:769
int SCIPgetNVarsSOS1(SCIP *scip, SCIP_CONS *cons)
Definition: cons_sos1.c:10614
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:3842
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:2854
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:2558
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:12764
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:9438
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2296
#define SCIP_HASHSIZE_NAMES
Definition: def.h:313
static unsigned int computeFieldWidth(unsigned int width)
Definition: reader_mps.c:2745
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
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_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
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:3103
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:3791
static void freeMatrix(SCIP *scip, SPARSEMATRIX *matrix)
Definition: reader_mps.c:2928
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1119
public methods for message output
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1421
void SCIPexprGetQuadraticBilinTerm(SCIP_EXPR *expr, int termidx, SCIP_EXPR **expr1, SCIP_EXPR **expr2, SCIP_Real *coef, int *pos2, SCIP_EXPR **prodexpr)
Definition: expr.c:4145
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17361
static SCIP_RETCODE mpsinputCreate(SCIP *scip, MPSINPUT **mpsi, SCIP_FILE *fp)
Definition: reader_mps.c:173
#define SCIP_Real
Definition: def.h:186
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8339
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:415
int SCIPgetNVarsAnd(SCIP *scip, SCIP_CONS *cons)
Definition: cons_and.c:5127
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:2892
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:8279
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8269
SCIP_RETCODE SCIPsetReaderRead(SCIP *scip, SCIP_READER *reader, SCIP_DECL_READERREAD((*readerread)))
Definition: scip_reader.c:195
#define SCIP_Longint
Definition: def.h:171
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17581
static void printBoundSectionName(SCIP *scip, FILE *file)
Definition: reader_mps.c:3473
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17407
SCIP_Bool SCIPhashtableExists(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2609
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:3167
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:10410
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:2383
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:17967
static SCIP_DECL_HASHKEYEQ(hashKeyEqString)
Definition: reader_mps.c:2710
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:3106
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:2782
SCIP_CONS * SCIPgetLinearConsIndicator(SCIP_CONS *cons)
SCIP_Longint * SCIPgetWeightsKnapsack(SCIP *scip, SCIP_CONS *cons)
public methods for reader plugins
#define SCIPABORT()
Definition: def.h:366
public methods for global and local (sub)problems
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17433
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition: misc.c:10729
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:3778
SCIP_RETCODE SCIPincludeReaderMps(SCIP *scip)
Definition: reader_mps.c:3808
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
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:2943
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:2584
(extended) MPS file reader
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17397
#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