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