Scippy

SCIP

Solving Constraint Integer Programs

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