Scippy

SoPlex

Sequential object-oriented simPlex

soplex.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 soplex.cpp
17  * @brief Preconfigured SoPlex LP solver
18  */
19 
20 #ifndef SOPLEX_LEGACY
21 #include <assert.h>
22 #include "limits.h"
23 #include <iostream>
24 
25 #ifndef _MSC_VER
26 #include <strings.h>
27 #endif
28 
29 #include "soplex.h"
30 #include "spxfileio.h"
31 #include "spxgithash.h"
32 #include "statistics.h"
33 #include "mpsinput.h"
34 
35 /// maximum length of lines in settings file
36 #define SET_MAX_LINE_LEN 500
37 
38 #ifdef _MSC_VER
39 #define strncasecmp _strnicmp
40 #endif
41 
42 namespace soplex
43 {
44  /// class of parameter settings
46  {
47  public:
48  /// array of names for boolean parameters
50 
51  /// array of names for integer parameters
53 
54  /// array of names for real parameters
56 
57 #ifdef SOPLEX_WITH_RATIONALPARAM
58  /// array of names for rational parameters
59  static std::string _rationalParamName[SoPlex::RATIONALPARAM_COUNT];
60 #endif
61 
62  /// array of descriptions for boolean parameters
64 
65  /// array of descriptions for integer parameters
67 
68  /// array of descriptions for real parameters
70 
71 #ifdef SOPLEX_WITH_RATIONALPARAM
72  /// array of descriptions for rational parameters
73  static std::string _rationalParamDescription[SoPlex::RATIONALPARAM_COUNT];
74 #endif
75 
76  /// array of default values for boolean parameters
78 
79  /// array of default values for integer parameters
81 
82  /// array of default values for real parameters
84 
85 #ifdef SOPLEX_WITH_RATIONALPARAM
86  /// array of default values for rational parameters
87  static Rational _rationalParamDefault[SoPlex::RATIONALPARAM_COUNT];
88 #endif
89 
90  /// array of lower bounds for int parameter values
92 
93  /// array of upper bounds for int parameter values
95 
96  /// array of lower bounds for real parameter values
98 
99  /// array of upper bounds for real parameter values
101 
102 #ifdef SOPLEX_WITH_RATIONALPARAM
103  /// array of lower bounds for rational parameter values
104  static Rational _rationalParamLower[SoPlex::RATIONALPARAM_COUNT];
105 
106  /// array of upper bounds for rational parameter values
107  static Rational _rationalParamUpper[SoPlex::RATIONALPARAM_COUNT];
108 #endif
109 
110  /// have static arrays been initialized?
112 
113  /// array of current boolean parameter values
115 
116  /// array of current integer parameter values
118 
119  /// array of current real parameter values
121 
122 #ifdef SOPLEX_WITH_RATIONALPARAM
123  /// array of current rational parameter values
124  Rational _rationalParamValues[SoPlex::RATIONALPARAM_COUNT];
125 #endif
126 
127  /// default constructor initializing default settings
129  {
130  if( !_defaultsAndBoundsInitialized )
131  {
132  // should lifting be used to reduce range of nonzero matrix coefficients?
133  _boolParamName[SoPlex::LIFTING] = "lifting";
134  _boolParamDescription[SoPlex::LIFTING] = "should lifting be used to reduce range of nonzero matrix coefficients?";
135  _boolParamDefault[SoPlex::LIFTING] = false;
136 
137  // should LP be transformed to equality form before a rational solve?
138  _boolParamName[SoPlex::EQTRANS] = "eqtrans";
139  _boolParamDescription[SoPlex::EQTRANS] = "should LP be transformed to equality form before a rational solve?";
140  _boolParamDefault[SoPlex::EQTRANS] = false;
141 
142  // should dual infeasibility be tested in order to try to return a dual solution even if primal infeasible?
143  _boolParamName[SoPlex::TESTDUALINF] = "testdualinf";
144  _boolParamDescription[SoPlex::TESTDUALINF] = "should dual infeasibility be tested in order to try to return a dual solution even if primal infeasible?";
145  _boolParamDefault[SoPlex::TESTDUALINF] = false;
146 
147  // should a rational factorization be performed after iterative refinement?
148  _boolParamName[SoPlex::RATFAC] = "ratfac";
149  _boolParamDescription[SoPlex::RATFAC] = "should a rational factorization be performed after iterative refinement?";
150  _boolParamDefault[SoPlex::RATFAC] = true;
151 
152  // should cycling solutions be accepted during iterative refinement?
153  _boolParamName[SoPlex::ACCEPTCYCLING] = "acceptcycling";
154  _boolParamDescription[SoPlex::ACCEPTCYCLING] = "should cycling solutions be accepted during iterative refinement?";
155  _boolParamDefault[SoPlex::ACCEPTCYCLING] = false;
156 
157  // apply rational reconstruction after each iterative refinement?
158  _boolParamName[SoPlex::RATREC] = "ratrec";
159  _boolParamDescription[SoPlex::RATREC] = "apply rational reconstruction after each iterative refinement?";
160  _boolParamDefault[SoPlex::RATREC] = true;
161 
162  // round scaling factors for iterative refinement to powers of two?
163  _boolParamName[SoPlex::POWERSCALING] = "powerscaling";
164  _boolParamDescription[SoPlex::POWERSCALING] = "round scaling factors for iterative refinement to powers of two?";
165  _boolParamDefault[SoPlex::POWERSCALING] = true;
166 
167  // continue iterative refinement with exact basic solution if not optimal?
168  _boolParamName[SoPlex::RATFACJUMP] = "ratfacjump";
169  _boolParamDescription[SoPlex::RATFACJUMP] = "continue iterative refinement with exact basic solution if not optimal?";
170  _boolParamDefault[SoPlex::RATFACJUMP] = false;
171 
172  // should feasibility be tested with relaxed bounds and sides?
173  _boolParamName[SoPlex::FEASRELAX] = "feasrelax";
174  _boolParamDescription[SoPlex::FEASRELAX] = "should feasibility be tested with relaxed bounds and sides?";
175  _boolParamDefault[SoPlex::FEASRELAX] = false;
176 
177  // use bound flipping also for row representation?
178  _boolParamName[SoPlex::ROWBOUNDFLIPS] = "rowboundflips";
179  _boolParamDescription[SoPlex::ROWBOUNDFLIPS] = "use bound flipping also for row representation?";
180  _boolParamDefault[SoPlex::ROWBOUNDFLIPS] = false;
181 
182  // objective sense
183  _intParamName[SoPlex::OBJSENSE] = "objsense";
184  _intParamDescription[SoPlex::OBJSENSE] = "objective sense (-1 - minimize, +1 - maximize)";
185  _intParamLower[SoPlex::OBJSENSE] = -1;
186  _intParamUpper[SoPlex::OBJSENSE] = 1;
187  _intParamDefault[SoPlex::OBJSENSE] = SoPlex::OBJSENSE_MAXIMIZE;
188 
189  // type of computational form, i.e., column or row representation
190  _intParamName[SoPlex::REPRESENTATION] = "representation";
191  _intParamDescription[SoPlex::REPRESENTATION] = "type of computational form (0 - auto, 1 - column representation, 2 - row representation)";
192  _intParamLower[SoPlex::REPRESENTATION] = 0;
193  _intParamUpper[SoPlex::REPRESENTATION] = 2;
195 
196  // type of algorithm, i.e., primal or dual
197  _intParamName[SoPlex::ALGORITHM] = "algorithm";
198  _intParamDescription[SoPlex::ALGORITHM] = "type of algorithm (0 - primal, 1 - dual)";
199  _intParamLower[SoPlex::ALGORITHM] = 0;
200  _intParamUpper[SoPlex::ALGORITHM] = 1;
201  _intParamDefault[SoPlex::ALGORITHM] = SoPlex::ALGORITHM_DUAL;
202 
203  // type of LU update
204  _intParamName[SoPlex::FACTOR_UPDATE_TYPE] = "factor_update_type";
205  _intParamDescription[SoPlex::FACTOR_UPDATE_TYPE] = "type of LU update (0 - eta update, 1 - Forrest-Tomlin update)";
206  _intParamLower[SoPlex::FACTOR_UPDATE_TYPE] = 0;
207  _intParamUpper[SoPlex::FACTOR_UPDATE_TYPE] = 1;
209 
210  ///@todo which value?
211  // maximum number of updates without fresh factorization
212  _intParamName[SoPlex::FACTOR_UPDATE_MAX] = "factor_update_max";
213  _intParamDescription[SoPlex::FACTOR_UPDATE_MAX] = "maximum number of LU updates without fresh factorization";
214  _intParamLower[SoPlex::FACTOR_UPDATE_MAX] = 0;
215  _intParamUpper[SoPlex::FACTOR_UPDATE_MAX] = INT_MAX;
216  _intParamDefault[SoPlex::FACTOR_UPDATE_MAX] = 200;
217 
218  // iteration limit (-1 if unlimited)
219  _intParamName[SoPlex::ITERLIMIT] = "iterlimit";
220  _intParamDescription[SoPlex::ITERLIMIT] = "iteration limit (-1 - no limit)";
221  _intParamLower[SoPlex::ITERLIMIT] = -1;
222  _intParamUpper[SoPlex::ITERLIMIT] = INT_MAX;
223  _intParamDefault[SoPlex::ITERLIMIT] = -1;
224 
225  // refinement limit (-1 if unlimited)
226  _intParamName[SoPlex::REFLIMIT] = "reflimit";
227  _intParamDescription[SoPlex::REFLIMIT] = "refinement limit (-1 - no limit)";
228  _intParamLower[SoPlex::REFLIMIT] = -1;
229  _intParamUpper[SoPlex::REFLIMIT] = INT_MAX;
230  _intParamDefault[SoPlex::REFLIMIT] = -1;
231 
232  // stalling refinement limit (-1 if unlimited)
233  _intParamName[SoPlex::STALLREFLIMIT] = "stallreflimit";
234  _intParamDescription[SoPlex::STALLREFLIMIT] = "stalling refinement limit (-1 - no limit)";
235  _intParamLower[SoPlex::STALLREFLIMIT] = -1;
236  _intParamUpper[SoPlex::STALLREFLIMIT] = INT_MAX;
237  _intParamDefault[SoPlex::STALLREFLIMIT] = -1;
238 
239  // display frequency
240  _intParamName[SoPlex::DISPLAYFREQ] = "displayfreq";
241  _intParamDescription[SoPlex::DISPLAYFREQ] = "display frequency";
242  _intParamLower[SoPlex::DISPLAYFREQ] = 1;
243  _intParamUpper[SoPlex::DISPLAYFREQ] = INT_MAX;
244  _intParamDefault[SoPlex::DISPLAYFREQ] = 200;
245 
246  // verbosity level
247  _intParamName[SoPlex::VERBOSITY] = "verbosity";
248  _intParamDescription[SoPlex::VERBOSITY] = "verbosity level (0 - error, 1 - warning, 2 - debug, 3 - normal, 4 - high, 5 - full)";
249  _intParamLower[SoPlex::VERBOSITY] = 0;
250  _intParamUpper[SoPlex::VERBOSITY] = 5;
251  _intParamDefault[SoPlex::VERBOSITY] = SoPlex::VERBOSITY_NORMAL;
252 
253  // type of simplifier
254  _intParamName[SoPlex::SIMPLIFIER] = "simplifier";
255  _intParamDescription[SoPlex::SIMPLIFIER] = "simplifier (0 - off, 1 - auto)";
256  _intParamLower[SoPlex::SIMPLIFIER] = 0;
257  _intParamUpper[SoPlex::SIMPLIFIER] = 1;
258  _intParamDefault[SoPlex::SIMPLIFIER] = SoPlex::SIMPLIFIER_AUTO;
259 
260  // type of scaler
261  _intParamName[SoPlex::SCALER] = "scaler";
262  _intParamDescription[SoPlex::SCALER] = "scaling (0 - off, 1 - uni-equilibrium, 2 - bi-equilibrium, 3 - geometric, 4 - iterated geometric)";
263  _intParamLower[SoPlex::SCALER] = 0;
264  _intParamUpper[SoPlex::SCALER] = 4;
265  _intParamDefault[SoPlex::SCALER] = SoPlex::SCALER_BIEQUI;
266 
267  // type of starter used to create crash basis
268  _intParamName[SoPlex::STARTER] = "starter";
269  _intParamDescription[SoPlex::STARTER] = "crash basis generated when starting from scratch (0 - none, 1 - weight, 2 - sum, 3 - vector)";
270  _intParamLower[SoPlex::STARTER] = 0;
271  _intParamUpper[SoPlex::STARTER] = 3;
272  _intParamDefault[SoPlex::STARTER] = SoPlex::STARTER_OFF;
273 
274  // type of pricer
275  _intParamName[SoPlex::PRICER] = "pricer";
276  _intParamDescription[SoPlex::PRICER] = "pricing method (0 - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)";
277  _intParamLower[SoPlex::PRICER] = 0;
278  _intParamUpper[SoPlex::PRICER] = 5;
279  _intParamDefault[SoPlex::PRICER] = SoPlex::PRICER_AUTO;
280 
281  // type of ratio test
282  _intParamName[SoPlex::RATIOTESTER] = "ratiotester";
283  _intParamDescription[SoPlex::RATIOTESTER] = "method for ratio test (0 - textbook, 1 - harris, 2 - fast, 3 - boundflipping)";
284  _intParamLower[SoPlex::RATIOTESTER] = 0;
285  _intParamUpper[SoPlex::RATIOTESTER] = 3;
287 
288  // mode for synchronizing real and rational LP
289  _intParamName[SoPlex::SYNCMODE] = "syncmode";
290  _intParamDescription[SoPlex::SYNCMODE] = "mode for synchronizing real and rational LP (0 - store only real LP, 1 - auto, 2 - manual)";
291  _intParamLower[SoPlex::SYNCMODE] = 0;
292  _intParamUpper[SoPlex::SYNCMODE] = 2;
293  _intParamDefault[SoPlex::SYNCMODE] = SoPlex::SYNCMODE_ONLYREAL;
294 
295  // mode for reading LP files
296  _intParamName[SoPlex::READMODE] = "readmode";
297  _intParamDescription[SoPlex::READMODE] = "mode for reading LP files (0 - floating-point, 1 - rational)";
298  _intParamLower[SoPlex::READMODE] = 0;
299  _intParamUpper[SoPlex::READMODE] = 1;
300  _intParamDefault[SoPlex::READMODE] = SoPlex::READMODE_REAL;
301 
302  // mode for iterative refinement strategy
303  _intParamName[SoPlex::SOLVEMODE] = "solvemode";
304  _intParamDescription[SoPlex::SOLVEMODE] = "mode for iterative refinement strategy (0 - floating-point solve, 1 - auto, 2 - exact rational solve)";
305  _intParamLower[SoPlex::SOLVEMODE] = 0;
306  _intParamUpper[SoPlex::SOLVEMODE] = 2;
307  _intParamDefault[SoPlex::SOLVEMODE] = SoPlex::SOLVEMODE_AUTO;
308 
309  // mode for iterative refinement strategy
310  _intParamName[SoPlex::CHECKMODE] = "checkmode";
311  _intParamDescription[SoPlex::CHECKMODE] = "mode for a posteriori feasibility checks (0 - floating-point check, 1 - auto, 2 - exact rational check)";
312  _intParamLower[SoPlex::CHECKMODE] = 0;
313  _intParamUpper[SoPlex::CHECKMODE] = 2;
314  _intParamDefault[SoPlex::CHECKMODE] = SoPlex::CHECKMODE_AUTO;
315 
316  // type of timing
317  _intParamName[SoPlex::TIMER] = "timer";
318  _intParamDescription[SoPlex::TIMER] = "type of timer (1 - cputime, aka. usertime, 2 - wallclock time, 0 - no timing)";
319  _intParamLower[SoPlex::TIMER] = 0;
320  _intParamUpper[SoPlex::TIMER] = 2;
321  _intParamDefault[SoPlex::TIMER] = SoPlex::TIMER_CPU;
322 
323  // mode for hyper sparse pricing
324  _intParamName[SoPlex::HYPER_PRICING] = "hyperpricing";
325  _intParamDescription[SoPlex::HYPER_PRICING] = "mode for hyper sparse pricing (0 - off, 1 - auto, 2 - always)";
326  _intParamLower[SoPlex::HYPER_PRICING] = 0;
327  _intParamUpper[SoPlex::HYPER_PRICING] = 2;
329 
330  // minimum number of stalling refinements since last pivot to trigger rational factorization
331  _intParamName[SoPlex::RATFAC_MINSTALLS] = "ratfac_minstalls";
332  _intParamDescription[SoPlex::RATFAC_MINSTALLS] = "minimum number of stalling refinements since last pivot to trigger rational factorization";
333  _intParamLower[SoPlex::RATFAC_MINSTALLS] = 0;
334  _intParamUpper[SoPlex::RATFAC_MINSTALLS] = INT_MAX;
335  _intParamDefault[SoPlex::RATFAC_MINSTALLS] = 2;
336 
337  // primal feasibility tolerance
338  _realParamName[SoPlex::FEASTOL] = "feastol";
339  _realParamDescription[SoPlex::FEASTOL] = "primal feasibility tolerance";
340  _realParamLower[SoPlex::FEASTOL] = 0.0;
341  _realParamUpper[SoPlex::FEASTOL] = 1.0;
342  _realParamDefault[SoPlex::FEASTOL] = 1e-6;
343 
344  // dual feasibility tolerance
345  _realParamName[SoPlex::OPTTOL] = "opttol";
346  _realParamDescription[SoPlex::OPTTOL] = "dual feasibility tolerance";
347  _realParamLower[SoPlex::OPTTOL] = 0.0;
348  _realParamUpper[SoPlex::OPTTOL] = 1.0;
349  _realParamDefault[SoPlex::OPTTOL] = 1e-6;
350 
351  ///@todo define suitable values depending on Real type
352  // general zero tolerance
353  _realParamName[SoPlex::EPSILON_ZERO] = "epsilon_zero";
354  _realParamDescription[SoPlex::EPSILON_ZERO] = "general zero tolerance";
355  _realParamLower[SoPlex::EPSILON_ZERO] = 0.0;
356  _realParamUpper[SoPlex::EPSILON_ZERO] = 1.0;
357  _realParamDefault[SoPlex::EPSILON_ZERO] = DEFAULT_EPS_ZERO;
358 
359  ///@todo define suitable values depending on Real type
360  // zero tolerance used in factorization
361  _realParamName[SoPlex::EPSILON_FACTORIZATION] = "epsilon_factorization";
362  _realParamDescription[SoPlex::EPSILON_FACTORIZATION] = "zero tolerance used in factorization";
363  _realParamLower[SoPlex::EPSILON_FACTORIZATION] = 0.0;
364  _realParamUpper[SoPlex::EPSILON_FACTORIZATION] = 1.0;
366 
367  ///@todo define suitable values depending on Real type
368  // zero tolerance used in update of the factorization
369  _realParamName[SoPlex::EPSILON_UPDATE] = "epsilon_update";
370  _realParamDescription[SoPlex::EPSILON_UPDATE] = "zero tolerance used in update of the factorization";
371  _realParamLower[SoPlex::EPSILON_UPDATE] = 0.0;
372  _realParamUpper[SoPlex::EPSILON_UPDATE] = 1.0;
373  _realParamDefault[SoPlex::EPSILON_UPDATE] = DEFAULT_EPS_UPDATE;
374 
375  ///@todo define suitable values depending on Real type
376  // pivot zero tolerance used in factorization
377  _realParamName[SoPlex::EPSILON_PIVOT] = "epsilon_pivot";
378  _realParamDescription[SoPlex::EPSILON_PIVOT] = "pivot zero tolerance used in factorization";
379  _realParamLower[SoPlex::EPSILON_PIVOT] = 0.0;
380  _realParamUpper[SoPlex::EPSILON_PIVOT] = 1.0;
381  _realParamDefault[SoPlex::EPSILON_PIVOT] = DEFAULT_EPS_PIVOT;
382 
383  ///@todo define suitable values depending on Real type
384  // infinity threshold
385  _realParamName[SoPlex::INFTY] = "infty";
386  _realParamDescription[SoPlex::INFTY] = "infinity threshold";
387  _realParamLower[SoPlex::INFTY] = 1e10;
388  _realParamUpper[SoPlex::INFTY] = 1e100;
389  _realParamDefault[SoPlex::INFTY] = DEFAULT_INFINITY;
390 
391  // time limit in seconds (INFTY if unlimited)
392  _realParamName[SoPlex::TIMELIMIT] = "timelimit";
393  _realParamDescription[SoPlex::TIMELIMIT] = "time limit in seconds";
394  _realParamLower[SoPlex::TIMELIMIT] = 0.0;
395  _realParamUpper[SoPlex::TIMELIMIT] = DEFAULT_INFINITY;
396  _realParamDefault[SoPlex::TIMELIMIT] = DEFAULT_INFINITY;
397 
398  // lower limit on objective value
399  _realParamName[SoPlex::OBJLIMIT_LOWER] = "objlimit_lower";
400  _realParamDescription[SoPlex::OBJLIMIT_LOWER] = "lower limit on objective value";
401  _realParamLower[SoPlex::OBJLIMIT_LOWER] = -DEFAULT_INFINITY;
402  _realParamUpper[SoPlex::OBJLIMIT_LOWER] = DEFAULT_INFINITY;
403  _realParamDefault[SoPlex::OBJLIMIT_LOWER] = -DEFAULT_INFINITY;
404 
405  // upper limit on objective value
406  _realParamName[SoPlex::OBJLIMIT_UPPER] = "objlimit_upper";
407  _realParamDescription[SoPlex::OBJLIMIT_UPPER] = "upper limit on objective value";
408  _realParamLower[SoPlex::OBJLIMIT_UPPER] = -DEFAULT_INFINITY;
409  _realParamUpper[SoPlex::OBJLIMIT_UPPER] = DEFAULT_INFINITY;
410  _realParamDefault[SoPlex::OBJLIMIT_UPPER] = DEFAULT_INFINITY;
411 
412  // working tolerance for feasibility in floating-point solver during iterative refinement
413  _realParamName[SoPlex::FPFEASTOL] = "fpfeastol";
414  _realParamDescription[SoPlex::FPFEASTOL] = "working tolerance for feasibility in floating-point solver during iterative refinement";
415  _realParamLower[SoPlex::FPFEASTOL] = 1e-12;
416  _realParamUpper[SoPlex::FPFEASTOL] = 1.0;
417  _realParamDefault[SoPlex::FPFEASTOL] = 1e-9;
418 
419  // working tolerance for optimality in floating-point solver during iterative refinement
420  _realParamName[SoPlex::FPOPTTOL] = "fpopttol";
421  _realParamDescription[SoPlex::FPOPTTOL] = "working tolerance for optimality in floating-point solver during iterative refinement";
422  _realParamLower[SoPlex::FPOPTTOL] = 1e-12;
423  _realParamUpper[SoPlex::FPOPTTOL] = 1.0;
424  _realParamDefault[SoPlex::FPOPTTOL] = 1e-9;
425 
426  // maximum increase of scaling factors between refinements
427  _realParamName[SoPlex::MAXSCALEINCR] = "maxscaleincr";
428  _realParamDescription[SoPlex::MAXSCALEINCR] = "maximum increase of scaling factors between refinements";
429  _realParamLower[SoPlex::MAXSCALEINCR] = 1.0;
430  _realParamUpper[SoPlex::MAXSCALEINCR] = DEFAULT_INFINITY;
431  _realParamDefault[SoPlex::MAXSCALEINCR] = 1e25;
432 
433  // lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)
434  _realParamName[SoPlex::LIFTMINVAL] = "liftminval";
435  _realParamDescription[SoPlex::LIFTMINVAL] = "lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)";
436  _realParamLower[SoPlex::LIFTMINVAL] = 0.0;
437  _realParamUpper[SoPlex::LIFTMINVAL] = 0.1;
438  _realParamDefault[SoPlex::LIFTMINVAL] = 0.000976562; // = 1/1024
439 
440  // upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulated)
441  _realParamName[SoPlex::LIFTMAXVAL] = "liftmaxval";
442  _realParamDescription[SoPlex::LIFTMAXVAL] = "lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)";
443  _realParamLower[SoPlex::LIFTMAXVAL] = 10.0;
444  _realParamUpper[SoPlex::LIFTMAXVAL] = DEFAULT_INFINITY;
445  _realParamDefault[SoPlex::LIFTMAXVAL] = 1024.0;
446 
447  // threshold for using sparse pricing (no. of violations need to be smaller than threshold * dimension of problem)
448  _realParamName[SoPlex::SPARSITY_THRESHOLD] = "sparsity_threshold";
449  _realParamDescription[SoPlex::SPARSITY_THRESHOLD] = "sparse pricing threshold (#violations < dimension * SPARSITY_THRESHOLD activates sparse pricing)";
450  _realParamLower[SoPlex::SPARSITY_THRESHOLD] = 0.0;
451  _realParamUpper[SoPlex::SPARSITY_THRESHOLD] = 1.0;
452  _realParamDefault[SoPlex::SPARSITY_THRESHOLD] = 0.6;
453 
454  // threshold on number of rows vs. number of columns for switching from column to row representations in auto mode
455  _realParamName[SoPlex::REPRESENTATION_SWITCH] = "representation_switch";
456  _realParamDescription[SoPlex::REPRESENTATION_SWITCH] = "threshold on number of rows vs. number of columns for switching from column to row representations in auto mode";
457  _realParamLower[SoPlex::REPRESENTATION_SWITCH] = 0.0;
459  _realParamDefault[SoPlex::REPRESENTATION_SWITCH] = DEFAULT_INFINITY;
460 
461  // geometric frequency at which to apply rational reconstruction
462  _realParamName[SoPlex::RATREC_FREQ] = "ratrec_freq";
463  _realParamDescription[SoPlex::RATREC_FREQ] = "geometric frequency at which to apply rational reconstruction";
464  _realParamLower[SoPlex::RATREC_FREQ] = 1.0;
465  _realParamUpper[SoPlex::RATREC_FREQ] = DEFAULT_INFINITY;
466  _realParamDefault[SoPlex::RATREC_FREQ] = 1.2;
467 
468  // minimal reduction (sum of removed rows/cols) to continue simplification
469  _realParamName[SoPlex::MINRED] = "minred";
470  _realParamDescription[SoPlex::MINRED] = "minimal reduction (sum of removed rows/cols) to continue simplification";
471  _realParamLower[SoPlex::MINRED] = 0.0;
472  _realParamUpper[SoPlex::MINRED] = 1.0;
473  _realParamDefault[SoPlex::MINRED] = 1e-4;
474 
475  _defaultsAndBoundsInitialized = true;
476  }
477 
478  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
479  _boolParamValues[i] = _boolParamDefault[i];
480 
481  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
482  _intParamValues[i] = _intParamDefault[i];
483 
484  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
485  _realParamValues[i] = _realParamDefault[i];
486 
487 #ifdef SOPLEX_WITH_RATIONALPARAM
488  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
489  _rationalParamValues[i] = _rationalParamDefault[i];
490 #endif
491  }
492 
493  /// copy constructor
495  {
496  *this = settings;
497  }
498 
499  /// assignment operator
501  {
502  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
503  _boolParamValues[i] = settings._boolParamValues[i];
504 
505  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
506  _intParamValues[i] = settings._intParamValues[i];
507 
508  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
509  _realParamValues[i] = settings._realParamValues[i];
510 
511 #ifdef SOPLEX_WITH_RATIONALPARAM
512  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
513  _rationalParamValues[i] = settings._rationalParamValues[i];
514 #endif
515 
516  return *this;
517  }
518  };
519 
520 
521 
523 
524 
525 
529 
530 
531 
537 
538 
539 
545 
546 
547 
548 #ifdef SOPLEX_WITH_RATIONALPARAM
549  std::string SoPlex::Settings::_rationalParamName[SoPlex::RATIONALPARAM_COUNT];
550  std::string SoPlex::Settings::_rationalParamDescription[SoPlex::RATIONALPARAM_COUNT];
551  Rational SoPlex::Settings::_rationalParamLower[SoPlex::RATIONALPARAM_COUNT];
552  Rational SoPlex::Settings::_rationalParamUpper[SoPlex::RATIONALPARAM_COUNT];
553  Rational SoPlex::Settings::_rationalParamDefault[SoPlex::RATIONALPARAM_COUNT];
554 #endif
555 
556 
557 
558  /// default constructor
560  : _statistics(0)
561  , _currentSettings(0)
562  , _scalerUniequi(false)
563  , _scalerBiequi(true)
564  , _scalerGeo1(1)
565  , _scalerGeo8(8)
566  , _simplifier(0)
567  , _scaler(0)
568  , _starter(0)
569  , _rationalLP(0)
571  , _status(SPxSolver::UNKNOWN)
572  , _hasBasis(false)
573  , _hasSolReal(false)
574  , _hasSolRational(false)
575  {
576  // transfer message handler
582 
583  // give lu factorization to solver
585 
586  // the real LP is initially stored in the solver; the rational LP is constructed, when the parameter SYNCMODE is
587  // initialized in setSettings() below
588  _realLP = &_solver;
589  _isRealLPLoaded = true;
591 
592  // initialize statistics
595 
596  // initialize parameter settings to default
599  setSettings(*_currentSettings, true, true);
600 
602 
603  assert(_isConsistent());
604  }
605 
606 
607 
608  /// assignment operator
610  {
611  if( this != &rhs )
612  {
613  // copy message handler
614  spxout = rhs.spxout;
615 
616  // copy statistics
617  *_statistics = *(rhs._statistics);
618 
619  // copy settings
621 
622  // copy solver components
623  _solver = rhs._solver;
624  _slufactor = rhs._slufactor;
628  _scalerGeo1 = rhs._scalerGeo1;
629  _scalerGeo8 = rhs._scalerGeo8;
631  _starterSum = rhs._starterSum;
633  _pricerAuto = rhs._pricerAuto;
643 
644  // copy solution data
645  _status = rhs._status;
649 
650  if( rhs._hasSolReal )
651  _solReal = rhs._solReal;
652 
653  if( rhs._hasSolRational )
655 
656  // set message handlers in members
662 
663  // transfer the lu solver
665 
666  // initialize pointers for simplifier, scaler, and starter
670 
671  // copy real LP if different from the LP in the solver
672  if( rhs._realLP != &(rhs._solver) )
673  {
674  _realLP = 0;
676  _realLP = new (_realLP) SPxLPReal(*(rhs._realLP));
677  }
678  else
679  _realLP = &_solver;
680 
681  // copy rational LP
682  if( rhs._rationalLP == 0 )
683  {
685  _rationalLP = 0;
686  }
687  else
688  {
690  _rationalLP = 0;
693  }
694 
695  // copy boolean flags
697  _hasSolReal = rhs._hasSolReal;
699  _hasBasis = rhs._hasBasis;
700  }
701 
702  assert(_isConsistent());
703 
704  return *this;
705  }
706 
707 
708 
709  /// copy constructor
710  ///@todo improve performance by implementing a separate copy constructor
711  SoPlex::SoPlex(const SoPlex& rhs)
712  {
713  // allocate memory as in default constructor
714  _statistics = 0;
717 
718  _currentSettings = 0;
721 
722  // call assignment operator
723  *this = rhs;
724  }
725 
726 
727 
728  /// destructor
730  {
731  assert(_isConsistent());
732 
733  // free settings
734  _currentSettings->~Settings();
736 
737  // free statistics
740 
741  // free real LP if different from the LP in the solver
742  assert(_realLP != 0);
743  if( _realLP != &_solver )
744  {
745  _realLP->~SPxLPReal();
746  spx_free(_realLP);
747  }
748 
749  // free rational LP
750  if( _rationalLP != 0 )
751  {
752  _rationalLP->~SPxLPRational();
754  }
755 
756  // free unit vectors
757  for( int i = 0; i < _unitMatrixRational.size(); i++ )
758  {
759  if( _unitMatrixRational[i] != 0 )
760  {
761  _unitMatrixRational[i]->~UnitVectorRational();
763  }
764  }
765  }
766 
767 
768 
769  /// returns number of rows
771  {
772  assert(_realLP != 0);
773  return _realLP->nRows();
774  }
775 
776 
777 
778  /// returns number of columns
780  {
781  assert(_realLP != 0);
782  return _realLP->nCols();
783  }
784 
785 
786 
787  /// returns number of nonzeros
789  {
790  assert(_realLP != 0);
791  return _realLP->nNzos();
792  }
793 
794 
795 
796  /// returns smallest non-zero element in absolute value
798  {
799  assert(_realLP != 0);
800  return _realLP->minAbsNzo();
801  }
802 
803 
804 
805  /// returns biggest non-zero element in absolute value
807  {
808  assert(_realLP != 0);
809  return _realLP->maxAbsNzo();
810  }
811 
812 
813 
814  /// gets row \p i
815  void SoPlex::getRowReal(int i, LPRowReal& lprow) const
816  {
817  assert(_realLP != 0);
818  _realLP->getRow(i, lprow);
819  }
820 
821 
822 
823  /// gets rows \p start, ..., \p end.
824  void SoPlex::getRowsReal(int start, int end, LPRowSetReal& lprowset) const
825  {
826  assert(_realLP != 0);
827  _realLP->getRows(start, end, lprowset);
828  }
829 
830 
831 
832  /// returns vector of row \p i
833  const SVectorReal& SoPlex::rowVectorReal(int i) const
834  {
835  assert(_realLP != 0);
836  return _realLP->rowVector(i);
837  }
838 
839 
840 
841  /// returns right-hand side vector
843  {
844  assert(_realLP != 0);
845  return _realLP->rhs();
846  }
847 
848 
849 
850  /// returns right-hand side of row \p i
851  Real SoPlex::rhsReal(int i) const
852  {
853  assert(_realLP != 0);
854  return _realLP->rhs(i);
855  }
856 
857 
858 
859  /// returns left-hand side vector
861  {
862  assert(_realLP != 0);
863  return _realLP->lhs();
864  }
865 
866 
867 
868  /// returns left-hand side of row \p i
869  Real SoPlex::lhsReal(int i) const
870  {
871  assert(_realLP != 0);
872  return _realLP->lhs(i);
873  }
874 
875 
876 
877  /// returns inequality type of row \p i
879  {
880  assert(_realLP != 0);
881  return _realLP->rowType(i);
882  }
883 
884 
885 
886  /// gets column \p i
887  void SoPlex::getColReal(int i, LPColReal& lpcol) const
888  {
889  assert(_realLP != 0);
890  return _realLP->getCol(i, lpcol);
891  }
892 
893 
894 
895  /// gets columns \p start, ..., \p end
896  void SoPlex::getColsReal(int start, int end, LPColSetReal& lpcolset) const
897  {
898  assert(_realLP != 0);
899  return _realLP->getCols(start, end, lpcolset);
900  }
901 
902 
903 
904  /// returns vector of column \p i
905  const SVectorReal& SoPlex::colVectorReal(int i) const
906  {
907  assert(_realLP != 0);
908  return _realLP->colVector(i);
909  }
910 
911 
912 
913  /// returns upper bound vector
915  {
916  assert(_realLP != 0);
917  return _realLP->upper();
918  }
919 
920 
921 
922  /// returns upper bound of column \p i
923  Real SoPlex::upperReal(int i) const
924  {
925  assert(_realLP != 0);
926  return _realLP->upper(i);
927  }
928 
929 
930 
931  /// returns lower bound vector
933  {
934  assert(_realLP != 0);
935  return _realLP->lower();
936  }
937 
938 
939 
940  /// returns lower bound of column \p i
941  Real SoPlex::lowerReal(int i) const
942  {
943  assert(_realLP != 0);
944  return _realLP->lower(i);
945  }
946 
947 
948 
949  /// gets objective function vector
951  {
952  assert(_realLP != 0);
953  _realLP->getObj(obj);
954  }
955 
956 
957 
958  /// returns objective value of column \p i
959  Real SoPlex::objReal(int i) const
960  {
961  assert(_realLP != 0);
962  return _realLP->obj(i);
963  }
964 
965 
966 
967  /// returns objective function vector after transformation to a maximization problem; since this is how it is stored
968  /// internally, this is generally faster
970  {
971  assert(_realLP != 0);
972  return _realLP->maxObj();
973  }
974 
975 
976 
977  /// returns objective value of column \p i after transformation to a maximization problem; since this is how it is
978  /// stored internally, this is generally faster
980  {
981  assert(_realLP != 0);
982  return _realLP->maxObj(i);
983  }
984 
985 
986 
987  /// gets number of available dual norms
988  void SoPlex::getNdualNorms(int& nnormsRow, int& nnormsCol) const
989  {
990  _solver.getNdualNorms(nnormsRow, nnormsCol);
991  }
992 
993 
994 
995  /// gets steepest edge norms and returns false if they are not available
996  bool SoPlex::getDualNorms(int& nnormsRow, int& nnormsCol, Real* norms) const
997  {
998  return _solver.getDualNorms(nnormsRow, nnormsCol, norms);
999  }
1000 
1001 
1002 
1003  /// sets steepest edge norms and returns false if that's not possible
1004  bool SoPlex::setDualNorms(int nnormsRow, int nnormsCol, Real* norms)
1005  {
1006  return _solver.setDualNorms(nnormsRow, nnormsCol, norms);
1007  }
1008 
1009 
1010 
1011  /// returns number of rows
1013  {
1014  assert(_rationalLP != 0);
1015  return _rationalLP->nRows();
1016  }
1017 
1018 
1019 
1020  /// returns number of columns
1022  {
1023  assert(_rationalLP != 0);
1024  return _rationalLP->nCols();
1025  }
1026 
1027 
1028 
1029  /// returns number of nonzeros
1031  {
1032  assert(_rationalLP != 0);
1033  return _rationalLP->nNzos();
1034  }
1035 
1036 
1037 
1038  /// returns smallest non-zero element in absolute value
1040  {
1041  assert(_rationalLP != 0);
1042  return _rationalLP->minAbsNzo();
1043  }
1044 
1045 
1046 
1047  /// returns biggest non-zero element in absolute value
1049  {
1050  assert(_rationalLP != 0);
1051  return _rationalLP->maxAbsNzo();
1052  }
1053 
1054 
1055 
1056  /// gets row \p i
1057  void SoPlex::getRowRational(int i, LPRowRational& lprow) const
1058  {
1059  assert(_rationalLP != 0);
1060  _rationalLP->getRow(i, lprow);
1061  }
1062 
1063 
1064 
1065  /// gets rows \p start, ..., \p end.
1066  void SoPlex::getRowsRational(int start, int end, LPRowSetRational& lprowset) const
1067  {
1068  assert(_rationalLP != 0);
1069  _rationalLP->getRows(start, end, lprowset);
1070  }
1071 
1072 
1073 
1074  /// returns vector of row \p i
1076  {
1077  assert(_rationalLP != 0);
1078  return _rationalLP->rowVector(i);
1079  }
1080 
1081 
1082 
1083  /// returns right-hand side vector
1085  {
1086  assert(_rationalLP != 0);
1087  return _rationalLP->rhs();
1088  }
1089 
1090 
1091 
1092  /// returns right-hand side of row \p i
1093  const Rational& SoPlex::rhsRational(int i) const
1094  {
1095  assert(_rationalLP != 0);
1096  return _rationalLP->rhs(i);
1097  }
1098 
1099 
1100 
1101  /// returns left-hand side vector
1103  {
1104  assert(_rationalLP != 0);
1105  return _rationalLP->lhs();
1106  }
1107 
1108 
1109 
1110  /// returns left-hand side of row \p i
1111  const Rational& SoPlex::lhsRational(int i) const
1112  {
1113  assert(_rationalLP != 0);
1114  return _rationalLP->lhs(i);
1115  }
1116 
1117 
1118 
1119  /// returns inequality type of row \p i
1121  {
1122  assert(_rationalLP != 0);
1123  return _rationalLP->rowType(i);
1124  }
1125 
1126 
1127 
1128  /// gets column \p i
1129  void SoPlex::getColRational(int i, LPColRational& lpcol) const
1130  {
1131  assert(_rationalLP != 0);
1132  return _rationalLP->getCol(i, lpcol);
1133  }
1134 
1135 
1136 
1137  /// gets columns \p start, ..., \p end
1138  void SoPlex::getColsRational(int start, int end, LPColSetRational& lpcolset) const
1139  {
1140  assert(_rationalLP != 0);
1141  return _rationalLP->getCols(start, end, lpcolset);
1142  }
1143 
1144 
1145 
1146  /// returns vector of column \p i
1148  {
1149  assert(_rationalLP != 0);
1150  return _rationalLP->colVector(i);
1151  }
1152 
1153 
1154 
1155  /// returns upper bound vector
1157  {
1158  assert(_rationalLP != 0);
1159  return _rationalLP->upper();
1160  }
1161 
1162 
1163 
1164  /// returns upper bound of column \p i
1165  const Rational& SoPlex::upperRational(int i) const
1166  {
1167  assert(_rationalLP != 0);
1168  return _rationalLP->upper(i);
1169  }
1170 
1171 
1172 
1173  /// returns lower bound vector
1175  {
1176  assert(_rationalLP != 0);
1177  return _rationalLP->lower();
1178  }
1179 
1180 
1181 
1182  /// returns lower bound of column \p i
1183  const Rational& SoPlex::lowerRational(int i) const
1184  {
1185  assert(_rationalLP != 0);
1186  return _rationalLP->lower(i);
1187  }
1188 
1189 
1190 
1191  /// gets objective function vector
1193  {
1194  assert(_rationalLP != 0);
1195  _rationalLP->getObj(obj);
1196  }
1197 
1198 
1199 
1200  /// gets objective value of column \p i
1201  void SoPlex::getObjRational(int i, Rational& obj) const
1202  {
1203  obj = maxObjRational(i);
1205  obj *= -1;
1206  }
1207 
1208 
1209 
1210  /// returns objective value of column \p i
1212  {
1213  assert(_rationalLP != 0);
1214  return _rationalLP->obj(i);
1215  }
1216 
1217 
1218 
1219  /// returns objective function vector after transformation to a maximization problem; since this is how it is stored
1220  /// internally, this is generally faster
1222  {
1223  assert(_rationalLP != 0);
1224  return _rationalLP->maxObj();
1225  }
1226 
1227 
1228 
1229  /// returns objective value of column \p i after transformation to a maximization problem; since this is how it is
1230  /// stored internally, this is generally faster
1231  const Rational& SoPlex::maxObjRational(int i) const
1232  {
1233  assert(_rationalLP != 0);
1234  return _rationalLP->maxObj(i);
1235  }
1236 
1237 
1238 
1239  /// adds a single row
1240  void SoPlex::addRowReal(const LPRowReal& lprow)
1241  {
1242  assert(_realLP != 0);
1243 
1244  _addRowReal(lprow);
1245 
1247  {
1248  _rationalLP->addRow(lprow);
1249  _rowTypes.append(_rangeTypeReal(lprow.lhs(), lprow.rhs()));
1250  }
1251 
1253  }
1254 
1255 
1256 
1257  /// adds multiple rows
1258  void SoPlex::addRowsReal(const LPRowSetReal& lprowset)
1259  {
1260  assert(_realLP != 0);
1261 
1262  _addRowsReal(lprowset);
1263 
1265  {
1266  _rationalLP->addRows(lprowset);
1267  for( int i = 0; i < lprowset.num(); i++ )
1268  _rowTypes.append(_rangeTypeReal(lprowset.lhs(i), lprowset.rhs(i)));
1269  }
1270 
1272  }
1273 
1274 
1275 
1276  /// adds a single column
1277  void SoPlex::addColReal(const LPColReal& lpcol)
1278  {
1279  assert(_realLP != 0);
1280 
1281  _addColReal(lpcol);
1282 
1284  {
1285  _rationalLP->addCol(lpcol);
1286  _colTypes.append(_rangeTypeReal(lpcol.lower(), lpcol.upper()));
1287  }
1288 
1290  }
1291 
1292 
1293 
1294  /// adds multiple columns
1295  void SoPlex::addColsReal(const LPColSetReal& lpcolset)
1296  {
1297  assert(_realLP != 0);
1298 
1299  _addColsReal(lpcolset);
1300 
1302  {
1303  _rationalLP->addCols(lpcolset);
1304  for( int i = 0; i < lpcolset.num(); i++ )
1305  _colTypes.append(_rangeTypeReal(lpcolset.lower(i), lpcolset.upper(i)));
1306  }
1307 
1309  }
1310 
1311 
1312 
1313  /// replaces row \p i with \p lprow
1314  void SoPlex::changeRowReal(int i, const LPRowReal& lprow)
1315  {
1316  assert(_realLP != 0);
1317 
1318  _changeRowReal(i, lprow);
1319 
1321  {
1322  _rationalLP->changeRow(i, lprow);
1323  _rowTypes[i] = _rangeTypeReal(lprow.lhs(), lprow.rhs());
1324  }
1325 
1327  }
1328 
1329 
1330 
1331  /// changes left-hand side vector for constraints to \p lhs
1333  {
1334  assert(_realLP != 0);
1335 
1336  _changeLhsReal(lhs);
1337 
1339  {
1341  for( int i = 0; i < numRowsRational(); i++ )
1343  }
1344 
1346  }
1347 
1348 
1349 
1350  /// changes left-hand side of row \p i to \p lhs
1351  void SoPlex::changeLhsReal(int i, const Real& lhs)
1352  {
1353  assert(_realLP != 0);
1354 
1355  _changeLhsReal(i, lhs);
1356 
1358  {
1359  _rationalLP->changeLhs(i, lhs);
1361  }
1362 
1364  }
1365 
1366 
1367 
1368  /// changes right-hand side vector to \p rhs
1370  {
1371  assert(_realLP != 0);
1372 
1373  _changeRhsReal(rhs);
1374 
1376  {
1378  for( int i = 0; i < numRowsRational(); i++ )
1380  }
1381 
1383  }
1384 
1385 
1386 
1387  /// changes right-hand side of row \p i to \p rhs
1388  void SoPlex::changeRhsReal(int i, const Real& rhs)
1389  {
1390  assert(_realLP != 0);
1391 
1392  _changeRhsReal(i, rhs);
1393 
1395  {
1396  _rationalLP->changeRhs(i, rhs);
1398  }
1399 
1401  }
1402 
1403 
1404 
1405  /// changes left- and right-hand side vectors
1406  void SoPlex::changeRangeReal(const VectorReal& lhs, const VectorReal& rhs)
1407  {
1408  assert(_realLP != 0);
1409 
1410  _changeRangeReal(lhs, rhs);
1411 
1413  {
1415  for( int i = 0; i < numRowsRational(); i++ )
1416  _rowTypes[i] = _rangeTypeReal(lhs[i], rhs[i]);
1417  }
1418 
1420  }
1421 
1422 
1423 
1424  /// changes left- and right-hand side of row \p i
1425  void SoPlex::changeRangeReal(int i, const Real& lhs, const Real& rhs)
1426  {
1427  assert(_realLP != 0);
1428 
1429  _changeRangeReal(i,lhs, rhs);
1430 
1432  {
1433  _rationalLP->changeRange(i, lhs, rhs);
1434  _rowTypes[i] = _rangeTypeReal(lhs, rhs);
1435  }
1436 
1438  }
1439 
1440 
1441 
1442  /// replaces column \p i with \p lpcol
1443  void SoPlex::changeColReal(int i, const LPColReal& lpcol)
1444  {
1445  assert(_realLP != 0);
1446 
1447  _changeColReal(i, lpcol);
1448 
1450  {
1451  _rationalLP->changeCol(i, lpcol);
1452  _colTypes[i] = _rangeTypeReal(lpcol.lower(), lpcol.upper());
1453  }
1454 
1456  }
1457 
1458 
1459 
1460  /// changes vector of lower bounds to \p lower
1462  {
1463  assert(_realLP != 0);
1464 
1465  _changeLowerReal(lower);
1466 
1468  {
1470  for( int i = 0; i < numColsRational(); i++ )
1472  }
1473 
1474 
1476  }
1477 
1478 
1479 
1480  /// changes lower bound of column i to \p lower
1481  void SoPlex::changeLowerReal(int i, const Real& lower)
1482  {
1483  assert(_realLP != 0);
1484 
1485  _changeLowerReal(i, lower);
1486 
1488  {
1489  _rationalLP->changeLower(i, lower);
1491  }
1492 
1494  }
1495 
1496 
1497 
1498  /// changes vector of upper bounds to \p upper
1500  {
1501  assert(_realLP != 0);
1502 
1503  _changeUpperReal(upper);
1504 
1506  {
1508  for( int i = 0; i < numColsRational(); i++ )
1510  }
1511 
1513  }
1514 
1515 
1516 
1517  /// changes \p i 'th upper bound to \p upper
1518  void SoPlex::changeUpperReal(int i, const Real& upper)
1519  {
1520  assert(_realLP != 0);
1521 
1522  _changeUpperReal(i, upper);
1523 
1525  {
1526  _rationalLP->changeUpper(i, upper);
1528  }
1529 
1531  }
1532 
1533 
1534 
1535  /// changes vectors of column bounds to \p lower and \p upper
1536  void SoPlex::changeBoundsReal(const VectorReal& lower, const VectorReal& upper)
1537  {
1538  assert(_realLP != 0);
1539 
1540  _changeBoundsReal(lower, upper);
1541 
1543  {
1545  for( int i = 0; i < numColsRational(); i++ )
1546  _colTypes[i] = _rangeTypeReal(lower[i], upper[i]);
1547  }
1548 
1550  }
1551 
1552 
1553 
1554  /// changes bounds of column \p i to \p lower and \p upper
1555  void SoPlex::changeBoundsReal(int i, const Real& lower, const Real& upper)
1556  {
1557  assert(_realLP != 0);
1558 
1559  _changeBoundsReal(i, lower, upper);
1560 
1562  {
1563  _rationalLP->changeBounds(i, lower, upper);
1564  _colTypes[i] = _rangeTypeReal(lower, upper);
1565  }
1567  }
1568 
1569 
1570 
1571  /// changes objective function vector to \p obj
1573  {
1574  assert(_realLP != 0);
1575 
1576  _realLP->changeObj(obj);
1577 
1580 
1582  }
1583 
1584 
1585 
1586  /// changes objective coefficient of column i to \p obj
1587  void SoPlex::changeObjReal(int i, const Real& obj)
1588  {
1589  assert(_realLP != 0);
1590 
1591  _realLP->changeObj(i, obj);
1592 
1594  _rationalLP->changeObj(i, obj);
1595 
1597  }
1598 
1599 
1600 
1601  /// changes matrix entry in row \p i and column \p j to \p val
1602  void SoPlex::changeElementReal(int i, int j, const Real& val)
1603  {
1604  assert(_realLP != 0);
1605 
1606  _changeElementReal(i, j, val);
1607 
1609  _rationalLP->changeElement(i, j, val);
1610 
1612  }
1613 
1614 
1615 
1616  /// removes row \p i
1618  {
1619  assert(_realLP != 0);
1620 
1621  _removeRowReal(i);
1622 
1624  {
1625  _rationalLP->removeRow(i);
1626  // only swap elements if not the last one was removed
1627  if( i < _rationalLP->nRows() )
1628  {
1630  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
1631  }
1633  }
1634 
1636  }
1637 
1638 
1639 
1640  /// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
1641  /// new index where row \p i has been moved to; note that \p perm must point to an array of size at least
1642  /// #numRowsReal()
1643  void SoPlex::removeRowsReal(int perm[])
1644  {
1645  assert(_realLP != 0);
1646 
1647  const int oldsize = numRowsReal();
1648  _removeRowsReal(perm);
1649 
1651  {
1652  _rationalLP->removeRows(perm);
1653  for( int i = 0; i < oldsize; i++ )
1654  {
1655  if( perm[i] >= 0 )
1656  _rowTypes[perm[i]] = _rowTypes[i];
1657  }
1659  for( int i = 0; i < numRowsRational(); i++ )
1660  {
1661  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
1662  }
1663  }
1664 
1666  }
1667 
1668 
1669 
1670  /// remove all rows with indices in array \p idx of size \p n; an array \p perm of size #numRowsReal() may be passed
1671  /// as buffer memory
1672  void SoPlex::removeRowsReal(int idx[], int n, int perm[])
1673  {
1674  if( perm == 0 )
1675  {
1677  _idxToPerm(idx, n, p.get_ptr(), numRowsReal());
1679  }
1680  else
1681  {
1682  _idxToPerm(idx, n, perm, numRowsReal());
1683  SoPlex::removeRowsReal(perm);
1684  }
1685  }
1686 
1687 
1688 
1689  /// removes rows \p start to \p end including both; an array \p perm of size #numRowsReal() may be passed as buffer
1690  /// memory
1691  void SoPlex::removeRowRangeReal(int start, int end, int perm[])
1692  {
1693  if( perm == 0 )
1694  {
1696  _rangeToPerm(start, end, p.get_ptr(), numRowsReal());
1698  }
1699  else
1700  {
1701  _rangeToPerm(start, end, perm, numRowsReal());
1702  SoPlex::removeRowsReal(perm);
1703  }
1704  }
1705 
1706 
1707 
1708  /// removes column i
1710  {
1711  assert(_realLP != 0);
1712 
1713  _removeColReal(i);
1714 
1716  {
1717  _rationalLP->removeCol(i);
1718  // only swap elements if not the last one was removed
1719  if( i < _rationalLP->nCols() )
1720  {
1723  }
1725  }
1726 
1728  }
1729 
1730 
1731 
1732  /// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
1733  /// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
1734  /// #numColsReal()
1735  void SoPlex::removeColsReal(int perm[])
1736  {
1737  assert(_realLP != 0);
1738 
1739  const int oldsize = numColsReal();
1740  _removeColsReal(perm);
1741 
1743  {
1744  _rationalLP->removeCols(perm);
1745  for( int i = 0; i < oldsize; i++ )
1746  {
1747  if( perm[i] >= 0 )
1748  _colTypes[perm[i]] = _colTypes[i];
1749  }
1751  for( int i = 0; i < numColsRational(); i++ )
1752  {
1754  }
1755  }
1756 
1758  }
1759 
1760 
1761 
1762  /// remove all columns with indices in array \p idx of size \p n; an array \p perm of size #numColsReal() may be
1763  /// passed as buffer memory
1764  void SoPlex::removeColsReal(int idx[], int n, int perm[])
1765  {
1766  if( perm == 0 )
1767  {
1769  _idxToPerm(idx, n, p.get_ptr(), numColsReal());
1771  }
1772  else
1773  {
1774  _idxToPerm(idx, n, perm, numColsReal());
1775  SoPlex::removeColsReal(perm);
1776  }
1777  }
1778 
1779 
1780 
1781  /// removes columns \p start to \p end including both; an array \p perm of size #numColsReal() may be passed as
1782  /// buffer memory
1783  void SoPlex::removeColRangeReal(int start, int end, int perm[])
1784  {
1785  if( perm == 0 )
1786  {
1788  _rangeToPerm(start, end, p.get_ptr(), numColsReal());
1790  }
1791  else
1792  {
1793  _rangeToPerm(start, end, perm, numColsReal());
1794  SoPlex::removeColsReal(perm);
1795  }
1796  }
1797 
1798 
1799 
1800  /// clears the LP
1802  {
1803  assert(_realLP != 0);
1804 
1805  _realLP->clear();
1806  _hasBasis = false;
1807 
1809  {
1810  _rationalLP->clear();
1811  _rowTypes.clear();
1812  _colTypes.clear();
1813  }
1814 
1816  }
1817 
1818 
1819 
1820  /// synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP, if sync mode is manual
1822  {
1823  assert(_isConsistent());
1824 
1826  _syncLPReal();
1827  }
1828 
1829 
1830 
1831  /// adds a single row
1833  {
1834  assert(_rationalLP != 0);
1835 
1837  return;
1838 
1839  _rationalLP->addRow(lprow);
1840  _rowTypes.append(_rangeTypeRational(lprow.lhs(), lprow.rhs()));
1841 
1843  _addRowReal(lprow);
1844 
1846  }
1847 
1848 
1849 
1850 #ifdef SOPLEX_WITH_GMP
1851  /// adds a single row
1852  void SoPlex::addRowRational(const mpq_t* lhs, const mpq_t* rowValues, const int* rowIndices, const int rowSize, const mpq_t* rhs)
1853  {
1854  assert(_rationalLP != 0);
1855 
1857  return;
1858 
1859  _rationalLP->addRow(lhs, rowValues, rowIndices, rowSize, rhs);
1860  int i = numRowsRational() - 1;
1862 
1865 
1867  }
1868 
1869 
1870 
1871  /// adds a set of rows
1872  void SoPlex::addRowsRational(const mpq_t* lhs, const mpq_t* rowValues, const int* rowIndices, const int* rowStarts, const int* rowLengths, const int numRows, const int numValues, const mpq_t* rhs)
1873  {
1874  assert(_rationalLP != 0);
1875 
1877  return;
1878 
1879  _rationalLP->addRows(lhs, rowValues, rowIndices, rowStarts, rowLengths, numRows, numValues, rhs);
1880  for( int i = numRowsRational() - numRows; i < numRowsRational(); i++ )
1882 
1884  {
1885  LPRowSetReal lprowset;
1886  for( int i = numRowsRational() - numRows; i < numRowsRational(); i++ )
1888  _addRowsReal(lprowset);
1889  }
1890 
1892  }
1893 #endif
1894 
1895 
1896 
1897  /// adds multiple rows
1899  {
1900  assert(_rationalLP != 0);
1901 
1903  return;
1904 
1905  _rationalLP->addRows(lprowset);
1906  for( int i = 0; i < lprowset.num(); i++ )
1907  _rowTypes.append(_rangeTypeRational(lprowset.lhs(i), lprowset.rhs(i)));
1908 
1910  _addRowsReal(lprowset);
1911 
1913  }
1914 
1915 
1916 
1917  /// adds a single column
1919  {
1920  assert(_rationalLP != 0);
1921 
1923  return;
1924 
1925  _rationalLP->addCol(lpcol);
1926  _colTypes.append(_rangeTypeRational(lpcol.lower(), lpcol.upper()));
1927 
1929  _addColReal(lpcol);
1930 
1932  }
1933 
1934 
1935 
1936 #ifdef SOPLEX_WITH_GMP
1937  /// adds a single column
1938  void SoPlex::addColRational(const mpq_t* obj, const mpq_t* lower, const mpq_t* colValues, const int* colIndices, const int colSize, const mpq_t* upper)
1939  {
1940  assert(_rationalLP != 0);
1941 
1943  return;
1944 
1945  _rationalLP->addCol(obj, lower, colValues, colIndices, colSize, upper);
1946  int i = numColsRational() - 1;
1948 
1952 
1954  }
1955 
1956 
1957 
1958  /// adds a set of columns
1959  void SoPlex::addColsRational(const mpq_t* obj, const mpq_t* lower, const mpq_t* colValues, const int* colIndices, const int* colStarts, const int* colLengths, const int numCols, const int numValues, const mpq_t* upper)
1960  {
1961  assert(_rationalLP != 0);
1962 
1964  return;
1965 
1966  _rationalLP->addCols(obj, lower, colValues, colIndices, colStarts, colLengths, numCols, numValues, upper);
1967  for( int i = numColsRational() - numCols; i < numColsRational(); i++ )
1969 
1971  {
1972  LPColSetReal lpcolset;
1973  for( int i = numColsRational() - numCols; i < numColsRational(); i++ )
1974  lpcolset.add(Real(maxObjRational(i)) * (intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MAXIMIZE ? 1.0 : -1.0),
1976  _addColsReal(lpcolset);
1977  }
1978 
1980  }
1981 #endif
1982 
1983 
1984 
1985  /// adds multiple columns
1987  {
1988  assert(_rationalLP != 0);
1989 
1991  return;
1992 
1993  _rationalLP->addCols(lpcolset);
1994  for( int i = 0; i < lpcolset.num(); i++ )
1995  _colTypes.append(_rangeTypeRational(lpcolset.lower(i), lpcolset.upper(i)));
1996 
1998  _addColsReal(lpcolset);
1999 
2001  }
2002 
2003 
2004 
2005  /// replaces row \p i with \p lprow
2006  void SoPlex::changeRowRational(int i, const LPRowRational& lprow)
2007  {
2008  assert(_rationalLP != 0);
2009 
2011  return;
2012 
2013  _rationalLP->changeRow(i, lprow);
2014  _rowTypes[i] = _rangeTypeRational(lprow.lhs(), lprow.rhs());
2015 
2017  _changeRowReal(i, lprow);
2018 
2020  }
2021 
2022 
2023 
2024  /// changes left-hand side vector for constraints to \p lhs
2026  {
2027  assert(_rationalLP != 0);
2028 
2030  return;
2031 
2032  _rationalLP->changeLhs(lhs);
2033  for( int i = 0; i < numRowsRational(); i++ )
2034  _rowTypes[i] = _rangeTypeRational(lhs[i], _rationalLP->rhs(i));
2035 
2038 
2040  }
2041 
2042 
2043 
2044  /// changes left-hand side of row \p i to \p lhs
2045  void SoPlex::changeLhsRational(int i, const Rational& lhs)
2046  {
2047  assert(_rationalLP != 0);
2048 
2050  return;
2051 
2052  _rationalLP->changeLhs(i, lhs);
2054 
2056  _changeLhsReal(i, Real(lhs));
2057 
2059  }
2060 
2061 
2062 
2063 #ifdef SOPLEX_WITH_GMP
2064  /// changes left-hand side of row \p i to \p lhs
2065  void SoPlex::changeLhsRational(int i, const mpq_t* lhs)
2066  {
2067  assert(_rationalLP != 0);
2068 
2070  return;
2071 
2072  _rationalLP->changeLhs(i, lhs);
2074 
2077 
2079  }
2080 #endif
2081 
2082 
2083 
2084  /// changes right-hand side vector to \p rhs
2086  {
2087  assert(_rationalLP != 0);
2088 
2090  return;
2091 
2092  _rationalLP->changeRhs(rhs);
2093  for( int i = 0; i < numRowsRational(); i++ )
2094  _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), rhs[i]);
2095 
2098 
2100  }
2101 
2102 
2103 
2104 #ifdef SOPLEX_WITH_GMP
2105  /// changes right-hand side vector to \p rhs
2106  void SoPlex::changeRhsRational(const mpq_t* rhs, int rhsSize)
2107  {
2108  assert(_rationalLP != 0);
2109 
2111  return;
2112 
2113  for( int i = 0; i < rhsSize; i++ )
2114  {
2115  _rationalLP->changeRhs(i, rhs[i]);
2117  }
2118 
2121 
2123  }
2124 #endif
2125 
2126 
2127 
2128  /// changes right-hand side of row \p i to \p rhs
2129  void SoPlex::changeRhsRational(int i, const Rational& rhs)
2130  {
2131  assert(_rationalLP != 0);
2132 
2134  return;
2135 
2136  _rationalLP->changeRhs(i, rhs);
2138 
2140  _changeRhsReal(i, Real(rhs));
2141 
2143  }
2144 
2145 
2146 
2147  /// changes left- and right-hand side vectors
2149  {
2150  assert(_rationalLP != 0);
2151 
2153  return;
2154 
2155  _rationalLP->changeRange(lhs, rhs);
2156  for( int i = 0; i < numRowsRational(); i++ )
2157  _rowTypes[i] = _rangeTypeRational(lhs[i], rhs[i]);
2158 
2161 
2163  }
2164 
2165 
2166 
2167  /// changes left- and right-hand side of row \p i
2168  void SoPlex::changeRangeRational(int i, const Rational& lhs, const Rational& rhs)
2169  {
2170  assert(_rationalLP != 0);
2171 
2173  return;
2174 
2175  _rationalLP->changeRange(i, lhs, rhs);
2176  _rowTypes[i] = _rangeTypeRational(lhs, rhs);
2177 
2179  _changeRangeReal(i, Real(lhs), Real(rhs));
2180 
2182  }
2183 
2184 
2185 
2186 #ifdef SOPLEX_WITH_GMP
2187  /// changes left-hand side of row \p i to \p lhs
2188  void SoPlex::changeRangeRational(int i, const mpq_t* lhs, const mpq_t* rhs)
2189  {
2190  assert(_rationalLP != 0);
2191 
2193  return;
2194 
2195  _rationalLP->changeRange(i, lhs, rhs);
2197 
2200 
2202  }
2203 #endif
2204 
2205 
2206 
2207  /// replaces column \p i with \p lpcol
2208  void SoPlex::changeColRational(int i, const LPColRational& lpcol)
2209  {
2210  assert(_rationalLP != 0);
2211 
2213  return;
2214 
2215  _rationalLP->changeCol(i, lpcol);
2216  _rowTypes[i] = _rangeTypeRational(lpcol.lower(), lpcol.upper());
2217 
2219  _changeColReal(i, lpcol);
2220 
2222  }
2223 
2224 
2225 
2226  /// changes vector of lower bounds to \p lower
2228  {
2229  assert(_rationalLP != 0);
2230 
2232  return;
2233 
2234  _rationalLP->changeLower(lower);
2235  for( int i = 0; i < numColsRational(); i++ )
2236  _colTypes[i] = _rangeTypeRational(lower[i], _rationalLP->upper(i));
2237 
2239  _changeLowerReal(DVectorReal(lower));
2240 
2242  }
2243 
2244 
2245 
2246  /// changes lower bound of column i to \p lower
2247  void SoPlex::changeLowerRational(int i, const Rational& lower)
2248  {
2249  assert(_rationalLP != 0);
2250 
2252  return;
2253 
2254  _rationalLP->changeLower(i, lower);
2255  _colTypes[i] = _rangeTypeRational(lower, _rationalLP->upper(i));
2256 
2258  _changeLowerReal(i, Real(lower));
2259 
2261  }
2262 
2263 
2264 
2265 #ifdef SOPLEX_WITH_GMP
2266  /// changes lower bound of column i to \p lower
2267  void SoPlex::changeLowerRational(int i, const mpq_t* lower)
2268  {
2269  assert(_rationalLP != 0);
2270 
2272  return;
2273 
2274  _rationalLP->changeLower(i, lower);
2276 
2279 
2281  }
2282 #endif
2283 
2284 
2285 
2286  /// changes vector of upper bounds to \p upper
2288  {
2289  assert(_rationalLP != 0);
2290 
2292  return;
2293 
2294  _rationalLP->changeUpper(upper);
2295  for( int i = 0; i < numColsRational(); i++ )
2296  _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), upper[i]);
2297 
2299  _changeUpperReal(DVectorReal(upper));
2300 
2302  }
2303 
2304 
2305 
2306  /// changes \p i 'th upper bound to \p upper
2307  void SoPlex::changeUpperRational(int i, const Rational& upper)
2308  {
2309  assert(_rationalLP != 0);
2310 
2312  return;
2313 
2314  _rationalLP->changeUpper(i, upper);
2315  _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), upper);
2316 
2318  _changeUpperReal(i, Real(upper));
2319 
2321  }
2322 
2323 
2324 
2325 #ifdef SOPLEX_WITH_GMP
2326  /// changes upper bound of column i to \p upper
2327  void SoPlex::changeUpperRational(int i, const mpq_t* upper)
2328  {
2329  assert(_rationalLP != 0);
2330 
2332  return;
2333 
2334  _rationalLP->changeUpper(i, upper);
2336 
2339 
2341  }
2342 #endif
2343 
2344 
2345 
2346  /// changes vectors of column bounds to \p lower and \p upper
2348  {
2349  assert(_rationalLP != 0);
2350 
2352  return;
2353 
2354  _rationalLP->changeBounds(lower, upper);
2355  for( int i = 0; i < numColsRational(); i++ )
2356  _colTypes[i] = _rangeTypeRational(lower[i], upper[i]);
2357 
2359  _changeBoundsReal(DVectorReal(lower), DVectorReal(upper));
2360 
2362  }
2363 
2364 
2365 
2366  /// changes bounds of column \p i to \p lower and \p upper
2367  void SoPlex::changeBoundsRational(int i, const Rational& lower, const Rational& upper)
2368  {
2369  assert(_rationalLP != 0);
2370 
2372  return;
2373 
2374  _rationalLP->changeBounds(i, lower, upper);
2375  _colTypes[i] = _rangeTypeRational(lower, upper);
2376 
2378  _changeBoundsReal(i, Real(lower), Real(upper));
2379 
2381  }
2382 
2383 
2384 
2385 #ifdef SOPLEX_WITH_GMP
2386  /// changes bounds of column \p i to \p lower and \p upper
2387  void SoPlex::changeBoundsRational(int i, const mpq_t* lower, const mpq_t* upper)
2388  {
2389  assert(_rationalLP != 0);
2390 
2392  return;
2393 
2394  _rationalLP->changeBounds(i, lower, upper);
2396 
2399 
2401  }
2402 #endif
2403 
2404 
2405 
2406  /// changes objective function vector to \p obj
2408  {
2409  assert(_rationalLP != 0);
2410 
2412  return;
2413 
2414  _rationalLP->changeObj(obj);
2415 
2417  _realLP->changeObj(DVectorReal(obj));
2418 
2420  }
2421 
2422 
2423 
2424  /// changes objective coefficient of column i to \p obj
2425  void SoPlex::changeObjRational(int i, const Rational& obj)
2426  {
2427  assert(_rationalLP != 0);
2428 
2430  return;
2431 
2432  _rationalLP->changeObj(i, obj);
2433 
2435  _realLP->changeObj(i, Real(obj));
2436 
2438  }
2439 
2440 
2441 
2442 #ifdef SOPLEX_WITH_GMP
2443  /// changes objective coefficient of column i to \p obj
2444  void SoPlex::changeObjRational(int i, const mpq_t* obj)
2445  {
2446  assert(_rationalLP != 0);
2447 
2449  return;
2450 
2451  _rationalLP->changeObj(i, obj);
2452 
2454  _realLP->changeObj(i, Real(objRational(i)));
2455 
2457  }
2458 #endif
2459 
2460 
2461 
2462  /// changes matrix entry in row \p i and column \p j to \p val
2463  void SoPlex::changeElementRational(int i, int j, const Rational& val)
2464  {
2465  assert(_rationalLP != 0);
2466 
2468  return;
2469 
2470  _rationalLP->changeElement(i, j, val);
2471 
2473  _changeElementReal(i, j, Real(val));
2474 
2476  }
2477 
2478 
2479 #ifdef SOPLEX_WITH_GMP
2480  /// changes matrix entry in row \p i and column \p j to \p val
2481  void SoPlex::changeElementRational(int i, int j, const mpq_t* val)
2482  {
2483  assert(_rationalLP != 0);
2484 
2486  return;
2487 
2488  _rationalLP->changeElement(i, j, val);
2489 
2491  _changeElementReal(i, j, mpq_get_d(*val));
2492 
2494  }
2495 #endif
2496 
2497 
2498  /// removes row \p i
2500  {
2501  assert(_rationalLP != 0);
2502 
2504  return;
2505 
2506  _rationalLP->removeRow(i);
2507  // only swap elements if not the last one was removed
2508  if( i < _rationalLP->nRows() )
2509  {
2511  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
2512  }
2514 
2516  _removeRowReal(i);
2517 
2519  }
2520 
2521 
2522 
2523  /// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the new
2524  /// index where row \p i has been moved to; note that \p perm must point to an array of size at least
2525  /// #numRowsRational()
2527  {
2528  assert(_rationalLP != 0);
2529 
2531  return;
2532 
2533  const int oldsize = numRowsRational();
2534  _rationalLP->removeRows(perm);
2535  for( int i = 0; i < oldsize; i++ )
2536  {
2537  if( perm[i] >= 0 )
2538  _rowTypes[perm[i]] = _rowTypes[i];
2539  }
2541  for( int i = 0; i < numRowsRational(); i++ )
2542  {
2543  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
2544  }
2545 
2546 
2548  _removeRowsReal(perm);
2549 
2551  }
2552 
2553 
2554 
2555  /// remove all rows with indices in array \p idx of size \p n; an array \p perm of size #numRowsRational() may be
2556  /// passed as buffer memory
2557  void SoPlex::removeRowsRational(int idx[], int n, int perm[])
2558  {
2559  if( perm == 0 )
2560  {
2562  _idxToPerm(idx, n, p.get_ptr(), numRowsRational());
2564  }
2565  else
2566  {
2567  _idxToPerm(idx, n, perm, numRowsRational());
2569  }
2570  }
2571 
2572 
2573 
2574  /// removes rows \p start to \p end including both; an array \p perm of size #numRowsRational() may be passed as
2575  /// buffer memory
2576  void SoPlex::removeRowRangeRational(int start, int end, int perm[])
2577  {
2578  if( perm == 0 )
2579  {
2581  _rangeToPerm(start, end, p.get_ptr(), numRowsRational());
2583  }
2584  else
2585  {
2586  _rangeToPerm(start, end, perm, numRowsRational());
2588  }
2589  }
2590 
2591 
2592 
2593  /// removes column i
2595  {
2596  assert(_rationalLP != 0);
2597 
2599  return;
2600 
2601  _rationalLP->removeCol(i);
2602  // only swap elements if not the last one was removed
2603  if( i < _rationalLP->nCols() )
2604  {
2607  }
2609 
2611  _removeColReal(i);
2612 
2614  }
2615 
2616 
2617 
2618  /// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
2619  /// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
2620  /// #numColsRational()
2622  {
2623  assert(_rationalLP != 0);
2624 
2626  return;
2627 
2628  const int oldsize = numColsRational();
2629  _rationalLP->removeCols(perm);
2630  for( int i = 0; i < oldsize; i++ )
2631  {
2632  if( perm[i] >= 0 )
2633  _colTypes[perm[i]] = _colTypes[i];
2634  }
2636  for( int i = 0; i < numColsRational(); i++ )
2637  {
2639  }
2640 
2642  _removeColsReal(perm);
2643 
2645  }
2646 
2647 
2648 
2649  /// remove all columns with indices in array \p idx of size \p n; an array \p perm of size #numColsRational() may be
2650  /// passed as buffer memory
2651  void SoPlex::removeColsRational(int idx[], int n, int perm[])
2652  {
2653  if( perm == 0 )
2654  {
2656  _idxToPerm(idx, n, p.get_ptr(), numColsRational());
2658  }
2659  else
2660  {
2661  _idxToPerm(idx, n, perm, numColsRational());
2663  }
2664  }
2665 
2666 
2667 
2668  /// removes columns \p start to \p end including both; an array \p perm of size #numColsRational() may be passed as
2669  /// buffer memory
2670  void SoPlex::removeColRangeRational(int start, int end, int perm[])
2671  {
2672  if( perm == 0 )
2673  {
2675  _rangeToPerm(start, end, p.get_ptr(), numColsRational());
2677  }
2678  else
2679  {
2680  _rangeToPerm(start, end, perm, numColsRational());
2682  }
2683  }
2684 
2685 
2686 
2687  /// clears the LP
2689  {
2690  assert(_rationalLP != 0);
2691 
2693  return;
2694 
2695  _rationalLP->clear();
2696  _rowTypes.clear();
2697  _colTypes.clear();
2698 
2700  {
2701  _realLP->clear();
2702  _hasBasis = false;
2703  }
2704 
2706  }
2707 
2708 
2709 
2710  /// synchronizes rational LP with real LP, i.e., copies real LP to rational LP, if sync mode is manual
2712  {
2713  assert(_isConsistent());
2714 
2716  _syncLPRational();
2717  }
2718 
2719 
2720 
2721  /// solves the LP
2723  {
2724  assert(_isConsistent());
2725 
2726  // clear statistics
2728 
2729  // the solution is no longer valid
2731 
2732  // decide whether to solve the rational LP with iterative refinement or call the standard floating-point solver
2734  && GE(realParam(SoPlex::FEASTOL), 1e-9) && GE(realParam(SoPlex::OPTTOL), 1e-9)) )
2735  {
2736  // ensure that tolerances are reasonable for the floating-point solver
2738  {
2739  MSG_WARNING( spxout, spxout << "Cannot call floating-point solver with feasibility tolerance below "
2740  << _currentSettings->_realParamLower[SoPlex::FPFEASTOL] << " - relaxing tolerance\n");
2742  }
2743  else
2745 
2747  {
2748  MSG_WARNING( spxout, spxout << "Cannot call floating-point solver with optimality tolerance below "
2749  << _currentSettings->_realParamLower[SoPlex::FPOPTTOL] << " - relaxing tolerance\n");
2751  }
2752  else
2754 
2755  _solveReal();
2756  }
2758  {
2759  _syncLPRational();
2760  _solveRational();
2761  }
2763  {
2764 #ifdef ENABLE_ADDITIONAL_CHECKS
2765  assert(areLPsInSync(true, true, false));
2766 #else
2767  assert(areLPsInSync(true, false, false));
2768 #endif
2769 
2770  _solveRational();
2771 
2772 #ifdef ENABLE_ADDITIONAL_CHECKS
2773  assert(areLPsInSync(true, true, false));
2774 #else
2775  assert(areLPsInSync(true, false, false));
2776 #endif
2777  }
2778  else
2779  {
2780 #ifdef ENABLE_ADDITIONAL_CHECKS
2781  assert(areLPsInSync(true, true, false));
2782 #else
2783  assert(areLPsInSync(true, false, false));
2784 #endif
2785 
2786  _solveRational();
2787  }
2788 
2789  MSG_INFO1( spxout, spxout << "\n";
2791  spxout << "\n" );
2792 
2793  return status();
2794  }
2795 
2796 
2797 
2798  /// returns the current solver status
2800  {
2801  return _status;
2802  }
2803 
2804 
2805 
2806  /// is a primal feasible solution available?
2807  bool SoPlex::hasPrimal() const
2808  {
2810  }
2811 
2812 
2813 
2814  /// is a primal unbounded ray available?
2816  {
2818  }
2819 
2820 
2821 
2822  /// is a dual feasible solution available?
2823  bool SoPlex::hasDual() const
2824  {
2826  }
2827 
2828 
2829 
2830  /// is Farkas proof of infeasibility available?
2832  {
2834  }
2835 
2836 
2837 
2838  /// returns the objective value if a primal or dual solution is available
2840  {
2841  assert(OBJSENSE_MAXIMIZE == 1);
2842  assert(OBJSENSE_MINIMIZE == -1);
2843 
2844  if( status() == SPxSolver::UNBOUNDED )
2846  else if( status() == SPxSolver::INFEASIBLE )
2848  else if( hasPrimal() )
2849  {
2851  return _solReal._primalObjVal;
2852  }
2853  else if( hasDual() )
2854  {
2856  return _solReal._dualObjVal;
2857  }
2858  else
2859  return 0.0;
2860  }
2861 
2862 
2863 
2864  /// gets the primal solution vector if available; returns true on success
2866  {
2867  if( hasPrimal() && vector.dim() >= numColsReal() )
2868  {
2870  _solReal.getPrimal(vector);
2871  return true;
2872  }
2873  else
2874  return false;
2875  }
2876 
2877 
2878 
2879  /// gets the vector of slack values if available; returns true on success
2881  {
2882  if( hasPrimal() && vector.dim() >= numRowsReal() )
2883  {
2885  _solReal.getSlacks(vector);
2886  return true;
2887  }
2888  else
2889  return false;
2890  }
2891 
2892 
2893 
2894  /// gets the primal ray if available; returns true on success
2896  {
2897  if( hasPrimalRay() && vector.dim() >= numColsReal() )
2898  {
2900  _solReal.getPrimalRay(vector);
2901  return true;
2902  }
2903  else
2904  return false;
2905  }
2906 
2907 
2908 
2909  /// gets the dual solution vector if available; returns true on success
2911  {
2912  if( hasDual() && vector.dim() >= numRowsReal() )
2913  {
2915  _solReal.getDual(vector);
2916  return true;
2917  }
2918  else
2919  return false;
2920  }
2921 
2922 
2923 
2924  /// gets the vector of reduced cost values if available; returns true on success
2926  {
2927  if( hasDual() && vector.dim() >= numColsReal() )
2928  {
2930  _solReal.getRedCost(vector);
2931  return true;
2932  }
2933  else
2934  return false;
2935  }
2936 
2937 
2938 
2939  /// gets the Farkas proof if available; returns true on success
2941  {
2942  if( hasDualFarkas() && vector.dim() >= numRowsReal() )
2943  {
2945  _solReal.getDualFarkas(vector);
2946  return true;
2947  }
2948  else
2949  return false;
2950  }
2951 
2952 
2953 
2954  /// gets violation of bounds; returns true on success
2955  bool SoPlex::getBoundViolationReal(Real& maxviol, Real& sumviol)
2956  {
2957  if( !hasPrimal() )
2958  return false;
2959 
2961  VectorReal& primal = _solReal._primal;
2962  assert(primal.dim() == numColsReal());
2963 
2964  maxviol = 0.0;
2965  sumviol = 0.0;
2966 
2967  for( int i = numColsReal() - 1; i >= 0; i-- )
2968  {
2969  Real viol = lowerReal(i) - primal[i];
2970  if( viol > 0.0 )
2971  {
2972  sumviol += viol;
2973  if( viol > maxviol )
2974  maxviol = viol;
2975  }
2976 
2977  viol = primal[i] - upperReal(i);
2978  if( viol > 0.0 )
2979  {
2980  sumviol += viol;
2981  if( viol > maxviol )
2982  maxviol = viol;
2983  }
2984  }
2985 
2986  return true;
2987  }
2988 
2989 
2990 
2991  /// gets violation of constraints; returns true on success
2992  bool SoPlex::getRowViolationReal(Real& maxviol, Real& sumviol)
2993  {
2994  if( !hasPrimal() )
2995  return false;
2996 
2998  VectorReal& primal = _solReal._primal;
2999  assert(primal.dim() == numColsReal());
3000 
3001  DVectorReal activity(numRowsReal());
3002  _realLP->computePrimalActivity(primal, activity);
3003  maxviol = 0.0;
3004  sumviol = 0.0;
3005 
3006  for( int i = numRowsReal() - 1; i >= 0; i-- )
3007  {
3008  Real viol = lhsReal(i) - activity[i];
3009  if( viol > 0.0 )
3010  {
3011  sumviol += viol;
3012  if( viol > maxviol )
3013  maxviol = viol;
3014  }
3015 
3016  viol = activity[i] - rhsReal(i);
3017  if( viol > 0.0 )
3018  {
3019  sumviol += viol;
3020  if( viol > maxviol )
3021  maxviol = viol;
3022  }
3023  }
3024 
3025  return true;
3026  }
3027 
3028 
3029 
3030  /// gets violation of reduced costs; returns true on success
3031  bool SoPlex::getRedCostViolationReal(Real& maxviol, Real& sumviol)
3032  {
3033  if( !hasDual() || !hasBasis() )
3034  return false;
3035 
3037  VectorReal& redcost = _solReal._redCost;
3038  assert(redcost.dim() == numColsReal());
3039 
3040  maxviol = 0.0;
3041  sumviol = 0.0;
3042 
3043  for( int c = numColsReal() - 1; c >= 0; c-- )
3044  {
3045  SPxSolver::VarStatus colStatus = basisColStatus(c);
3046 
3048  {
3049  if( colStatus != SPxSolver::ON_UPPER && colStatus != SPxSolver::FIXED && redcost[c] < 0.0 )
3050  {
3051  sumviol += -redcost[c];
3052  if( redcost[c] < -maxviol )
3053  maxviol = -redcost[c];
3054  }
3055  if( colStatus != SPxSolver::ON_LOWER && colStatus != SPxSolver::FIXED && redcost[c] > 0.0 )
3056  {
3057  sumviol += redcost[c];
3058  if( redcost[c] > maxviol )
3059  maxviol = redcost[c];
3060  }
3061  }
3062  else
3063  {
3064  if( colStatus != SPxSolver::ON_UPPER && colStatus != SPxSolver::FIXED && redcost[c] > 0.0 )
3065  {
3066  sumviol += redcost[c];
3067  if( redcost[c] > maxviol )
3068  maxviol = redcost[c];
3069  }
3070  if( colStatus != SPxSolver::ON_LOWER && colStatus != SPxSolver::FIXED && redcost[c] < 0.0 )
3071  {
3072  sumviol += -redcost[c];
3073  if( redcost[c] < -maxviol )
3074  maxviol = -redcost[c];
3075  }
3076  }
3077  }
3078 
3079  return true;
3080  }
3081 
3082 
3083 
3084  /// gets violation of dual multipliers; returns true on success
3085  bool SoPlex::getDualViolationReal(Real& maxviol, Real& sumviol)
3086  {
3087  if( !hasDual() || !hasBasis() )
3088  return false;
3089 
3091  VectorReal& dual = _solReal._dual;
3092  assert(dual.dim() == numRowsReal());
3093 
3094  maxviol = 0.0;
3095  sumviol = 0.0;
3096 
3097  for( int r = numRowsReal() - 1; r >= 0; r-- )
3098  {
3099  SPxSolver::VarStatus rowStatus = basisRowStatus(r);
3100 
3102  {
3103  if( rowStatus != SPxSolver::ON_UPPER && rowStatus != SPxSolver::FIXED && dual[r] < 0.0 )
3104  {
3105  sumviol += -dual[r];
3106  if( dual[r] < -maxviol )
3107  maxviol = -dual[r];
3108  }
3109  if( rowStatus != SPxSolver::ON_LOWER && rowStatus != SPxSolver::FIXED && dual[r] > 0.0 )
3110  {
3111  sumviol += dual[r];
3112  if( dual[r] > maxviol )
3113  maxviol = dual[r];
3114  }
3115  }
3116  else
3117  {
3118  if( rowStatus != SPxSolver::ON_UPPER && rowStatus != SPxSolver::FIXED && dual[r] > 0.0 )
3119  {
3120  sumviol += dual[r];
3121  if( dual[r] > maxviol )
3122  maxviol = dual[r];
3123  }
3124  if( rowStatus != SPxSolver::ON_LOWER && rowStatus != SPxSolver::FIXED && dual[r] < 0.0 )
3125  {
3126  sumviol += -dual[r];
3127  if( dual[r] < -maxviol )
3128  maxviol = -dual[r];
3129  }
3130  }
3131  }
3132 
3133  return true;
3134  }
3135 
3136 
3137 
3138  /// returns the objective value if a primal or dual solution is available
3140  {
3141  assert(OBJSENSE_MAXIMIZE == 1);
3142  assert(OBJSENSE_MINIMIZE == -1);
3143 
3144  if( status() == SPxSolver::UNBOUNDED )
3145  {
3147  return _rationalPosInfty;
3148  else
3149  return _rationalNegInfty;
3150  }
3151  else if( status() == SPxSolver::INFEASIBLE )
3152  {
3154  return _rationalNegInfty;
3155  else
3156  return _rationalPosInfty;
3157  }
3158  else if( hasPrimal() )
3159  {
3161  return _solRational._primalObjVal;
3162  }
3163  else if( hasDual() )
3164  {
3166  return _solRational._dualObjVal;
3167  }
3168  else
3169  return Rational::ZERO;
3170  }
3171 
3172 
3173 
3174  /// gets the primal solution vector if available; returns true on success
3176  {
3177  if( _rationalLP != 0 && hasPrimal() && vector.dim() >= numColsRational() )
3178  {
3180  _solRational.getPrimal(vector);
3181  return true;
3182  }
3183  else
3184  return false;
3185  }
3186 
3187 
3188 
3189  /// gets the vector of slack values if available; returns true on success
3191  {
3192  if( _rationalLP != 0 && hasPrimal() && vector.dim() >= numRowsRational() )
3193  {
3195  _solRational.getSlacks(vector);
3196  return true;
3197  }
3198  else
3199  return false;
3200  }
3201 
3202 
3203 
3204  /// gets the primal ray if LP is unbounded; returns true on success
3206  {
3207  if( _rationalLP != 0 && hasPrimalRay() && vector.dim() >= numColsRational() )
3208  {
3210  _solRational.getPrimalRay(vector);
3211  return true;
3212  }
3213  else
3214  return false;
3215  }
3216 
3217 
3218 
3219  /// gets the dual solution vector if available; returns true on success
3221  {
3222  if( _rationalLP != 0 && hasDual() && vector.dim() >= numRowsRational() )
3223  {
3225  _solRational.getDual(vector);
3226  return true;
3227  }
3228  else
3229  return false;
3230  }
3231 
3232 
3233 
3234  /// gets the vector of reduced cost values if available; returns true on success
3236  {
3237  if( _rationalLP != 0 && hasDual() && vector.dim() >= numColsRational() )
3238  {
3240  _solRational.getRedCost(vector);
3241  return true;
3242  }
3243  else
3244  return false;
3245  }
3246 
3247 
3248 
3249  /// gets the Farkas proof if LP is infeasible; returns true on success
3251  {
3252  if( _rationalLP != 0 && hasDualFarkas() && vector.dim() >= numRowsRational() )
3253  {
3255  _solRational.getDualFarkas(vector);
3256  return true;
3257  }
3258  else
3259  return false;
3260  }
3261 
3262 
3263 
3264  /// gets violation of bounds; returns true on success
3266  {
3267  if( !hasPrimal() )
3268  return false;
3269 
3270  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3272  _syncLPRational(false);
3273 
3276  assert(primal.dim() == numColsRational());
3277 
3278  maxviol = 0;
3279  sumviol = 0;
3280 
3281  for( int i = numColsRational() - 1; i >= 0; i-- )
3282  {
3283  Rational viol = lowerRational(i) - primal[i];
3284  if( viol > 0 )
3285  {
3286  sumviol += viol;
3287  if( viol > maxviol )
3288  maxviol = viol;
3289  }
3290 
3291  viol = primal[i] - upperRational(i);
3292  if( viol > 0 )
3293  {
3294  sumviol += viol;
3295  if( viol > maxviol )
3296  maxviol = viol;
3297  }
3298  }
3299 
3300  return true;
3301  }
3302 
3303 
3304 
3305  /// gets violation of constraints; returns true on success
3307  {
3308  if( !hasPrimal() )
3309  return false;
3310 
3311  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3313  _syncLPRational(false);
3314 
3317  assert(primal.dim() == numColsRational());
3318 
3319  DVectorRational activity(numRowsRational());
3320  _rationalLP->computePrimalActivity(primal, activity);
3321  maxviol = 0;
3322  sumviol = 0;
3323 
3324  for( int i = numRowsRational() - 1; i >= 0; i-- )
3325  {
3326  Rational viol = lhsRational(i) - activity[i];
3327  if( viol > 0 )
3328  {
3329  sumviol += viol;
3330  if( viol > maxviol )
3331  maxviol = viol;
3332  }
3333 
3334  viol = activity[i] - rhsRational(i);
3335  if( viol > 0 )
3336  {
3337  sumviol += viol;
3338  if( viol > maxviol )
3339  maxviol = viol;
3340  }
3341  }
3342 
3343  return true;
3344  }
3345 
3346 
3347 
3348  /// gets violation of reduced costs; returns true on success
3350  {
3351  if( !hasDual() || !hasPrimal() )
3352  return false;
3353 
3354  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3356  _syncLPRational(false);
3357 
3360  assert(redcost.dim() == numColsRational());
3361 
3362  maxviol = 0;
3363  sumviol = 0;
3364 
3365  for( int c = numColsReal() - 1; c >= 0; c-- )
3366  {
3367  assert(!_hasBasis || basisColStatus(c) != SPxSolver::UNDEFINED);
3368 
3369  if( _colTypes[c] == RANGETYPE_FIXED )
3370  {
3371  assert(lowerRational(c) == upperRational(c));
3372  continue;
3373  }
3374 
3379 
3381  {
3382  if( _solRational._primal[c] != upperRational(c) && redcost[c] < 0 )
3383  {
3384  sumviol += -redcost[c];
3385  if( redcost[c] < -maxviol )
3386  {
3387  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on upper bound: " << rationalToString(-redcost[c]) << "\n" );
3388  maxviol = -redcost[c];
3389  }
3390  }
3391  if( _solRational._primal[c] != lowerRational(c) && redcost[c] > 0 )
3392  {
3393  sumviol += redcost[c];
3394  if( redcost[c] > maxviol )
3395  {
3396  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on lower bound: " << rationalToString(redcost[c]) << "\n" );
3397  maxviol = redcost[c];
3398  }
3399  }
3400  }
3401  else
3402  {
3403  if( _solRational._primal[c] != upperRational(c) && redcost[c] > 0 )
3404  {
3405  sumviol += redcost[c];
3406  if( redcost[c] > maxviol )
3407  {
3408  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on upper bound: " << rationalToString(redcost[c]) << "\n" );
3409  maxviol = redcost[c];
3410  }
3411  }
3412  if( _solRational._primal[c] != lowerRational(c) && redcost[c] < 0 )
3413  {
3414  sumviol += -redcost[c];
3415  if( redcost[c] < -maxviol )
3416  {
3417  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on lower bound: " << rationalToString(-redcost[c]) << "\n" );
3418  maxviol = -redcost[c];
3419  }
3420  }
3421  }
3422  }
3423 
3424  return true;
3425  }
3426 
3427 
3428 
3429  /// gets violation of dual multipliers; returns true on success
3431  {
3432  if( !hasDual() || !hasPrimal() )
3433  return false;
3434 
3435  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3437  _syncLPRational(false);
3438 
3441  assert(dual.dim() == numRowsRational());
3442 
3443  maxviol = 0;
3444  sumviol = 0;
3445 
3446  for( int r = numRowsReal() - 1; r >= 0; r-- )
3447  {
3448  assert(!_hasBasis || basisRowStatus(r) != SPxSolver::UNDEFINED);
3449 
3450  if( _rowTypes[r] == RANGETYPE_FIXED )
3451  {
3452  assert(lhsRational(r) == rhsRational(r));
3453  continue;
3454  }
3455 
3460 
3462  {
3463  if( _solRational._slacks[r] < rhsRational(r) - _rationalFeastol && dual[r] < 0 )
3464  {
3465  sumviol += -dual[r];
3466  if( dual[r] < -maxviol )
3467  {
3468  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on upper bound: " << rationalToString(-dual[r])
3469  << " (slack = " << rationalToString(_solRational._slacks[r])
3470  << ", status = " << basisRowStatus(r)
3471  << ", lhs = " << rationalToString(lhsRational(r))
3472  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3473  maxviol = -dual[r];
3474  }
3475  }
3476  if( _solRational._slacks[r] > lhsRational(r) + _rationalFeastol && dual[r] > 0 )
3477  {
3478  sumviol += dual[r];
3479  if( dual[r] > maxviol )
3480  {
3481  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on lower bound: " << rationalToString(dual[r])
3482  << " (slack = " << rationalToString(_solRational._slacks[r])
3483  << ", status = " << basisRowStatus(r)
3484  << ", lhs = " << rationalToString(lhsRational(r))
3485  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3486  maxviol = dual[r];
3487  }
3488  }
3489  }
3490  else
3491  {
3492  if( _solRational._slacks[r] < rhsRational(r) - _rationalFeastol && dual[r] > 0 )
3493  {
3494  sumviol += dual[r];
3495  if( dual[r] > maxviol )
3496  {
3497  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on upper bound: " << rationalToString(dual[r])
3498  << " (slack = " << rationalToString(_solRational._slacks[r])
3499  << ", status = " << basisRowStatus(r)
3500  << ", lhs = " << rationalToString(lhsRational(r))
3501  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3502  maxviol = dual[r];
3503  }
3504  }
3505  if( _solRational._slacks[r] > lhsRational(r) + _rationalFeastol && dual[r] < 0 )
3506  {
3507  sumviol += -dual[r];
3508  if( dual[r] < -maxviol )
3509  {
3510  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on lower bound: " << rationalToString(-dual[r])
3511  << " (slack = " << rationalToString(_solRational._slacks[r])
3512  << ", status = " << basisRowStatus(r)
3513  << ", lhs = " << rationalToString(lhsRational(r))
3514  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3515  maxviol = -dual[r];
3516  }
3517  }
3518  }
3519  }
3520 
3521  return true;
3522  }
3523 
3524 
3525 
3526 #ifdef SOPLEX_WITH_GMP
3527  /// gets the primal solution vector if available; returns true on success
3528  bool SoPlex::getPrimalRational(mpq_t* vector, const int size)
3529  {
3530  assert(size >= numColsRational());
3531 
3532  if( hasPrimal() )
3533  {
3535  for( int i = 0; i < numColsRational(); i++ )
3536  mpq_set(vector[i], _solRational._primal[i].getMpqRef());
3537  return true;
3538  }
3539  else
3540  return false;
3541  }
3542 
3543 
3544  /// gets the vector of slack values if available; returns true on success
3545  bool SoPlex::getSlacksRational(mpq_t* vector, const int size)
3546  {
3547  assert(size >= numRowsRational());
3548 
3549  if( hasPrimal() )
3550  {
3552  for( int i = 0; i < numRowsRational(); i++ )
3553  mpq_set(vector[i], _solRational._slacks[i].getMpqRef());
3554  return true;
3555  }
3556  else
3557  return false;
3558  }
3559 
3560 
3561 
3562  /// gets the primal ray if LP is unbounded; returns true on success
3563  bool SoPlex::getPrimalRayRational(mpq_t* vector, const int size)
3564  {
3565  assert(size >= numColsRational());
3566 
3567  if( hasPrimalRay() )
3568  {
3570  for( int i = 0; i < numColsRational(); i++ )
3571  mpq_set(vector[i], _solRational._primalRay[i].getMpqRef());
3572  return true;
3573  }
3574  else
3575  return false;
3576  }
3577 
3578 
3579 
3580  /// gets the dual solution vector if available; returns true on success
3581  bool SoPlex::getDualRational(mpq_t* vector, const int size)
3582  {
3583  assert(size >= numRowsRational());
3584 
3585  if( hasDual() )
3586  {
3588  for( int i = 0; i < numRowsRational(); i++ )
3589  mpq_set(vector[i], _solRational._dual[i].getMpqRef());
3590  return true;
3591  }
3592  else
3593  return false;
3594  }
3595 
3596 
3597 
3598  /// gets the vector of reduced cost values if available; returns true on success
3599  bool SoPlex::getRedCostRational(mpq_t* vector, const int size)
3600  {
3601  assert(size >= numColsRational());
3602 
3603  if( hasDual() )
3604  {
3606  for( int i = 0; i < numColsRational(); i++ )
3607  mpq_set(vector[i], _solRational._redCost[i].getMpqRef());
3608  return true;
3609  }
3610  else
3611  return false;
3612  }
3613 
3614 
3615 
3616  /// gets the Farkas proof if LP is infeasible; returns true on success
3617  bool SoPlex::getDualFarkasRational(mpq_t* vector, const int size)
3618  {
3619  assert(size >= numRowsRational());
3620 
3621  if( hasDualFarkas() )
3622  {
3624  for( int i = 0; i < numRowsRational(); i++ )
3625  mpq_set(vector[i], _solRational._dualFarkas[i].getMpqRef());
3626  return true;
3627  }
3628  else
3629  return false;
3630  }
3631 #endif
3632 
3633 
3634 
3635  /// get size of primal solution
3637  {
3638  if( hasPrimal() || hasPrimalRay() )
3639  {
3641  return _solRational.totalSizePrimal(base);
3642  }
3643  else
3644  return 0;
3645  }
3646 
3647 
3648 
3649  /// get size of dual solution
3650  int SoPlex::totalSizeDualRational(const int base)
3651  {
3652  if( hasDual() || hasDualFarkas() )
3653  {
3655  return _solRational.totalSizeDual(base);
3656  }
3657  else
3658  return 0;
3659  }
3660 
3661 
3662 
3663  /// get size of least common multiple of denominators in primal solution
3665  {
3666  if( hasPrimal() || hasPrimalRay() )
3667  {
3669  return _solRational.dlcmSizePrimal(base);
3670  }
3671  else
3672  return 0;
3673  }
3674 
3675 
3676 
3677  /// get size of least common multiple of denominators in dual solution
3678  int SoPlex::dlcmSizeDualRational(const int base)
3679  {
3680  if( hasDual() || hasDualFarkas() )
3681  {
3683  return _solRational.dlcmSizeDual(base);
3684  }
3685  else
3686  return 0;
3687  }
3688 
3689 
3690 
3691  /// get size of largest denominator in primal solution
3693  {
3694  if( hasPrimal() || hasPrimalRay() )
3695  {
3697  return _solRational.dmaxSizePrimal(base);
3698  }
3699  else
3700  return 0;
3701  }
3702 
3703 
3704 
3705  /// get size of largest denominator in dual solution
3706  int SoPlex::dmaxSizeDualRational(const int base)
3707  {
3708  if( hasDual() || hasDualFarkas() )
3709  {
3711  return _solRational.dmaxSizeDual(base);
3712  }
3713  else
3714  return 0;
3715  }
3716 
3717 
3718 
3719  /// is an advanced starting basis available?
3720  bool SoPlex::hasBasis() const
3721  {
3722  return _hasBasis;
3723  }
3724 
3725 
3726 
3727  /// returns the current basis status
3729  {
3730  if( !hasBasis() )
3731  return SPxBasis::NO_PROBLEM;
3732  else if( status() == SPxSolver::OPTIMAL )
3733  return SPxBasis::OPTIMAL;
3734  else if( status() == SPxSolver::UNBOUNDED )
3735  return SPxBasis::UNBOUNDED;
3736  else if( status() == SPxSolver::INFEASIBLE )
3737  return SPxBasis::INFEASIBLE;
3738  else if( hasPrimal() )
3739  return SPxBasis::PRIMAL;
3740  else if( hasDual() )
3741  return SPxBasis::DUAL;
3742  else
3743  return SPxBasis::REGULAR;
3744  }
3745 
3746 
3747 
3748  /// returns basis status for a single row
3750  {
3751  assert(row >= 0);
3752  assert(row < numRowsReal());
3753 
3754  // if no basis is available, return slack basis; if index is out of range, return basic status as for a newly
3755  // added row
3756  if( !hasBasis() || row < 0 || row >= numRowsReal() )
3757  return SPxSolver::BASIC;
3758  // if the real LP is loaded, ask solver
3759  else if( _isRealLPLoaded )
3760  {
3761  return _solver.getBasisRowStatus(row);
3762  }
3763  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3764  else
3765  {
3766  assert(row < _basisStatusRows.size());
3767  return _basisStatusRows[row];
3768  }
3769  }
3770 
3771 
3772 
3773  /// returns basis status for a single column
3775  {
3776  assert(col >= 0);
3777  assert(col < numColsReal());
3778 
3779  // if index is out of range, return nonbasic status as for a newly added unbounded column
3780  if( col < 0 || col >= numColsReal() )
3781  {
3782  return SPxSolver::ZERO;
3783  }
3784  // if no basis is available, return slack basis
3785  else if( !hasBasis() )
3786  {
3787  if( lowerReal(col) > -realParam(SoPlex::INFTY) )
3788  return SPxSolver::ON_LOWER;
3789  else if( upperReal(col) < realParam(SoPlex::INFTY) )
3790  return SPxSolver::ON_UPPER;
3791  else
3792  return SPxSolver::ZERO;
3793  }
3794  // if the real LP is loaded, ask solver
3795  else if( _isRealLPLoaded )
3796  {
3797  return _solver.getBasisColStatus(col);
3798  }
3799  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3800  else
3801  {
3802  assert(col < _basisStatusCols.size());
3803  return _basisStatusCols[col];
3804  }
3805  }
3806 
3807 
3808 
3809  /// gets current basis
3811  {
3812  // if no basis is available, return slack basis
3813  if( !hasBasis() )
3814  {
3815  for( int i = numRowsReal() - 1; i >= 0; i-- )
3816  rows[i] = SPxSolver::BASIC;
3817 
3818  for( int i = numColsReal() - 1; i >= 0; i-- )
3819  {
3820  if( lowerReal(i) > -realParam(SoPlex::INFTY) )
3821  cols[i] = SPxSolver::ON_LOWER;
3822  else if( upperReal(i) < realParam(SoPlex::INFTY) )
3823  cols[i] = SPxSolver::ON_UPPER;
3824  else
3825  cols[i] = SPxSolver::ZERO;
3826  }
3827  }
3828  // if the real LP is loaded, ask solver
3829  else if( _isRealLPLoaded )
3830  {
3831  (void)_solver.getBasis(rows, cols);
3832  }
3833  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3834  else
3835  {
3836  assert(numRowsReal() == _basisStatusRows.size());
3837  assert(numColsReal() == _basisStatusCols.size());
3838 
3839  for( int i = numRowsReal() - 1; i >= 0; i-- )
3840  rows[i] = _basisStatusRows[i];
3841 
3842  for( int i = numColsReal() - 1; i >= 0; i-- )
3843  cols[i] = _basisStatusCols[i];
3844  }
3845  }
3846 
3847 
3848 
3849  /// returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m
3850  void SoPlex::getBasisInd(int* bind) const
3851  {
3852  // if no basis is available, return slack basis
3853  if( !hasBasis() )
3854  {
3855  for( int i = 0; i < numRowsReal(); ++i )
3856  bind[i] = -1 - i;
3857  }
3858  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3859  else if( !_isRealLPLoaded )
3860  {
3861  int k = 0;
3862 
3863  assert(numRowsReal() == _basisStatusRows.size());
3864  assert(numColsReal() == _basisStatusCols.size());
3865 
3866  for( int i = 0; i < numRowsReal(); ++i )
3867  {
3869  {
3870  bind[k] = -1 - i;
3871  k++;
3872  }
3873  }
3874 
3875  for( int j = 0; j < numColsReal(); ++j )
3876  {
3878  {
3879  bind[k] = j;
3880  k++;
3881  }
3882  }
3883 
3884  assert(k == numRowsReal());
3885  }
3886  // if the real LP is loaded, the basis is stored in the solver and we need to distinguish between column and row
3887  // representation; ask the solver itself which representation it has, since the REPRESENTATION parameter of this
3888  // class might be set to automatic
3889  else if( _solver.rep() == SPxSolver::COLUMN )
3890  {
3891  for( int i = 0; i < numRowsReal(); ++i )
3892  {
3893  SPxId id = _solver.basis().baseId(i);
3894  bind[i] = (id.isSPxColId() ? _solver.number(id) : - 1 - _solver.number(id));
3895  }
3896  }
3897  // for row representation, return the complement of the basis; for this, we need to loop through all rows and columns
3898  else
3899  {
3900  assert(_solver.rep() == SPxSolver::ROW);
3901 
3902  int k = 0;
3903 
3904  for( int i = 0; i < numRowsReal(); ++i )
3905  {
3906  if( !_solver.isRowBasic(i) )
3907  {
3908  bind[k] = -1 - i;
3909  k++;
3910  }
3911  }
3912 
3913  for( int j = 0; j < numColsReal(); ++j )
3914  {
3915  if( !_solver.isColBasic(j) )
3916  {
3917  bind[k] = j;
3918  k++;
3919  }
3920  }
3921 
3922  assert(k == numRowsReal());
3923  }
3924  }
3925 
3926 
3927 
3928  /// computes an estimated condition number for the current basis matrix using the power method; returns true on success
3930  {
3932  if( !_isRealLPLoaded )
3933  return false;
3934 
3936  return false;
3937 
3938  condition = _solver.basis().getEstimatedCondition();
3939 
3940  return true;
3941  }
3942 
3943  /// computes the exact condition number for the current basis matrix using the power method; returns true on success
3945  {
3947  if( !_isRealLPLoaded )
3948  return false;
3949 
3951  return false;
3952 
3953  condition = _solver.basis().getExactCondition();
3954 
3955  return true;
3956  }
3957 
3958  /// computes row r of basis inverse; returns true on success
3959  bool SoPlex::getBasisInverseRowReal(int r, Real* coef, int* inds, int* ninds)
3960  {
3961  assert(r >= 0);
3962  assert(r < numRowsReal());
3963  assert(coef != 0);
3964 
3965  if( !hasBasis() || r < 0 || r >= numRowsReal() )
3966  return false;
3967 
3969 
3970  if( !_isRealLPLoaded )
3971  return false;
3972 
3973  // we need to distinguish between column and row representation; ask the solver itself which representation it
3974  // has, since the REPRESENTATION parameter of this class might be set to automatic
3975  if( _solver.rep() == SPxSolver::COLUMN )
3976  {
3977  int idx;
3979  try
3980  {
3982  }
3983  catch( const SPxException& E )
3984  {
3985  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
3986  return false;
3987  }
3988  // copy sparse data to dense result vector based on coef array
3989  if( ninds != NULL && inds != NULL )
3990  {
3991  // during solving SoPlex may have destroyed the sparsity structure so we need to restore it
3992  x.setup();
3993  *ninds = x.size();
3994  for( int i = 0; i < *ninds; ++i )
3995  {
3996  idx = x.index(i);
3997  coef[idx] = x[idx];
3998  // set sparsity pattern of coef array
3999  inds[i] = idx;
4000  }
4001  }
4002  else
4003  {
4004  VectorReal y(numRowsReal(), coef);
4005  y = x;
4006  if( ninds != NULL )
4007  *ninds = -1;
4008  }
4009  }
4010  else
4011  {
4012  assert(_solver.rep() == SPxSolver::ROW);
4013 
4014  // @todo should rhs be a reference?
4015  DSVector rhs(numColsReal());
4016  SSVector y(numColsReal());
4017  int* bind = 0;
4018  int index;
4019 
4020  // get ordering of column basis matrix
4021  spx_alloc(bind, numRowsReal());
4022  getBasisInd(bind);
4023 
4024  // get vector corresponding to requested index r
4025  index = bind[r];
4026 
4027  // r corresponds to a row vector
4028  if( index < 0 )
4029  {
4030  // transform index to actual row index
4031  index = -index - 1;
4032 
4033  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4034  assert(index >= 0);
4035  assert(index < numRowsReal());
4036  assert(!_solver.isRowBasic(index));
4037 
4038  // get row vector
4039  rhs = _solver.rowVector(index);
4040  rhs *= -1.0;
4041  }
4042  // r corresponds to a column vector
4043  else
4044  {
4045  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4046  assert(index < numColsReal());
4047  assert(!_solver.isColBasic(index));
4048 
4049  // get unit vector
4050  rhs = UnitVectorReal(index);
4051  }
4052 
4053  // solve system "y B = rhs", where B is the row basis matrix
4054  try
4055  {
4056  _solver.basis().solve(y, rhs);
4057  }
4058  catch( const SPxException& E )
4059  {
4060  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4061  return false;
4062  }
4063 
4064  // initialize result vector x as zero
4065  memset(coef, 0, (unsigned int)numRowsReal() * sizeof(Real));
4066 
4067  // add nonzero entries
4068  for( int i = 0; i < numColsReal(); ++i )
4069  {
4070  SPxId id = _solver.basis().baseId(i);
4071 
4072  if( id.isSPxRowId() )
4073  {
4074  assert(_solver.number(id) >= 0);
4075  assert(_solver.number(id) < numRowsReal());
4076  assert(bind[r] >= 0 || _solver.number(id) != index);
4077 
4078  coef[_solver.number(id)] = y[i];
4079  }
4080  }
4081 
4082  // if r corresponds to a row vector, we have to add a 1 at position r
4083  if( bind[r] < 0 )
4084  {
4085  assert(coef[index] == 0.0);
4086  coef[index] = 1.0;
4087  }
4088 
4089  // @todo implement returning of sparsity information like in column wise case
4090  if( ninds != NULL)
4091  *ninds = -1;
4092 
4093  // free memory
4094  spx_free(bind);
4095  }
4096 
4097  return true;
4098  }
4099 
4100 
4101 
4102  /// computes column c of basis inverse; returns true on success
4103  bool SoPlex::getBasisInverseColReal(int c, Real* coef, int* inds, int* ninds)
4104  {
4105  assert(c >= 0);
4106  assert(c < numRowsReal());
4107  assert(coef != 0);
4108 
4109  if( !hasBasis() || c < 0 || c >= numRowsReal() )
4110  return false;
4111 
4113 
4114  if( !_isRealLPLoaded )
4115  return false;
4116 
4117  // we need to distinguish between column and row representation; ask the solver itself which representation it
4118  // has, since the REPRESENTATION parameter of this class might be set to automatic
4119  if( _solver.rep() == SPxSolver::COLUMN )
4120  {
4121  int idx;
4123  try
4124  {
4126  }
4127  catch( const SPxException& E )
4128  {
4129  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4130  return false;
4131  }
4132  // copy sparse data to dense result vector based on coef array
4133  if( ninds != NULL && inds != NULL )
4134  {
4135  // SoPlex may have destroyed the sparsity structure so we need to restore it
4136  x.setup();
4137  *ninds = x.size();
4138  for( int i = 0; i < *ninds; ++i )
4139  {
4140  idx = x.index(i);
4141  coef[idx] = x[idx];
4142  // set sparsity pattern of coef array
4143  inds[i] = idx;
4144  }
4145  }
4146  else
4147  {
4148  VectorReal y(numColsReal(), coef);
4149  y = x;
4150  if( ninds != NULL )
4151  *ninds = -1;
4152  }
4153  }
4154  else
4155  {
4156  assert(_solver.rep() == SPxSolver::ROW);
4157 
4158  // @todo should rhs be a reference?
4159  DSVectorReal rhs(numColsReal());
4161  int* bind = 0;
4162  int index;
4163 
4164  // get ordering of column basis matrix
4165  spx_alloc(bind, numRowsReal());
4166  getBasisInd(bind);
4167 
4168  // get vector corresponding to requested index r
4169  index = bind[c];
4170 
4171  // c corresponds to a row vector
4172  if( index < 0 )
4173  {
4174  // transform index to actual row index
4175  index = -index - 1;
4176 
4177  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4178  assert(index >= 0);
4179  assert(index < numRowsReal());
4180  assert(!_solver.isRowBasic(index));
4181 
4182  // get row vector
4183  rhs = _solver.rowVector(index);
4184  rhs *= -1.0;
4185  }
4186  // c corresponds to a column vector
4187  else
4188  {
4189  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4190  assert(index < numColsReal());
4191  assert(!_solver.isColBasic(index));
4192 
4193  // get unit vector
4194  rhs = UnitVectorReal(index);
4195  }
4196 
4197  // solve system "y B = rhs", where B is the row basis matrix
4198  try
4199  {
4200  _solver.basis().coSolve(y, rhs);
4201  }
4202  catch( const SPxException& E )
4203  {
4204  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4205  return false;
4206  }
4207 
4208  // initialize result vector x as zero
4209  memset(coef, 0, (unsigned int)numRowsReal() * sizeof(Real));
4210 
4211  // add nonzero entries
4212  for( int i = 0; i < numColsReal(); ++i )
4213  {
4214  SPxId id = _solver.basis().baseId(i);
4215 
4216  if( id.isSPxRowId() )
4217  {
4218  assert(_solver.number(id) >= 0);
4219  assert(_solver.number(id) < numRowsReal());
4220  assert(bind[c] >= 0 || _solver.number(id) != index);
4221 
4222  coef[_solver.number(id)] = y[i];
4223  }
4224  }
4225 
4226  // if r corresponds to a row vector, we have to add a 1 at position r
4227  if( bind[c] < 0 )
4228  {
4229  assert(coef[index] == 0.0);
4230  coef[index] = 1.0;
4231  }
4232 
4233  // @todo implement returning of sparsity information like in column wise case
4234  if( ninds != NULL)
4235  *ninds = -1;
4236 
4237  // free memory
4238  spx_free(bind);
4239  }
4240 
4241  return true;
4242  }
4243 
4244 
4245 
4246  /// computes dense solution of basis matrix B * sol = rhs; returns true on success
4248  {
4249  VectorReal v(numRowsReal(), rhs);
4250  VectorReal x(numRowsReal(), sol);
4251 
4252  if( !hasBasis() )
4253  return false;
4254 
4256 
4257  if( !_isRealLPLoaded )
4258  return false;
4259 
4260  // we need to distinguish between column and row representation; ask the solver itself which representation it
4261  // has, since the REPRESENTATION parameter of this class might be set to automatic; in the column case we can use
4262  // the existing factorization
4263  if( _solver.rep() == SPxSolver::COLUMN )
4264  {
4265  // solve system "x = B^-1 * A_c" to get c'th column of B^-1 * A
4266  try
4267  {
4268  _solver.basis().solve(x, v);
4269  }
4270  catch( const SPxException& E )
4271  {
4272  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while solving with basis matrix.\n" );
4273  return false;
4274  }
4275  }
4276  else
4277  {
4278  assert(_solver.rep() == SPxSolver::ROW);
4279 
4280  DSVectorReal rowrhs(numColsReal());
4282  int* bind = 0;
4283 
4284  // get ordering of column basis matrix
4285  spx_alloc(bind, numRowsReal());
4286  getBasisInd(bind);
4287 
4288  // fill right-hand side for row-based system
4289  for( int i = 0; i < numColsReal(); ++i )
4290  {
4291  SPxId id = _solver.basis().baseId(i);
4292 
4293  if( id.isSPxRowId() )
4294  {
4295  assert(_solver.number(id) >= 0);
4296  assert(_solver.number(id) < numRowsReal());
4297 
4298  rowrhs.add(i, v[_solver.number(id)]);
4299  }
4300  else
4301  {
4302  assert(rowrhs[i] == 0.0);
4303  }
4304  }
4305 
4306  // solve system "B y = rowrhs", where B is the row basis matrix
4307  try
4308  {
4309  _solver.basis().coSolve(y, rowrhs);
4310  }
4311  catch( const SPxException& E )
4312  {
4313  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while solving with basis matrix.\n" );
4314  return false;
4315  }
4316 
4317  // fill result w.r.t. order given by bind
4318  for( int i = 0; i < numRowsReal(); ++i )
4319  {
4320  int index;
4321 
4322  index = bind[i];
4323 
4324  if( index < 0 )
4325  {
4326  index = -index-1;
4327 
4328  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4329  assert(index >= 0);
4330  assert(index < numRowsReal());
4331  assert(!_solver.isRowBasic(index));
4332 
4333  x[i] = v[index] - (rowVectorReal(index) * Vector(numColsReal(), y.get_ptr()));
4334  }
4335  else
4336  {
4337  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4338  assert(index >= 0);
4339  assert(index < numColsReal());
4340  assert(!_solver.isColBasic(index));
4341 
4342  x[i] = y[index];
4343  }
4344  }
4345 
4346  // free memory
4347  spx_free(bind);
4348  }
4349  return true;
4350  }
4351 
4352 
4353 
4354  /// sets starting basis via arrays of statuses
4356  {
4357  if( _isRealLPLoaded )
4358  {
4359  assert(numRowsReal() == _solver.nRows());
4360  assert(numColsReal() == _solver.nCols());
4361 
4362  _solver.setBasis(rows, cols);
4364  }
4365  else
4366  {
4367  _basisStatusRows.reSize(numRowsReal());
4368  _basisStatusCols.reSize(numColsReal());
4369 
4370  for( int i = numRowsReal() - 1; i >= 0; i-- )
4371  _basisStatusRows[i] = rows[i];
4372 
4373  for( int j = numColsReal() - 1; j >= 0; j-- )
4374  _basisStatusCols[j] = cols[j];
4375 
4376  _hasBasis = true;
4377  }
4378  }
4379 
4380 
4381 
4382  /// clears starting basis
4384  {
4385  _solver.reLoad();
4386  _status = _solver.status();
4387  _hasBasis = false;
4388  }
4389 
4390 
4391 
4392  /// number of iterations since last call to solve
4394  {
4395  return _statistics->iterations;
4396  }
4397 
4398 
4399 
4400  /// time spent in last call to solve
4402  {
4403  return _statistics->solvingTime->time();
4404  }
4405 
4406 
4407 
4408  /// statistical information in form of a string
4409  std::string SoPlex::statisticString() const
4410  {
4411  std::stringstream s;
4412  s << "Factorizations : " << std::setw(10) << _statistics->luFactorizationsReal << std::endl
4413  << " Time spent : " << std::setw(10) << std::fixed << std::setprecision(2) << _statistics->luFactorizationTimeReal << std::endl
4414  << "Solves : " << std::setw(10) << _statistics->luSolvesReal << std::endl
4415  << " Time spent : " << std::setw(10) << _statistics->luSolveTimeReal << std::endl
4416  << "Solution time : " << std::setw(10) << std::fixed << std::setprecision(2) << solveTime() << std::endl
4417  << "Iterations : " << std::setw(10) << numIterations() << std::endl;
4418 
4419  return s.str();
4420  }
4421 
4422 
4423 
4424  /// name of starter
4426  {
4427  if( _starter )
4428  return _starter->getName();
4429  else
4430  return "none";
4431  }
4432 
4433 
4434 
4435  /// name of simplifier
4437  {
4438  if( _simplifier )
4439  return _simplifier->getName();
4440  else
4441  return "none";
4442  }
4443 
4444 
4445 
4446  /// name of scaling method after simplifier
4448  {
4449  if( _scaler )
4450  return _scaler->getName();
4451  else
4452  return "none";
4453  }
4454 
4455 
4456 
4457  /// name of currently loaded pricer
4459  {
4460  return _solver.pricer()->getName();
4461  }
4462 
4463 
4464 
4465  /// name of currently loaded ratiotester
4467  {
4468  return _solver.ratiotester()->getName();
4469  }
4470 
4471 
4472 
4473  /// reads LP file in LP or MPS format according to READMODE parameter; gets row names, column names, and
4474  /// integer variables if desired; returns true on success
4475  bool SoPlex::readFile(const char* filename, NameSet* rowNames, NameSet* colNames, DIdxSet* intVars)
4476  {
4478  return _readFileReal(filename, rowNames, colNames, intVars);
4479  else
4480  return _readFileRational(filename, rowNames, colNames, intVars);
4481  }
4482 
4483  /// writes real LP to file; LP or MPS format is chosen from the extension in \p filename; if \p rowNames and \p
4484  /// colNames are \c NULL, default names are used; if \p intVars is not \c NULL, the variables contained in it are
4485  /// marked as integer; returns true on success
4486  bool SoPlex::writeFileReal(const char* filename, const NameSet* rowNames, const NameSet* colNames, const DIdxSet* intVars) const
4487  {
4488  ///@todo implement return value
4489  _realLP->writeFile(filename, rowNames, colNames, intVars);
4490  return true;
4491  }
4492 
4493 
4494 
4495  /// writes rational LP to file; LP or MPS format is chosen from the extension in \p filename; if \p rowNames and \p
4496  /// colNames are \c NULL, default names are used; if \p intVars is not \c NULL, the variables contained in it are
4497  /// marked as integer; returns true on success
4498  bool SoPlex::writeFileRational(const char* filename, const NameSet* rowNames, const NameSet* colNames, const DIdxSet* intVars) const
4499  {
4501  return false;
4502  else
4503  {
4504  assert(_rationalLP != 0);
4505  _rationalLP->writeFile(filename, rowNames, colNames, intVars);
4506 
4507  ///@todo implement return value
4508  return true;
4509  }
4510  }
4511 
4512 
4513 
4514  /// reads basis information from \p filename and returns true on success; if \p rowNames and \p colNames are \c NULL,
4515  /// default names are assumed; returns true on success
4516  bool SoPlex::readBasisFile(const char* filename, const NameSet* rowNames, const NameSet* colNames)
4517  {
4518 #if 1
4519  assert(filename != 0);
4520  assert(_realLP != 0);
4521 
4522  // start timing
4524 
4525  // read
4526  if( !_isRealLPLoaded )
4527  {
4528  assert(_realLP != &_solver);
4529 
4531  _realLP->~SPxLPReal();
4532  spx_free(_realLP);
4533  _realLP = &_solver;
4534  _isRealLPLoaded = true;
4535  }
4536  _hasBasis = _solver.readBasisFile(filename, rowNames, colNames);
4537  assert(_hasBasis == (_solver.basis().status() > SPxBasis::NO_PROBLEM));
4538 
4539  // stop timing
4541 
4542  return _hasBasis;
4543 #else
4544  // this is alternative code for reading bases without the SPxSolver class
4545  assert(filename != 0);
4546 
4547  // start timing
4549 
4550  // read
4551  spxifstream file(filename);
4552 
4553  if( !file )
4554  return false;
4555 
4556  // get problem size
4557  int numRows = numRowsReal();
4558  int numCols = numColsReal();
4559 
4560  // prepare column names
4561  const NameSet* colNamesPtr = colNames;
4562  NameSet* tmpColNames = 0;
4563  if( colNames == 0 )
4564  {
4565  std::stringstream name;
4566 
4567  spx_alloc(tmpColNames);
4568  tmpColNames = new (tmpColNames) NameSet();
4569  tmpColNames->reMax(numCols);
4570 
4571  for( int j = 0; j < numCols; ++j )
4572  {
4573  name << "x" << j;
4574  tmpColNames->add(name.str().c_str());
4575  }
4576 
4577  colNamesPtr = tmpColNames;
4578  }
4579 
4580  // prepare row names
4581  const NameSet* rowNamesPtr = rowNames;
4582  NameSet* tmpRowNames = 0;
4583  if( rowNamesPtr == 0 )
4584  {
4585  std::stringstream name;
4586 
4587  spx_alloc(tmpRowNames);
4588  tmpRowNames = new (tmpRowNames) NameSet();
4589  tmpRowNames->reMax(numRows);
4590 
4591  for( int i = 0; i < numRows; ++i )
4592  {
4593  name << "C" << i;
4594  tmpRowNames->add(name.str().c_str());
4595  }
4596 
4597  rowNamesPtr = tmpRowNames;
4598  }
4599 
4600  // initialize with default slack basis
4601  _basisStatusRows.reSize(numRows);
4602  _basisStatusCols.reSize(numCols);
4603 
4604  for( int i = 0; i < numRows; i++ )
4606 
4607  for( int i = 0; i < numCols; i++ )
4608  {
4609  if( lowerReal(i) == upperReal(i) )
4611  else if( lowerReal(i) <= double(-realParam(SoPlex::INFTY)) && upperReal(i) >= double(realParam(SoPlex::INFTY)) )
4613  else if( lowerReal(i) <= double(-realParam(SoPlex::INFTY)) )
4615  else
4617  }
4618 
4619  // read basis
4620  MPSInput mps(file);
4621  if( mps.readLine() && (mps.field0() != 0) && !strcmp(mps.field0(), "NAME") )
4622  {
4623  while( mps.readLine() )
4624  {
4625  int c = -1;
4626  int r = -1;
4627 
4628  if( mps.field0() != 0 && !strcmp(mps.field0(), "ENDATA") )
4629  {
4631  break;
4632  }
4633 
4634  if( mps.field1() == 0 || mps.field2() == 0 )
4635  break;
4636 
4637  if( (c = colNamesPtr->number(mps.field2())) < 0 )
4638  break;
4639 
4640  if( *mps.field1() == 'X' )
4641  {
4642  if( mps.field3() == 0 || (r = rowNamesPtr->number(mps.field3())) < 0 )
4643  break;
4644  }
4645 
4646  if( !strcmp(mps.field1(), "XU") )
4647  {
4651  else if( _rowTypes[r] == SoPlex::RANGETYPE_FIXED )
4653  else
4655  }
4656  else if( !strcmp(mps.field1(), "XL") )
4657  {
4661  else if( _rowTypes[r] == SoPlex::RANGETYPE_FIXED )
4663  else
4665  }
4666  else if( !strcmp(mps.field1(), "UL") )
4667  {
4669  }
4670  else if( !strcmp(mps.field1(), "LL") )
4671  {
4673  }
4674  else
4675  {
4676  mps.syntaxError();
4677  break;
4678  }
4679  }
4680  }
4681 
4682  if( rowNames == 0 )
4683  {
4684  tmpRowNames->~NameSet();
4685  spx_free(tmpRowNames);
4686  }
4687 
4688  if( colNames == 0 )
4689  {
4690  tmpColNames->~NameSet();
4691  spx_free(tmpColNames);
4692  }
4693 
4694  _hasBasis = !mps.hasError();
4695 
4696  // stop timing
4698 
4699  return _hasBasis;
4700 #endif
4701  }
4702 
4703 
4704 
4705  /// writes basis information to \p filename; if \p rowNames and \p colNames are \c NULL, default names are used;
4706  /// returns true on success
4707  bool SoPlex::writeBasisFile(const char* filename, const NameSet* rowNames, const NameSet* colNames, const bool cpxFormat) const
4708  {
4709  assert(filename != 0);
4710 
4711  if( _isRealLPLoaded )
4712  return _solver.writeBasisFile(filename, rowNames, colNames, cpxFormat);
4713  else
4714  {
4715  std::ofstream file(filename);
4716  if( !file.good() )
4717  return false;
4718 
4719  file.setf(std::ios::left);
4720  file << "NAME " << filename << "\n";
4721 
4722  // do not write basis if there is none
4723  if( !_hasBasis )
4724  {
4725  file << "ENDATA\n";
4726  return true;
4727  }
4728 
4729  // start writing
4730  int numRows = _basisStatusRows.size();
4731  int numCols = _basisStatusCols.size();
4732  int row = 0;
4733 
4734  for( int col = 0; col < numCols; col++ )
4735  {
4736  assert(_basisStatusCols[col] != SPxSolver::UNDEFINED);
4737 
4738  if( _basisStatusCols[col] == SPxSolver::BASIC )
4739  {
4740  // find nonbasic row
4741  for( ; row < numRows; row++ )
4742  {
4743  assert(_basisStatusRows[row] != SPxSolver::UNDEFINED);
4744  if( _basisStatusRows[row] != SPxSolver::BASIC )
4745  break;
4746  }
4747 
4748  assert(row != numRows);
4749 
4750  if( _basisStatusRows[row] == SPxSolver::ON_UPPER && (!cpxFormat || _rowTypes[row] == SoPlex::RANGETYPE_BOXED) )
4751  file << " XU ";
4752  else
4753  file << " XL ";
4754 
4755  file << std::setw(8);
4756  if( colNames != 0 && colNames->has(col) )
4757  file << (*colNames)[col];
4758  else
4759  file << "x" << col;
4760 
4761  file << " ";
4762  if( rowNames != 0 && rowNames->has(row) )
4763  file << (*rowNames)[row];
4764  else
4765  file << "C" << row;
4766 
4767  file << "\n";
4768  row++;
4769  }
4770  else
4771  {
4773  {
4774  file << " UL ";
4775 
4776  file << std::setw(8);
4777  if( colNames != 0 && colNames->has(col) )
4778  file << (*colNames)[col];
4779  else
4780  file << "x" << col;
4781 
4782  file << "\n";
4783  }
4784  }
4785  }
4786 
4787  file << "ENDATA\n";
4788 
4789 #ifndef NDEBUG
4790  // check that the remaining rows are basic
4791  for( ; row < numRows; row++ )
4792  {
4793  assert(_basisStatusRows[row] == SPxSolver::BASIC);
4794  }
4795 #endif
4796 
4797  return true;
4798  }
4799  }
4800 
4801 
4802 
4803  /// writes internal LP, basis information, and parameter settings; if \p rowNames and \p colNames are \c NULL,
4804  /// default names are used
4805  void SoPlex::writeStateReal(const char* filename, const NameSet* rowNames, const NameSet* colNames, const bool cpxFormat) const
4806  {
4807  std::string ofname;
4808 
4809  // write parameter settings
4810  ofname = std::string(filename) + ".set";
4811  saveSettingsFile(ofname.c_str());
4812 
4813  // write problem in MPS/LP format
4814  ofname = std::string(filename) + ((cpxFormat) ? ".lp" : ".mps");
4815  writeFileReal(ofname.c_str(), rowNames, colNames, 0);
4816 
4817  // write basis
4818  ofname = std::string(filename) + ".bas";
4819  writeBasisFile(ofname.c_str(), rowNames, colNames, cpxFormat);
4820  }
4821 
4822 
4823 
4824  /// writes internal LP, basis information, and parameter settings; if \p rowNames and \p colNames are \c NULL,
4825  /// default names are used
4826  void SoPlex::writeStateRational(const char* filename, const NameSet* rowNames, const NameSet* colNames, const bool cpxFormat) const
4827  {
4828  std::string ofname;
4829 
4830  // write parameter settings
4831  ofname = std::string(filename) + ".set";
4832  saveSettingsFile(ofname.c_str());
4833 
4834  // write problem in MPS/LP format
4835  ofname = std::string(filename) + ((cpxFormat) ? ".lp" : ".mps");
4836  writeFileRational(ofname.c_str(), rowNames, colNames, 0);
4837 
4838  // write basis
4839  ofname = std::string(filename) + ".bas";
4840  writeBasisFile(ofname.c_str(), rowNames, colNames, cpxFormat);
4841  }
4842 
4843 
4844 
4845  /// returns boolean parameter value
4846  bool SoPlex::boolParam(const BoolParam param) const
4847  {
4848  assert(param >= 0);
4849  assert(param < SoPlex::BOOLPARAM_COUNT);
4850  return _currentSettings->_boolParamValues[param];
4851  }
4852 
4853 
4854 
4855  /// returns integer parameter value
4856  int SoPlex::intParam(const IntParam param) const
4857  {
4858  assert(param >= 0);
4859  assert(param < INTPARAM_COUNT);
4860  return _currentSettings->_intParamValues[param];
4861  }
4862 
4863 
4864 
4865  /// returns real parameter value
4866  Real SoPlex::realParam(const RealParam param) const
4867  {
4868  assert(param >= 0);
4869  assert(param < REALPARAM_COUNT);
4870  return _currentSettings->_realParamValues[param];
4871  }
4872 
4873 
4874 
4875 #ifdef SOPLEX_WITH_RATIONALPARAM
4876  /// returns rational parameter value
4877  Rational SoPlex::rationalParam(const RationalParam param) const
4878  {
4879  assert(param >= 0);
4880  assert(param < RATIONALPARAM_COUNT);
4881  return _currentSettings->_rationalParamValues[param];
4882  }
4883 #endif
4884 
4885 
4886 
4887  /// returns current parameter settings
4889  {
4890  return *_currentSettings;
4891  }
4892 
4893 
4894 
4895  /// sets boolean parameter value; returns true on success
4896  bool SoPlex::setBoolParam(const BoolParam param, const bool value, const bool quiet, const bool init)
4897  {
4898  assert(param >= 0);
4899  assert(param < SoPlex::BOOLPARAM_COUNT);
4900  assert(init || _isConsistent());
4901 
4902  if( !init && value == boolParam(param) )
4903  return true;
4904 
4905  switch( param )
4906  {
4907  case LIFTING:
4908  break;
4909  case EQTRANS:
4910  break;
4911  case TESTDUALINF:
4912  break;
4913  case RATFAC:
4914  break;
4915  case ACCEPTCYCLING:
4916  break;
4917  case RATREC:
4918  break;
4919  case POWERSCALING:
4920  break;
4921  case RATFACJUMP:
4922  break;
4923  case FEASRELAX:
4924  break;
4925  case ROWBOUNDFLIPS:
4927  break;
4928  default:
4929  return false;
4930  }
4931 
4932  _currentSettings->_boolParamValues[param] = value;
4933  return true;
4934  }
4935 
4936 
4937 
4938  /// sets integer parameter value; returns true on success
4939  bool SoPlex::setIntParam(const IntParam param, const int value, const bool quiet, const bool init)
4940  {
4941  assert(param >= 0);
4942  assert(param < INTPARAM_COUNT);
4943  assert(init || _isConsistent());
4944 
4945  if( !init && value == intParam(param) )
4946  return true;
4947 
4948  // check for a valid parameter value wrt bounds
4949  if( value < _currentSettings->_intParamLower[param] || value > _currentSettings->_intParamUpper[param] )
4950  return false;
4951 
4952  switch( param )
4953  {
4954  // objective sense
4955  case SoPlex::OBJSENSE:
4956  if( value != SoPlex::OBJSENSE_MAXIMIZE && value != SoPlex::OBJSENSE_MINIMIZE )
4957  return false;
4959  if( _rationalLP != 0 )
4962  break;
4963 
4964  // type of computational form, i.e., column or row representation
4967  return false;
4968  break;
4969 
4970  // type of algorithm, i.e., primal or dual
4971  case SoPlex::ALGORITHM:
4972  // decide upon entering/leaving at solve time depending on representation
4973  break;
4974 
4975  // type of LU update
4978  return false;
4980  break;
4981 
4982  // maximum number of updates before fresh factorization
4984  _solver.basis().setMaxUpdates(value);
4985  break;
4986 
4987  // iteration limit (-1 if unlimited)
4988  case SoPlex::ITERLIMIT:
4989  break;
4990 
4991  // refinement limit (-1 if unlimited)
4992  case SoPlex::REFLIMIT:
4993  break;
4994 
4995  // stalling refinement limit (-1 if unlimited)
4996  case SoPlex::STALLREFLIMIT:
4997  break;
4998 
4999  // display frequency
5000  case SoPlex::DISPLAYFREQ:
5001  _solver.setDisplayFreq(value);
5002  break;
5003 
5004  // verbosity level
5005  case SoPlex::VERBOSITY:
5006  switch(value)
5007  {
5008  case 0:
5010  break;
5011  case 1:
5013  break;
5014  case 2:
5016  break;
5017  case 3:
5019  break;
5020  case 4:
5022  break;
5023  case 5:
5025  break;
5026  }
5027  break;
5028 
5029  // type of simplifier
5030  case SoPlex::SIMPLIFIER:
5031  switch( value )
5032  {
5033  case SIMPLIFIER_OFF:
5034  _simplifier = 0;
5035  break;
5036  case SIMPLIFIER_AUTO:
5038  assert(_simplifier != 0);
5039  break;
5040  default:
5041  return false;
5042  }
5043  break;
5044 
5045  // type of scaler
5046  case SoPlex::SCALER:
5047  switch( value )
5048  {
5049  case SCALER_OFF:
5050  _scaler = 0;
5051  break;
5052  case SCALER_UNIEQUI:
5054  break;
5055  case SCALER_BIEQUI:
5057  break;
5058  case SCALER_GEO1:
5059  _scaler = &_scalerGeo1;
5060  break;
5061  case SCALER_GEO8:
5062  _scaler = &_scalerGeo8;
5063  break;
5064  default:
5065  return false;
5066  }
5067  break;
5068 
5069  // type of starter used to create crash basis
5070  case SoPlex::STARTER:
5071  switch( value )
5072  {
5073  case STARTER_OFF:
5074  _starter = 0;
5075  break;
5076  case STARTER_WEIGHT:
5078  break;
5079  case STARTER_SUM:
5080  _starter = &_starterSum;
5081  break;
5082  case STARTER_VECTOR:
5084  break;
5085  default:
5086  return false;
5087  }
5088  break;
5089 
5090  // type of pricer
5091  case SoPlex::PRICER:
5092  switch( value )
5093  {
5094  case PRICER_AUTO:
5096  break;
5097  case PRICER_DANTZIG:
5099  break;
5100  case PRICER_PARMULT:
5102  break;
5103  case PRICER_DEVEX:
5105  break;
5106  case PRICER_QUICKSTEEP:
5108  break;
5109  case PRICER_STEEP:
5111  break;
5112  default:
5113  return false;
5114  }
5115  break;
5116 
5117  // mode for synchronizing real and rational LP
5118  case SoPlex::SYNCMODE:
5119  switch( value )
5120  {
5121  case SYNCMODE_ONLYREAL:
5122  if( _rationalLP != 0 )
5123  {
5124  _rationalLP->~SPxLPRational();
5126  }
5127  break;
5128  case SYNCMODE_AUTO:
5129  if( intParam(param) == SYNCMODE_ONLYREAL )
5130  _syncLPRational();
5131  break;
5132  case SYNCMODE_MANUAL:
5134  break;
5135  default:
5136  return false;
5137  }
5138  break;
5139 
5140  // mode for reading LP files; nothing to do but change the value if valid
5141  case SoPlex::READMODE:
5142  switch( value )
5143  {
5144  case READMODE_REAL:
5145  case READMODE_RATIONAL:
5146  break;
5147  default:
5148  return false;
5149  }
5150  break;
5151 
5152  // mode for iterative refinement strategy; nothing to do but change the value if valid
5153  case SoPlex::SOLVEMODE:
5154  switch( value )
5155  {
5156  case SOLVEMODE_REAL:
5157  case SOLVEMODE_AUTO:
5158  case SOLVEMODE_RATIONAL:
5159  break;
5160  default:
5161  return false;
5162  }
5163  break;
5164 
5165  // mode for a posteriori feasibility checks; nothing to do but change the value if valid
5166  case SoPlex::CHECKMODE:
5167  switch( value )
5168  {
5169  case CHECKMODE_REAL:
5170  case CHECKMODE_AUTO:
5171  case CHECKMODE_RATIONAL:
5172  break;
5173  default:
5174  return false;
5175  }
5176  break;
5177 
5178  // type of ratio test
5179  case SoPlex::RATIOTESTER:
5180  switch( value )
5181  {
5182  case RATIOTESTER_TEXTBOOK:
5184  break;
5185  case RATIOTESTER_HARRIS:
5187  break;
5188  case RATIOTESTER_FAST:
5190  break;
5193  break;
5194  default:
5195  return false;
5196  }
5197  break;
5198 
5199  // type of timer
5200  case SoPlex::TIMER:
5201  switch( value )
5202  {
5203  case TIMER_OFF:
5205  break;
5206  case TIMER_CPU:
5208  break;
5209  case TIMER_WALLCLOCK:
5211  break;
5212  default:
5213  return false;
5214  }
5215  break;
5216 
5217  // mode of hyper pricing
5218  case SoPlex::HYPER_PRICING:
5219  switch( value )
5220  {
5221  case HYPER_PRICING_OFF:
5222  case HYPER_PRICING_AUTO:
5223  case HYPER_PRICING_ON:
5224  break;
5225  default:
5226  return false;
5227  }
5228  break;
5229 
5230  // minimum number of stalling refinements since last pivot to trigger rational factorization
5232  break;
5233 
5234  default:
5235  return false;
5236  }
5237 
5238  _currentSettings->_intParamValues[param] = value;
5239  return true;
5240  }
5241 
5242 
5243 
5244  /// sets real parameter value; returns true on success
5245  bool SoPlex::setRealParam(const RealParam param, const Real value, const bool quiet, const bool init)
5246  {
5247  assert(param >= 0);
5248  assert(param < REALPARAM_COUNT);
5249  assert(init || _isConsistent());
5250 
5251  if( !init && value == realParam(param) )
5252  return true;
5253 
5254  if( value < _currentSettings->_realParamLower[param] || value > _currentSettings->_realParamUpper[param] )
5255  return false;
5256 
5257  switch( param )
5258  {
5259  // primal feasibility tolerance; passed to the floating point solver only when calling solve()
5260  case SoPlex::FEASTOL:
5261  _rationalFeastol = value;
5262  break;
5263 
5264  // dual feasibility tolerance; passed to the floating point solver only when calling solve()
5265  case SoPlex::OPTTOL:
5266  _rationalOpttol = value;
5267  break;
5268 
5269  // general zero tolerance
5270  case SoPlex::EPSILON_ZERO:
5271  Param::setEpsilon(value);
5272  break;
5273 
5274  // zero tolerance used in factorization
5277  break;
5278 
5279  // zero tolerance used in update of the factorization
5281  Param::setEpsilonUpdate(value);
5282  break;
5283 
5284  // pivot zero tolerance used in factorization (declare numerical singularity for small LU pivots)
5285  case SoPlex::EPSILON_PIVOT:
5286  Param::setEpsilonPivot(value);
5287  break;
5288 
5289  // infinity threshold
5290  case SoPlex::INFTY:
5291  _rationalPosInfty = value;
5292  _rationalNegInfty = -value;
5295  break;
5296 
5297  // time limit in seconds (INFTY if unlimited)
5298  case SoPlex::TIMELIMIT:
5299  break;
5300 
5301  // lower limit on objective value is set in solveReal()
5303  break;
5304 
5305  // upper limit on objective value is set in solveReal()
5307  break;
5308 
5309  // working tolerance for feasibility in floating-point solver
5310  case SoPlex::FPFEASTOL:
5311  break;
5312 
5313  // working tolerance for optimality in floating-point solver
5314  case SoPlex::FPOPTTOL:
5315  break;
5316 
5317  // maximum increase of scaling factors between refinements
5318  case SoPlex::MAXSCALEINCR:
5319  _rationalMaxscaleincr = value;
5320  break;
5321 
5322  // lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)
5323  case SoPlex::LIFTMINVAL:
5324  break;
5325 
5326  // upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulated)
5327  case SoPlex::LIFTMAXVAL:
5328  break;
5329 
5330  // threshold for sparse pricing
5332  break;
5333 
5334  // threshold on number of rows vs. number of columns for switching from column to row representations in auto mode
5336  break;
5337 
5338  // geometric frequency at which to apply rational reconstruction
5339  case SoPlex::RATREC_FREQ:
5340  break;
5341 
5342  // minimal reduction (sum of removed rows/cols) to continue simplification
5343  case SoPlex::MINRED:
5344  break;
5345 
5346  default:
5347  return false;
5348  }
5349 
5350  _currentSettings->_realParamValues[param] = value;
5351  return true;
5352  }
5353 
5354 
5355 
5356 #ifdef SOPLEX_WITH_RATIONALPARAM
5357  /// sets rational parameter value; returns true on success
5358  bool SoPlex::setRationalParam(const RationalParam param, const Rational value, const bool quiet, const bool init)
5359  {
5360  assert(param >= 0);
5361  assert(param < RATIONALPARAM_COUNT);
5362  assert(init || _isConsistent());
5363 
5364  if( !init && value == rationalParam(param) )
5365  return true;
5366 
5367  if( value < _currentSettings->_rationalParamLower[param] || value > _currentSettings->_rationalParamUpper[param] )
5368  return false;
5369 
5370  switch( param )
5371  {
5372  default:
5373  // currently, there are no rational-valued parameters
5374  return false;
5375  }
5376 
5377  _currentSettings->_rationalParamValues[param] = value;
5378  return true;
5379  }
5380 #endif
5381 
5382 
5383 
5384  /// sets parameter settings; returns true on success
5385  bool SoPlex::setSettings(const Settings& newSettings, const bool quiet, const bool init)
5386  {
5387  assert(init || _isConsistent());
5388 
5389  bool success = true;
5390 
5391  *_currentSettings = newSettings;
5392 
5393  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
5394  success &= setBoolParam((BoolParam)i, _currentSettings->_boolParamValues[i], quiet, init);
5395 
5396  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
5397  success &= setIntParam((IntParam)i, _currentSettings->_intParamValues[i], quiet, init);
5398 
5399  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
5400  success &= setRealParam((RealParam)i, _currentSettings->_realParamValues[i], quiet, init);
5401 
5402 #ifdef SOPLEX_WITH_RATIONALPARAM
5403  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
5404  success &= setRationalParam((RationalParam)i, _currentSettings->_rationalParamValues[i], quiet, init);
5405 #endif
5406 
5407  assert(_isConsistent());
5408 
5409  return success;
5410  }
5411 
5412 
5413 
5414  /// print non-default parameter values
5416  {
5417  bool printedValue = false;
5418 
5419  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
5420  {
5422  continue;
5423 
5424  spxout << "bool:" << _currentSettings->_boolParamName[i] << " = " << (_currentSettings->_boolParamValues[i] ? "true\n" : "false\n");
5425  printedValue = true;
5426  }
5427 
5428  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
5429  {
5431  continue;
5432 
5433  spxout << "int:" << _currentSettings->_intParamName[i] << " = " << _currentSettings->_intParamValues[i] << "\n";
5434  printedValue = true;
5435  }
5436 
5437  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
5438  {
5440  continue;
5441 
5442  spxout << "real:" << _currentSettings->_realParamName[i] << " = " << _currentSettings->_realParamValues[i] << "\n";
5443  printedValue = true;
5444  }
5445 
5446 #ifdef SOPLEX_WITH_RATIONALPARAM
5447  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
5448  {
5449  if( _currentSettings->_rationalParamValues[i] == _currentSettings->_rationalParamDefault[i] )
5450  continue;
5451 
5452  spxout << "rational:" << _currentSettings->_rationalParamName[i] << " = " << _currentSettings->_rationalParamValues[i] << "\n";
5453  printedValue = true;
5454  }
5455 #endif
5456  if( printedValue )
5457  spxout << std::endl;
5458  }
5459 
5460 
5461 
5462  /// writes settings file; returns true on success
5463  bool SoPlex::saveSettingsFile(const char* filename, const bool onlyChanged) const
5464  {
5465  assert(filename != 0);
5466 
5467  std::ofstream file(filename);
5468  if( !file.good() )
5469  return false;
5470 
5471  file.setf(std::ios::left);
5472  file << "# SoPlex version " << SOPLEX_VERSION / 100 << "." << (SOPLEX_VERSION / 10) % 10 << "." << SOPLEX_VERSION % 10;
5473 #if SOPLEX_SUBVERSION > 0
5474  file << "." << SOPLEX_SUBVERSION;
5475 #endif
5476  file << "\n";
5477 
5478  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
5479  {
5481  continue;
5482 
5483  file << "\n";
5484  file << "# " << _currentSettings->_boolParamDescription[i] << "\n";
5485  file << "# range {true, false}, default " << (_currentSettings->_boolParamDefault[i] ? "true\n" : "false\n");
5486  file << "bool:" << _currentSettings->_boolParamName[i] << " = " << (_currentSettings->_boolParamValues[i] ? "true\n" : "false\n");
5487  }
5488 
5489  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
5490  {
5491  if( onlyChanged && _currentSettings->_intParamValues[i] == _currentSettings->_intParamDefault[i] )
5492  continue;
5493 
5494  file << "\n";
5495  file << "# " << _currentSettings->_intParamDescription[i] << "\n";
5496  file << "# range [-2147483648,2147483647], default " << _currentSettings->_intParamDefault[i] << "\n";
5497  file << "int:" << _currentSettings->_intParamName[i] << " = " << _currentSettings->_intParamValues[i] << "\n";
5498  }
5499 
5500  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
5501  {
5503  continue;
5504 
5505  file << "\n";
5506  file << "# " << _currentSettings->_realParamDescription[i] << "\n";
5507  file << "# range [" << _currentSettings->_realParamLower[i] << "," << _currentSettings->_realParamUpper[i]
5508  << "], default " << _currentSettings->_realParamDefault[i] << "\n";
5509  file << "real:" << _currentSettings->_realParamName[i] << " = " << _currentSettings->_realParamValues[i] << "\n";
5510  }
5511 
5512 #ifdef SOPLEX_WITH_RATIONALPARAM
5513  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
5514  {
5515  if( onlyChanged && _currentSettings->_rationalParamValues[i] == _currentSettings->_rationalParamDefault[i] )
5516  continue;
5517 
5518  file << "\n";
5519  file << "# " << _currentSettings->_rationalParamDescription[i] << "\n";
5520  file << "# range [" << _currentSettings->_rationalParamLower[i] << "," << _currentSettings->_rationalParamUpper[i]
5521  << "], default " << _currentSettings->_rationalParamDefault[i] << "\n";
5522  file << "rational:" << _currentSettings->_rationalParamName[i] << " = " << _currentSettings->_rationalParamValues[i] << "\n";
5523  }
5524 #endif
5525 
5526  return true;
5527  }
5528 
5529 
5530 
5531  /// reads settings file; returns true on success
5532  bool SoPlex::loadSettingsFile(const char* filename)
5533  {
5534  assert(filename != 0);
5535 
5536  // start timing
5538 
5539  MSG_INFO1( spxout, spxout << "Loading settings file <" << filename << "> . . .\n" );
5540 
5541  // open file
5542  spxifstream file(filename);
5543 
5544  if( !file )
5545  {
5546  MSG_ERROR( std::cerr << "Error opening settings file.\n" );
5547  return false;
5548  }
5549 
5550  // read file
5551  char line[SET_MAX_LINE_LEN];
5552  int lineNumber = 0;
5553  bool readError = false;
5554  bool parseError = false;
5555 
5556  while( !readError && !parseError)
5557  {
5558  lineNumber++;
5559  readError = !file.getline(line, sizeof(line));
5560  if( !readError )
5561  parseError = !_parseSettingsLine(line, lineNumber);
5562  }
5563  readError = readError && !file.eof();
5564 
5565  if( readError && strlen(line) == SET_MAX_LINE_LEN - 1 )
5566  {
5567  MSG_ERROR( std::cerr << "Error reading settings file: line " << lineNumber << " in settings file exceeds " << SET_MAX_LINE_LEN - 2 << " characters.\n" );
5568  }
5569  else if( readError )
5570  {
5571  MSG_ERROR( std::cerr << "Error reading settings file: line " << lineNumber << ".\n" );
5572  }
5573 
5574  // stop timing
5576 
5577  return !readError && !parseError;
5578  }
5579 
5580  /// parses one setting string and returns true on success
5581  bool SoPlex::parseSettingsString(char* string)
5582  {
5583  assert(string != 0);
5584  if( string == 0 )
5585  return false;
5586 
5587  char parseString[SET_MAX_LINE_LEN];
5588  strncpy(parseString, string, SET_MAX_LINE_LEN-1);
5589  parseString[SET_MAX_LINE_LEN-1] = '\0';
5590 
5591  char* line = parseString;
5592 
5593  // find the start of the parameter type
5594  while( *line == ' ' || *line == '\t' || *line == '\r' )
5595  line++;
5596  if( *line == '\0' || *line == '\n' || *line == '#' )
5597  return true;
5598  char* paramTypeString = line;
5599 
5600  // find the end of the parameter type
5601  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != ':' )
5602  line++;
5603  if( *line == ':' )
5604  {
5605  *line = '\0';
5606  line++;
5607  }
5608  else
5609  {
5610  *line = '\0';
5611  line++;
5612 
5613  // search for the ':' char in the line
5614  while( *line == ' ' || *line == '\t' || *line == '\r' )
5615  line++;
5616  if( *line != ':' )
5617  {
5618  MSG_ERROR( std::cerr << "Error parsing setting string: no ':' separating parameter type and name.\n" );
5619  return false;
5620  }
5621  line++;
5622  }
5623 
5624  // find the start of the parameter name
5625  while( *line == ' ' || *line == '\t' || *line == '\r' )
5626  line++;
5627  if( *line == '\0' || *line == '\n' || *line == '#' )
5628  {
5629  MSG_ERROR( std::cerr << "Error parsing setting string: no parameter name.\n");
5630  return false;
5631  }
5632  char* paramName = line;
5633 
5634  // find the end of the parameter name
5635  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != '=' )
5636  line++;
5637  if( *line == '=' )
5638  {
5639  *line = '\0';
5640  line++;
5641  }
5642  else
5643  {
5644  *line = '\0';
5645  line++;
5646 
5647  // search for the '=' char in the line
5648  while( *line == ' ' || *line == '\t' || *line == '\r' )
5649  line++;
5650  if( *line != '=' )
5651  {
5652  MSG_ERROR( std::cerr << "Error parsing setting string: no '=' after parameter name.\n" );
5653  return false;
5654  }
5655  line++;
5656  }
5657 
5658  // find the start of the parameter value string
5659  while( *line == ' ' || *line == '\t' || *line == '\r' )
5660  line++;
5661  if( *line == '\0' || *line == '\n' || *line == '#' )
5662  {
5663  MSG_ERROR( std::cerr << "Error parsing setting string: no parameter value.\n");
5664  return false;
5665  }
5666  char* paramValueString = line;
5667 
5668  // find the end of the parameter value string
5669  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' )
5670  line++;
5671  if( *line != '\0' )
5672  {
5673  // check, if the rest of the line is clean
5674  *line = '\0';
5675  line++;
5676  while( *line == ' ' || *line == '\t' || *line == '\r' )
5677  line++;
5678  if( *line != '\0' && *line != '\n' && *line != '#' )
5679  {
5680  MSG_ERROR( std::cerr << "Error parsing setting string: additional character '" << *line << "' after parameter value.\n" );
5681  return false;
5682  }
5683  }
5684 
5685  // check whether we have a bool parameter
5686  if( strncmp(paramTypeString, "bool", 4) == 0 )
5687  {
5688  for( int param = 0; ; param++ )
5689  {
5690  if( param >= SoPlex::BOOLPARAM_COUNT )
5691  {
5692  MSG_ERROR( std::cerr << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
5693  return false;
5694  }
5695  else if( strncmp(paramName, _currentSettings->_boolParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
5696  {
5697  if( strncasecmp(paramValueString, "true", 4) == 0
5698  || strncasecmp(paramValueString, "TRUE", 4) == 0
5699  || strncasecmp(paramValueString, "t", 4) == 0
5700  || strncasecmp(paramValueString, "T", 4) == 0
5701  || strtol(paramValueString, NULL, 4) == 1 )
5702  {
5703  setBoolParam((SoPlex::BoolParam)param, true);
5704  break;
5705  }
5706  else if( strncasecmp(paramValueString, "false", 5) == 0
5707  || strncasecmp(paramValueString, "FALSE", 5) == 0
5708  || strncasecmp(paramValueString, "f", 5) == 0
5709  || strncasecmp(paramValueString, "F", 5) == 0
5710  || strtol(paramValueString, NULL, 5) == 0 )
5711  {
5712  setBoolParam((SoPlex::BoolParam)param, false);
5713  break;
5714  }
5715  else
5716  {
5717  MSG_ERROR( std::cerr << "Error parsing setting string: invalid value <" << paramValueString << "> for bool parameter <" << paramName << ">.\n" );
5718  return false;
5719  }
5720  }
5721  }
5722 
5723  return true;
5724  }
5725 
5726  // check whether we have an integer parameter
5727  if( strncmp(paramTypeString, "int", 3) == 0 )
5728  {
5729  for( int param = 0; ; param++ )
5730  {
5731  if( param >= SoPlex::INTPARAM_COUNT )
5732  {
5733  MSG_ERROR( std::cerr << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
5734  return false;
5735  }
5736  else if( strncmp(paramName, _currentSettings->_intParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
5737  {
5738  int value;
5739 
5740  if( sscanf(paramValueString, "%d", &value) == 1 && setIntParam((SoPlex::IntParam)param, value) )
5741  break;
5742  else
5743  {
5744  MSG_ERROR( std::cerr << "Error parsing setting string: invalid value <" << paramValueString << "> for int parameter <" << paramName << ">.\n" );
5745  return false;
5746  }
5747  }
5748  }
5749 
5750  return true;
5751  }
5752 
5753  // check whether we have a real parameter
5754  if( strncmp(paramTypeString, "real", 4) == 0 )
5755  {
5756  for( int param = 0; ; param++ )
5757  {
5758  if( param >= SoPlex::REALPARAM_COUNT )
5759  {
5760  MSG_ERROR( std::cerr << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
5761  return false;
5762  }
5763  else if( strncmp(paramName, _currentSettings->_realParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
5764  {
5765  Real value;
5766 
5767  if( sscanf(paramValueString, "%" REAL_FORMAT, &value) == 1 && setRealParam((SoPlex::RealParam)param, value) )
5768  break;
5769  else
5770  {
5771  MSG_ERROR( std::cerr << "Error parsing setting string: invalid value <" << paramValueString << "> for real parameter <" << paramName << ">.\n" );
5772  return false;
5773  }
5774  }
5775  }
5776 
5777  return true;
5778  }
5779 
5780 #ifdef SOPLEX_WITH_RATIONALPARAM
5781  // check whether we have a rational parameter
5782  if( strncmp(paramTypeString, "rational", 8) == 0 )
5783  {
5784  for( int param = 0; ; param++ )
5785  {
5786  if( param >= SoPlex::RATIONALPARAM_COUNT )
5787  {
5788  MSG_ERROR( std::cerr << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
5789  return false;
5790  }
5791  else if( strncmp(paramName, _currentSettings->_rationalParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
5792  {
5793  Rational value;
5794 
5795  if( readStringRational(paramValueString, value) && setRationalParam((SoPlex::RationalParam)param, value) )
5796  break;
5797  else
5798  {
5799  MSG_ERROR( std::cerr << "Error parsing setting string: invalid value <" << paramValueString << "> for rational parameter <" << paramName << ">.\n" );
5800  return false;
5801  }
5802  }
5803  }
5804 
5805  return true;
5806  }
5807 #endif
5808 
5809  MSG_ERROR( std::cerr << "Error parsing setting string: invalid parameter type <" << paramTypeString << "> for parameter <" << paramName << ">.\n" );
5810 
5811  return false;
5812  }
5813 
5814 
5815 
5816 
5817  /// prints solution statistics
5818  void SoPlex::printSolutionStatistics(std::ostream& os)
5819  {
5821  {
5822  os << std::scientific << std::setprecision(8)
5823  << "Solution (real) : \n"
5824  << " Objective Value : " << objValueReal() << "\n";
5825  }
5826  else if( _lastSolveMode == SOLVEMODE_RATIONAL )
5827  {
5828  os << "Solution (rational) : \n"
5829  << " Objective value : " << rationalToString(objValueRational()) << "\n";
5830  os << "Size (base 2/10) : \n"
5831  << " Total primal : " << totalSizePrimalRational() << " / " << totalSizePrimalRational(10) << "\n"
5832  << " Total dual : " << totalSizeDualRational() << " / " << totalSizeDualRational(10) << "\n"
5833  << " DLCM primal : " << dlcmSizePrimalRational() << " / " << dlcmSizePrimalRational(10) << "\n"
5834  << " DLCM dual : " << dlcmSizeDualRational() << " / " << dlcmSizeDualRational(10) << "\n"
5835  << " DMAX primal : " << dmaxSizePrimalRational() << " / " << dmaxSizePrimalRational(10) << "\n"
5836  << " DMAX dual : " << dmaxSizeDualRational() << " / " << dmaxSizeDualRational(10) << "\n";
5837  }
5838  else
5839  {
5840  os << "Solution : \n"
5841  << " Objective value : -\n";
5842  }
5843 
5846  {
5847  Rational maxviol;
5848  Rational sumviol;
5849 
5850  os << "Violation (rational): \n";
5851  if( getBoundViolationRational(maxviol, sumviol) )
5852  os << " Max/sum bound : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5853  else
5854  os << " Max/sum bound : - / -\n";
5855  if( getRowViolationRational(maxviol, sumviol) )
5856  os << " Max/sum row : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5857  else
5858  os << " Max/sum row : - / -\n";
5859  if( getRedCostViolationRational(maxviol, sumviol) )
5860  os << " Max/sum redcost : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5861  else
5862  os << " Max/sum redcost : - / -\n";
5863  if( getDualViolationRational(maxviol, sumviol) )
5864  os << " Max/sum dual : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5865  else
5866  os << " Max/sum dual : - / -\n";
5867  }
5868  else
5869  {
5870  Real maxviol;
5871  Real sumviol;
5872 
5873  os << "Violations (real) : \n";
5874  if( getBoundViolationReal(maxviol, sumviol) )
5875  os << " Max/sum bound : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5876  else
5877  os << " Max/sum bound : - / -\n";
5878  if( getRowViolationReal(maxviol, sumviol) )
5879  os << " Max/sum row : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5880  else
5881  os << " Max/sum row : - / -\n";
5882  if( getRedCostViolationReal(maxviol, sumviol) )
5883  os << " Max/sum redcost : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5884  else
5885  os << " Max/sum redcost : - / -\n";
5886  if( getDualViolationReal(maxviol, sumviol) )
5887  os << " Max/sum dual : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
5888  else
5889  os << " Max/sum dual : - / -\n";
5890  }
5891  }
5892 
5893 
5894 
5895  /// prints statistics on solving process
5896  void SoPlex::printSolvingStatistics(std::ostream& os)
5897  {
5898  assert(_statistics != 0);
5899  _statistics->print(os);
5900  }
5901 
5902 
5903 
5904  /// prints short statistics
5905  void SoPlex::printShortStatistics(std::ostream& os)
5906  {
5907  printStatus(os, _status);
5908  os << "Solving time (sec) : " << std::fixed << std::setprecision(2) << _statistics->solvingTime->time() << "\n"
5909  << "Iterations : " << _statistics->iterations << "\n"
5910  << "Objective value : " << std::scientific << std::setprecision(8) << objValueReal() << std::fixed << "\n";
5911  }
5912 
5913 
5914 
5915  /// prints complete statistics
5916  void SoPlex::printStatistics(std::ostream& os)
5917  {
5918  os << std::setprecision(2);
5919 
5920  printStatus(os, _status);
5921 
5922  os << "Original problem : \n";
5925  else
5927 
5928  os << "Objective sense : " << (intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE ? "minimize\n" : "maximize\n");
5931  }
5932 
5933 
5934 
5935  /// prints status
5936  void SoPlex::printStatus(std::ostream& os, SPxSolver::Status stat)
5937  {
5938  os << "SoPlex status : ";
5939 
5940  switch( stat )
5941  {
5942  case SPxSolver::ERROR:
5943  os << "error [unspecified]";
5944  break;
5946  os << "error [no ratiotester loaded]";
5947  break;
5948  case SPxSolver::NO_PRICER:
5949  os << "error [no pricer loaded]";
5950  break;
5951  case SPxSolver::NO_SOLVER:
5952  os << "error [no linear solver loaded]";
5953  break;
5954  case SPxSolver::NOT_INIT:
5955  os << "error [not initialized]";
5956  break;
5958  os << "solving aborted [cycling]";
5959  break;
5960  case SPxSolver::ABORT_TIME:
5961  os << "solving aborted [time limit reached]";
5962  break;
5963  case SPxSolver::ABORT_ITER:
5964  os << "solving aborted [iteration limit reached]";
5965  break;
5967  os << "solving aborted [objective limit reached]";
5968  break;
5969  case SPxSolver::NO_PROBLEM:
5970  os << "no problem loaded";
5971  break;
5972  case SPxSolver::REGULAR:
5973  os << "basis is regular";
5974  break;
5975  case SPxSolver::SINGULAR:
5976  os << "basis is singular";
5977  break;
5978  case SPxSolver::OPTIMAL:
5979  os << "problem is solved [optimal]";
5980  break;
5981  case SPxSolver::UNBOUNDED:
5982  os << "problem is solved [unbounded]";
5983  break;
5984  case SPxSolver::INFEASIBLE:
5985  os << "problem is solved [infeasible]";
5986  break;
5987  case SPxSolver::INForUNBD:
5988  os << "problem is solved [infeasible or unbounded]";
5989  break;
5990  default:
5991  case SPxSolver::UNKNOWN:
5992  os << "unknown";
5993  break;
5994  }
5995 
5996  os << "\n";
5997  }
5998 
5999 
6000 
6001  /// prints version and compilation options
6003  {
6004  // do not use preprocessor directives within the MSG_INFO1 macro
6005 #if (SOPLEX_SUBVERSION > 0)
6006  MSG_INFO1( spxout, spxout << "SoPlex version " << SOPLEX_VERSION/100
6007  << "." << (SOPLEX_VERSION % 100)/10
6008  << "." << SOPLEX_VERSION % 10
6009  << "." << SOPLEX_SUBVERSION );
6010 #else
6011  MSG_INFO1( spxout, spxout << "SoPlex version " << SOPLEX_VERSION/100
6012  << "." << (SOPLEX_VERSION % 100)/10
6013  << "." << SOPLEX_VERSION % 10 );
6014 #endif
6015 
6016 #ifndef NDEBUG
6017  MSG_INFO1( spxout, spxout << " [mode: debug]" );
6018 #else
6019  MSG_INFO1( spxout, spxout << " [mode: optimized]" );
6020 #endif
6021 
6022  MSG_INFO1( spxout, spxout << " [precision: " << (int)sizeof(Real) << " byte]" );
6023 
6024 #ifdef SOPLEX_WITH_GMP
6025 #ifdef mpir_version
6026  MSG_INFO1( spxout, spxout << " [rational: MPIR " << mpir_version << "]" );
6027 #else
6028  MSG_INFO1( spxout, spxout << " [rational: GMP " << gmp_version << "]" );
6029 #endif
6030 #else
6031  MSG_INFO1( spxout, spxout << " [rational: long double]" );
6032 #endif
6033 
6034  MSG_INFO1( spxout, spxout << " [githash: " << getGitHash() << "]\n" );
6035  }
6036 
6037 
6038 
6039  /// checks if real LP and rational LP are in sync; dimensions will always be compared,
6040  /// vector and matrix values only if the respective parameter is set to true.
6041  /// If quiet is set to true the function will only display which vectors are different.
6042  bool SoPlex::areLPsInSync(const bool checkVecVals, const bool checkMatVals, const bool quiet) const
6043  {
6044  bool result = true;
6045  bool nRowsMatch = true;
6046  bool nColsMatch = true;
6047  bool rhsDimMatch = true;
6048  bool lhsDimMatch = true;
6049  bool maxObjDimMatch = true;
6050  bool upperDimMatch = true;
6051  bool lowerDimMatch = true;
6052 
6053  // compare number of Rows
6054  if( _realLP->nRows() != _rationalLP->nRows() )
6055  {
6056  MSG_ERROR( std::cerr << "The number of Rows in the Real LP does not match the one in the Rational LP."
6057  << " Real LP: " << _realLP->nRows() << " Rational LP: " << _rationalLP->nRows() << std::endl);
6058  result = false;
6059  nRowsMatch = false;
6060  }
6061 
6062  // compare number of Columns
6063  if( _realLP->nCols() != _rationalLP->nCols() )
6064  {
6065  MSG_ERROR( std::cerr << "The number of Columns in the Real LP does not match the one in the Rational LP."
6066  << " Real LP: " << _realLP->nCols() << " Rational LP: " << _rationalLP->nCols() << std::endl);
6067  result = false;
6068  nColsMatch = false;
6069  }
6070 
6071  // compare number of nonZeros
6072  if( _realLP->nNzos() != _rationalLP->nNzos() )
6073  {
6074  MSG_ERROR( std::cerr << "The number of nonZeros in the Real LP does not match the one in the Rational LP."
6075  << " Real LP: " << _realLP->nNzos() << " Rational LP: " << _rationalLP->nNzos() << std::endl);
6076  result = false;
6077  }
6078 
6079  // compare the dimensions of the right hand side vectors
6080  if( _realLP->rhs().dim() != _rationalLP->rhs().dim() )
6081  {
6082  MSG_ERROR( std::cerr << "The dimension of the right hand side vector of the Real LP does not match the one of the Rational LP."
6083  << " Real LP: " << _realLP->rhs().dim() << " Rational LP: " << _rationalLP->rhs().dim() << std::endl);
6084  result = false;
6085  rhsDimMatch = false;
6086 
6087  }
6088 
6089  // compare the dimensions of the left hand side vectors
6090  if( _realLP->lhs().dim() != _rationalLP->lhs().dim() )
6091  {
6092  MSG_ERROR( std::cerr << "The dimension of the left hand side vector of the Real LP does not match the one of the Rational LP."
6093  << " Real LP: " << _realLP->lhs().dim() << " Rational LP: " << _rationalLP->lhs().dim() << std::endl);
6094  result = false;
6095  lhsDimMatch = false;
6096  }
6097 
6098  // compare the dimensions of the objective function vectors
6099  if( _realLP->maxObj().dim() != _rationalLP->maxObj().dim() )
6100  {
6101  MSG_ERROR( std::cerr << "The dimension of the objective function vector of the Real LP does not match the one of the Rational LP."
6102  << " Real LP: " << _realLP->maxObj().dim() << " Rational LP: " << _rationalLP->maxObj().dim() << std::endl);
6103  result = false;
6104  maxObjDimMatch = false;
6105  }
6106 
6107  // compare the sense
6108  if( (int)_realLP->spxSense() != (int)_rationalLP->spxSense() )
6109  {
6110  MSG_ERROR( std::cerr << "The objective function sense of the Real LP does not match the one of the Rational LP."
6111  << " Real LP: " << (_realLP->spxSense() == SPxLPReal::MINIMIZE ? "MIN" : "MAX")
6112  << " Rational LP: " << (_rationalLP->spxSense() == SPxLPRational::MINIMIZE ? "MIN" : "MAX") << std::endl);
6113  result = false;
6114  }
6115 
6116  // compare the dimensions of upper bound vectors
6117  if( _realLP->upper().dim() != _rationalLP->upper().dim() )
6118  {
6119  MSG_ERROR( std::cerr << "The dimension of the upper bound vector of the Real LP does not match the one of the Rational LP."
6120  << " Real LP: " << _realLP->upper().dim() << " Rational LP: " << _rationalLP->upper().dim() << std::endl);
6121  result = false;
6122  upperDimMatch = false;
6123  }
6124 
6125  // compare the dimensions of the objective function vectors
6126  if( _realLP->lower().dim() != _rationalLP->lower().dim() )
6127  {
6128  MSG_ERROR( std::cerr << "The dimension of the lower bound vector of the Real LP does not match the one of the Rational LP."
6129  << " Real LP: " << _realLP->lower().dim() << " Rational LP: " << _rationalLP->lower().dim() << std::endl);
6130  result = false;
6131  lowerDimMatch = false;
6132  }
6133 
6134  // compares the values of the rhs, lhs, maxObj, upper, lower vectors
6135  if( checkVecVals )
6136  {
6137  bool rhsValMatch = true;
6138  bool lhsValMatch = true;
6139  bool maxObjValMatch = true;
6140  bool upperValMatch = true;
6141  bool lowerValMatch = true;
6142 
6143  // compares the values of the right hand side vectors
6144  if( rhsDimMatch )
6145  {
6146  for( int i = 0; i < _realLP->rhs().dim(); i++ )
6147  {
6148  if( (GE(_realLP->rhs()[i], realParam(SoPlex::INFTY)) != (_rationalLP->rhs()[i] >= _rationalPosInfty))
6150  && !_rationalLP->rhs()[i].isAdjacentTo((double)_realLP->rhs()[i])) )
6151  {
6152  if( !quiet )
6153  {
6154  MSG_ERROR( std::cerr << "Entries number " << i << " of the right hand side vectors don't match."
6155  << " Real LP: " << _realLP->rhs()[i] << " Rational LP: " << _rationalLP->rhs()[i] << std::endl);
6156  }
6157  rhsValMatch = false;
6158  result = false;
6159  }
6160  }
6161 
6162  if( !rhsValMatch && quiet )
6163  {
6164  MSG_ERROR( std::cerr << "The values of the right hand side vectors don't match." << std::endl );
6165  }
6166  }
6167 
6168  // compares the values of the left hand side vectors
6169  if( lhsDimMatch )
6170  {
6171  for( int i = 0; i < _realLP->lhs().dim(); i++ )
6172  {
6173  if( (LE(_realLP->lhs()[i], -realParam(SoPlex::INFTY)) != (_rationalLP->lhs()[i] <= _rationalNegInfty))
6175  && !_rationalLP->lhs()[i].isAdjacentTo((double)_realLP->lhs()[i])) )
6176  {
6177  if( !quiet )
6178  {
6179  MSG_ERROR( std::cerr << "Entries number " << i << " of the left hand side vectors don't match."
6180  << " Real LP: " << _realLP->lhs()[i] << " Rational LP: " << _rationalLP->lhs()[i] << std::endl);
6181  }
6182  lhsValMatch = false;
6183  result = false;
6184  }
6185  }
6186 
6187  if( !lhsValMatch && quiet )
6188  {
6189  MSG_ERROR( std::cerr << "The values of the left hand side vectors don't match." << std::endl );
6190  }
6191  }
6192 
6193  // compares the values of the objective function vectors
6194  if( maxObjDimMatch )
6195  {
6196  for( int i = 0; i < _realLP->maxObj().dim(); i++ )
6197  {
6198  if( !_rationalLP->maxObj()[i].isAdjacentTo((double)_realLP->maxObj()[i]) )
6199  {
6200  if( !quiet )
6201  {
6202  MSG_ERROR( std::cerr << "Entries number " << i << " of the objective function vectors don't match."
6203  << " Real LP: " << _realLP->maxObj()[i] << " Rational LP: " << _rationalLP->maxObj()[i] << std::endl);
6204  }
6205  maxObjValMatch = false;
6206  result = false;
6207  }
6208  }
6209 
6210  if( !maxObjValMatch && quiet )
6211  {
6212  MSG_ERROR( std::cerr << "The values of the objective function vectors don't match." << std::endl );
6213  }
6214  }
6215 
6216  // compares the values of the upper bound vectors
6217  if( upperDimMatch )
6218  {
6219  for( int i = 0; i < _realLP->upper().dim(); i++ )
6220  {
6223  && !_rationalLP->upper()[i].isAdjacentTo((double)_realLP->upper()[i])) )
6224  {
6225  if( !quiet )
6226  {
6227  MSG_ERROR( std::cerr << "Entries number " << i << " of the upper bound vectors don't match."
6228  << " Real LP: " << _realLP->upper()[i] << " Rational LP: " << _rationalLP->upper()[i] << std::endl);
6229  }
6230  upperValMatch = false;
6231  result = false;
6232  }
6233  }
6234 
6235  if( !upperValMatch && quiet )
6236  {
6237  MSG_ERROR( std::cerr << "The values of the upper bound vectors don't match." << std::endl );
6238  }
6239  }
6240 
6241  // compares the values of the lower bound vectors
6242  if( lowerDimMatch )
6243  {
6244  for( int i = 0; i < _realLP->lower().dim(); i++ )
6245  {
6248  && !_rationalLP->lower()[i].isAdjacentTo((double)_realLP->lower()[i])) )
6249  {
6250  if( !quiet )
6251  {
6252  MSG_ERROR( std::cerr << "Entries number " << i << " of the lower bound vectors don't match."
6253  << " Real LP: " << _realLP->lower()[i] << " Rational LP: " << _rationalLP->lower()[i] << std::endl);
6254  }
6255  lowerValMatch = false;
6256  result = false;
6257  }
6258  }
6259 
6260  if( !lowerValMatch && quiet )
6261  {
6262  MSG_ERROR( std::cerr << "The values of the lower bound vectors don't match." << std::endl );
6263  }
6264  }
6265  }
6266 
6267  // compare the values of the matrix
6268  if( checkMatVals && nRowsMatch && nColsMatch )
6269  {
6270  bool matrixValMatch = true;
6271 
6272  for( int i = 0; i < _realLP->nCols() ; i++ )
6273  {
6274  for( int j = 0;j < _realLP->nRows() ; j++ )
6275  {
6276  if( !_rationalLP->colVector(i)[j].isAdjacentTo((double)_realLP->colVector(i)[j]) )
6277  {
6278  if( !quiet )
6279  {
6280  MSG_ERROR( std::cerr << "Entries number " << j << " of column number " << i << " don't match."
6281  << " Real LP: " << _realLP->colVector(i)[j] << " Rational LP: " << _rationalLP->colVector(i)[j] << std::endl);
6282  }
6283  matrixValMatch = false;
6284  result = false;
6285  }
6286  }
6287  }
6288 
6289  if( !matrixValMatch && quiet )
6290  {
6291  MSG_ERROR( std::cerr << "The values of the matrices don't match." << std::endl );
6292  }
6293  }
6294 
6295  return result;
6296  }
6297 
6298 
6299 
6300  /// extends sparse vector to hold newmax entries if and only if it holds no more free entries
6301  void SoPlex::_ensureDSVectorRationalMemory(DSVectorRational& vec, const int newmax) const
6302  {
6303  assert(newmax > vec.size());
6304  if( vec.size() >= vec.max() )
6305  vec.setMax(newmax);
6306  }
6307 
6308 
6309 
6310  /// creates a permutation for removing rows/columns from an array of indices
6311  void SoPlex::_idxToPerm(int* idx, int idxSize, int* perm, int permSize) const
6312  {
6313  assert(idx != 0);
6314  assert(idxSize >= 0);
6315  assert(perm != 0);
6316  assert(permSize >= 0);
6317 
6318  for( int i = 0; i < permSize; i++ )
6319  perm[i] = i;
6320 
6321  for( int i = 0; i < idxSize; i++ )
6322  {
6323  assert(idx[i] >= 0);
6324  assert(idx[i] < permSize);
6325  perm[idx[i]] = -1;
6326  }
6327  }
6328 
6329 
6330 
6331  /// creates a permutation for removing rows/columns from a range of indices
6332  void SoPlex::_rangeToPerm(int start, int end, int* perm, int permSize) const
6333  {
6334  assert(perm != 0);
6335  assert(permSize >= 0);
6336 
6337  for( int i = 0; i < permSize; i++ )
6338  perm[i] = (i < start || i > end) ? i : -1;
6339  }
6340 
6341 
6342 
6343  /// checks consistency
6345  {
6346  assert(_statistics != 0);
6347  assert(_currentSettings != 0);
6348 
6349  assert(_realLP != 0);
6351 
6352  assert(_realLP != &_solver || _isRealLPLoaded);
6353  assert(_realLP == &_solver || !_isRealLPLoaded);
6354 
6355  assert(!_hasBasis || _isRealLPLoaded || _basisStatusRows.size() == numRowsReal());
6356  assert(!_hasBasis || _isRealLPLoaded || _basisStatusCols.size() == numColsReal());
6357 
6358  return true;
6359  }
6360 
6361 
6362 
6363  /// should solving process be stopped?
6364  bool SoPlex::_isSolveStopped(bool& stoppedTime, bool& stoppedIter) const
6365  {
6366  assert(_statistics != 0);
6367 
6369  stoppedIter = (intParam(ITERLIMIT) >= 0 && _statistics->iterations >= intParam(ITERLIMIT))
6372 
6373  return stoppedTime || stoppedIter;
6374  }
6375 
6376 
6377 
6378  /// determines RangeType from real bounds
6379  SoPlex::RangeType SoPlex::_rangeTypeReal(const Real& lower, const Real& upper) const
6380  {
6381  assert(lower <= upper);
6382 
6383  if( lower <= -infinity )
6384  {
6385  if( upper >= infinity )
6386  return RANGETYPE_FREE;
6387  else
6388  return RANGETYPE_UPPER;
6389  }
6390  else
6391  {
6392  if( upper >= infinity )
6393  return RANGETYPE_LOWER;
6394  else if( lower == upper )
6395  return RANGETYPE_FIXED;
6396  else
6397  return RANGETYPE_BOXED;
6398  }
6399  }
6400 
6401 
6402 
6403  /// determines RangeType from rational bounds
6405  {
6406  assert(lower <= upper);
6407 
6408  if( lower <= _rationalNegInfty )
6409  {
6410  if( upper >= _rationalPosInfty )
6411  return RANGETYPE_FREE;
6412  else
6413  return RANGETYPE_UPPER;
6414  }
6415  else
6416  {
6417  if( upper >= _rationalPosInfty )
6418  return RANGETYPE_LOWER;
6419  else if( lower == upper )
6420  return RANGETYPE_FIXED;
6421  else
6422  return RANGETYPE_BOXED;
6423  }
6424  }
6425 
6426 
6427 
6428  /// switches RANGETYPE_LOWER to RANGETYPE_UPPER and vice versa
6430  {
6431  if( rangeType == RANGETYPE_LOWER )
6432  return RANGETYPE_UPPER;
6433  else if( rangeType == RANGETYPE_UPPER )
6434  return RANGETYPE_LOWER;
6435  else
6436  return rangeType;
6437  }
6438 
6439 
6440 
6441  /// checks whether RangeType corresponds to finite lower bound
6442  bool SoPlex::_lowerFinite(const RangeType& rangeType) const
6443  {
6444  return (rangeType == RANGETYPE_LOWER || rangeType == RANGETYPE_BOXED || rangeType == RANGETYPE_FIXED);
6445  }
6446 
6447 
6448 
6449  /// checks whether RangeType corresponds to finite upper bound
6450  bool SoPlex::_upperFinite(const RangeType& rangeType) const
6451  {
6452  return (rangeType == RANGETYPE_UPPER || rangeType == RANGETYPE_BOXED || rangeType == RANGETYPE_FIXED);
6453  }
6454 
6455 
6456 
6457  /// adds a single row to the real LP and adjusts basis
6458  void SoPlex::_addRowReal(const LPRowReal& lprow)
6459  {
6460  assert(_realLP != 0);
6461 
6462  _realLP->addRow(lprow);
6463 
6464  if( _isRealLPLoaded )
6466  else if( _hasBasis )
6468  }
6469 
6470 
6471 
6472  /// adds a single row to the real LP and adjusts basis
6473  void SoPlex::_addRowReal(Real lhs, const SVectorReal& lprow, Real rhs)
6474  {
6475  assert(_realLP != 0);
6476 
6477  _realLP->addRow(lhs, lprow, rhs);
6478 
6479  if( _isRealLPLoaded )
6481  else if( _hasBasis )
6483  }
6484 
6485 
6486 
6487  /// adds multiple rows to the real LP and adjusts basis
6488  void SoPlex::_addRowsReal(const LPRowSetReal& lprowset)
6489  {
6490  assert(_realLP != 0);
6491 
6492  _realLP->addRows(lprowset);
6493 
6494  if( _isRealLPLoaded )
6496  else if( _hasBasis )
6497  _basisStatusRows.append(lprowset.num(), SPxSolver::BASIC);
6498  }
6499 
6500 
6501  /// adds a single column to the real LP and adjusts basis
6502  void SoPlex::_addColReal(const LPColReal& lpcol)
6503  {
6504  assert(_realLP != 0);
6505 
6506  _realLP->addCol(lpcol);
6507 
6508  if( _isRealLPLoaded )
6510  else if( _hasBasis )
6511  {
6512  if( lpcol.lower() > -realParam(SoPlex::INFTY) )
6514  else if( lpcol.upper() < realParam(SoPlex::INFTY) )
6516  else
6518  }
6519  }
6520 
6521 
6522 
6523  /// adds a single column to the real LP and adjusts basis
6524  void SoPlex::_addColReal(Real obj, Real lower, const SVectorReal& lpcol, Real upper)
6525  {
6526  assert(_realLP != 0);
6527 
6528  _realLP->addCol(obj, lower, lpcol, upper);
6529 
6530  if( _isRealLPLoaded )
6532  else if( _hasBasis )
6534  }
6535 
6536 
6537 
6538  /// adds multiple columns to the real LP and adjusts basis
6539  void SoPlex::_addColsReal(const LPColSetReal& lpcolset)
6540  {
6541  assert(_realLP != 0);
6542 
6543  _realLP->addCols(lpcolset);
6544 
6545  if( _isRealLPLoaded )
6547  else if( _hasBasis )
6548  {
6549  for( int i = 0; i < lpcolset.num(); i++ )
6550  {
6551  if( lpcolset.lower(i) > -realParam(SoPlex::INFTY) )
6553  else if( lpcolset.upper(i) < realParam(SoPlex::INFTY) )
6555  else
6557  }
6558  }
6559  }
6560 
6561 
6562  /// replaces row \p i with \p lprow and adjusts basis
6563  void SoPlex::_changeRowReal(int i, const LPRowReal& lprow)
6564  {
6565  assert(_realLP != 0);
6566 
6567  _realLP->changeRow(i, lprow);
6568 
6569  if( _isRealLPLoaded )
6571  else if( _hasBasis )
6572  {
6574  _hasBasis = false;
6575  else if( _basisStatusRows[i] == SPxSolver::ON_LOWER && lprow.lhs() <= -realParam(SoPlex::INFTY) )
6577  else if( _basisStatusRows[i] == SPxSolver::ON_UPPER && lprow.rhs() >= realParam(SoPlex::INFTY) )
6579  }
6580  }
6581 
6582 
6583 
6584  /// changes left-hand side vector for constraints to \p lhs and adjusts basis
6586  {
6587  assert(_realLP != 0);
6588 
6589  _realLP->changeLhs(lhs);
6590 
6591  if( _isRealLPLoaded )
6593  else if( _hasBasis )
6594  {
6595  for( int i = numRowsReal() - 1; i >= 0; i-- )
6596  {
6597  if( _basisStatusRows[i] == SPxSolver::ON_LOWER && lhs[i] <= -realParam(SoPlex::INFTY) )
6599  }
6600  }
6601  }
6602 
6603 
6604 
6605  /// changes left-hand side of row \p i to \p lhs and adjusts basis
6606  void SoPlex::_changeLhsReal(int i, const Real& lhs)
6607  {
6608  assert(_realLP != 0);
6609 
6610  _realLP->changeLhs(i, lhs);
6611 
6612  if( _isRealLPLoaded )
6613  {
6615  }
6616  else if( _hasBasis && _basisStatusRows[i] == SPxSolver::ON_LOWER && lhs <= -realParam(SoPlex::INFTY) )
6618 
6619  }
6620 
6621 
6622 
6623  /// changes right-hand side vector to \p rhs and adjusts basis
6625  {
6626  assert(_realLP != 0);
6627 
6628  _realLP->changeRhs(rhs);
6629 
6630  if( _isRealLPLoaded )
6631  {
6633  }
6634  else if( _hasBasis )
6635  {
6636  for( int i = numRowsReal() - 1; i >= 0; i-- )
6637  {
6640  }
6641  }
6642  }
6643 
6644 
6645 
6646  /// changes right-hand side of row \p i to \p rhs and adjusts basis
6647  void SoPlex::_changeRhsReal(int i, const Real& rhs)
6648  {
6649  assert(_realLP != 0);
6650 
6651  _realLP->changeRhs(i, rhs);
6652 
6653  if( _isRealLPLoaded )
6654  {
6656  }
6659  }
6660 
6661 
6662 
6663  /// changes left- and right-hand side vectors and adjusts basis
6664  void SoPlex::_changeRangeReal(const VectorReal& lhs, const VectorReal& rhs)
6665  {
6666  assert(_realLP != 0);
6667 
6668  _realLP->changeRange(lhs, rhs);
6669 
6670  if( _isRealLPLoaded )
6671  {
6673  }
6674  else if( _hasBasis )
6675  {
6676  for( int i = numRowsReal() - 1; i >= 0; i-- )
6677  {
6678  if( _basisStatusRows[i] == SPxSolver::ON_LOWER && lhs[i] <= -realParam(SoPlex::INFTY) )
6680  else if( _basisStatusRows[i] == SPxSolver::ON_UPPER && rhs[i] >= realParam(SoPlex::INFTY) )
6682  }
6683  }
6684  }
6685 
6686 
6687 
6688  /// changes left- and right-hand side of row \p i and adjusts basis
6689  void SoPlex::_changeRangeReal(int i, const Real& lhs, const Real& rhs)
6690  {
6691  assert(_realLP != 0);
6692 
6693  _realLP->changeRange(i, lhs, rhs);
6694 
6695  if( _isRealLPLoaded )
6696  {
6698  }
6699  else if( _hasBasis )
6700  {
6703  else if( _basisStatusRows[i] == SPxSolver::ON_UPPER && rhs >= realParam(SoPlex::INFTY) )
6705  }
6706  }
6707 
6708 
6709 
6710  /// replaces column \p i with \p lpcol and adjusts basis
6711  void SoPlex::_changeColReal(int i, const LPColReal& lpcol)
6712  {
6713  assert(_realLP != 0);
6714 
6715  _realLP->changeCol(i, lpcol);
6716 
6717  if( _isRealLPLoaded )
6718  {
6720  }
6721  else if( _hasBasis )
6722  {
6724  _hasBasis = false;
6725  else if( _basisStatusCols[i] == SPxSolver::ON_LOWER && lpcol.lower() <= -realParam(SoPlex::INFTY) )
6727  else if( _basisStatusCols[i] == SPxSolver::ON_UPPER && lpcol.upper() >= realParam(SoPlex::INFTY) )
6729  }
6730  }
6731 
6732 
6733 
6734  /// changes vector of lower bounds to \p lower and adjusts basis
6736  {
6737  assert(_realLP != 0);
6738 
6739  _realLP->changeLower(lower);
6740 
6741  if( _isRealLPLoaded )
6742  {
6744  }
6745  else if( _hasBasis )
6746  {
6747  for( int i = numColsReal() - 1; i >= 0; i-- )
6748  {
6749  if( _basisStatusCols[i] == SPxSolver::ON_LOWER && lower[i] <= -realParam(SoPlex::INFTY) )
6751  }
6752  }
6753  }
6754 
6755 
6756 
6757  /// changes lower bound of column i to \p lower and adjusts basis
6758  void SoPlex::_changeLowerReal(int i, const Real& lower)
6759  {
6760  assert(_realLP != 0);
6761 
6762  _realLP->changeLower(i, lower);
6763 
6764  if( _isRealLPLoaded )
6765  {
6767  }
6768  else if( _hasBasis && _basisStatusCols[i] == SPxSolver::ON_LOWER && lower <= -realParam(SoPlex::INFTY) )
6770  }
6771 
6772 
6773 
6774  /// changes vector of upper bounds to \p upper and adjusts basis
6776  {
6777  assert(_realLP != 0);
6778 
6779  _realLP->changeUpper(upper);
6780 
6781  if( _isRealLPLoaded )
6782  {
6784  }
6785  else if( _hasBasis )
6786  {
6787  for( int i = numColsReal() - 1; i >= 0; i-- )
6788  {
6789  if( _basisStatusCols[i] == SPxSolver::ON_UPPER && upper[i] >= realParam(SoPlex::INFTY) )
6791  }
6792  }
6793  }
6794 
6795 
6796 
6797  /// changes \p i 'th upper bound to \p upper and adjusts basis
6798  void SoPlex::_changeUpperReal(int i, const Real& upper)
6799  {
6800  assert(_realLP != 0);
6801 
6802  _realLP->changeUpper(i, upper);
6803 
6804  if( _isRealLPLoaded )
6805  {
6807  }
6808  else if( _hasBasis && _basisStatusCols[i] == SPxSolver::ON_UPPER && upper >= realParam(SoPlex::INFTY) )
6810  }
6811 
6812 
6813 
6814  /// changes vectors of column bounds to \p lower and \p upper and adjusts basis
6815  void SoPlex::_changeBoundsReal(const VectorReal& lower, const VectorReal& upper)
6816  {
6817  assert(_realLP != 0);
6818 
6819  _realLP->changeBounds(lower, upper);
6820 
6821  if( _isRealLPLoaded )
6822  {
6824  }
6825  else if( _hasBasis )
6826  {
6827  for( int i = numColsReal() - 1; i >= 0; i-- )
6828  {
6829  if( _basisStatusCols[i] == SPxSolver::ON_LOWER && lower[i] <= -realParam(SoPlex::INFTY) )
6831  else if( _basisStatusCols[i] == SPxSolver::ON_UPPER && upper[i] >= realParam(SoPlex::INFTY) )
6833  }
6834  }
6835  }
6836 
6837 
6838 
6839  /// changes bounds of column \p i to \p lower and \p upper and adjusts basis
6840  void SoPlex::_changeBoundsReal(int i, const Real& lower, const Real& upper)
6841  {
6842  assert(_realLP != 0);
6843 
6844  _realLP->changeBounds(i, lower, upper);
6845 
6846  if( _isRealLPLoaded )
6847  {
6849  }
6850  else if( _hasBasis )
6851  {
6854  else if( _basisStatusCols[i] == SPxSolver::ON_UPPER && upper >= realParam(SoPlex::INFTY) )
6856  }
6857  }
6858 
6859 
6860 
6861  /// changes matrix entry in row \p i and column \p j to \p val and adjusts basis
6862  void SoPlex::_changeElementReal(int i, int j, const Real& val)
6863  {
6864  assert(_realLP != 0);
6865 
6866  _realLP->changeElement(i, j, val);
6867 
6868  if( _isRealLPLoaded )
6869  {
6871  }
6872  else if( _hasBasis )
6873  {
6875  _hasBasis = false;
6876  }
6877  }
6878 
6879 
6880 
6881  /// removes row \p i and adjusts basis
6883  {
6884  assert(_realLP != 0);
6885 
6886  _realLP->removeRow(i);
6887 
6888  if( _isRealLPLoaded )
6889  {
6891  }
6892  else if( _hasBasis )
6893  {
6895  _hasBasis = false;
6896  else
6897  {
6899  _basisStatusRows.removeLast();
6900  }
6901  }
6902  }
6903 
6904 
6905 
6906  /// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
6907  /// new index where row \p i has been moved to; note that \p perm must point to an array of size at least
6908  /// #numRowsReal()
6909  void SoPlex::_removeRowsReal(int perm[])
6910  {
6911  assert(_realLP != 0);
6912 
6913  _realLP->removeRows(perm);
6914 
6915  if( _isRealLPLoaded )
6916  {
6918  }
6919  else if( _hasBasis )
6920  {
6921  for( int i = numRowsReal() - 1; i >= 0 && _hasBasis; i-- )
6922  {
6923  if( perm[i] < 0 && _basisStatusRows[i] != SPxSolver::BASIC )
6924  _hasBasis = false;
6925  else if( perm[i] >= 0 && perm[i] != i )
6926  {
6927  assert(perm[i] < numRowsReal());
6928  assert(perm[perm[i]] < 0);
6929 
6930  _basisStatusRows[perm[i]] = _basisStatusRows[i];
6931  }
6932  }
6933 
6934  if( _hasBasis )
6935  _basisStatusRows.reSize(numRowsReal());
6936  }
6937  }
6938 
6939 
6940 
6941  /// removes column i
6943  {
6944  assert(_realLP != 0);
6945 
6946  _realLP->removeCol(i);
6947 
6948  if( _isRealLPLoaded )
6949  {
6951  }
6952  else if( _hasBasis )
6953  {
6955  _hasBasis = false;
6956  else
6957  {
6959  _basisStatusCols.removeLast();
6960  }
6961  }
6962  }
6963 
6964 
6965 
6966  /// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
6967  /// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
6968  /// #numColsReal()
6969  void SoPlex::_removeColsReal(int perm[])
6970  {
6971  assert(_realLP != 0);
6972 
6973  _realLP->removeCols(perm);
6974 
6975  if( _isRealLPLoaded )
6976  {
6978  }
6979  else if( _hasBasis )
6980  {
6981  for( int i = numColsReal() - 1; i >= 0 && _hasBasis; i-- )
6982  {
6983  if( perm[i] < 0 && _basisStatusCols[i] == SPxSolver::BASIC )
6984  _hasBasis = false;
6985  else if( perm[i] >= 0 && perm[i] != i )
6986  {
6987  assert(perm[i] < numColsReal());
6988  assert(perm[perm[i]] < 0);
6989 
6990  _basisStatusCols[perm[i]] = _basisStatusCols[i];
6991  }
6992  }
6993 
6994  if( _hasBasis )
6995  _basisStatusCols.reSize(numColsReal());
6996  }
6997  }
6998 
6999 
7000 
7001  /// invalidates solution
7003  {
7004  ///@todo maybe this should be done individually at the places when this method is called
7006 
7007  _solReal.invalidate();
7008  _hasSolReal = false;
7009 
7011  _hasSolRational = false;
7012  }
7013 
7014 
7015 
7016  /// enables simplifier and scaler
7018  {
7019  // type of simplifier
7020  switch( intParam(SoPlex::SIMPLIFIER) )
7021  {
7022  case SIMPLIFIER_OFF:
7023  _simplifier = 0;
7024  break;
7025  case SIMPLIFIER_AUTO:
7027  assert(_simplifier != 0);
7029  break;
7030  default:
7031  break;
7032  }
7033 
7034  // type of scaler
7035  switch( intParam(SoPlex::SCALER) )
7036  {
7037  case SCALER_OFF:
7038  _scaler = 0;
7039  break;
7040  case SCALER_UNIEQUI:
7042  break;
7043  case SCALER_BIEQUI:
7045  break;
7046  case SCALER_GEO1:
7047  _scaler = &_scalerGeo1;
7048  break;
7049  case SCALER_GEO8:
7050  _scaler = &_scalerGeo8;
7051  break;
7052  default:
7053  break;
7054  }
7055  }
7056 
7057 
7058 
7059  /// disables simplifier and scaler
7061  {
7062  _simplifier = 0;
7063  _scaler = 0;
7064  }
7065 
7066 
7067 
7068  /// ensures that the rational LP is available; performs no sync
7070  {
7071  if( _rationalLP == 0 )
7072  {
7076  }
7077  }
7078 
7079 
7080 
7081  /// ensures that the real LP and the basis are loaded in the solver; performs no sync
7083  {
7084  if( !_isRealLPLoaded )
7085  {
7086  assert(_realLP != &_solver);
7087 
7089  _realLP->~SPxLPReal();
7090  spx_free(_realLP);
7091  _realLP = &_solver;
7092  _isRealLPLoaded = true;
7093 
7094  if( _hasBasis )
7095  {
7096  ///@todo this should not fail even if the basis is invalid (wrong dimension or wrong number of basic
7097  /// entries); fix either in SPxSolver or in SPxBasis
7098  assert(_basisStatusRows.size() == numRowsReal());
7099  assert(_basisStatusCols.size() == numColsReal());
7100  _solver.setBasis(_basisStatusRows.get_const_ptr(), _basisStatusCols.get_const_ptr());
7102  }
7103  }
7104  }
7105 
7106 
7107 
7108  /// call floating-point solver and update statistics on iterations etc.
7110  {
7111  bool _hadBasis = _hasBasis;
7112 
7113  // set time and iteration limit
7114  if( intParam(SoPlex::ITERLIMIT) >= 0 )
7118 
7119  // ensure that tolerances are not too small
7120  if( _solver.feastol() < 1e-12 )
7121  _solver.setFeastol(1e-12);
7122  if( _solver.opttol() < 1e-12 )
7123  _solver.setOpttol(1e-12);
7124 
7125  // set correct representation
7128  && _solver.rep() != SPxSolver::COLUMN )
7129  {
7131  }
7134  &&_solver.rep() != SPxSolver::ROW )
7135  {
7137  }
7138 
7139  // set correct type
7142  && _solver.type() != SPxSolver::ENTER )
7143  {
7145  }
7148  && _solver.type() != SPxSolver::LEAVE )
7149  {
7151  }
7152 
7153  // set pricing modes
7158  _solver.hyperPricing(true);
7160  _solver.hyperPricing(false);
7161 
7162  // call floating-point solver and catch exceptions
7164  try
7165  {
7166  _solver.solve();
7167  }
7168  catch( const SPxException& E )
7169  {
7170  MSG_ERROR( std::cerr << "Caught exception <" << E.what() << "> while solving real LP.\n" );
7172  }
7173  catch( ... )
7174  {
7175  MSG_ERROR( std::cerr << "Caught unknown exception while solving real LP.\n" );
7177  }
7179 
7180  // record statistics
7183  _statistics->iterationsFromBasis += _hadBasis ? _solver.iterations() : 0;
7190  }
7191 
7192 
7193 
7194  /// reads real LP in LP or MPS format from file and returns true on success; gets row names, column names, and
7195  /// integer variables if desired
7196  bool SoPlex::_readFileReal(const char* filename, NameSet* rowNames, NameSet* colNames, DIdxSet* intVars)
7197  {
7198  assert(_realLP != 0);
7199 
7200  // clear statistics
7202 
7203  // update status
7206  _hasBasis = false;
7207 
7208  // start timing
7210 
7211  // read
7212  bool success = _realLP->readFile(filename, rowNames, colNames, intVars);
7213 
7214  // stop timing
7216 
7217  if( success )
7218  {
7220  _realLP->changeObjOffset(0.0);
7221 
7222  // if sync mode is auto, we have to copy the (rounded) real LP to the rational LP; this is counted to sync time
7223  // and not to reading time
7225  _syncLPRational();
7226  }
7227  else
7228  clearLPReal();
7229 
7230  return success;
7231  }
7232 
7233 
7234 
7235  /// reads rational LP in LP or MPS format from file and returns true on success; gets row names, column names, and
7236  /// integer variables if desired
7237  bool SoPlex::_readFileRational(const char* filename, NameSet* rowNames, NameSet* colNames, DIdxSet* intVars)
7238  {
7239  // clear statistics
7241 
7242  // start timing
7244 
7245  // update status
7248  _hasBasis = false;
7249 
7250  // read
7252  bool success = _rationalLP->readFile(filename, rowNames, colNames, intVars);
7253 
7254  // stop timing
7256 
7257  if( success )
7258  {
7262 
7263  // if sync mode is auto, we have to copy the (rounded) real LP to the rational LP; this is counted to sync time
7264  // and not to reading time
7266  _syncLPReal();
7267  // if a rational LP file is read, but only the (rounded) real LP should be kept, we have to free the rational LP
7269  {
7270  _syncLPReal();
7271  _rationalLP->~SPxLPRational();
7273  }
7274  }
7275  else
7276  clearLPRational();
7277 
7278  return success;
7279  }
7280 
7281 
7282 
7283  /// recomputes range types from scratch using real LP
7285  {
7287  for( int i = 0; i < numRowsReal(); i++ )
7288  _rowTypes[i] = _rangeTypeReal(_realLP->lhs(i), _realLP->rhs(i));
7290  for( int i = 0; i < numColsReal(); i++ )
7292  }
7293 
7294 
7295 
7296  /// recomputes range types from scratch using rational LP
7298  {
7300  for( int i = 0; i < numRowsRational(); i++ )
7303  for( int i = 0; i < numColsRational(); i++ )
7305  }
7306 
7307 
7308 
7309  /// synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP, without looking at the sync mode
7310  void SoPlex::_syncLPReal(bool time)
7311  {
7312  // start timing
7313  if( time )
7315 
7316  // copy LP
7317  if( _isRealLPLoaded )
7319  else
7320  *_realLP = *_rationalLP;
7321 
7322  ///@todo try loading old basis
7323  _hasBasis = false;
7324 
7325  // stop timing
7326  if( time )
7328  }
7329 
7330 
7331 
7332  /// synchronizes rational LP with real LP, i.e., copies real LP to rational LP, without looking at the sync mode
7333  void SoPlex::_syncLPRational(bool time)
7334  {
7335  // start timing
7336  if( time )
7338 
7339  // copy LP
7341  *_rationalLP = *_realLP;
7343 
7344  // stop timing
7345  if( time )
7347  }
7348 
7349 
7350 
7351  /// synchronizes real solution with rational solution, i.e., copies real solution to rational solution
7353  {
7354  if( _hasSolRational && !_hasSolReal )
7355  {
7357  _hasSolReal = true;
7358  }
7359  }
7360 
7361 
7362 
7363  /// synchronizes rational solution with real solution, i.e., copies (rounded) rational solution to real solution
7365  {
7366  if( _hasSolReal && !_hasSolRational )
7367  {
7369  _hasSolRational = true;
7370  }
7371  }
7372 
7373 
7374 
7375  /// returns pointer to a constant unit vector available until destruction of the SoPlex class
7377  {
7378  assert(i >= 0);
7379 
7380  if( i < 0 )
7381  return 0;
7382  else if( i >= _unitMatrixRational.size() )
7383  _unitMatrixRational.append(i + 1 - _unitMatrixRational.size(), (UnitVectorRational*)0);
7384  assert(i < _unitMatrixRational.size());
7385 
7386  if( _unitMatrixRational[i] == 0 )
7387  {
7390  }
7391  assert(_unitMatrixRational[i] != 0);
7392 
7393  return _unitMatrixRational[i];
7394  }
7395 
7396 
7397 
7398  /// parses one line in a settings file and returns true on success; note that the string is modified
7399  bool SoPlex::_parseSettingsLine(char* line, const int lineNumber)
7400  {
7401  assert(line != 0);
7402 
7403  // find the start of the parameter type
7404  while( *line == ' ' || *line == '\t' || *line == '\r' )
7405  line++;
7406  if( *line == '\0' || *line == '\n' || *line == '#' )
7407  return true;
7408  char* paramTypeString = line;
7409 
7410  // find the end of the parameter type
7411  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != ':' )
7412  line++;
7413  if( *line == ':' )
7414  {
7415  *line = '\0';
7416  line++;
7417  }
7418  else
7419  {
7420  *line = '\0';
7421  line++;
7422 
7423  // search for the ':' char in the line
7424  while( *line == ' ' || *line == '\t' || *line == '\r' )
7425  line++;
7426  if( *line != ':' )
7427  {
7428  MSG_ERROR( std::cerr << "Error parsing settings file: no ':' separating parameter type and name in line " << lineNumber << ".\n" );
7429  return false;
7430  }
7431  line++;
7432  }
7433 
7434  // find the start of the parameter name
7435  while( *line == ' ' || *line == '\t' || *line == '\r' )
7436  line++;
7437  if( *line == '\0' || *line == '\n' || *line == '#' )
7438  {
7439  MSG_ERROR( std::cerr << "Error parsing settings file: no parameter name in line " << lineNumber << ".\n");
7440  return false;
7441  }
7442  char* paramName = line;
7443 
7444  // find the end of the parameter name
7445  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != '=' )
7446  line++;
7447  if( *line == '=' )
7448  {
7449  *line = '\0';
7450  line++;
7451  }
7452  else
7453  {
7454  *line = '\0';
7455  line++;
7456 
7457  // search for the '=' char in the line
7458  while( *line == ' ' || *line == '\t' || *line == '\r' )
7459  line++;
7460  if( *line != '=' )
7461  {
7462  MSG_ERROR( std::cerr << "Error parsing settings file: no '=' after parameter name in line " << lineNumber << ".\n" );
7463  return false;
7464  }
7465  line++;
7466  }
7467 
7468  // find the start of the parameter value string
7469  while( *line == ' ' || *line == '\t' || *line == '\r' )
7470  line++;
7471  if( *line == '\0' || *line == '\n' || *line == '#' )
7472  {
7473  MSG_ERROR( std::cerr << "Error parsing settings file: no parameter value in line " << lineNumber << ".\n");
7474  return false;
7475  }
7476  char* paramValueString = line;
7477 
7478  // find the end of the parameter value string
7479  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' )
7480  line++;
7481  if( *line != '\0' )
7482  {
7483  // check, if the rest of the line is clean
7484  *line = '\0';
7485  line++;
7486  while( *line == ' ' || *line == '\t' || *line == '\r' )
7487  line++;
7488  if( *line != '\0' && *line != '\n' && *line != '#' )
7489  {
7490  MSG_ERROR( std::cerr << "Error parsing settings file: additional character '" << *line << "' after parameter value in line " << lineNumber << ".\n" );
7491  return false;
7492  }
7493  }
7494 
7495  // check whether we have a bool parameter
7496  if( strncmp(paramTypeString, "bool", 4) == 0 )
7497  {
7498  for( int param = 0; ; param++ )
7499  {
7500  if( param >= SoPlex::BOOLPARAM_COUNT )
7501  {
7502  MSG_ERROR( std::cerr << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
7503  return false;
7504  }
7505  else if( strncmp(paramName, _currentSettings->_boolParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
7506  {
7507  if( strncasecmp(paramValueString, "true", 4) == 0
7508  || strncasecmp(paramValueString, "TRUE", 4) == 0
7509  || strncasecmp(paramValueString, "t", 4) == 0
7510  || strncasecmp(paramValueString, "T", 4) == 0
7511  || strtol(paramValueString, NULL, 4) == 1 )
7512  {
7513  setBoolParam((SoPlex::BoolParam)param, true);
7514  break;
7515  }
7516  else if( strncasecmp(paramValueString, "false", 5) == 0
7517  || strncasecmp(paramValueString, "FALSE", 5) == 0
7518  || strncasecmp(paramValueString, "f", 5) == 0
7519  || strncasecmp(paramValueString, "F", 5) == 0
7520  || strtol(paramValueString, NULL, 5) == 0 )
7521  {
7522  setBoolParam((SoPlex::BoolParam)param, false);
7523  break;
7524  }
7525  else
7526  {
7527  MSG_ERROR( std::cerr << "Error parsing settings file: invalid value <" << paramValueString << "> for bool parameter <" << paramName << "> in line " << lineNumber << ".\n" );
7528  return false;
7529  }
7530  }
7531  }
7532 
7533  return true;
7534  }
7535 
7536  // check whether we have an integer parameter
7537  if( strncmp(paramTypeString, "int", 3) == 0 )
7538  {
7539  for( int param = 0; ; param++ )
7540  {
7541  if( param >= SoPlex::INTPARAM_COUNT )
7542  {
7543  MSG_ERROR( std::cerr << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
7544  return false;
7545  }
7546  else if( strncmp(paramName, _currentSettings->_intParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
7547  {
7548  int value;
7549 
7550  if( sscanf(paramValueString, "%d", &value) == 1 && setIntParam((SoPlex::IntParam)param, value) )
7551  break;
7552  else
7553  {
7554  MSG_ERROR( std::cerr << "Error parsing settings file: invalid value <" << paramValueString << "> for int parameter <" << paramName << "> in line " << lineNumber << ".\n" );
7555  return false;
7556  }
7557  }
7558  }
7559 
7560  return true;
7561  }
7562 
7563  // check whether we have a real parameter
7564  if( strncmp(paramTypeString, "real", 4) == 0 )
7565  {
7566  for( int param = 0; ; param++ )
7567  {
7568  if( param >= SoPlex::REALPARAM_COUNT )
7569  {
7570  MSG_ERROR( std::cerr << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
7571  return false;
7572  }
7573  else if( strncmp(paramName, _currentSettings->_realParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
7574  {
7575  Real value;
7576 
7577  if( sscanf(paramValueString, "%" REAL_FORMAT, &value) == 1 && setRealParam((SoPlex::RealParam)param, value) )
7578  break;
7579  else
7580  {
7581  MSG_ERROR( std::cerr << "Error parsing settings file: invalid value <" << paramValueString << "> for real parameter <" << paramName << "> in line " << lineNumber << ".\n" );
7582  return false;
7583  }
7584  }
7585  }
7586 
7587  return true;
7588  }
7589 
7590 #ifdef SOPLEX_WITH_RATIONALPARAM
7591  // check whether we have a rational parameter
7592  if( strncmp(paramTypeString, "rational", 8) == 0 )
7593  {
7594  for( int param = 0; ; param++ )
7595  {
7596  if( param >= SoPlex::RATIONALPARAM_COUNT )
7597  {
7598  MSG_ERROR( std::cerr << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
7599  return false;
7600  }
7601  else if( strncmp(paramName, _currentSettings->_rationalParamName[param].c_str(), SET_MAX_LINE_LEN) == 0 )
7602  {
7603  Rational value;
7604 
7605  if( readStringRational(paramValueString, value) && setRationalParam((SoPlex::RationalParam)param, value) )
7606  break;
7607  else
7608  {
7609  MSG_ERROR( std::cerr << "Error parsing settings file: invalid value <" << paramValueString << "> for rational parameter <" << paramName << "> in line " << lineNumber << ".\n" );
7610  return false;
7611  }
7612  }
7613  }
7614 
7615  return true;
7616  }
7617 #endif
7618 
7619  MSG_ERROR( std::cerr << "Error parsing settings file: invalid parameter type <" << paramTypeString << "> for parameter <" << paramName << "> in line " << lineNumber << ".\n" );
7620 
7621  return false;
7622  }
7623 } // namespace soplex
7624 #endif
void changeLhsRational(const VectorRational &lhs)
changes left-hand side vector for constraints to lhs
Definition: soplex.cpp:2025
virtual void addRows(const LPRowSetBase< R > &pset)
Definition: spxlpbase.h:543
int _lastSolveMode
Definition: soplex.h:1429
floating-point check
Definition: soplex.h:1106
RangeType
type of bounds and sides
Definition: soplex.h:1401
SPxLPBase< Real > SPxLPReal
Definition: spxlp.h:36
const char * getRatiotesterName()
name of currently loaded ratiotester
Definition: soplex.cpp:4466
DVectorBase< R > _slacks
Definition: solbase.h:223
textbook ratio test without stabilization
Definition: soplex.h:1054
R obj(int i) const
Returns objective value of column i.
Definition: spxlpbase.h:362
void _changeUpperReal(const VectorReal &upper)
changes vector of upper bounds to upper and adjusts basis
Definition: soplex.cpp:6775
static std::string _boolParamName[SoPlex::BOOLPARAM_COUNT]
array of names for boolean parameters
Definition: soplex.cpp:49
int numColsReal() const
returns number of columns
Definition: soplex.cpp:779
const VectorReal & lowerReal() const
returns lower bound vector
Definition: soplex.cpp:932
bool getSlacks(VectorBase< R > &vector) const
gets the vector of slack values if available; returns true on success
Definition: solbase.h:66
const Settings & settings() const
returns current parameter settings
Definition: soplex.cpp:4888
virtual void removeRow(int i)
Removes i &#39;th row.
Definition: spxlpbase.h:813
zero tolerance used in factorization
Definition: soplex.h:1154
Rational _rationalMaxscaleincr
Definition: soplex.h:1325
Basis is dual feasible.
Definition: spxbasis.h:95
free variable fixed to zero.
Definition: spxsolver.h:182
#define DEFAULT_EPS_FACTOR
Definition: spxdefines.h:215
Real maxAbsNonzeroReal() const
returns biggest non-zero element in absolute value
Definition: soplex.cpp:806
SoPlex()
default constructor
Definition: soplex.cpp:559
not initialised error
Definition: spxsolver.h:196
bool getDualViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of dual multipliers; returns true on success
Definition: soplex.cpp:3430
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:406
bool GE(Real a, Real b, Real eps=Param::epsilon())
returns true iff a >= b + eps
Definition: spxdefines.h:401
R minAbsNzo() const
Absolute smallest non-zero element in LP.
Definition: spxlpbase.h:150
void printSolutionStatistics(std::ostream &os)
prints solution statistics
Definition: soplex.cpp:5818
DVectorBase< R > _dualFarkas
Definition: solbase.h:227
Timer * syncTime
time for synchronization between real and rational LP (included in solving time)
Definition: statistics.h:92
void setRep(Representation p_rep)
switch to ROW or COLUMN representation if not already used.
Definition: spxsolver.cpp:256
Basis is not known to be dual nor primal feasible.
Definition: spxbasis.h:94
Real minAbsNonzeroReal() const
returns smallest non-zero element in absolute value
Definition: soplex.cpp:797
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:678
void _addColReal(const LPColReal &lpcol)
adds a single column to the real LP and adjusts basis
Definition: soplex.cpp:6502
static void setEpsilon(Real eps)
Definition: spxdefines.cpp:45
void removeRowsRational(int perm[])
removes all rows with an index i such that perm[i] < 0; upon completion, perm[i] >= 0 indicates the n...
Definition: soplex.cpp:2526
virtual const std::string what() const
returns exception message
Definition: exceptions.h:57
type of starter used to create crash basis
Definition: soplex.h:885
const VectorBase< R > & lhs() const
Returns the vector of lhs values.
Definition: lprowsetbase.h:93
bool setSettings(const Settings &newSettings, const bool quiet=false, const bool init=false)
sets parameter settings; returns true on success
Definition: soplex.cpp:5385
void removeColsReal(int perm[])
removes all columns with an index i such that perm[i] < 0; upon completion, perm[i] >= 0 indicates th...
Definition: soplex.cpp:1735
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:384
upper limit on objective value
Definition: soplex.h:1172
virtual void changeRhs(const VectorBase< R > &newRhs)
Changes right hand side vector for constraints to newRhs.
Definition: spxlpbase.h:1371
void _changeElementReal(int i, int j, const Real &val)
changes matrix entry in row i and column j to val and adjusts basis
Definition: soplex.cpp:6862
general zero tolerance
Definition: soplex.h:1151
void setOutstream(SPxOut &newOutstream)
Definition: spxlpbase.h:118
Real _realParamValues[SoPlex::REALPARAM_COUNT]
array of current real parameter values
Definition: soplex.cpp:120
bool hasBasis() const
is an advanced starting basis available?
Definition: soplex.cpp:3720
void _changeRangeReal(const VectorReal &lhs, const VectorReal &rhs)
changes left- and right-hand side vectors and adjusts basis
Definition: soplex.cpp:6664
type of ratio test
Definition: soplex.h:891
void writeStateRational(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const bool cpxFormat=false) const
writes internal LP, basis information, and parameter settings; if rowNames and colNames are NULL...
Definition: soplex.cpp:4826
void removeColReal(int i)
removes column i
Definition: soplex.cpp:1709
void _rangeToPerm(int start, int end, int *perm, int permSize) const
creates a permutation for removing rows/columns from a range of indices
Definition: soplex.cpp:6332
maximum increase of scaling factors between refinements
Definition: soplex.h:1181
bool setBoolParam(const BoolParam param, const bool value, const bool quiet=false, const bool init=false)
sets boolean parameter value; returns true on success
Definition: soplex.cpp:4896
SPxMainSM _simplifierMainSM
Definition: soplex.h:1335
verbosity level
Definition: soplex.h:876
continue iterative refinement with exact basic solution if not optimal?
Definition: soplex.h:833
void setBasis(const VarStatus rows[], const VarStatus cols[])
set the lp solver&#39;s basis.
Definition: spxsolver.cpp:1795
bool hasDual() const
is a dual feasible solution available?
Definition: soplex.cpp:2823
type of timer
Definition: soplex.h:906
void setMaxUpdates(int maxUp)
change maximum number of iterations until a refactorization is performed
Definition: spxbasis.h:444
static bool _defaultsAndBoundsInitialized
have static arrays been initialized?
Definition: soplex.cpp:111
void resetCounters()
reset timers and counters
Definition: slufactor.h:256
Read MPS format files.
number of real parameters
Definition: soplex.h:1202
apply standard floating-point algorithm
Definition: soplex.h:1093
virtual void changeObj(const VectorBase< R > &newObj)
Changes objective vector to newObj.
Definition: spxlpbase.h:1182
int numNonzerosRational() const
returns number of nonzeros
Definition: soplex.cpp:1030
type of computational form, i.e., column or row representation
Definition: soplex.h:852
int stallRefinements
number of refinement steps without pivots
Definition: statistics.h:110
virtual const char * getName() const
get name of pricer.
Definition: spxpricer.h:109
void changeColRational(int i, const LPColRational &lpcol)
replaces column i with lpcol
Definition: soplex.cpp:2208
bool getPrimalReal(VectorReal &vector)
gets the primal solution vector if available; returns true on success
Definition: soplex.cpp:2865
T * get_ptr()
get a C pointer to the data.
Definition: dataarray.h:110
void reMax(int newmax=0)
resets max() to newmax.
Definition: nameset.cpp:138
int num() const
Returns the number of LPColBases currently in LPColSetBase.
Definition: lpcolsetbase.h:80
bool _isConsistent() const
checks consistency
Definition: soplex.cpp:6344
equilibrium scaling on rows or columns
Definition: soplex.h:1000
pivot zero tolerance used in factorization
Definition: soplex.h:1160
SPxSolver::Status solve()
solves the LP
Definition: soplex.cpp:2722
bool getDualRational(VectorRational &vector)
gets the dual solution vector if available; returns true on success
Definition: soplex.cpp:3220
refinement limit (-1 if unlimited)
Definition: soplex.h:867
SPxSolver::VarStatus basisRowStatus(int row) const
returns basis status for a single row
Definition: soplex.cpp:3749
class of parameter settings
Definition: soplex.cpp:45
SPxLPRational * _rationalLP
Definition: soplex.h:1374
void printShortStatistics(std::ostream &os)
prints short statistics
Definition: soplex.cpp:5905
bool getSlacksRational(VectorRational &vector)
gets the vector of slack values if available; returns true on success
Definition: soplex.cpp:3190
standard Harris ratio test
Definition: soplex.h:1057
int max() const
Maximal number of indices.
Definition: svectorbase.h:159
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:419
static const Rational ZERO
rational zero
Definition: rational.h:63
int totalSizePrimalRational(const int base=2)
get size of primal solution
Definition: soplex.cpp:3636
void _addColsReal(const LPColSetReal &lpcolset)
adds multiple columns to the real LP and adjusts basis
Definition: soplex.cpp:6539
Basis is optimal, i.e. dual and primal feasible.
Definition: spxbasis.h:97
bool hasPrimal() const
is a primal feasible solution available?
Definition: solbase.h:51
void getRowsReal(int start, int end, LPRowSetReal &lprowset) const
gets rows start, ..., end.
Definition: soplex.cpp:824
const VectorRational & rhsRational() const
returns right-hand side vector
Definition: soplex.cpp:1084
time limit in seconds (INFTY if unlimited)
Definition: soplex.h:1166
mode for iterative refinement strategy
Definition: soplex.h:900
virtual Real time() const =0
SPxGeometSC _scalerGeo8
Definition: soplex.h:1339
void changeRangeReal(const VectorReal &lhs, const VectorReal &rhs)
changes left- and right-hand side vectors
Definition: soplex.cpp:1406
void _idxToPerm(int *idx, int idxSize, int *perm, int permSize) const
creates a permutation for removing rows/columns from an array of indices
Definition: soplex.cpp:6311
virtual bool readFile(const char *filename, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
Reads LP from a file.
Definition: spxlpbase.h:1059
Rational _rationalFeastol
Definition: soplex.h:1323
DVectorBase< R > _primalRay
Definition: solbase.h:224
void setUtype(UpdateType tp)
sets update type.
Definition: slufactor.h:122
void _removeColsReal(int perm[])
removes all columns with an index i such that perm[i] < 0; upon completion, perm[i] >= 0 indicates th...
Definition: soplex.cpp:6969
modified Harris ratio test
Definition: soplex.h:1060
virtual ~SoPlex()
destructor
Definition: soplex.cpp:729
virtual void removeCols(int perm[])
Removes multiple columns.
Definition: spxlpbase.h:929
bool getRedCostRational(VectorRational &vector)
gets the vector of reduced cost values if available; returns true on success
Definition: soplex.cpp:3235
bool LE(Real a, Real b, Real eps=Param::epsilon())
returns true iff a <= b + eps
Definition: spxdefines.h:389
void getColsRational(int start, int end, LPColSetRational &lpcolset) const
gets columns start, ..., end
Definition: soplex.cpp:1138
DVectorBase< R > _redCost
Definition: solbase.h:226
int num() const
Returns the number of LPRowBases in LPRowSetBase.
Definition: lprowsetbase.h:81
crash basis from a greedy solution
Definition: soplex.h:1022
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:450
primal feasibility tolerance
Definition: soplex.h:1145
static std::string _intParamDescription[SoPlex::INTPARAM_COUNT]
array of descriptions for integer parameters
Definition: soplex.cpp:66
bool LT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a < b + eps
Definition: spxdefines.h:383
standard verbosity level
Definition: soplex.h:974
void setType(Type tp)
set LEAVE or ENTER algorithm.
Definition: spxsolver.cpp:169
int numRowsReal() const
message handler
Definition: soplex.cpp:770
bound flipping ratio test for long steps in the dual simplex
Definition: soplex.h:1063
const char * field0() const
Definition: mpsinput.h:144
bool isRowBasic(int i) const
is the i &#39;th row vector basic ?
Definition: spxsolver.h:1151
void _addRowReal(const LPRowReal &lprow)
adds a single row to the real LP and adjusts basis
Definition: soplex.cpp:6458
solve() aborted due to iteration limit.
Definition: spxsolver.h:199
SPxScaler * _scaler
Definition: soplex.h:1356
cpu or user time
Definition: soplex.h:1122
const char * field2() const
Definition: mpsinput.h:148
#define SOPLEX_VERSION
Definition: spxdefines.h:42
bool readBasisFile(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0)
reads basis information from filename and returns true on success; if rowNames and colNames are NULL...
Definition: soplex.cpp:4516
void changeRangeRational(const VectorRational &lhs, const VectorRational &rhs)
changes left- and right-hand side vectors
Definition: soplex.cpp:2148
mode for reading LP files
Definition: soplex.h:897
const SVectorBase< R > & colVector(int i) const
Returns column vector of column i.
Definition: spxlpbase.h:341
virtual void addCols(const LPColSetBase< R > &pset)
Definition: spxlpbase.h:702
mode for synchronizing real and rational LP
Definition: soplex.h:894
void _syncLPReal(bool time=true)
synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP...
Definition: soplex.cpp:7310
No Problem has been loaded.
Definition: spxsolver.h:202
bool getDualFarkasReal(VectorReal &vector)
gets the Farkas proof if available; returns true on success
Definition: soplex.cpp:2940
void getNdualNorms(int &nnormsRow, int &nnormsCol) const
get number of dual norms
Definition: spxsolver.cpp:1814
automatic sync of real and rational LP
Definition: soplex.h:1073
virtual void changeLhs(const VectorBase< R > &newLhs)
Changes left hand side vector for constraints to newLhs.
Definition: spxlpbase.h:1342
void _recomputeRangeTypesRational()
recomputes range types from scratch using rational LP
Definition: soplex.cpp:7297
int size() const
Number of used indices.
Definition: svectorbase.h:152
bool isColBasic(int i) const
is the i &#39;th column vector basic ?
Definition: spxsolver.h:1157
void syntaxError()
Definition: mpsinput.h:198
iteration limit (-1 if unlimited)
Definition: soplex.h:864
bool hasDualFarkas() const
is a dual farkas ray available?
Definition: solbase.h:114
void changeObjReal(const VectorReal &obj)
changes objective function vector to obj
Definition: soplex.cpp:1572
void changeRowRational(int i, const LPRowRational &lprow)
replaces row i with lprow
Definition: soplex.cpp:2006
bool getRowViolationReal(Real &maxviol, Real &sumviol)
gets violation of constraints; returns true on success
Definition: soplex.cpp:2992
SPxFastRT _ratiotesterFast
Definition: soplex.h:1351
should cycling solutions be accepted during iterative refinement?
Definition: soplex.h:824
void _disableSimplifierAndScaler()
disables simplifier and scaler
Definition: soplex.cpp:7060
bool getRowViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of constraints; returns true on success
Definition: soplex.cpp:3306
const VectorBase< R > & lower() const
Returns lower bound vector.
Definition: spxlpbase.h:420
void add(const LPColBase< R > &pcol)
Definition: lpcolsetbase.h:253
#define DEFAULT_INFINITY
Definition: spxdefines.h:223
void _removeRowReal(int i)
removes row i and adjusts basis
Definition: soplex.cpp:6882
lower bound is finite, upper bound is infinite
Definition: soplex.h:1407
bool _readFileReal(const char *filename, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
reads real LP in LP or MPS format from file and returns true on success; gets row names...
Definition: soplex.cpp:7196
decide according to problem size
Definition: soplex.h:1135
UnitVectorBase< Rational > UnitVectorRational
Definition: unitvector.h:31
int totalSizeDual(const int base=2) const
returns total size of dual solution
Definition: solbase.h:143
Timer * simplexTime
simplex time
Definition: statistics.h:91
void addColsRational(const LPColSetRational &lpcolset)
adds multiple columns
Definition: soplex.cpp:1986
int luSolvesReal
number of (forward and backward) solves with basis matrix in real precision
Definition: statistics.h:106
bool _upperFinite(const RangeType &rangeType) const
checks whether RangeType corresponds to finite upper bound
Definition: soplex.cpp:6450
int refinements
number of refinement steps
Definition: statistics.h:109
const char * getStarterName()
name of starter
Definition: soplex.cpp:4425
void clear()
remove all elements.
Definition: dataarray.h:205
variable fixed to identical bounds.
Definition: spxsolver.h:181
int luFactorizationsReal
number of basis matrix factorizations in real precision
Definition: statistics.h:105
objective sense
Definition: soplex.h:849
int numColsRational() const
returns number of columns
Definition: soplex.cpp:1021
#define DEFAULT_EPS_UPDATE
Definition: spxdefines.h:218
int numIterations() const
number of iterations since last call to solve
Definition: soplex.cpp:4393
virtual void removeCol(int i)
Removes i &#39;th column.
Definition: spxlpbase.h:910
LP has been proven to be primal infeasible.
Definition: spxsolver.h:208
bool getDualNorms(int &nnormsRow, int &nnormsCol, Real *norms) const
gets steepest edge norms and returns false if they are not available
Definition: soplex.cpp:996
Rational minAbsNonzeroRational() const
returns smallest non-zero element in absolute value
Definition: soplex.cpp:1039
static std::string _intParamName[SoPlex::INTPARAM_COUNT]
array of names for integer parameters
Definition: soplex.cpp:52
bool readFile(const char *filename, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
reads LP file in LP or MPS format according to READMODE parameter; gets row names, column names, and integer variables if desired; returns true on success
Definition: soplex.cpp:4475
bool setIntParam(const IntParam param, const int value, const bool quiet=false, const bool init=false)
sets integer parameter value; returns true on success
Definition: soplex.cpp:4939
void setSparsePricingFactor(Real fac)
Definition: spxsolver.h:737
display frequency
Definition: soplex.h:873
void setOpttol(Real d)
set parameter opttol.
Definition: spxsolver.cpp:916
int dmaxSizePrimal(const int base=2) const
returns size of largest denominator in primal solution
Definition: solbase.h:185
void _ensureRationalLP()
ensures that the rational LP is available; performs no sync
Definition: soplex.cpp:7069
minimum number of stalling refinements since last pivot to trigger rational factorization ...
Definition: soplex.h:912
minimal reduction (sum of removed rows/cols) to continue simplification
Definition: soplex.h:1199
R maxAbsNzo() const
Absolute biggest non-zero element in LP.
Definition: spxlpbase.h:169
Wrapper for GMP type mpq_class.We wrap mpq_class so that we can replace it by a double type if GMP is...
Definition: rational.h:45
automatic choice
Definition: soplex.h:990
void _changeRhsReal(const VectorReal &rhs)
changes right-hand side vector to rhs and adjusts basis
Definition: soplex.cpp:6624
void changeElementReal(int i, int j, const Real &val)
changes matrix entry in row i and column j to val
Definition: soplex.cpp:1602
bool hasDualFarkas() const
is Farkas proof of infeasibility available?
Definition: soplex.cpp:2831
disable timing
Definition: soplex.h:1119
void printStatistics(std::ostream &os)
prints complete statistics
Definition: soplex.cpp:5916
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:402
should a rational factorization be performed after iterative refinement?
Definition: soplex.h:821
#define REAL_FORMAT
Definition: spxdefines.h:204
virtual bool readBasisFile(const char *filename, const NameSet *rowNames, const NameSet *colNames)
Definition: spxfileio.cpp:24
rowwise representation.
Definition: spxsolver.h:107
mode for hyper sparse pricing
Definition: soplex.h:909
void add(const LPRowBase< R > &row)
Definition: lprowsetbase.h:319
bool setDualNorms(int nnormsRow, int nnormsCol, Real *norms)
set dual norms
Definition: spxsolver.cpp:1826
maximum number of updates without fresh factorization
Definition: soplex.h:861
const VectorReal & upperReal() const
returns upper bound vector
Definition: soplex.cpp:914
Real opttol() const
allowed optimality, i.e., dual feasibility tolerance.
Definition: spxsolver.h:697
void removeColRangeRational(int start, int end, int perm[]=0)
removes columns start to end including both; an array perm of size numColsRational() may be passed as...
Definition: soplex.cpp:2670
virtual void setTerminationTime(Real time=infinity)
set time limit.
Definition: spxsolver.cpp:1478
std::string statisticString() const
statistical information in form of a string
Definition: soplex.cpp:4409
virtual void setSolver(SLinSolver *slu, const bool destroy=false)
setup linear solver to use. If destroy is true, slusolver will be freed in destructor.
Definition: spxsolver.cpp:83
const VectorRational & maxObjRational() const
returns objective function vector after transformation to a maximization problem; since this is how i...
Definition: soplex.cpp:1221
void changeUpperRational(const VectorRational &upper)
changes vector of upper bounds to upper
Definition: soplex.cpp:2287
bool _boolParamValues[SoPlex::BOOLPARAM_COUNT]
array of current boolean parameter values
Definition: soplex.cpp:114
Rational _rationalPosInfty
Definition: soplex.h:1321
number of integer parameters
Definition: soplex.h:915
Rational _rationalOpttol
Definition: soplex.h:1324
bool _isSolveStopped(bool &stoppedTime, bool &stoppedIter) const
should solving process be stopped?
Definition: soplex.cpp:6364
RealParam
real parameters
Definition: soplex.h:1142
virtual void changeObjOffset(const R &o)
Definition: spxlpbase.h:1611
R upper() const
Gets upper bound.
Definition: lpcolbase.h:125
bool setDualNorms(int nnormsRow, int nnormsCol, Real *norms)
sets steepest edge norms and returns false if that&#39;s not possible
Definition: soplex.cpp:1004
Real realParam(const RealParam param) const
returns real parameter value
Definition: soplex.cpp:4866
virtual void removeRows(int perm[])
Removes multiple rows.
Definition: spxlpbase.h:832
void _solveReal()
solves real LP
Definition: solvereal.cpp:26
const SVectorReal & rowVectorReal(int i) const
returns vector of row i
Definition: soplex.cpp:833
SPxEquiliSC _scalerBiequi
Definition: soplex.h:1337
steepest edge pricer with exact initialization of norms
Definition: soplex.h:1047
bool hasPrimalRay() const
is a primal unbounded ray available?
Definition: soplex.cpp:2815
virtual void changeUpper(const VectorBase< R > &newUpper)
Changes vector of upper bounds to newUpper.
Definition: spxlpbase.h:1278
void removeColRangeReal(int start, int end, int perm[]=0)
removes columns start to end including both; an array perm of size numColsReal() may be passed as buf...
Definition: soplex.cpp:1783
void addColReal(const LPCol &lpcol)
adds a single column
Definition: soplex.cpp:1277
void clearLPRational()
clears the LP
Definition: soplex.cpp:2688
No ratiotester loaded.
Definition: spxsolver.h:193
int iterations() const
get number of iterations of current solution.
Definition: spxsolver.h:1934
No pricer loaded.
Definition: spxsolver.h:194
void addRowsRational(const LPRowSetRational &lprowset)
adds multiple rows
Definition: soplex.cpp:1898
static std::string _realParamName[SoPlex::REALPARAM_COUNT]
array of names for real parameters
Definition: soplex.cpp:55
const SVectorRational & rowVectorRational(int i) const
returns vector of row i
Definition: soplex.cpp:1075
virtual void start()=0
start timer, resume accounting user, system and real time.
Entering Simplex.
Definition: spxsolver.h:134
#define HYPERPRICINGTHRESHOLD
Definition: spxsolver.h:37
void addRowRational(const LPRowRational &lprow)
adds a single row
Definition: soplex.cpp:1832
void addColRational(const LPColRational &lpcol)
adds a single column
Definition: soplex.cpp:1918
virtual Real stop()=0
stop timer, return accounted user time.
void getCol(int i, LPColBase< R > &col) const
Gets i &#39;th column.
Definition: spxlpbase.h:316
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
static Real _realParamDefault[SoPlex::REALPARAM_COUNT]
array of default values for real parameters
Definition: soplex.cpp:83
Real getExactCondition()
Definition: spxbasis.h:594
const UnitVectorRational * _unitVectorRational(const int i)
returns pointer to a constant unit vector available until destruction of the SoPlex class ...
Definition: soplex.cpp:7376
bool readLine()
reads an MPS format data line and parse the fields.
Definition: mpsinput.cpp:57
virtual void addCol(const LPColBase< R > &col)
Definition: spxlpbase.h:650
void _syncRealSolution()
synchronizes real solution with rational solution, i.e., copies real solution to rational solution ...
Definition: soplex.cpp:7352
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
const SPxRatioTester * ratiotester() const
return loaded SPxRatioTester.
Definition: spxsolver.h:1636
void removeColsRational(int perm[])
removes all columns with an index i such that perm[i] < 0; upon completion, perm[i] >= 0 indicates th...
Definition: soplex.cpp:2621
virtual void changeCol(int n, const LPColBase< R > &newCol)
Replaces i &#39;th column of LP with newCol.
Definition: spxlpbase.h:1494
bool _lowerFinite(const RangeType &rangeType) const
checks whether RangeType corresponds to finite lower bound
Definition: soplex.cpp:6442
LP is primal infeasible or unbounded.
Definition: spxsolver.h:209
void getObjReal(VectorReal &obj) const
gets objective function vector
Definition: soplex.cpp:950
void changeRhsRational(const VectorRational &rhs)
changes right-hand side vector to rhs
Definition: soplex.cpp:2085
virtual void setOutstream(SPxOut &newOutstream)
set message handler
Definition: spxscaler.h:100
Leaving Simplex.
Definition: spxsolver.h:143
standard floating-point parsing
Definition: soplex.h:1083
int dmaxSizeDualRational(const int base=2)
get size of largest denominator in dual solution
Definition: soplex.cpp:3706
virtual void changeLower(const VectorBase< R > &newLower)
Changes vector of lower bounds to newLower.
Definition: spxlpbase.h:1247
RangeType _rangeTypeReal(const Real &lower, const Real &upper) const
determines RangeType from real bounds
Definition: soplex.cpp:6379
Real luFactorizationTimeReal
time for factorizing bases matrices in real precision
Definition: statistics.h:97
int dlcmSizePrimalRational(const int base=2)
get size of least common multiple of denominators in primal solution
Definition: soplex.cpp:3664
Rational objValueRational()
returns the objective value if a primal solution is available
Definition: soplex.cpp:3139
virtual void changeRange(const VectorBase< R > &newLhs, const VectorBase< R > &newRhs)
Changes left and right hand side vectors.
Definition: spxlpbase.h:1392
DataArray< SPxSolver::VarStatus > _basisStatusCols
Definition: soplex.h:1432
void getRows(int start, int end, LPRowSetBase< R > &set) const
Gets rows start, ... end.
Definition: spxlpbase.h:203
bool getDualFarkas(VectorBase< R > &vector) const
gets the Farkas proof if available; returns true on success
Definition: solbase.h:120
nothing known about basis status (possibly due to a singular basis in transformed problem) ...
Definition: spxsolver.h:184
decide depending on tolerances whether to apply iterative refinement
Definition: soplex.h:1096
bool boolParam(const BoolParam param) const
returns boolean parameter value
Definition: soplex.cpp:4846
SPxSolver::Status status() const
returns the current solver status
Definition: soplex.cpp:2799
declaration of types for file output
DataArray< RangeType > _colTypes
Definition: soplex.h:1419
type of scaler
Definition: soplex.h:882
automatic choice according to number of rows and columns
Definition: soplex.h:932
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
void removeRowRangeReal(int start, int end, int perm[]=0)
removes rows start to end including both; an array perm of size numRowsReal() may be passed as buffer...
Definition: soplex.cpp:1691
SPxBoundFlippingRT _ratiotesterBoundFlipping
Definition: soplex.h:1352
VarStatus getBasisRowStatus(int row) const
gets basis status for a single row
Definition: spxsolver.cpp:1710
bool _isRealLPLoaded
Definition: soplex.h:1359
geometric mean scaling on rows and columns, max 8 rounds
Definition: soplex.h:1009
void getRow(int i, LPRowBase< R > &row) const
Gets i &#39;th row.
Definition: spxlpbase.h:188
const VectorReal & maxObjReal() const
returns objective function vector after transformation to a maximization problem; since this is how i...
Definition: soplex.cpp:969
void _solveRealLPAndRecordStatistics()
call floating-point solver and update statistics on iterations etc.
Definition: soplex.cpp:7109
DVectorBase< R > _primal
Definition: solbase.h:222
virtual const char * getName() const
get name of starter.
Definition: spxstarter.h:88
int index(int n) const
Returns index of the n &#39;th nonzero element.
Definition: ssvectorbase.h:174
number of boolean parameters
Definition: soplex.h:842
SPxEquiliSC _scalerUniequi
Definition: soplex.h:1336
#define MSG_DEBUG(x)
Definition: spxdefines.h:127
int getFactorCount() const
number of factorizations performed
Definition: slufactor.h:236
bool writeBasisFile(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const bool cpxFormat=false) const
writes basis information to filename; if rowNames and colNames are NULL, default names are used; retu...
Definition: soplex.cpp:4707
void printSolvingStatistics(std::ostream &os)
prints statistics on solving process
Definition: soplex.cpp:5896
bool _readFileRational(const char *filename, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
reads rational LP in LP or MPS format from file and returns true on success; gets row names...
Definition: soplex.cpp:7237
lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformula...
Definition: soplex.h:1184
bool getPrimalRayReal(VectorReal &vector)
gets the primal ray if available; returns true on success
Definition: soplex.cpp:2895
Real objReal(int i) const
returns objective value of column i
Definition: soplex.cpp:959
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
Definition: spxdefines.h:395
static void setEpsilonPivot(Real eps)
Definition: spxdefines.cpp:60
void changeLhsReal(const VectorReal &lhs)
changes left-hand side vector for constraints to lhs
Definition: soplex.cpp:1332
int getSolveCount() const
number of solves performed
Definition: slufactor.h:251
const VectorReal & rhsReal() const
returns right-hand side vector
Definition: soplex.cpp:842
DVectorBase< Real > DVectorReal
Definition: dvector.h:29
greedy crash basis weighted by objective, bounds, and sides
Definition: soplex.h:1019
void _changeLowerReal(const VectorReal &lower)
changes vector of lower bounds to lower and adjusts basis
Definition: soplex.cpp:6735
bool setRealParam(const RealParam param, const Real value, const bool quiet=false, const bool init=false)
sets real parameter value; returns true on success
Definition: soplex.cpp:5245
dual simplex algorithm, i.e., leaving for column and entering for row representation ...
Definition: soplex.h:948
Status getBasis(VarStatus rows[], VarStatus cols[], const int rowsSize=-1, const int colsSize=-1) const
get current basis, and return solver status.
Definition: spxsolver.cpp:1722
steepest edge pricer with initialization to unit norms
Definition: soplex.h:1044
int dlcmSizeDual(const int base=2) const
returns size of least common multiple of denominators in dual solution
Definition: solbase.h:171
static std::string _boolParamDescription[SoPlex::BOOLPARAM_COUNT]
array of descriptions for boolean parameters
Definition: soplex.cpp:63
LP has been solved to optimality.
Definition: spxsolver.h:206
std::ostream & getStream(const Verbosity &verbosity) const
Returns the stream for the specified verbosity level.
Definition: spxout.h:156
int numRowsRational() const
returns number of rows
Definition: soplex.cpp:1012
VectorBase< Real > Vector
Definition: vector.h:29
virtual void setPricer(SPxPricer *pricer, const bool destroy=false)
setup pricer to use. If destroy is true, pricer will be freed in destructor.
Definition: spxsolver.cpp:101
VarStatus getBasisColStatus(int col) const
gets basis status for a single column
Definition: spxsolver.cpp:1716
const VectorRational & lowerRational() const
returns lower bound vector
Definition: soplex.cpp:1174
bool _hasBasis
Definition: soplex.h:1438
use bound flipping also for row representation?
Definition: soplex.h:839
void _invalidateSolution()
invalidates solution
Definition: soplex.cpp:7002
bool getDualViolationReal(Real &maxviol, Real &sumviol)
gets violation of dual multipliers; returns true on success
Definition: soplex.cpp:3085
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:133
void append(const T &t)
append element t.
Definition: dataarray.h:121
const char * getSimplifierName()
name of simplifier
Definition: soplex.cpp:4436
void getColsReal(int start, int end, LPColSetReal &lpcolset) const
gets columns start, ..., end
Definition: soplex.cpp:896
void changeLowerReal(const VectorReal &lower)
changes vector of lower bounds to lower
Definition: soplex.cpp:1461
int dlcmSizePrimal(const int base=2) const
returns size of least common multiple of denominators in primal solution
Definition: solbase.h:157
DVectorBase< Rational > DVectorRational
Definition: dvector.h:30
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1616
LPRowReal::Type rowTypeReal(int i) const
returns inequality type of row i
Definition: soplex.cpp:878
static std::string _realParamDescription[SoPlex::REALPARAM_COUNT]
array of descriptions for real parameters
Definition: soplex.cpp:69
const char * getPricerName()
name of currently loaded pricer
Definition: soplex.cpp:4458
Class for collecting statistical information.
void setDisplayFreq(int freq)
set display frequency
Definition: spxsolver.h:732
solve() aborted due to time limit.
Definition: spxsolver.h:198
static Real _realParamLower[SoPlex::REALPARAM_COUNT]
array of lower bounds for real parameter values
Definition: soplex.cpp:97
int totalSizePrimal(const int base=2) const
returns total size of primal solution
Definition: solbase.h:129
an error occured.
Definition: spxsolver.h:192
round scaling factors for iterative refinement to powers of two?
Definition: soplex.h:830
virtual void setMinReduction(const Real minRed)
set minimal reduction threshold to continue simplification
void removeRowReal(int i)
removes row i
Definition: soplex.cpp:1617
Forrest-Tomlin type update.
Definition: soplex.h:958
#define DEFAULT_EPS_ZERO
default allowed additive zero: 1.0 + EPS_ZERO == 1.0
Definition: spxdefines.h:212
int dlcmSizeDualRational(const int base=2)
get size of least common multiple of denominators in dual solution
Definition: soplex.cpp:3678
virtual void setVerbosity(const Verbosity &v)
Definition: spxout.h:111
SPxWeightST _starterWeight
Definition: soplex.h:1340
Statistics * _statistics
statistics since last call to solveReal() or solveRational()
Definition: soplex.h:1308
#define DEFAULT_EPS_PIVOT
Definition: spxdefines.h:221
void _solveRational()
solves rational LP
type of simplifier
Definition: soplex.h:879
RangeType _switchRangeType(const RangeType &rangeType) const
switches RANGETYPE_LOWER to RANGETYPE_UPPER and vice versa
Definition: soplex.cpp:6429
const SPxPricer * pricer() const
return loaded SPxPricer.
Definition: spxsolver.h:1626
void _removeRowsReal(int perm[])
removes all rows with an index i such that perm[i] < 0; upon completion, perm[i] >= 0 indicates the n...
Definition: soplex.cpp:6909
void _syncLPRational(bool time=true)
synchronizes rational LP with real LP, i.e., copies real LP to rational LP, without looking at the sy...
Definition: soplex.cpp:7333
void printUserSettings()
print non-default parameter values
Definition: soplex.cpp:5415
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:109
void changeBoundsReal(const VectorReal &lower, const VectorReal &upper)
changes vectors of column bounds to lower and upper
Definition: soplex.cpp:1536
SPxSteepPR _pricerQuickSteep
Definition: soplex.h:1347
Real getEstimatedCondition()
Definition: spxbasis.h:588
void syncLPReal()
synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP...
Definition: soplex.cpp:1821
SPxDantzigPR _pricerDantzig
Definition: soplex.h:1344
const VectorBase< R > & lower() const
Definition: lpcolsetbase.h:128
SPxParMultPR _pricerParMult
Definition: soplex.h:1345
bool getPrimalRational(VectorRational &vector)
gets the primal solution vector if available; returns true on success
Definition: soplex.cpp:3175
void changeObjRational(const VectorRational &obj)
changes objective function vector to obj
Definition: soplex.cpp:2407
void getObjRational(VectorRational &obj) const
gets objective function vector
Definition: soplex.cpp:1192
SLUFactor _slufactor
Definition: soplex.h:1334
variable set to its upper bound.
Definition: spxsolver.h:179
static Real _realParamUpper[SoPlex::REALPARAM_COUNT]
array of upper bounds for real parameter values
Definition: soplex.cpp:100
int nNzos() const
Returns number of nonzeros in LP.
Definition: spxlpbase.h:139
void getBasis(SPxSolver::VarStatus rows[], SPxSolver::VarStatus cols[]) const
gets current basis via arrays of statuses
Definition: soplex.cpp:3810
bool getDual(VectorBase< R > &vector) const
gets the dual solution vector if available; returns true on success
Definition: solbase.h:96
Dynamic index set.Class DIdxSet provides dynamic IdxSet in the sense, that no restrictions are posed ...
Definition: didxset.h:42
void getObj(VectorBase< R > &pobj) const
Gets objective vector.
Definition: spxlpbase.h:353
void clearBasis()
clears starting basis
Definition: soplex.cpp:4383
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:113
void syncLPRational()
synchronizes rational LP with real LP, i.e., copies real LP to rational LP, if sync mode is manual ...
Definition: soplex.cpp:2711
int dim() const
Dimension of vector.
Definition: vectorbase.h:174
bool getRedCostReal(VectorReal &vector)
gets the vector of reduced cost values if available; returns true on success
Definition: soplex.cpp:2925
void add(const char *str)
Definition: nameset.cpp:25
Type type() const
return current Type.
Definition: spxsolver.h:412
~Statistics()
destructor
Definition: statistics.h:52
user sync of real and rational LP
Definition: soplex.h:1076
void _ensureDSVectorRationalMemory(DSVectorRational &vec, const int newmax) const
extends sparse vector to hold newmax entries if and only if it holds no more free entries ...
Definition: soplex.cpp:6301
SPxSteepExPR _pricerSteep
Definition: soplex.h:1348
int dmaxSizeDual(const int base=2) const
returns size of largest denominator in dual solution
Definition: solbase.h:199
virtual const char * getName() const
get name of ratio tester.
bool parseSettingsString(char *line)
parses one setting string and returns true on success; note that string is modified ...
Definition: soplex.cpp:5581
SPxLPBase< Rational > SPxLPRational
Definition: spxlp.h:37
SPxOut spxout
Definition: soplex.h:1215
infinity threshold
Definition: soplex.h:1163
void changeBoundsRational(const VectorRational &lower, const VectorRational &upper)
changes vectors of column bounds to lower and upper
Definition: soplex.cpp:2347
virtual bool writeBasisFile(const char *filename, const NameSet *rowNames, const NameSet *colNames, const bool cpxFormat=false) const
Definition: spxfileio.cpp:39
SPxDefaultRT _ratiotesterTextbook
Definition: soplex.h:1349
virtual void changeBounds(const VectorBase< R > &newLower, const VectorBase< R > &newUpper)
Changes variable bounds to newLower and newUpper.
Definition: spxlpbase.h:1309
(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
variable set to its lower bound.
Definition: spxsolver.h:180
Settings * _currentSettings
Definition: soplex.h:1319
SPxId & baseId(int i)
Definition: spxbasis.h:497
Preconfigured SoPlex LP solver.
Sparse vector .A UnitVectorBase is an SVectorBase that can take only one nonzero value with value 1 b...
const SVectorRational & colVectorRational(int i) const
returns vector of column i
Definition: soplex.cpp:1147
void getCols(int start, int end, LPColSetBase< R > &set) const
Gets columns start, ..., end.
Definition: spxlpbase.h:332
void getRowReal(int i, LPRowReal &lprow) const
gets row i
Definition: soplex.cpp:815
void _syncRationalSolution()
synchronizes rational solution with real solution, i.e., copies (rounded) rational solution to real s...
Definition: soplex.cpp:7364
int _intParamValues[SoPlex::INTPARAM_COUNT]
array of current integer parameter values
Definition: soplex.cpp:117
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
Real getFactorTime() const
time spent in factorizations
Definition: slufactor.h:226
partial multiple pricer based on Dantzig pricing
Definition: soplex.h:1038
lower and upper bound finite, but different
Definition: soplex.h:1413
bool hasError() const
Definition: mpsinput.h:162
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:84
equilibrium scaling on rows and columns
Definition: soplex.h:1003
Real getSolveTime() const
time spent in solves
Definition: slufactor.h:241
Real luSolveTimeReal
time for solving linear systems in real precision
Definition: statistics.h:98
R * get_ptr()
Only used in slufactor.cpp.
Definition: ssvectorbase.h:99
Settings(const Settings &settings)
copy constructor
Definition: soplex.cpp:494
Rational _rationalNegInfty
Definition: soplex.h:1322
const VectorReal & lhsReal() const
returns left-hand side vector
Definition: soplex.cpp:860
void printStatus(std::ostream &os, SPxSolver::Status status)
prints status
Definition: soplex.cpp:5936
virtual void setTerminationIter(int iteration=-1)
set iteration limit.
Definition: spxsolver.cpp:1490
threshold on number of rows vs. number of columns for switching from column to row representations in...
Definition: soplex.h:1193
lower bound equals upper bound
Definition: soplex.h:1416
column representation Ax - s = 0, lower <= x <= upper, lhs <= s <= rhs
Definition: soplex.h:935
bool getSlacksReal(VectorReal &vector)
gets the vector of slack values if available; returns true on success
Definition: soplex.cpp:2880
bool writeFileRational(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0) const
writes rational LP to file; LP or MPS format is chosen from the extension in filename; if rowNames an...
Definition: soplex.cpp:4498
bool areLPsInSync(const bool checkVecVals=true, const bool checkMatVals=false, const bool quiet=false) const
checks if real LP and rational LP are in sync; dimensions will always be compared, vector and matrix values only if the respective parameter is set to true. If quiet is set to true the function will only display which vectors are different.
Definition: soplex.cpp:6042
void getRowsRational(int start, int end, LPRowSetRational &lprowset) const
gets rows start, ..., end.
Definition: soplex.cpp:1066
automatic pricer
Definition: soplex.h:1032
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
const SVector & unitVector(int i) const
return i &#39;th unit vector.
Definition: spxsolver.h:1097
const char * field1() const
Definition: mpsinput.h:146
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:242
Everything should be within this namespace.
void getNdualNorms(int &nnormsRow, int &nnormsCol) const
gets number of available dual norms
Definition: soplex.cpp:988
void _changeLhsReal(const VectorReal &lhs)
changes left-hand side vector for constraints to lhs and adjusts basis
Definition: soplex.cpp:6585
working tolerance for feasibility in floating-point solver during iterative refinement ...
Definition: soplex.h:1175
SPxLPReal * _realLP
Definition: soplex.h:1354
returns the current git hash of SoPlex
bool loadSettingsFile(const char *filename)
reads settings file; returns true on success
Definition: soplex.cpp:5532
SPxGeometSC _scalerGeo1
Definition: soplex.h:1338
const char * field3() const
Definition: mpsinput.h:150
SoPlex & operator=(const SoPlex &rhs)
assignment operator
Definition: soplex.cpp:609
bool getRedCostViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of reduced costs; returns true on success
Definition: soplex.cpp:3349
Rational maxAbsNonzeroRational() const
returns biggest non-zero element in absolute value
Definition: soplex.cpp:1048
SPxDevexPR _pricerDevex
Definition: soplex.h:1346
virtual void setTester(SPxRatioTester *tester, const bool destroy=false)
setup ratio-tester to use. If destroy is true, tester will be freed in destructor.
Definition: spxsolver.cpp:128
Settings & operator=(const Settings &settings)
assignment operator
Definition: soplex.cpp:500
DataArray< RangeType > _rowTypes
Definition: soplex.h:1420
void _removeColReal(int i)
removes column i
Definition: soplex.cpp:6942
void _changeRowReal(int i, const LPRowReal &lprow)
replaces row i with lprow and adjusts basis
Definition: soplex.cpp:6563
bool hasPrimalRay() const
is a primal unbounded ray available?
Definition: solbase.h:75
SPxSumST _starterSum
Definition: soplex.h:1341
bool readStringRational(const char *s, Rational &value)
read Rational from string
Definition: rational.cpp:3478
bool getBasisInverseTimesVecReal(Real *rhs, Real *sol)
computes dense solution of basis matrix B * sol = rhs; returns true on success
Definition: soplex.cpp:4247
row representation (lower,lhs) <= (x,Ax) <= (upper,rhs)
Definition: soplex.h:938
apply rational reconstruction after each iterative refinement?
Definition: soplex.h:827
void _changeColReal(int i, const LPColReal &lpcol)
replaces column i with lpcol and adjusts basis
Definition: soplex.cpp:6711
solve() aborted due to detection of cycling.
Definition: spxsolver.h:197
SPxBasis::SPxStatus basisStatus() const
returns the current basis status
Definition: soplex.cpp:3728
type of pricer
Definition: soplex.h:888
Saving LPs in a form suitable for SoPlex.Class SPxLPBase provides the data structures required for sa...
Definition: spxlpbase.h:76
bool getDualReal(VectorReal &vector)
gets the dual solution vector if available; returns true on success
Definition: soplex.cpp:2910
SPxHarrisRT _ratiotesterHarris
Definition: soplex.h:1350
DSVectorBase< Real > DSVectorReal
Definition: dsvector.h:29
void changeColReal(int i, const LPColReal &lpcol)
replaces column i with lpcol
Definition: soplex.cpp:1443
working tolerance for optimality in floating-point solver during iterative refinement ...
Definition: soplex.h:1178
void clearLPReal()
clears the LP
Definition: soplex.cpp:1801
Preconfigured SoPlex LP-solver.
Definition: soplex.h:86
void getColRational(int i, LPColRational &lpcol) const
gets column i
Definition: soplex.cpp:1129
void removeRowRational(int i)
removes row i
Definition: soplex.cpp:2499
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:111
Type
(In)Equality type of an LP row.
Definition: lprowbase.h:72
int iterations
number of iterations/pivots
Definition: statistics.h:101
Real feastol() const
allowed primal feasibility tolerance.
Definition: spxsolver.h:689
virtual void changeRow(int n, const LPRowBase< R > &newRow)
Replaces i &#39;th row of LP with newRow.
Definition: spxlpbase.h:1456
bool writeFileReal(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0) const
writes real LP to file; LP or MPS format is chosen from the extension in filename; if rowNames and co...
Definition: soplex.cpp:4486
SPxVectorST _starterVector
Definition: soplex.h:1342
void setup()
Initializes nonzero indices for elements with absolute values above epsilon and sets all other elemen...
Definition: ssvectorbase.h:132
#define SET_MAX_LINE_LEN
maximum length of lines in settings file
Definition: soplex.cpp:36
static void setEpsilonUpdate(Real eps)
Definition: spxdefines.cpp:55
RangeType _rangeTypeRational(const Rational &lower, const Rational &upper) const
determines RangeType from rational bounds
Definition: soplex.cpp:6404
bool getBoundViolationReal(Real &maxviol, Real &sumviol)
gets violation of bounds; returns true on success
Definition: soplex.cpp:2955
R lhs() const
Left-hand side value.
Definition: lprowbase.h:203
int boundflips
number of dual bound flips
Definition: statistics.h:104
decide according to READMODE
Definition: soplex.h:1109
void printVersion() const
prints version and compilation options
Definition: soplex.cpp:6002
SPxSolver::VarStatus basisColStatus(int col) const
returns basis status for a single column
Definition: soplex.cpp:3774
void clearAllData()
clears all statistics
Definition: statistics.cpp:90
SPxSolver _solver
Definition: soplex.h:1333
bool getBasisInverseColReal(int c, Real *coef, int *inds=NULL, int *ninds=NULL)
computes column c of basis inverse; returns true on success
Definition: soplex.cpp:4103
const char * getGitHash()
Definition: spxgithash.cpp:23
mode for a posteriori feasibility checks
Definition: soplex.h:903
nothing known on loaded problem.
Definition: spxsolver.h:205
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
variable is basic.
Definition: spxsolver.h:183
type of algorithm, i.e., primal or dual
Definition: soplex.h:855
void print(std::ostream &os)
prints statistics
Definition: statistics.cpp:126
void clearSolvingData()
clears statistics on solving process
Definition: statistics.cpp:97
void _recomputeRangeTypesReal()
recomputes range types from scratch using real LP
Definition: soplex.cpp:7284
should feasibility be tested with relaxed bounds and sides?
Definition: soplex.h:836
const VectorRational & lhsRational() const
returns left-hand side vector
Definition: soplex.cpp:1102
DataArray< UnitVectorRational * > _unitMatrixRational
Definition: soplex.h:1395
bool getDualFarkasRational(VectorRational &vector)
gets the Farkas proof if LP is infeasible; returns true on success
Definition: soplex.cpp:3250
virtual const char * getName() const
get name of simplifier.
Status status() const
Status of solution process.
Definition: spxsolve.cpp:1536
stalling refinement limit (-1 if unlimited)
Definition: soplex.h:870
DataArray< SPxSolver::VarStatus > _basisStatusRows
Definition: soplex.h:1431
std::ifstream spxifstream
Definition: spxfileio.h:43
Timer * readingTime
reading time not included in solving time
Definition: statistics.h:88
virtual void changeElement(int i, int j, const R &val)
Changes LP element (i, j) to val.
Definition: spxlpbase.h:1532
int iterationsFromBasis
number of iterations from Basis
Definition: statistics.h:103
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:438
Rational objRational(int i) const
returns objective value of column i
Definition: soplex.cpp:1211
LPRowBase< R >::Type rowType(int i) const
Returns the inequality type of the i&#39;th LPRow.
Definition: spxlpbase.h:304
should dual infeasibility be tested in order to try to return a dual solution even if primal infeasib...
Definition: soplex.h:818
virtual void changeSense(SPxSense sns)
Changes optimization sense to sns.
Definition: spxlpbase.h:1601
Timer * solvingTime
solving time
Definition: statistics.h:89
generic solution-based crash basis
Definition: soplex.h:1025
int intParam(const IntParam param) const
returns integer parameter value
Definition: soplex.cpp:4856
should lifting be used to reduce range of nonzero matrix coefficients?
Definition: soplex.h:812
void printProblemStatistics(std::ostream &os)
Definition: spxlpbase.h:1097
int dmaxSizePrimalRational(const int base=2)
get size of largest denominator in primal solution
Definition: soplex.cpp:3692
static int _intParamDefault[SoPlex::INTPARAM_COUNT]
array of default values for integer parameters
Definition: soplex.cpp:80
const Real infinity
Definition: spxdefines.cpp:26
bool getEstimatedCondition(Real &condition)
computes an estimated condition number for the current basis matrix using the power method; returns t...
Definition: soplex.cpp:3929
const VectorBase< R > & rhs() const
Returns the vector of rhs values.
Definition: lprowsetbase.h:129
LPRowRational::Type rowTypeRational(int i) const
returns inequality type of row i
Definition: soplex.cpp:1120
bool getExactCondition(Real &condition)
computes the exact condition number for the current basis matrix using the power method; returns true...
Definition: soplex.cpp:3944
SPxStatus
basis status.
Definition: spxbasis.h:90
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:224
const char * getScalerName()
name of scaling method
Definition: soplex.cpp:4447
void addColsReal(const LPColSetReal &lpcolset)
adds multiple columns
Definition: soplex.cpp:1295
bool saveSettingsFile(const char *filename, const bool onlyChanged=false) const
writes settings file; returns true on success
Definition: soplex.cpp:5463
R lower() const
Gets lower bound.
Definition: lpcolbase.h:137
bool getBasisInverseRowReal(int r, Real *coef, int *inds=NULL, int *ninds=NULL)
computes row r of basis inverse; returns true on success
Definition: soplex.cpp:3959
SolReal _solReal
Definition: soplex.h:1434
zero tolerance used in update of the factorization
Definition: soplex.h:1157
int iterationsPrimal
number of iterations with Primal
Definition: statistics.h:102
void changeLowerRational(const VectorRational &lower)
changes vector of lower bounds to lower
Definition: soplex.cpp:2227
lower limit on objective value
Definition: soplex.h:1169
int boundFlips() const
get number of bound flips.
Definition: spxsolver.h:1928
void writeStateReal(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const bool cpxFormat=false) const
writes internal LP, basis information, and parameter settings; if rowNames and colNames are NULL...
Definition: soplex.cpp:4805
both bounds are infinite
Definition: soplex.h:1404
bool getRedCostViolationReal(Real &maxviol, Real &sumviol)
gets violation of reduced costs; returns true on success
Definition: soplex.cpp:3031
BoolParam
boolean parameters
Definition: soplex.h:809
bool _hasSolReal
Definition: soplex.h:1439
void _changeBoundsReal(const VectorReal &lower, const VectorReal &upper)
changes vectors of column bounds to lower and upper and adjusts basis
Definition: soplex.cpp:6815
#define SOPLEX_SUBVERSION
Definition: spxdefines.h:43
Settings()
default constructor initializing default settings
Definition: soplex.cpp:128
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:212
sparse pricing threshold (#violations < dimension * SPARSITY_THRESHOLD activates sparse pricing) ...
Definition: soplex.h:1190
bool getPrimalRay(VectorBase< R > &vector) const
gets the primal unbounded ray if available; returns true on success
Definition: solbase.h:81
void setFeastol(Real d)
set parameter feastol.
Definition: spxsolver.cpp:904
virtual void loadLP(const SPxLP &LP)
copy LP.
Definition: spxsolver.cpp:68
void addRowReal(const LPRowReal &lprow)
adds a single row
Definition: soplex.cpp:1240
virtual void addRow(const LPRowBase< R > &row)
Definition: spxlpbase.h:488
static void setEpsilonFactorization(Real eps)
Definition: spxdefines.cpp:50
bool getPrimalRayRational(VectorRational &vector)
gets the primal ray if LP is unbounded; returns true on success
Definition: soplex.cpp:3205
dual feasibility tolerance
Definition: soplex.h:1148
void _ensureRealLPLoaded()
ensures that the real LP and the basis are loaded in the solver; performs no sync ...
Definition: soplex.cpp:7082
void invalidate()
invalidate solution
Definition: solbase.h:213
void changeRowReal(int i, const LPRowReal &lprow)
replaces row i with lprow
Definition: soplex.cpp:1314
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:605
SolRational _solRational
Definition: soplex.h:1435
UnitVectorBase< Real > UnitVectorReal
Definition: unitvector.h:30
std::string rationalToString(const Rational &r, const int precision)
convert rational number to string
Definition: rational.cpp:3468
Real objValueReal()
returns the objective value if a primal solution is available
Definition: soplex.cpp:2839
bool _parseSettingsLine(char *line, const int lineNumber)
parses one line in a settings file and returns true on success; note that the string is modified ...
Definition: soplex.cpp:7399
int numNonzerosReal() const
returns number of nonzeros
Definition: soplex.cpp:788
void changeRhsReal(const VectorReal &rhs)
changes right-hand side vector to rhs
Definition: soplex.cpp:1369
geometric frequency at which to apply rational reconstruction
Definition: soplex.h:1196
void changeElementRational(int i, int j, const Rational &val)
changes matrix entry in row i and column j to val
Definition: soplex.cpp:2463
SPxStarter * _starter
Definition: soplex.h:1357
static bool _boolParamDefault[SoPlex::BOOLPARAM_COUNT]
array of default values for boolean parameters
Definition: soplex.cpp:77
Real solveTime() const
time spent in last call to solve
Definition: soplex.cpp:4401
bool _hasSolRational
Definition: soplex.h:1440
void hyperPricing(bool h)
enable or disable hyper sparse pricing
Definition: spxsolver.cpp:938
void _enableSimplifierAndScaler()
enables simplifier and scaler according to current parameters
Definition: soplex.cpp:7017
primal simplex algorithm, i.e., entering for column and leaving for row representation ...
Definition: soplex.h:945
void getRowRational(int i, LPRowRational &lprow) const
gets row i
Definition: soplex.cpp:1057
should LP be transformed to equality form before a rational solve?
Definition: soplex.h:815
void setOutstream(SPxOut &newOutstream)
Definition: spxsolver.h:387
void getBasisInd(int *bind) const
gets the indices of the basic columns and rows; basic column n gives value n, basic row m gives value...
Definition: soplex.cpp:3850
DVectorBase< R > _dual
Definition: solbase.h:225
virtual void clear()
clears the LP.
Definition: spxlpbase.h:1007
virtual const char * getName() const
get name of scaler.
Definition: spxscaler.cpp:97
const VectorRational & upperRational() const
returns upper bound vector
Definition: soplex.cpp:1156
virtual void writeFile(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *p_intvars=0) const
Write loaded LP to filename.
Definition: spxlpbase.h:1080
store only real LP
Definition: soplex.h:1070
virtual void reLoad()
reload LP.
Definition: spxsolver.cpp:55
bool getDualNorms(int &nnormsRow, int &nnormsCol, Real *norms) const
get dual norms
Definition: spxsolver.cpp:1820
upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulat...
Definition: soplex.h:1187
void _addRowsReal(const LPRowSetReal &lprowset)
adds multiple rows to the real LP and adjusts basis
Definition: soplex.cpp:6488
const SVectorReal & colVectorReal(int i) const
returns vector of column i
Definition: soplex.cpp:905
virtual Status solve()
solve loaded LP.
Definition: spxsolve.cpp:73
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
void changeUpperReal(const VectorReal &upper)
changes vector of upper bounds to upper
Definition: soplex.cpp:1499
bool hasDual() const
is a dual solution available?
Definition: solbase.h:90
bool has(int pnum) const
does NameSet has a name with number pnum?
Definition: nameset.h:231
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:223
void removeColRational(int i)
removes column i
Definition: soplex.cpp:2594
bool hasPrimal() const
is a primal feasible solution available?
Definition: soplex.cpp:2807
static int _intParamUpper[SoPlex::INTPARAM_COUNT]
array of upper bounds for int parameter values
Definition: soplex.cpp:94
IntParam
integer parameters
Definition: soplex.h:846
force iterative refinement
Definition: soplex.h:1099
~NameSet()
destructor.
Definition: nameset.cpp:259
SPxSolver::Status _status
Definition: soplex.h:1428
void setTiming(Timer::TYPE ttype)
set timing type
Definition: spxsolver.h:719
virtual void computePrimalActivity(const VectorBase< R > &primal, VectorBase< R > &activity) const
Computes activity of the rows for a given primal vector; activity does not need to be zero...
Definition: spxlpbase.h:1619
void getColReal(int i, LPColReal &lpcol) const
gets column i
Definition: soplex.cpp:887
LP column.Class LPColBase provides a datatype for storing the column of an LP a the form similar to ...
Definition: lpcolbase.h:45
solve() aborted due to objective limit.
Definition: spxsolver.h:200
columnwise representation.
Definition: spxsolver.h:108
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:109
SPxSimplifier * _simplifier
Definition: soplex.h:1355
void removeRowRangeRational(int start, int end, int perm[]=0)
removes rows start to end including both; an array perm of size numRowsRational() may be passed as bu...
Definition: soplex.cpp:2576
void addRowsReal(const LPRowSetReal &lprowset)
adds multiple rows
Definition: soplex.cpp:1258
geometric mean scaling on rows and columns, max 1 round
Definition: soplex.h:1006
R rhs() const
Right-hand side value.
Definition: lprowbase.h:215
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:199
Basis is singular, numerical troubles?
Definition: spxsolver.h:201
void setBasis(SPxSolver::VarStatus rows[], SPxSolver::VarStatus cols[])
sets starting basis via arrays of statuses
Definition: soplex.cpp:4355
Basis is primal feasible.
Definition: spxbasis.h:96
upper bound is finite, lower bound is infinite
Definition: soplex.h:1410
bool getBoundViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of bounds; returns true on success
Definition: soplex.cpp:3265
LP has a usable Basis (maybe LP is changed).
Definition: spxsolver.h:203
bool getPrimal(VectorBase< R > &vector) const
gets the primal solution vector if available; returns true on success
Definition: solbase.h:57
SPxAutoPR _pricerAuto
Definition: soplex.h:1343
int primalIterations()
return number of iterations done with primal algorithm
Definition: spxsolver.h:1940
static int _intParamLower[SoPlex::INTPARAM_COUNT]
array of lower bounds for int parameter values
Definition: soplex.cpp:91
void setMax(int newmax=1)
Reset nonzero memory to >= newmax.
Definition: dsvectorbase.h:248
LP has been proven to be primal unbounded.
Definition: spxsolver.h:207
int totalSizeDualRational(const int base=2)
get size of dual solution
Definition: soplex.cpp:3650
LP has been proven to be primal infeasible.
Definition: spxbasis.h:99
No Problem has been loaded to the basis.
Definition: spxbasis.h:92
No linear solver loaded.
Definition: spxsolver.h:195
void removeRowsReal(int perm[])
removes all rows with an index i such that perm[i] < 0; upon completion, perm[i] >= 0 indicates the n...
Definition: soplex.cpp:1643
bool getRedCost(VectorBase< R > &vector) const
gets the vector of reduced cost values if available; returns true on success
Definition: solbase.h:105