Scippy

SoPlex

Sequential object-oriented simPlex

spxlpbase_real.cpp
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file spxlpbase_real.cpp
17  * @brief Saving LPs with Real values in a form suitable for SoPlex.
18  */
19 
20 #include <assert.h>
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <iostream>
24 
25 #include "spxdefines.h"
26 #include "spxlpbase.h"
27 #include "spxout.h"
28 #include "mpsinput.h"
29 #include "exceptions.h"
30 
31 namespace soplex
32 {
33 // ---------------------------------------------------------------------------------------------------------------------
34 // Specialization for reading LP format
35 // ---------------------------------------------------------------------------------------------------------------------
36 
37 #define LPF_MAX_LINE_LEN 8192 ///< maximum length of a line (8190 + \\n + \\0)
38 
39 /// Is \p c a \c space, \c tab, \c nl or \c cr ?
40 static inline bool LPFisSpace(int c)
41 {
42  return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
43 }
44 
45 
46 
47 /// Is there a number at the beginning of \p s ?
48 static bool LPFisValue(const char* s)
49 {
50  return ((*s >= '0') && (*s <= '9')) || (*s == '+') || (*s == '-') || (*s == '.');
51 }
52 
53 
54 
55 /// Is there a possible column name at the beginning of \p s ?
56 static bool LPFisColName(const char* s)
57 {
58  // strchr() gives a true for the null char.
59  if( *s == '\0' )
60  return false;
61 
62  return ((*s >= 'A') && (*s <= 'Z'))
63  || ((*s >= 'a') && (*s <= 'z'))
64  || (strchr("!\"#$%&()/,;?@_'`{}|~", *s) != 0);
65 }
66 
67 
68 
69 /// Is there a comparison operator at the beginning of \p s ?
70 static bool LPFisSense(const char* s)
71 {
72  return (*s == '<') || (*s == '>') || (*s == '=');
73 }
74 
75 
76 
77 static bool LPFisInfinity(const char* s)
78 {
79  return ((s[0] == '-') || (s[0] == '+'))
80  && (tolower(s[1]) == 'i')
81  && (tolower(s[2]) == 'n')
82  && (tolower(s[3]) == 'f');
83 }
84 
85 
86 
87 static bool LPFisFree(const char* s)
88 {
89  return (tolower(s[0]) == 'f')
90  && ( tolower(s[1]) == 'r')
91  && ( tolower(s[2]) == 'e')
92  && ( tolower(s[3]) == 'e');
93 }
94 
95 
96 
97 /// Read the next number and advance \p pos.
98 /** If only a sign is encountered, the number is assumed to be \c sign * 1.0. This routine will not catch malformatted
99  * numbers like .e10 !
100  */
101 static Real LPFreadValue(char*& pos, SPxOut* spxout)
102 {
103  assert(LPFisValue(pos));
104 
105  char tmp[LPF_MAX_LINE_LEN];
106  const char* s = pos;
107  char* t;
108  Real value = 1.0;
109  bool has_digits = false;
110  bool has_emptyexponent = false;
111 
112  // 1. sign
113  if( (*s == '+') || (*s == '-') )
114  s++;
115 
116  // 2. Digits before the decimal dot
117  while( (*s >= '0') && (*s <= '9') )
118  {
119  has_digits = true;
120  s++;
121  }
122 
123  // 3. Decimal dot
124  if( *s == '.' )
125  {
126  s++;
127 
128  // 4. If there was a dot, possible digit behind it
129  while( (*s >= '0') && (*s <= '9') )
130  {
131  has_digits = true;
132  s++;
133  }
134  }
135 
136  // 5. Exponent
137  if( tolower(*s) == 'e' )
138  {
139  has_emptyexponent = true;
140  s++;
141 
142  // 6. Exponent sign
143  if( (*s == '+') || (*s == '-') )
144  s++;
145 
146  // 7. Exponent digits
147  while( (*s >= '0') && (*s <= '9') )
148  {
149  has_emptyexponent = false;
150  s++;
151  }
152  }
153  assert(s != pos);
154 
155  if( has_emptyexponent )
156  {
157  MSG_WARNING( (*spxout), (*spxout) << "WLPFRD01 Warning: found empty exponent in LP file - check for forbidden variable names with initial 'e' or 'E'\n"; )
158  }
159 
160  if( !has_digits )
161  value = (*pos == '-') ? -1.0 : 1.0;
162  else
163  {
164  for( t = tmp; pos != s; pos++ )
165  *t++ = *pos;
166  *t = '\0';
167  value = atof(tmp);
168  }
169 
170  pos += s - pos;
171 
172  assert(pos == s);
173 
174  MSG_DEBUG( std::cout << "DLPFRD01 LPFreadValue = " << value << std::endl; )
175 
176  if( LPFisSpace(*pos) )
177  pos++;
178 
179  return value;
180 }
181 
182 
183 
184 /// Read the next column name from the input.
185 /** The name read is looked up and if not found \p emptycol
186  * is added to \p colset. \p pos is advanced behind the name.
187  * @return The Index of the named column.
188  */
189 static int LPFreadColName(char*& pos, NameSet* colnames, LPColSetBase<Real>& colset, const LPColBase<Real>* emptycol, SPxOut* spxout)
190 {
191  assert(LPFisColName(pos));
192  assert(colnames != 0);
193 
194  char name[LPF_MAX_LINE_LEN];
195  const char* s = pos;
196  int i;
197  int colidx;
198 
199  // These are the characters that are not allowed in a column name.
200  while( (strchr("+-.<>= ", *s) == 0) && (*s != '\0') )
201  s++;
202 
203  for( i = 0; pos != s; i++, pos++ )
204  name[i] = *pos;
205 
206  name[i] = '\0';
207 
208  if( (colidx = colnames->number(name)) < 0 )
209  {
210  // We only add the name if we got an empty column.
211  if( emptycol == 0 )
212  MSG_WARNING( (*spxout), (*spxout) << "WLPFRD02 Unknown variable \"" << name << "\" "; )
213  else
214  {
215  colidx = colnames->num();
216  colnames->add(name);
217  colset.add(*emptycol);
218  }
219  }
220 
221  MSG_DEBUG( std::cout << "DLPFRD03 LPFreadColName [" << name << "] = " << colidx << std::endl; )
222 
223  if( LPFisSpace(*pos) )
224  pos++;
225 
226  return colidx;
227 }
228 
229 
230 
231 /// Read the next <,>,=,==,<=,=<,>=,=> and advance \p pos.
232 static int LPFreadSense(char*& pos)
233 {
234  assert(LPFisSense(pos));
235 
236  int sense = *pos++;
237 
238  if( (*pos == '<') || (*pos == '>') )
239  sense = *pos++;
240  else if( *pos == '=' )
241  pos++;
242 
243  MSG_DEBUG( std::cout << "DLPFRD04 LPFreadSense = " << static_cast<char>(sense) << std::endl; )
244 
245  if( LPFisSpace(*pos) )
246  pos++;
247 
248  return sense;
249 }
250 
251 
252 
253 /// Is the \p keyword present in \p buf ? If yes, advance \p pos.
254 /** \p keyword should be lower case. It can contain optional sections which are enclosed in '[' ']' like "min[imize]".
255  */
256 static bool LPFhasKeyword(char*& pos, const char* keyword)
257 {
258  int i;
259  int k;
260 
261  assert(keyword != 0);
262 
263  for( i = 0, k = 0; keyword[i] != '\0'; i++, k++ )
264  {
265  if( keyword[i] == '[' )
266  {
267  i++;
268 
269  // Here we assumed that we have a ']' for the '['.
270  while( (tolower(pos[k]) == keyword[i]) && (pos[k] != '\0') )
271  {
272  k++;
273  i++;
274  }
275  while( keyword[i] != ']' )
276  i++;
277  --k;
278  }
279  else
280  {
281  if( keyword[i] != tolower(pos[k]) )
282  break;
283  }
284  }
285 
286  // we have to be at the end of the keyword and the word found on the line also has to end here. Attention: The
287  // LPFisSense is a kludge to allow LPFhasKeyword also to process Inf[inity] keywords in the bounds section.
288  if( keyword[i] == '\0' && (pos[k] == '\0' || LPFisSpace(pos[k]) || LPFisSense(&pos[k])) )
289  {
290  pos += k;
291 
292  MSG_DEBUG( std::cout << "DLPFRD05 LPFhasKeyword: " << keyword << std::endl; )
293 
294  return true;
295  }
296 
297  return false;
298 }
299 
300 
301 
302 /// If \p buf start with "name:" store the name in \p rownames and advance \p pos.
303 static bool LPFhasRowName(char*& pos, NameSet* rownames)
304 {
305  const char* s = strchr(pos, ':');
306 
307  if( s == 0 )
308  return false;
309 
310  int dcolpos = int(s - pos);
311 
312  int end;
313  int srt;
314 
315  // skip spaces between name and ":"
316  for( end = dcolpos-1; end >= 0; end-- )
317  if( pos[end] != ' ')
318  break;
319 
320  // are there only spaces in front of the ":" ?
321  if( end < 0 )
322  {
323  pos = &(pos[dcolpos+1]);
324  return false;
325  }
326 
327  // skip spaces in front of name
328  for( srt = end-1; srt >= 0; srt-- )
329  if( pos[srt] == ' ' )
330  break;
331 
332  // go back to the non-space character
333  srt++;
334 
335  assert(srt <= end && pos[srt] != ' ');
336 
337  char name[LPF_MAX_LINE_LEN];
338  int i;
339  int k = 0;
340 
341  for( i = srt; i <= end; i++ )
342  name[k++] = pos[i];
343 
344  name[k] = '\0';
345 
346  if( rownames != 0 )
347  rownames->add(name);
348 
349  pos = &(pos[dcolpos+1]);
350 
351  return true;
352 }
353 
354 
355 
356 static Real LPFreadInfinity(char*& pos)
357 {
358  assert(LPFisInfinity(pos));
359 
360  Real sense = (*pos == '-') ? -1.0 : 1.0;
361 
362  (void) LPFhasKeyword(++pos, "inf[inity]");
363 
364  return sense * infinity;
365 }
366 
367 
368 
369 /// Read LP in "CPLEX LP File Format".
370  /** The specification is taken from the ILOG CPLEX 7.0 Reference Manual, Appendix E, Page 527.
371  *
372  * This routine should read (most?) valid LP format files. What it will not do, is find all cases where a file is ill
373  * formed. If this happens it may complain and read nothing or read "something".
374  *
375  * Problem: A line ending in '+' or '-' followed by a line starting with a number, will be regarded as an error.
376  *
377  * The reader will accept the keyword INT[egers] as a synonym for GEN[erals] which is an undocumented feature in CPLEX.
378  *
379  * A difference to the CPLEX reader, is that no name for the objective row is required.
380  *
381  * The manual says the maximum allowed line length is 255 characters, but CPLEX does not complain if the lines are
382  * longer.
383  *
384  * @return true if the file was read correctly
385  */
386 template <>
388  std::istream& p_input, ///< input stream.
389  NameSet* p_rnames, ///< row names.
390  NameSet* p_cnames, ///< column names.
391  DIdxSet* p_intvars) ///< integer variables.
392 {
393  enum
394  {
395  START, OBJECTIVE, CONSTRAINTS, BOUNDS, INTEGERS, BINARIES
396  } section = START;
397 
398  NameSet* rnames; ///< row names.
399  NameSet* cnames; ///< column names.
400 
401  LPColSetBase<Real> cset; ///< the set of columns read.
402  LPRowSetBase<Real> rset; ///< the set of rows read.
403  LPColBase<Real> emptycol; ///< reusable empty column.
404  LPRowBase<Real> row; ///< last assembled row.
405  DSVectorBase<Real> vec; ///< last assembled vector (from row).
406 
407  Real val = 1.0;
408  int colidx;
409  int sense = 0;
410 
411  char buf[LPF_MAX_LINE_LEN];
412  char tmp[LPF_MAX_LINE_LEN];
413  char line[LPF_MAX_LINE_LEN];
414  int lineno = 0;
415  bool unnamed = true;
416  bool finished = false;
417  bool other;
418  bool have_value = true;
419  int i;
420  int k;
421  char* s;
422  char* pos;
423  char* pos_old = 0;
424 
425  if( p_cnames )
426  cnames = p_cnames;
427  else
428  {
429  cnames = 0;
430  spx_alloc(cnames);
431  cnames = new (cnames) NameSet();
432  }
433 
434  cnames->clear();
435 
436  if( p_rnames )
437  rnames = p_rnames;
438  else
439  {
440  try
441  {
442  rnames = 0;
443  spx_alloc(rnames);
444  rnames = new (rnames) NameSet();
445  }
446  catch( const SPxMemoryException& x )
447  {
448  if( !p_cnames )
449  {
450  cnames->~NameSet();
451  spx_free(cnames);
452  }
453  throw x;
454  }
455  }
456 
457  rnames->clear();
458 
459  SPxLPBase<Real>::clear(); // clear the LP.
460 
461  //--------------------------------------------------------------------------
462  //--- Main Loop
463  //--------------------------------------------------------------------------
464  for(;;)
465  {
466  // 0. Read a line from the file.
467  if( !p_input.getline(buf, sizeof(buf)) )
468  {
469  if( strlen(buf) == LPF_MAX_LINE_LEN - 1 )
470  {
471  MSG_ERROR( std::cerr << "ELPFRD06 Line exceeds " << LPF_MAX_LINE_LEN - 2
472  << " characters" << std::endl; )
473  }
474  else
475  {
476  MSG_ERROR( std::cerr << "ELPFRD07 No 'End' marker found" << std::endl; )
477  finished = true;
478  }
479  break;
480  }
481  lineno++;
482  i = 0;
483  pos = buf;
484 
485  MSG_DEBUG( std::cout << "DLPFRD08 Reading line " << lineno
486  << " (pos=" << pos << ")" << std::endl; )
487 
488  // 1. Remove comments.
489  if( 0 != (s = strchr(buf, '\\')) )
490  *s = '\0';
491 
492  // 2. Look for keywords.
493  if( section == START )
494  {
495  if( LPFhasKeyword(pos, "max[imize]") )
496  {
497  changeSense(SPxLPBase<Real>::MAXIMIZE);
498  section = OBJECTIVE;
499  }
500  else if( LPFhasKeyword(pos, "min[imize]") )
501  {
502  changeSense(SPxLPBase<Real>::MINIMIZE);
503  section = OBJECTIVE;
504  }
505  }
506  else if( section == OBJECTIVE )
507  {
508  if( LPFhasKeyword(pos, "s[ubject][ ]t[o]")
509  || LPFhasKeyword(pos, "s[uch][ ]t[hat]")
510  || LPFhasKeyword(pos, "s[.][ ]t[.]")
511  || LPFhasKeyword(pos, "lazy con[straints]") )
512  {
513  // store objective vector
514  for( int j = vec.size() - 1; j >= 0; --j )
515  cset.maxObj_w(vec.index(j)) = vec.value(j);
516  // multiplication with -1 for minimization is done below
517  vec.clear();
518  have_value = true;
519  val = 1.0;
520  section = CONSTRAINTS;
521  }
522  }
523  else if( section == CONSTRAINTS &&
524  (LPFhasKeyword(pos, "s[ubject][ ]t[o]")
525  || LPFhasKeyword(pos, "s[uch][ ]t[hat]")
526  || LPFhasKeyword(pos, "s[.][ ]t[.]")) )
527  {
528  have_value = true;
529  val = 1.0;
530  }
531  else
532  {
533  if( LPFhasKeyword(pos, "lazy con[straints]") )
534  ;
535  else if( LPFhasKeyword(pos, "bound[s]") )
536  section = BOUNDS;
537  else if( LPFhasKeyword(pos, "bin[ary]") )
538  section = BINARIES;
539  else if( LPFhasKeyword(pos, "bin[aries]") )
540  section = BINARIES;
541  else if( LPFhasKeyword(pos, "gen[erals]") )
542  section = INTEGERS;
543  else if( LPFhasKeyword(pos, "int[egers]") ) // this is undocumented
544  section = INTEGERS;
545  else if( LPFhasKeyword(pos, "end") )
546  {
547  finished = true;
548  break;
549  }
550  else if( LPFhasKeyword(pos, "s[ubject][ ]t[o]") // second time
551  || LPFhasKeyword(pos, "s[uch][ ]t[hat]")
552  || LPFhasKeyword(pos, "s[.][ ]t[.]")
553  || LPFhasKeyword(pos, "lazy con[straints]") )
554  {
555  // In principle this has to checked for all keywords above,
556  // otherwise we just ignore any half finished constraint
557  if( have_value )
558  goto syntax_error;
559 
560  have_value = true;
561  val = 1.0;
562  }
563  }
564 
565  // 3a. Look for row names in objective and drop it.
566  if( section == OBJECTIVE )
567  LPFhasRowName(pos, 0);
568 
569  // 3b. Look for row name in constraint and store it.
570  if( section == CONSTRAINTS )
571  if( LPFhasRowName(pos, rnames) )
572  unnamed = false;
573 
574  // 4a. Remove initial spaces.
575  while( LPFisSpace(pos[i]) )
576  i++;
577 
578  // 4b. remove spaces if they do not appear before the name of a vaiable.
579  for( k = 0; pos[i] != '\0'; i++ )
580  if( !LPFisSpace(pos[i]) || LPFisColName(&pos[i + 1]) )
581  tmp[k++] = pos[i];
582 
583  tmp[k] = '\0';
584 
585  // 5. Is this an empty line ?
586  if( tmp[0] == '\0' )
587  continue;
588 
589  // 6. Collapse sequences of '+' and '-'. e.g ++---+ => -
590  for( i = 0, k = 0; tmp[i] != '\0'; i++ )
591  {
592  while( ((tmp[i] == '+') || (tmp[i] == '-')) && ((tmp[i + 1] == '+') || (tmp[i + 1] == '-')) )
593  {
594  if( tmp[i++] == '-' )
595  tmp[i] = (tmp[i] == '-') ? '+' : '-';
596  }
597  line[k++] = tmp[i];
598  }
599  line[k] = '\0';
600 
601  //-----------------------------------------------------------------------
602  //--- Line processing loop
603  //-----------------------------------------------------------------------
604  pos = line;
605 
606  MSG_DEBUG( std::cout << "DLPFRD09 pos=" << pos << std::endl; )
607 
608  // 7. We have something left to process.
609  while( (pos != 0) && (*pos != '\0') )
610  {
611  // remember our position, so we are sure we make progress.
612  pos_old = pos;
613 
614  // now process the sections
615  switch( section )
616  {
617  case OBJECTIVE:
618  if( LPFisValue(pos) )
619  {
620  Real pre_sign = 1.0;
621 
622  /* Already having here a value could only result from being the first number in a constraint, or a sign
623  * '+' or '-' as last token on the previous line.
624  */
625  if( have_value )
626  {
627  if( NE(spxAbs(val), 1.0) )
628  goto syntax_error;
629 
630  if( EQ(val, -1.0) )
631  pre_sign = val;
632  }
633  have_value = true;
634  val = LPFreadValue(pos, spxout) * pre_sign;
635  }
636  if( *pos == '\0' )
637  continue;
638 
639  if( !have_value || !LPFisColName(pos) )
640  goto syntax_error;
641 
642  have_value = false;
643  colidx = LPFreadColName(pos, cnames, cset, &emptycol, spxout);
644  vec.add(colidx, val);
645  break;
646  case CONSTRAINTS:
647  if( LPFisValue(pos) )
648  {
649  Real pre_sign = 1.0;
650 
651  /* Already having here a value could only result from being the first number in a constraint, or a sign
652  * '+' or '-' as last token on the previous line.
653  */
654  if( have_value )
655  {
656  if( NE(spxAbs(val), 1.0) )
657  goto syntax_error;
658 
659  if( EQ(val, -1.0) )
660  pre_sign = val;
661  }
662 
663  have_value = true;
664  val = LPFreadValue(pos, spxout) * pre_sign;
665 
666  if( sense != 0 )
667  {
668  if( sense == '<' )
669  {
670  row.setLhs(-infinity);
671  row.setRhs(val);
672  }
673  else if( sense == '>' )
674  {
675  row.setLhs(val);
676  row.setRhs(infinity);
677  }
678  else
679  {
680  assert(sense == '=');
681 
682  row.setLhs(val);
683  row.setRhs(val);
684  }
685  row.setRowVector(vec);
686  rset.add(row);
687  vec.clear();
688 
689  if( !unnamed )
690  unnamed = true;
691  else
692  {
693  char name[16];
694  sprintf(name, "C%d", rset.num());
695  rnames->add(name);
696  }
697  have_value = true;
698  val = 1.0;
699  sense = 0;
700  pos = 0;
701  // next line
702  continue;
703  }
704  }
705  if( *pos == '\0' )
706  continue;
707 
708  if( have_value )
709  {
710  if( LPFisColName(pos) )
711  {
712  colidx = LPFreadColName(pos, cnames, cset, &emptycol, spxout);
713 
714  if( val != 0.0 )
715  {
716  // Do we have this index already in the row?
717  int n = vec.number(colidx);
718 
719  // if not, add it
720  if( n < 0 )
721  vec.add(colidx, val);
722  // if yes, add them up and remove the element if it amounts to zero
723  else
724  {
725  assert(vec.index(n) == colidx);
726 
727  val += vec.value(n);
728 
729  if( val == 0.0 )
730  vec.remove(n);
731  else
732  vec.value(n) = val;
733 
734  assert(cnames->has(colidx));
735 
736  MSG_WARNING( (*spxout), (*spxout) << "WLPFRD10 Duplicate index "
737  << (*cnames)[colidx]
738  << " in line " << lineno
739  << std::endl; )
740  }
741  }
742  have_value = false;
743  }
744  else
745  {
746  // We have a row like c1: <= 5 with no variables. We can not handle 10 <= 5; issue a syntax error.
747  if( val != 1.0 )
748  goto syntax_error;
749 
750  // If the next thing is not the sense we give up also.
751  if( !LPFisSense(pos) )
752  goto syntax_error;
753 
754  have_value = false;
755  }
756  }
757  assert(!have_value);
758 
759  if( LPFisSense(pos) )
760  sense = LPFreadSense(pos);
761  break;
762  case BOUNDS:
763  other = false;
764  sense = 0;
765 
766  if( LPFisValue(pos) )
767  {
768  val = LPFisInfinity(pos) ? LPFreadInfinity(pos) : LPFreadValue(pos, spxout);
769 
770  if( !LPFisSense(pos) )
771  goto syntax_error;
772 
773  sense = LPFreadSense(pos);
774  other = true;
775  }
776 
777  if( !LPFisColName(pos) )
778  goto syntax_error;
779 
780  if( (colidx = LPFreadColName(pos, cnames, cset, 0, spxout)) < 0 )
781  {
782  MSG_WARNING( (*spxout), (*spxout) << "WLPFRD11 in Bounds section line "
783  << lineno << " ignored" << std::endl; )
784  *pos = '\0';
785  continue;
786  }
787 
788  if( sense )
789  {
790  if( sense == '<' )
791  cset.lower_w(colidx) = val;
792  else if( sense == '>' )
793  cset.upper_w(colidx) = val;
794  else
795  {
796  assert(sense == '=');
797  cset.lower_w(colidx) = val;
798  cset.upper_w(colidx) = val;
799  }
800  }
801 
802  if( LPFisFree(pos) )
803  {
804  cset.lower_w(colidx) = -infinity;
805  cset.upper_w(colidx) = infinity;
806  other = true;
807  pos += 4; // set position after the word "free"
808  }
809  else if( LPFisSense(pos) )
810  {
811  sense = LPFreadSense(pos);
812  other = true;
813 
814  if( !LPFisValue(pos) )
815  goto syntax_error;
816 
817  val = LPFisInfinity(pos) ? LPFreadInfinity(pos) : LPFreadValue(pos, spxout);
818 
819  if( sense == '<' )
820  cset.upper_w(colidx) = val;
821  else if( sense == '>' )
822  cset.lower_w(colidx) = val;
823  else
824  {
825  assert(sense == '=');
826  cset.lower_w(colidx) = val;
827  cset.upper_w(colidx) = val;
828  }
829  }
830 
831  /* Do we have only a single column name in the input line? We could ignore this savely, but it is probably
832  * a sign of some other error.
833  */
834  if( !other )
835  goto syntax_error;
836  break;
837  case BINARIES:
838  case INTEGERS:
839  if( (colidx = LPFreadColName(pos, cnames, cset, 0, spxout)) < 0 )
840  {
841  MSG_WARNING( (*spxout), (*spxout) << "WLPFRD12 in Binary/General section line " << lineno << " ignored" << std::endl; )
842  }
843  else
844  {
845  if( section == BINARIES )
846  {
847  if( cset.lower(colidx) < 0.0 )
848  {
849  cset.lower_w(colidx) = 0.0;
850  }
851  if( cset.upper(colidx) > 1.0 )
852  {
853  cset.upper_w(colidx) = 1.0;
854  }
855  }
856 
857  if( p_intvars != 0 )
858  p_intvars->addIdx(colidx);
859  }
860  break;
861  case START:
862  MSG_ERROR( std::cerr << "ELPFRD13 This seems to be no LP format file" << std::endl; )
863  goto syntax_error;
864  default:
865  throw SPxInternalCodeException("XLPFRD01 This should never happen.");
866  }
867 
868  if( pos == pos_old )
869  goto syntax_error;
870  }
871  }
872 
873  assert(isConsistent());
874 
875  addCols(cset);
876  assert(isConsistent());
877 
878  addRows(rset);
879  assert(isConsistent());
880 
881 syntax_error:
882  if( finished )
883  {
884  MSG_INFO2( (*spxout), (*spxout) << "Finished reading " << lineno << " lines" << std::endl; )
885  }
886  else
887  MSG_ERROR( std::cerr << "ELPFRD15 Syntax error in line " << lineno << std::endl; )
888 
889  if( p_cnames == 0 )
890  spx_free(cnames);
891  if( p_rnames == 0 )
892  spx_free(rnames);
893 
894  return finished;
895 }
896 
897 
898 
899 // ---------------------------------------------------------------------------------------------------------------------
900 // Specialization for reading MPS format
901 // ---------------------------------------------------------------------------------------------------------------------
902 
903 /// Process NAME section.
904 static void MPSreadName(MPSInput& mps, SPxOut* spxout)
905 {
906  do
907  {
908  // This has to be the Line with the NAME section.
909  if( !mps.readLine() || (mps.field0() == 0) || strcmp(mps.field0(), "NAME") )
910  break;
911 
912  // Sometimes the name is omitted.
913  mps.setProbName((mps.field1() == 0) ? "_MPS_" : mps.field1());
914 
915  MSG_INFO2( (*spxout), (*spxout) << "IMPSRD01 Problem name : " << mps.probName() << std::endl; )
916 
917  // This has to be a new section
918  if( !mps.readLine() || (mps.field0() == 0) )
919  break;
920 
921  if( !strcmp(mps.field0(), "ROWS") )
923  else if( !strncmp(mps.field0(), "OBJSEN", 6) )
924  mps.setSection(MPSInput::OBJSEN);
925  else if( !strcmp(mps.field0(), "OBJNAME") )
926  mps.setSection(MPSInput::OBJNAME);
927  else
928  break;
929 
930  return;
931  }
932  while(false);
933 
934  mps.syntaxError();
935 }
936 
937 
938 
939 /// Process OBJSEN section. This Section is an ILOG extension.
940 static void MPSreadObjsen(MPSInput& mps)
941 {
942  do
943  {
944  // This has to be the Line with MIN or MAX.
945  if( !mps.readLine() || (mps.field1() == 0) )
946  break;
947 
948  if( !strcmp(mps.field1(), "MIN") )
949  mps.setObjSense(MPSInput::MINIMIZE);
950  else if( !strcmp(mps.field1(), "MAX") )
951  mps.setObjSense(MPSInput::MAXIMIZE);
952  else
953  break;
954 
955  // Look for ROWS or OBJNAME Section
956  if( !mps.readLine() || (mps.field0() == 0) )
957  break;
958 
959  if( !strcmp(mps.field0(), "ROWS") )
961  else if( !strcmp(mps.field0(), "OBJNAME") )
962  mps.setSection(MPSInput::OBJNAME);
963  else
964  break;
965 
966  return;
967  }
968  while(false);
969 
970  mps.syntaxError();
971 }
972 
973 
974 
975 /// Process OBJNAME section. This Section is an ILOG extension.
976 static void MPSreadObjname(MPSInput& mps)
977 {
978  do
979  {
980  // This has to be the Line with the name.
981  if( !mps.readLine() || (mps.field1() == 0) )
982  break;
983 
984  mps.setObjName(mps.field1());
985 
986  // Look for ROWS Section
987  if( !mps.readLine() || (mps.field0() == 0) )
988  break;
989 
990  if( strcmp(mps.field0(), "ROWS") )
991  break;
992 
994 
995  return;
996  }
997  while(false);
998 
999  mps.syntaxError();
1000 }
1001 
1002 
1003 
1004 /// Process ROWS section.
1005 static void MPSreadRows(MPSInput& mps, LPRowSetBase<Real>& rset, NameSet& rnames, SPxOut* spxout)
1006 {
1007  LPRowBase<Real> row;
1008 
1009  while( mps.readLine() )
1010  {
1011  if( mps.field0() != 0 )
1012  {
1013  MSG_INFO2( (*spxout), (*spxout) << "IMPSRD02 Objective name : " << mps.objName() << std::endl; )
1014 
1015  if( strcmp(mps.field0(), "COLUMNS") )
1016  break;
1017 
1018  mps.setSection(MPSInput::COLUMNS);
1019 
1020  return;
1021  }
1022 
1023  if( (mps.field1() == 0) || (mps.field2() == 0) )
1024  break;
1025 
1026  if( *mps.field1() == 'N' )
1027  {
1028  if( *mps.objName() == '\0' )
1029  mps.setObjName(mps.field2());
1030  }
1031  else
1032  {
1033  if( rnames.has(mps.field2()) )
1034  break;
1035 
1036  rnames.add(mps.field2());
1037 
1038  switch( *mps.field1() )
1039  {
1040  case 'G':
1041  row.setLhs(0.0);
1042  row.setRhs(infinity);
1043  break;
1044  case 'E':
1045  row.setLhs(0.0);
1046  row.setRhs(0.0);
1047  break;
1048  case 'L':
1049  row.setLhs(-infinity);
1050  row.setRhs(0.0);
1051  break;
1052  default:
1053  mps.syntaxError();
1054  return;
1055  }
1056 
1057  rset.add(row);
1058  }
1059 
1060  assert((*mps.field1() == 'N') || (rnames.number(mps.field2()) == rset.num() - 1));
1061  }
1062 
1063  mps.syntaxError();
1064 }
1065 
1066 
1067 
1068 /// Process COLUMNS section.
1069 static void MPSreadCols(MPSInput& mps, const LPRowSetBase<Real>& rset, const NameSet& rnames, LPColSetBase<Real>& cset, NameSet& cnames, DIdxSet* intvars)
1070 {
1071  Real val;
1072  int idx;
1073  char colname[MPSInput::MAX_LINE_LEN] = { '\0' };
1074  LPColBase<Real> col(rset.num());
1075  DSVectorBase<Real> vec;
1076 
1077  col.setObj(0.0);
1078  vec.clear();
1079 
1080  while( mps.readLine() )
1081  {
1082  if( mps.field0() != 0 )
1083  {
1084  if( strcmp(mps.field0(), "RHS") )
1085  break;
1086 
1087  if( colname[0] != '\0' )
1088  {
1089  col.setColVector(vec);
1090  cset.add(col);
1091  }
1092 
1093  mps.setSection(MPSInput::RHS);
1094 
1095  return;
1096  }
1097 
1098  if( (mps.field1() == 0) || (mps.field2() == 0) || (mps.field3() == 0) )
1099  break;
1100 
1101  // new column?
1102  if( strcmp(colname, mps.field1()) )
1103  {
1104  // first column?
1105  if( colname[0] != '\0' )
1106  {
1107  col.setColVector(vec);
1108  cset.add(col);
1109  }
1110 
1111  // save copy of string (make sure string ends with \0)
1112  strncpy(colname, mps.field1(), MPSInput::MAX_LINE_LEN-1);
1113  colname[MPSInput::MAX_LINE_LEN-1] = '\0';
1114  cnames.add(colname);
1115  vec.clear();
1116  col.setObj(0.0);
1117  col.setLower(0.0);
1118  col.setUpper(infinity);
1119 
1120  if( mps.isInteger() )
1121  {
1122  assert(cnames.number(colname) == cset.num());
1123 
1124  if( intvars != 0 )
1125  intvars->addIdx(cnames.number(colname));
1126 
1127  // for Integer variable the default bounds are 0/1
1128  col.setUpper(1.0);
1129  }
1130  }
1131 
1132  val = atof(mps.field3());
1133 
1134  if( !strcmp(mps.field2(), mps.objName()) )
1135  col.setObj(val);
1136  else
1137  {
1138  if( (idx = rnames.number(mps.field2())) < 0 )
1139  mps.entryIgnored("Column", mps.field1(), "row", mps.field2());
1140  else if( val != 0.0 )
1141  vec.add(idx, val);
1142  }
1143 
1144  if( mps.field5() != 0 )
1145  {
1146  assert(mps.field4() != 0);
1147 
1148  val = atof(mps.field5());
1149 
1150  if( !strcmp(mps.field4(), mps.objName()) )
1151  col.setObj(val);
1152  else
1153  {
1154  if( (idx = rnames.number(mps.field4())) < 0 )
1155  mps.entryIgnored("Column", mps.field1(), "row", mps.field4());
1156  else if( val != 0.0 )
1157  vec.add(idx, val);
1158  }
1159  }
1160  }
1161 
1162  mps.syntaxError();
1163 }
1164 
1165 
1166 
1167 /// Process RHS section.
1168 static void MPSreadRhs(MPSInput& mps, LPRowSetBase<Real>& rset, const NameSet& rnames, SPxOut* spxout)
1169 {
1170  char rhsname[MPSInput::MAX_LINE_LEN] = { '\0' };
1171  char addname[MPSInput::MAX_LINE_LEN] = { '\0' };
1172  int idx;
1173  Real val;
1174 
1175  while( mps.readLine() )
1176  {
1177  if( mps.field0() != 0 )
1178  {
1179  MSG_INFO2( (*spxout), (*spxout) << "IMPSRD03 RHS name : " << rhsname << std::endl; );
1180 
1181  if( !strcmp(mps.field0(), "RANGES") )
1182  mps.setSection(MPSInput::RANGES);
1183  else if( !strcmp(mps.field0(), "BOUNDS") )
1184  mps.setSection(MPSInput::BOUNDS);
1185  else if( !strcmp(mps.field0(), "ENDATA") )
1186  mps.setSection(MPSInput::ENDATA);
1187  else
1188  break;
1189 
1190  return;
1191  }
1192 
1193  if( ((mps.field2() != 0) && (mps.field3() == 0)) || ((mps.field4() != 0) && (mps.field5() == 0)) )
1194  mps.insertName("_RHS_");
1195 
1196  if( (mps.field1() == 0) || (mps.field2() == 0) || (mps.field3() == 0) )
1197  break;
1198 
1199  if( *rhsname == '\0' )
1200  strcpy(rhsname, mps.field1());
1201 
1202  if( strcmp(rhsname, mps.field1()) )
1203  {
1204  if( strcmp(addname, mps.field1()) )
1205  {
1206  assert(strlen(mps.field1()) < MPSInput::MAX_LINE_LEN);
1207  strcpy(addname, mps.field1());
1208  MSG_INFO3( (*spxout), (*spxout) << "IMPSRD07 RHS ignored : " << addname << std::endl );
1209  }
1210  }
1211  else
1212  {
1213  if( (idx = rnames.number(mps.field2())) < 0 )
1214  mps.entryIgnored("RHS", mps.field1(), "row", mps.field2());
1215  else
1216  {
1217  val = atof(mps.field3());
1218 
1219  // LE or EQ
1220  if( rset.rhs(idx) < infinity )
1221  rset.rhs_w(idx) = val;
1222  // GE or EQ
1223  if( rset.lhs(idx) > -infinity )
1224  rset.lhs_w(idx) = val;
1225  }
1226 
1227  if( mps.field5() != 0 )
1228  {
1229  if( (idx = rnames.number(mps.field4())) < 0 )
1230  mps.entryIgnored("RHS", mps.field1(), "row", mps.field4());
1231  else
1232  {
1233  val = atof(mps.field5());
1234 
1235  // LE or EQ
1236  if( rset.rhs(idx) < infinity )
1237  rset.rhs_w(idx) = val;
1238  // GE or EQ
1239  if( rset.lhs(idx) > -infinity )
1240  rset.lhs_w(idx) = val;
1241  }
1242  }
1243  }
1244  }
1245 
1246  mps.syntaxError();
1247 }
1248 
1249 
1250 
1251 /// Process RANGES section.
1252 static void MPSreadRanges(MPSInput& mps, LPRowSetBase<Real>& rset, const NameSet& rnames, SPxOut* spxout)
1253 {
1254  char rngname[MPSInput::MAX_LINE_LEN] = { '\0' };
1255  int idx;
1256  Real val;
1257 
1258  while( mps.readLine() )
1259  {
1260  if( mps.field0() != 0 )
1261  {
1262  MSG_INFO2( (*spxout), (*spxout) << "IMPSRD04 Range name : " << rngname << std::endl; );
1263 
1264  if( !strcmp(mps.field0(), "BOUNDS") )
1265  mps.setSection(MPSInput::BOUNDS);
1266  else if( !strcmp(mps.field0(), "ENDATA") )
1267  mps.setSection(MPSInput::ENDATA);
1268  else
1269  break;
1270 
1271  return;
1272  }
1273 
1274  if( ((mps.field2() != 0) && (mps.field3() == 0)) || ((mps.field4() != 0) && (mps.field5() == 0)) )
1275  mps.insertName("_RNG_");
1276 
1277  if( (mps.field1() == 0) || (mps.field2() == 0) || (mps.field3() == 0) )
1278  break;
1279 
1280  if( *rngname == '\0' )
1281  {
1282  assert(strlen(mps.field2()) < MPSInput::MAX_LINE_LEN);
1283  strcpy(rngname, mps.field1());
1284  }
1285 
1286  /* The rules are:
1287  * Row Sign LHS RHS
1288  * ----------------------------------------
1289  * G +/- rhs rhs + |range|
1290  * L +/- rhs - |range| rhs
1291  * E + rhs rhs + range
1292  * E - rhs + range rhs
1293  * ----------------------------------------
1294  */
1295  if( !strcmp(rngname, mps.field1()) )
1296  {
1297  if( (idx = rnames.number(mps.field2())) < 0 )
1298  mps.entryIgnored("Range", mps.field1(), "row", mps.field2());
1299  else
1300  {
1301  val = atof(mps.field3());
1302 
1303  // EQ
1304  if( (rset.lhs(idx) > -infinity) && (rset.rhs_w(idx) < infinity) )
1305  {
1306  assert(rset.lhs(idx) == rset.rhs(idx));
1307 
1308  if( val >= 0 )
1309  rset.rhs_w(idx) += val;
1310  else
1311  rset.lhs_w(idx) += val;
1312  }
1313  else
1314  {
1315  // GE
1316  if( rset.lhs(idx) > -infinity )
1317  rset.rhs_w(idx) = rset.lhs(idx) + spxAbs(val);
1318  // LE
1319  else
1320  rset.lhs_w(idx) = rset.rhs(idx) - spxAbs(val);
1321  }
1322  }
1323 
1324  if( mps.field5() != 0 )
1325  {
1326  if( (idx = rnames.number(mps.field4())) < 0 )
1327  mps.entryIgnored("Range", mps.field1(), "row", mps.field4());
1328  else
1329  {
1330  val = atof(mps.field5());
1331 
1332  // EQ
1333  if( (rset.lhs(idx) > -infinity) && (rset.rhs(idx) < infinity) )
1334  {
1335  assert(rset.lhs(idx) == rset.rhs(idx));
1336 
1337  if( val >= 0 )
1338  rset.rhs_w(idx) += val;
1339  else
1340  rset.lhs_w(idx) += val;
1341  }
1342  else
1343  {
1344  // GE
1345  if( rset.lhs(idx) > -infinity )
1346  rset.rhs_w(idx) = rset.lhs(idx) + spxAbs(val);
1347  // LE
1348  else
1349  rset.lhs_w(idx) = rset.rhs(idx) - spxAbs(val);
1350  }
1351  }
1352  }
1353  }
1354  }
1355 
1356  mps.syntaxError();
1357 }
1358 
1359 
1360 
1361 /// Process BOUNDS section.
1362 static void MPSreadBounds(MPSInput& mps, LPColSetBase<Real>& cset, const NameSet& cnames, DIdxSet* intvars, SPxOut* spxout)
1363 {
1364  DIdxSet oldbinvars;
1365  char bndname[MPSInput::MAX_LINE_LEN] = { '\0' };
1366  int idx;
1367  Real val;
1368 
1369  while( mps.readLine() )
1370  {
1371  if( mps.field0() != 0 )
1372  {
1373  MSG_INFO2( (*spxout), (*spxout) << "IMPSRD05 Bound name : " << bndname << std::endl; )
1374 
1375  if( strcmp(mps.field0(), "ENDATA") )
1376  break;
1377 
1378  mps.setSection(MPSInput::ENDATA);
1379 
1380  return;
1381  }
1382 
1383  // Is the value field used ?
1384  if( (!strcmp(mps.field1(), "LO"))
1385  || (!strcmp(mps.field1(), "UP"))
1386  || (!strcmp(mps.field1(), "FX"))
1387  || (!strcmp(mps.field1(), "LI"))
1388  || (!strcmp(mps.field1(), "UI")) )
1389  {
1390  if( (mps.field3() != 0) && (mps.field4() == 0) )
1391  mps.insertName("_BND_", true);
1392  }
1393  else
1394  {
1395  if( (mps.field2() != 0) && (mps.field3() == 0) )
1396  mps.insertName("_BND_", true);
1397  }
1398 
1399  if( (mps.field1() == 0) || (mps.field2() == 0) || (mps.field3() == 0) )
1400  break;
1401 
1402  if( *bndname == '\0' )
1403  {
1404  assert(strlen(mps.field2()) < MPSInput::MAX_LINE_LEN);
1405  strcpy(bndname, mps.field2());
1406  }
1407 
1408  // Only read the first Bound in section
1409  if( !strcmp(bndname, mps.field2()) )
1410  {
1411  if( (idx = cnames.number(mps.field3())) < 0 )
1412  mps.entryIgnored("column", mps.field3(), "bound", bndname);
1413  else
1414  {
1415  val = (mps.field4() == 0) ? 0.0 : atof(mps.field4());
1416 
1417  // ILOG extension (Integer Bound)
1418  if( mps.field1()[1] == 'I' )
1419  {
1420  if( intvars != 0 )
1421  intvars->addIdx(idx);
1422 
1423  // if the variable has appeared in the MARKER section of the COLUMNS section then its default bounds were
1424  // set to 0,1; the first time it is declared integer we need to change to default bounds 0,infinity
1425  if( oldbinvars.number(idx) < 0 )
1426  {
1427  cset.upper_w(idx) = infinity;
1428  oldbinvars.addIdx(idx);
1429  }
1430  }
1431 
1432  switch( *mps.field1() )
1433  {
1434  case 'L':
1435  cset.lower_w(idx) = val;
1436  break;
1437  case 'U':
1438  cset.upper_w(idx) = val;
1439  break;
1440  case 'F':
1441  if( mps.field1()[1] == 'X' )
1442  {
1443  cset.lower_w(idx) = val;
1444  cset.upper_w(idx) = val;
1445  }
1446  else
1447  {
1448  cset.lower_w(idx) = -infinity;
1449  cset.upper_w(idx) = infinity;
1450  }
1451  break;
1452  case 'M':
1453  cset.lower_w(idx) = -infinity;
1454  break;
1455  case 'P':
1456  cset.upper_w(idx) = infinity;
1457  break;
1458  // Ilog extension (Binary)
1459  case 'B':
1460  cset.lower_w(idx) = 0.0;
1461  cset.upper_w(idx) = 1.0;
1462 
1463  if( intvars != 0 )
1464  intvars->addIdx(idx);
1465  break;
1466  default:
1467  mps.syntaxError();
1468  return;
1469  }
1470  }
1471  }
1472  }
1473 
1474  mps.syntaxError();
1475 }
1476 
1477 
1478 
1479 /// Read LP in MPS File Format.
1480 /**
1481  * The specification is taken from the IBM Optimization Library Guide and Reference, online available at
1482  * http://www.software.ibm.com/sos/features/libuser.htm and from the ILOG CPLEX 7.0 Reference Manual, Appendix E, Page
1483  * 531.
1484  *
1485  * This routine should read all valid MPS format files. What it will not do, is find all cases where a file is ill
1486  * formed. If this happens it may complain and read nothing or read "something".
1487  *
1488  * @return true if the file was read correctly.
1489  */
1490 #define INIT_COLS 10000 ///< initialy allocated columns.
1491 #define INIT_NZOS 100000 ///< initialy allocated non zeros.
1492 template <>
1494  std::istream& p_input, ///< input stream.
1495  NameSet* p_rnames, ///< row names.
1496  NameSet* p_cnames, ///< column names.
1497  DIdxSet* p_intvars) ///< integer variables.
1498 {
1499  LPRowSetBase<Real>& rset = *this;
1500  LPColSetBase<Real>& cset = *this;
1501  NameSet* rnames;
1502  NameSet* cnames;
1503 
1504  if( p_cnames )
1505  cnames = p_cnames;
1506  else
1507  {
1508  cnames = 0;
1509  spx_alloc(cnames);
1510  cnames = new (cnames) NameSet();
1511  }
1512 
1513  cnames->clear();
1514 
1515  if( p_rnames )
1516  rnames = p_rnames;
1517  else
1518  {
1519  try
1520  {
1521  rnames = 0;
1522  spx_alloc(rnames);
1523  rnames = new (rnames) NameSet();
1524  }
1525  catch( const SPxMemoryException& x)
1526  {
1527  if( !p_cnames )
1528  {
1529  cnames->~NameSet();
1530  spx_free(cnames);
1531  }
1532  throw x;
1533  }
1534  }
1535 
1536  rnames->clear();
1537 
1538  SPxLPBase<Real>::clear(); // clear the LP.
1539 
1540  cset.memRemax(INIT_NZOS);
1541  cset.reMax(INIT_COLS);
1542 
1543  MPSInput mps(p_input);
1544 
1545  MPSreadName(mps, spxout);
1546 
1547  if( mps.section() == MPSInput::OBJSEN )
1548  MPSreadObjsen(mps);
1549 
1550  if( mps.section() == MPSInput::OBJNAME )
1551  MPSreadObjname(mps);
1552 
1553  if( mps.section() == MPSInput::ROWS )
1554  MPSreadRows(mps, rset, *rnames, spxout);
1555 
1556  addedRows(rset.num());
1557 
1558  if( mps.section() == MPSInput::COLUMNS )
1559  MPSreadCols(mps, rset, *rnames, cset, *cnames, p_intvars);
1560 
1561  if( mps.section() == MPSInput::RHS )
1562  MPSreadRhs(mps, rset, *rnames, spxout);
1563 
1564  if( mps.section() == MPSInput::RANGES )
1565  MPSreadRanges(mps, rset, *rnames, spxout);
1566 
1567  if( mps.section() == MPSInput::BOUNDS )
1568  MPSreadBounds(mps, cset, *cnames, p_intvars, spxout);
1569 
1570  if( mps.section() != MPSInput::ENDATA )
1571  mps.syntaxError();
1572 
1573  if( mps.hasError() )
1574  clear();
1575  else
1576  {
1577  changeSense(mps.objSense() == MPSInput::MINIMIZE ? SPxLPBase<Real>::MINIMIZE : SPxLPBase<Real>::MAXIMIZE);
1578 
1579  MSG_INFO2( (*spxout), (*spxout) << "IMPSRD06 Objective sense: " << ((mps.objSense() == MPSInput::MINIMIZE) ? "Minimize\n" : "Maximize\n") );
1580 
1581  added2Set(
1582  *(reinterpret_cast<SVSetBase<Real>*>(static_cast<LPRowSetBase<Real>*>(this))),
1583  *(reinterpret_cast<SVSetBase<Real>*>(static_cast<LPColSetBase<Real>*>(this))),
1584  cset.num());
1585  addedCols(cset.num());
1586 
1587  assert(isConsistent());
1588  }
1589 
1590  if( p_cnames == 0 )
1591  {
1592  cnames->~NameSet();
1593  spx_free(cnames);
1594  }
1595 
1596  if( p_rnames == 0 )
1597  {
1598  rnames->~NameSet();
1599  spx_free(rnames);
1600  }
1601 
1602  return !mps.hasError();
1603 }
1604 
1605 
1606 
1607 // ---------------------------------------------------------------------------------------------------------------------
1608 // Specialization for writing LP format
1609 // ---------------------------------------------------------------------------------------------------------------------
1610 
1611 // get the name of a row or construct one
1612 static const char* LPFgetRowName(
1613  const SPxLPBase<Real>& p_lp,
1614  int p_idx,
1615  const NameSet* p_rnames,
1616  char* p_buf,
1617  int p_num_written_rows
1618  )
1619 {
1620  assert(p_buf != 0);
1621  assert(p_idx >= 0);
1622  assert(p_idx < p_lp.nRows());
1623 
1624  if( p_rnames != 0 )
1625  {
1626  DataKey key = p_lp.rId(p_idx);
1627 
1628  if( p_rnames->has(key) )
1629  return (*p_rnames)[key];
1630  }
1631 
1632  sprintf(p_buf, "C%d", p_num_written_rows);
1633 
1634  return p_buf;
1635 }
1636 
1637 
1638 
1639 // get the name of a column or construct one
1640 static const char* getColName(
1641  const SPxLPBase<Real>& p_lp,
1642  int p_idx,
1643  const NameSet* p_cnames,
1644  char* p_buf
1645  )
1646 {
1647  assert(p_buf != 0);
1648  assert(p_idx >= 0);
1649  assert(p_idx < p_lp.nCols());
1650 
1651  if( p_cnames != 0 )
1652  {
1653  DataKey key = p_lp.cId(p_idx);
1654 
1655  if( p_cnames->has(key) )
1656  return (*p_cnames)[key];
1657  }
1658 
1659  sprintf(p_buf, "x%d", p_idx);
1660 
1661  return p_buf;
1662 }
1663 
1664 
1665 
1666 // write an SVector
1667 #define NUM_ENTRIES_PER_LINE 5
1668 static void LPFwriteSVector(
1669  const SPxLPBase<Real>& p_lp, ///< the LP
1670  std::ostream& p_output, ///< output stream
1671  const NameSet* p_cnames, ///< column names
1672  const SVectorBase<Real>& p_svec ) ///< vector to write
1673 {
1674 
1675  char name[16];
1676  int num_coeffs = 0;
1677 
1678  for( int j = 0; j < p_lp.nCols(); ++j )
1679  {
1680  const Real coeff = p_svec[j];
1681 
1682  if( coeff == 0 )
1683  continue;
1684 
1685  if( num_coeffs == 0 )
1686  p_output << coeff << " " << getColName(p_lp, j, p_cnames, name);
1687  else
1688  {
1689  // insert a line break every NUM_ENTRIES_PER_LINE columns
1690  if( num_coeffs % NUM_ENTRIES_PER_LINE == 0 )
1691  p_output << "\n\t";
1692 
1693  if( coeff < 0 )
1694  p_output << " - " << -coeff;
1695  else
1696  p_output << " + " << coeff;
1697 
1698  p_output << " " << getColName(p_lp, j, p_cnames, name);
1699  }
1700 
1701  ++num_coeffs;
1702  }
1703 }
1704 
1705 
1706 
1707 // write the objective
1708 static void LPFwriteObjective(
1709  const SPxLPBase<Real>& p_lp, ///< the LP
1710  std::ostream& p_output, ///< output stream
1711  const NameSet* p_cnames ///< column names
1712  )
1713 {
1714 
1715  const int sense = p_lp.spxSense();
1716 
1717  p_output << ((sense == SPxLPBase<Real>::MINIMIZE) ? "Minimize\n" : "Maximize\n");
1718  p_output << " obj: ";
1719 
1720  const VectorBase<Real>& obj = p_lp.maxObj();
1721  DSVectorBase<Real> svec(obj.dim());
1722  svec.operator=(obj);
1723  svec *= Real(sense);
1724  LPFwriteSVector(p_lp, p_output, p_cnames, svec);
1725  p_output << "\n";
1726 }
1727 
1728 
1729 
1730 // write non-ranged rows
1731 static void LPFwriteRow(
1732  const SPxLPBase<Real>& p_lp, ///< the LP
1733  std::ostream& p_output, ///< output stream
1734  const NameSet* p_cnames, ///< column names
1735  const SVectorBase<Real>& p_svec, ///< vector of the row
1736  const Real& p_lhs, ///< lhs of the row
1737  const Real& p_rhs ///< rhs of the row
1738  )
1739 {
1740 
1741  LPFwriteSVector(p_lp, p_output, p_cnames, p_svec);
1742 
1743  if( p_lhs == p_rhs )
1744  p_output << " = " << p_rhs;
1745  else if( p_lhs <= -infinity )
1746  p_output << " <= " << p_rhs;
1747  else
1748  {
1749  assert(p_rhs >= infinity);
1750  p_output << " >= " << p_lhs;
1751  }
1752 
1753  p_output << "\n";
1754 }
1755 
1756 
1757 
1758 // write all rows
1759 static void LPFwriteRows(
1760  const SPxLPBase<Real>& p_lp, ///< the LP
1761  std::ostream& p_output, ///< output stream
1762  const NameSet* p_rnames, ///< row names
1763  const NameSet* p_cnames ///< column names
1764  )
1765 {
1766 
1767  char name[16];
1768 
1769  p_output << "Subject To\n";
1770 
1771  int num_written_rows = 0; // num_written_rows > nRows with ranged rows
1772  for( int i = 0; i < p_lp.nRows(); ++i )
1773  {
1774  const Real lhs = p_lp.lhs(i);
1775  const Real rhs = p_lp.rhs(i);
1776 
1777  if( lhs > -infinity && rhs < infinity && lhs != rhs )
1778  {
1779  // ranged row -> write two non-ranged rows
1780  p_output << " " << LPFgetRowName(p_lp, i, p_rnames, name, ++num_written_rows) << "_1 : ";
1781  LPFwriteRow(p_lp, p_output, p_cnames, p_lp.rowVector(i), lhs, infinity);
1782 
1783  p_output << " " << LPFgetRowName(p_lp, i, p_rnames, name, ++num_written_rows) << "_2 : ";
1784  LPFwriteRow(p_lp, p_output, p_cnames, p_lp.rowVector(i), -infinity, rhs);
1785  }
1786  else
1787  {
1788  p_output << " " << LPFgetRowName(p_lp, i, p_rnames, name, ++num_written_rows) << " : ";
1789  LPFwriteRow(p_lp, p_output, p_cnames, p_lp.rowVector(i), lhs, rhs);
1790  }
1791  }
1792 }
1793 
1794 
1795 
1796 // write the variable bounds
1797 // (the default bounds 0 <= x <= infinity are not written)
1798 static void LPFwriteBounds(
1799  const SPxLPBase<Real>& p_lp, ///< the LP to write
1800  std::ostream& p_output, ///< output stream
1801  const NameSet* p_cnames ///< column names
1802  )
1803 {
1804 
1805  char name[16];
1806 
1807  p_output << "Bounds\n";
1808 
1809  for( int j = 0; j < p_lp.nCols(); ++j )
1810  {
1811  const Real lower = p_lp.lower(j);
1812  const Real upper = p_lp.upper(j);
1813 
1814  if( lower == upper )
1815  {
1816  p_output << " " << getColName(p_lp, j, p_cnames, name) << " = " << upper << '\n';
1817  }
1818  else if( lower > -infinity )
1819  {
1820  if( upper < infinity )
1821  {
1822  // range bound
1823  if( lower != 0 )
1824  p_output << " " << lower << " <= "
1825  << getColName(p_lp, j, p_cnames, name)
1826  << " <= " << upper << '\n';
1827  else
1828  p_output << " " << getColName(p_lp, j, p_cnames, name)
1829  << " <= " << upper << '\n';
1830  }
1831  else if( lower != 0 )
1832  p_output << " " << lower << " <= "
1833  << getColName(p_lp, j, p_cnames, name)
1834  << '\n';
1835  }
1836  else if( upper < infinity )
1837  p_output << " -Inf <= "
1838  << getColName(p_lp, j, p_cnames, name)
1839  << " <= " << upper << '\n';
1840  else
1841  p_output << " " << getColName(p_lp, j, p_cnames, name)
1842  << " free\n";
1843  }
1844 }
1845 
1846 
1847 
1848 // write the generals section
1849 static void LPFwriteGenerals(
1850  const SPxLPBase<Real>& p_lp, ///< the LP to write
1851  std::ostream& p_output, ///< output stream
1852  const NameSet* p_cnames, ///< column names
1853  const DIdxSet* p_intvars ///< integer variables
1854  )
1855 {
1856 
1857  char name[16];
1858 
1859  if( p_intvars == NULL || p_intvars->size() <= 0 )
1860  return; // no integer variables
1861 
1862  p_output << "Generals\n";
1863 
1864  for( int j = 0; j < p_lp.nCols(); ++j )
1865  if( p_intvars->number(j) >= 0 )
1866  p_output << " " << getColName(p_lp, j, p_cnames, name) << "\n";
1867 }
1868 
1869 
1870 
1871 /// Write LP in LP Format.
1872 template <>
1874  std::ostream& p_output, ///< output stream
1875  const NameSet* p_rnames, ///< row names
1876  const NameSet* p_cnames, ///< column names
1877  const DIdxSet* p_intvars ///< integer variables
1878  ) const
1879 {
1880 
1881  p_output << std::setprecision(15);
1882  LPFwriteObjective(*this, p_output, p_cnames);
1883  LPFwriteRows(*this, p_output, p_rnames, p_cnames);
1884  LPFwriteBounds(*this, p_output, p_cnames);
1885  LPFwriteGenerals(*this, p_output, p_cnames, p_intvars);
1886 
1887  p_output << "End" << std::endl;
1888 }
1889 
1890 
1891 
1892 // ---------------------------------------------------------------------------------------------------------------------
1893 // Specialization for writing MPS format
1894 // ---------------------------------------------------------------------------------------------------------------------
1895 
1896 static void MPSwriteRecord(
1897  std::ostream& os,
1898  const char* indicator,
1899  const char* name,
1900  const char* name1 = 0,
1901  const Real value1 = 0.0,
1902  const char* name2 = 0,
1903  const Real value2 = 0.0
1904  )
1905 {
1906  char buf[81];
1907 
1908  sprintf(buf, " %-2.2s %-8.8s", (indicator == 0) ? "" : indicator, (name == 0) ? "" : name);
1909  os << buf;
1910 
1911  if( name1 != 0 )
1912  {
1913  sprintf(buf, " %-8.8s %.15" REAL_FORMAT, name1, value1);
1914  os << buf;
1915 
1916  if( name2 != 0 )
1917  {
1918  sprintf(buf, " %-8.8s %.15" REAL_FORMAT, name2, value2);
1919  os << buf;
1920  }
1921  }
1922 
1923  os << std::endl;
1924 }
1925 
1926 
1927 
1928 static Real MPSgetRHS(Real left, Real right)
1929 {
1930  Real rhsval;
1931 
1932  if( left > -infinity ) /// This includes ranges
1933  rhsval = left;
1934  else if( right < infinity )
1935  rhsval = right;
1936  else
1937  throw SPxInternalCodeException("XMPSWR01 This should never happen.");
1938 
1939  return rhsval;
1940 }
1941 
1942 
1943 
1944 static const char* MPSgetRowName(
1945  const SPxLPBase<Real>& lp,
1946  int idx,
1947  const NameSet* rnames,
1948  char* buf
1949  )
1950 {
1951  assert(buf != 0);
1952  assert(idx >= 0);
1953  assert(idx < lp.nRows());
1954 
1955  if( rnames != 0 )
1956  {
1957  DataKey key = lp.rId(idx);
1958 
1959  if( rnames->has(key) )
1960  return (*rnames)[key];
1961  }
1962 
1963  sprintf(buf, "C%d", idx);
1964 
1965  return buf;
1966 }
1967 
1968 
1969 
1970 /// Write LP in MPS format.
1971 /** @note There will always be a BOUNDS section, even if there are no bounds.
1972  */
1973 template <>
1975  std::ostream& p_output, ///< output stream.
1976  const NameSet* p_rnames, ///< row names.
1977  const NameSet* p_cnames, ///< column names.
1978  const DIdxSet* p_intvars ///< integer variables.
1979  ) const
1980 {
1981 
1982  const char* indicator;
1983  char name [16];
1984  char name1[16];
1985  char name2[16];
1986  bool has_ranges = false;
1987  int i;
1988  int k;
1989 
1990  // --- NAME Section ---
1991  p_output << "NAME MPSDATA" << std::endl;
1992 
1993  // --- ROWS Section ---
1994  p_output << "ROWS" << std::endl;
1995 
1996  for( i = 0; i < nRows(); i++ )
1997  {
1998  if( lhs(i) == rhs(i) )
1999  indicator = "E";
2000  else if( (lhs(i) > -infinity) && (rhs(i) < infinity) )
2001  {
2002  indicator = "E";
2003  has_ranges = true;
2004  }
2005  else if( lhs(i) > -infinity )
2006  indicator = "G";
2007  else if( rhs(i) < infinity )
2008  indicator = "L";
2009  else
2010  throw SPxInternalCodeException("XMPSWR02 This should never happen.");
2011 
2012  MPSwriteRecord(p_output, indicator, MPSgetRowName(*this, i, p_rnames, name));
2013  }
2014 
2015  MPSwriteRecord(p_output, "N", "MINIMIZE");
2016 
2017  // --- COLUMNS Section ---
2018  p_output << "COLUMNS" << std::endl;
2019 
2020  bool has_intvars = (p_intvars != 0) && (p_intvars->size() > 0);
2021 
2022  for( int j = 0; j < (has_intvars ? 2 : 1); j++ )
2023  {
2024  bool is_intrun = has_intvars && (j == 1);
2025 
2026  if( is_intrun )
2027  p_output << " MARK0001 'MARKER' 'INTORG'" << std::endl;
2028 
2029  for( i = 0; i < nCols(); i++ )
2030  {
2031  bool is_intvar = has_intvars && (p_intvars->number(i) >= 0);
2032 
2033  if( ( is_intrun && !is_intvar) || (!is_intrun && is_intvar) )
2034  continue;
2035 
2036  const SVectorBase<Real>& col = colVector(i);
2037  int colsize2 = (col.size() / 2) * 2;
2038 
2039  assert(colsize2 % 2 == 0);
2040 
2041  for( k = 0; k < colsize2; k += 2 )
2042  MPSwriteRecord(p_output, 0, getColName(*this, i, p_cnames, name),
2043  MPSgetRowName(*this, col.index(k), p_rnames, name1), col.value(k),
2044  MPSgetRowName(*this, col.index(k + 1), p_rnames, name2), col.value(k + 1));
2045 
2046  if( colsize2 != col.size() )
2047  MPSwriteRecord(p_output, 0, getColName(*this, i, p_cnames, name),
2048  MPSgetRowName(*this, col.index(k), p_rnames, name1), col.value(k));
2049 
2050  if( isNotZero(maxObj(i)) )
2051  MPSwriteRecord(p_output, 0, getColName(*this, i, p_cnames, name), "MINIMIZE", -maxObj(i));
2052  }
2053 
2054  if( is_intrun )
2055  p_output << " MARK0001 'MARKER' 'INTEND'" << std::endl;
2056  }
2057 
2058  // --- RHS Section ---
2059  p_output << "RHS" << std::endl;
2060 
2061  i = 0;
2062  while( i < nRows() )
2063  {
2064  Real rhsval1 = 0.0;
2065  Real rhsval2 = 0.0;
2066 
2067  for( ; i < nRows(); i++ )
2068  if( (rhsval1 = MPSgetRHS(lhs(i), rhs(i))) != 0.0 )
2069  break;
2070 
2071  if( i < nRows() )
2072  {
2073  for( k = i + 1; k < nRows(); k++ )
2074  {
2075  if( (rhsval2 = MPSgetRHS(lhs(k), rhs(k))) != 0.0 )
2076  break;
2077  }
2078 
2079  if( k < nRows() )
2080  {
2081  MPSwriteRecord(p_output, 0, "RHS", MPSgetRowName(*this, i, p_rnames, name1), rhsval1,
2082  MPSgetRowName(*this, k, p_rnames, name2), rhsval2);
2083  }
2084  else
2085  MPSwriteRecord(p_output, 0, "RHS", MPSgetRowName(*this, i, p_rnames, name1), rhsval1);
2086 
2087  i = k + 1;
2088  }
2089  }
2090 
2091  // --- RANGES Section ---
2092  if( has_ranges )
2093  {
2094  p_output << "RANGES" << std::endl;
2095 
2096  for( i = 0; i < nRows(); i++ )
2097  {
2098  if( (lhs(i) > -infinity) && (rhs(i) < infinity) )
2099  MPSwriteRecord(p_output, "", "RANGE", MPSgetRowName(*this, i, p_rnames, name1), rhs(i) - lhs(i));
2100  }
2101  }
2102 
2103  // --- BOUNDS Section ---
2104  p_output << "BOUNDS" << std::endl;
2105 
2106  for( i = 0; i < nCols(); i++ )
2107  {
2108  // skip variables that do not appear in the objective function or any constraint
2109  const SVectorBase<Real>& col = colVector(i);
2110 
2111  if( col.size() == 0 && isZero(maxObj(i)) )
2112  continue;
2113 
2114  if( lower(i) == upper(i) )
2115  {
2116  MPSwriteRecord(p_output, "FX", "BOUND", getColName(*this, i, p_cnames, name1), lower(i));
2117  continue;
2118  }
2119 
2120  if( (lower(i) <= -infinity) && (upper(i) >= infinity) )
2121  {
2122  MPSwriteRecord(p_output, "FR", "BOUND", getColName(*this, i, p_cnames, name1));
2123  continue;
2124  }
2125 
2126  if( lower(i) != 0.0 )
2127  {
2128  if( lower(i) > -infinity )
2129  MPSwriteRecord(p_output, "LO", "BOUND", getColName(*this, i, p_cnames, name1), lower(i));
2130  else
2131  MPSwriteRecord(p_output, "MI", "BOUND", getColName(*this, i, p_cnames, name1));
2132  }
2133 
2134  if( has_intvars && (p_intvars->number(i) >= 0) )
2135  {
2136  // Integer variables have default upper bound 1.0, but we should write
2137  // it nevertheless since CPLEX seems to assume infinity otherwise.
2138  MPSwriteRecord(p_output, "UP", "BOUND", getColName(*this, i, p_cnames, name1), upper(i));
2139  }
2140  else
2141  {
2142  // Continous variables have default upper bound infinity
2143  if( upper(i) < infinity )
2144  MPSwriteRecord(p_output, "UP", "BOUND", getColName(*this, i, p_cnames, name1), upper(i));
2145  }
2146  }
2147 
2148  // --- ENDATA Section ---
2149  p_output << "ENDATA" << std::endl;
2150 
2151  // Output warning when writing a maximisation problem
2152  if( spxSense() == SPxLPBase<Real>::MAXIMIZE )
2153  {
2154  MSG_WARNING( (*spxout), (*spxout) << "XMPSWR03 Warning: objective function inverted when writing maximization problem in MPS file format\n" );
2155  }
2156 }
2157 
2158 
2159 
2160 // ---------------------------------------------------------------------------------------------------------------------
2161 // Explicit instantiation
2162 // ---------------------------------------------------------------------------------------------------------------------
2163 
2164 template class SPxLPBase < Real >;
2165 
2166 } // namespace soplex
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3925
static int LPFreadColName(char *&pos, NameSet *colnames, LPColSetBase< Rational > &colset, const LPColBase< Rational > *emptycol, SPxOut *spxout)
Read the next column name from the input.
bool isNotZero(Real a, Real eps=Param::epsilon())
returns true iff |a| > eps
Definition: spxdefines.h:413
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
static void MPSreadCols(MPSInput &mps, const LPRowSetBase< Real > &rset, const NameSet &rnames, LPColSetBase< Real > &cset, NameSet &cnames, DIdxSet *intvars)
Process COLUMNS section.
static bool LPFisValue(const char *s)
Is there a number at the beginning of s ?
void memRemax(int newmax)
Resets length of nonzero memory.
Definition: lpcolsetbase.h:523
static Rational LPFreadInfinity(char *&pos)
#define INIT_NZOS
initialy allocated non zeros.
static bool LPFisFree(const char *s)
const VectorBase< R > & lhs() const
Returns the vector of lhs values.
Definition: lprowsetbase.h:93
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:384
void entryIgnored(const char *what, const char *what_name, const char *entity, const char *entity_name)
Definition: mpsinput.h:205
const char * probName() const
Definition: mpsinput.h:156
static void MPSreadRanges(MPSInput &mps, LPRowSetBase< Real > &rset, const NameSet &rnames, SPxOut *spxout)
Process RANGES section.
Read MPS format files.
int num() const
Returns the number of LPColBases currently in LPColSetBase.
Definition: lpcolsetbase.h:80
static Real LPFreadValue(char *&pos, SPxOut *spxout)
Read the next number and advance pos.
Exception classes for SoPlex.
int num() const
Returns the number of LPRowBases in LPRowSetBase.
Definition: lprowsetbase.h:81
const char * field0() const
Definition: mpsinput.h:144
const char * field2() const
Definition: mpsinput.h:148
static void MPSreadObjsen(MPSInput &mps)
Process OBJSEN section. This Section is an ILOG extension.
#define INIT_COLS
Read LP in MPS File Format.
bool NE(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| > eps
Definition: spxdefines.h:377
int size() const
Number of used indices.
Definition: svectorbase.h:152
void syntaxError()
Definition: mpsinput.h:198
static Real MPSgetRHS(Real left, Real right)
int num() const
returns nr. of names in NameSet.
Definition: nameset.h:168
static Rational LPFreadValue(char *&pos, SPxOut *spxout, const int lineno=-1)
Read the next number and advance pos.
const VectorBase< R > & lower() const
Returns lower bound vector.
Definition: spxlpbase.h:420
void add(const LPColBase< R > &pcol)
Definition: lpcolsetbase.h:253
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:254
static void LPFwriteSVector(const SPxLPBase< Real > &p_lp, std::ostream &p_output, const NameSet *p_cnames, const SVectorBase< Real > &p_svec)
VectorBase< R > & lhs_w()
Returns the vector of lhs values.
Definition: lprowsetbase.h:99
VectorBase< R > & maxObj_w()
Returns vector of objective values w.r.t. maximization.
Definition: lpcolsetbase.h:98
void remove(int n, int m)
Remove nonzeros n thru m.
Definition: svectorbase.h:361
static void LPFwriteGenerals(const SPxLPBase< Real > &p_lp, std::ostream &p_output, const NameSet *p_cnames, const DIdxSet *p_intvars)
VectorBase< R > & lower_w()
Returns vector of lower bound values.
Definition: lpcolsetbase.h:134
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:402
#define REAL_FORMAT
Definition: spxdefines.h:204
void add(const LPRowBase< R > &row)
Definition: lprowsetbase.h:319
VectorBase< R > & upper_w()
Returns vector of upper bound values.
Definition: lpcolsetbase.h:170
static void LPFwriteRow(const SPxLPBase< Real > &p_lp, std::ostream &p_output, const NameSet *p_cnames, const SVectorBase< Real > &p_svec, const Real &p_lhs, const Real &p_rhs)
bool isInteger() const
Definition: mpsinput.h:164
Saving LPs in a form suitable for SoPlex.
Entry identifier class for items of a DataSet.Every item in a DataSet is assigned a DataKey by which ...
Definition: datakey.h:46
static void LPFwriteObjective(const SPxLPBase< Real > &p_lp, std::ostream &p_output, const NameSet *p_cnames)
static const char * getColName(const SPxLPBase< Real > &p_lp, int p_idx, const NameSet *p_cnames, char *p_buf)
Wrapper for different output streams and verbosity levels.
void add(const SVectorBase< S > &vec)
Append nonzeros of sv.
Definition: dsvectorbase.h:216
Section section() const
Definition: mpsinput.h:140
Exception class for out of memory exceptions.This class is derived from the SoPlex exception base cla...
Definition: exceptions.h:70
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
static Real LPFreadInfinity(char *&pos)
bool readLine()
reads an MPS format data line and parse the fields.
Definition: mpsinput.cpp:57
static void MPSreadBounds(MPSInput &mps, LPColSetBase< Real > &cset, const NameSet &cnames, DIdxSet *intvars, SPxOut *spxout)
Process BOUNDS section.
static bool LPFhasRowName(char *&pos, NameSet *rownames)
If buf start with "name:" store the name in rownames and advance pos.
#define NUM_ENTRIES_PER_LINE
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
static void LPFwriteRows(const SPxLPBase< Real > &p_lp, std::ostream &p_output, const NameSet *p_rnames, const NameSet *p_cnames)
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:115
static bool LPFisSense(const char *s)
Is there a comparison operator at the beginning of s ?
#define MSG_DEBUG(x)
Definition: spxdefines.h:127
int number(int i) const
returns the position number of index i.
Definition: idxset.cpp:32
int number(int i) const
Number of index i.
Definition: svectorbase.h:185
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:236
SPxRowId rId(int n) const
Returns the row identifier for row n.
Definition: spxlpbase.h:470
int size() const
returns the number of used indices.
Definition: idxset.h:124
Wrapper for several output streams. A verbosity level is used to decide which stream to use and wheth...
Definition: spxout.h:63
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:133
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:75
virtual bool readLPF(std::istream &in, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
Reads LP in LP format from input stream in.
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:109
static int LPFreadColName(char *&pos, NameSet *colnames, LPColSetBase< Real > &colset, const LPColBase< Real > *emptycol, SPxOut *spxout)
Read the next column name from the input.
static const char * LPFgetRowName(const SPxLPBase< Real > &p_lp, int p_idx, const NameSet *p_rnames, char *p_buf, int p_num_written_rows)
const VectorBase< R > & lower() const
Definition: lpcolsetbase.h:128
Dynamic index set.Class DIdxSet provides dynamic IdxSet in the sense, that no restrictions are posed ...
Definition: didxset.h:42
int dim() const
Dimension of vector.
Definition: vectorbase.h:174
void add(const char *str)
Definition: nameset.cpp:25
void setObjSense(Sense sense)
Definition: mpsinput.h:188
static void MPSreadRows(MPSInput &mps, LPRowSetBase< Real > &rset, NameSet &rnames, SPxOut *spxout)
Process ROWS section.
(In)equality for LPs.Class LPRowBase provides constraints for linear programs in the form where a is...
Definition: lprowbase.h:45
void setSection(Section p_section)
Definition: mpsinput.h:171
void clear()
removes all names from NameSet.
Definition: nameset.cpp:131
void setObjName(const char *p_objname)
Definition: mpsinput.h:182
Debugging, floating point type and parameter definitions.
Set of strings.Class NameSet implements a symbol or name table. It allows to store or remove names (i...
Definition: nameset.h:61
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:127
void setLhs(const R &p_left)
Sets left-hand side value.
Definition: lprowbase.h:209
bool hasError() const
Definition: mpsinput.h:162
bool EQ(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| <= eps
Definition: spxdefines.h:371
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:242
const char * field1() const
Definition: mpsinput.h:146
Everything should be within this namespace.
const char * field3() const
Definition: mpsinput.h:150
static void LPFwriteBounds(const SPxLPBase< Real > &p_lp, std::ostream &p_output, const NameSet *p_cnames)
static void MPSreadObjname(MPSInput &mps)
Process OBJNAME section. This Section is an ILOG extension.
void clear()
Remove all indices.
Definition: svectorbase.h:396
Saving LPs in a form suitable for SoPlex.Class SPxLPBase provides the data structures required for sa...
Definition: spxlpbase.h:76
#define LPF_MAX_LINE_LEN
maximum length of a line (8190 + \n + \0)
void setObj(const R &p_object)
Sets objective value.
Definition: lpcolbase.h:119
SPxColId cId(int n) const
Returns the column identifier for column n.
Definition: spxlpbase.h:476
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:111
void setRowVector(const DSVectorBase< R > &p_vec)
access constraint row vector.
Definition: lprowbase.h:245
const char * field4() const
Definition: mpsinput.h:152
static void MPSreadRhs(MPSInput &mps, LPRowSetBase< Real > &rset, const NameSet &rnames, SPxOut *spxout)
Process RHS section.
const VectorBase< R > & upper() const
Definition: lpcolsetbase.h:164
int number(const DataKey &pkey) const
returns number of name with DataKey pkey in NameSet.
Definition: nameset.h:212
static int LPFreadSense(char *&pos)
Read the next <,>,=,==,<=,=<,>=,=> and advance pos.
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:438
void setProbName(const char *p_probname)
Definition: mpsinput.h:176
static bool LPFisColName(const char *s)
Is there a possible column name at the beginning of s ?
static bool LPFhasKeyword(char *&pos, const char *keyword)
Is the keyword present in buf ? If yes, advance pos.
const Real infinity
Definition: spxdefines.cpp:26
const VectorBase< R > & rhs() const
Returns the vector of rhs values.
Definition: lprowsetbase.h:129
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:224
void insertName(const char *name, bool second=false)
Inserts name as field 1 and shifts all other fields up.
Definition: mpsinput.cpp:250
static bool LPFisSpace(int c)
Is c a space, tab, nl or cr ?
#define ROWS
Definition: spxmainsm.cpp:48
static const char * MPSgetRowName(const SPxLPBase< Real > &lp, int idx, const NameSet *rnames, char *buf)
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:212
bool isZero(Real a, Real eps=Param::epsilon())
returns true iff |a| <= eps
Definition: spxdefines.h:407
void setColVector(const SVectorBase< R > &p_vec)
Sets constraint column vector.
Definition: lpcolbase.h:154
const char * field5() const
Definition: mpsinput.h:154
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:117
VectorBase< R > & rhs_w()
Returns the vector of rhs values (writeable).
Definition: lprowsetbase.h:135
Sense objSense() const
Definition: mpsinput.h:160
void reMax(int newmax=0)
Reallocates memory to be able to store newmax LPColBases.
Definition: lpcolsetbase.h:502
void setRhs(const R &p_right)
Sets right-hand side value.
Definition: lprowbase.h:221
bool has(int pnum) const
does NameSet has a name with number pnum?
Definition: nameset.h:231
~NameSet()
destructor.
Definition: nameset.cpp:259
LP column.Class LPColBase provides a datatype for storing the column of an LP a the form similar to ...
Definition: lpcolbase.h:45
const char * objName() const
Definition: mpsinput.h:158
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:109
static void MPSreadName(MPSInput &mps, SPxOut *spxout)
Process NAME section.
static bool LPFisInfinity(const char *s)
static void MPSwriteRecord(std::ostream &os, const char *indicator, const char *name, const char *name1=0, const Real value1=0.0, const char *name2=0, const Real value2=0.0)