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