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-2017 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 {
45  // should lifting be used to reduce range of nonzero matrix coefficients?
46  name[SoPlex::LIFTING] = "lifting";
47  description[SoPlex::LIFTING] = "should lifting be used to reduce range of nonzero matrix coefficients?";
49 
50  // should LP be transformed to equality form before a rational solve?
51  name[SoPlex::EQTRANS] = "eqtrans";
52  description[SoPlex::EQTRANS] = "should LP be transformed to equality form before a rational solve?";
54 
55  // should dual infeasibility be tested in order to try to return a dual solution even if primal infeasible?
56  name[SoPlex::TESTDUALINF] = "testdualinf";
57  description[SoPlex::TESTDUALINF] = "should dual infeasibility be tested in order to try to return a dual solution even if primal infeasible?";
59 
60  // should a rational factorization be performed after iterative refinement?
61  name[SoPlex::RATFAC] = "ratfac";
62  description[SoPlex::RATFAC] = "should a rational factorization be performed after iterative refinement?";
64 
65  // should the decomposition based dual simplex be used to solve the LP? Setting this to true forces the solve mode to
66  // SOLVEMODE_REAL and the basis representation to REPRESENTATION_ROW
67  name[SoPlex::USEDECOMPDUALSIMPLEX] = "decompositiondualsimplex";
68  description[SoPlex::USEDECOMPDUALSIMPLEX] = "should the decomposition based dual simplex be used to solve the LP?";
70 
71  // should the degeneracy be computed for each basis?
72  name[SoPlex::COMPUTEDEGEN] = "computedegen";
73  description[SoPlex::COMPUTEDEGEN] = "should the degeneracy be computed for each basis?";
75 
76  // should the dual of the complementary problem be used in the decomposition simplex?
77  name[SoPlex::USECOMPDUAL] = "usecompdual";
78  description[SoPlex::USECOMPDUAL] = "should the dual of the complementary problem be used in the decomposition simplex?";
80 
81  /// should row and bound violations be computed explicitly in the update of reduced problem in the decomposition
82  // simplex
83  name[SoPlex::EXPLICITVIOL] = "explicitviol";
84  description[SoPlex::EXPLICITVIOL] = "Should be violations of the original problem be explicitly computed in the decomposition simplex?";
86 
87  // should cycling solutions be accepted during iterative refinement?
88  name[SoPlex::ACCEPTCYCLING] = "acceptcycling";
89  description[SoPlex::ACCEPTCYCLING] = "should cycling solutions be accepted during iterative refinement?";
91 
92  // apply rational reconstruction after each iterative refinement?
93  name[SoPlex::RATREC] = "ratrec";
94  description[SoPlex::RATREC] = "apply rational reconstruction after each iterative refinement?";
96 
97  // round scaling factors for iterative refinement to powers of two?
98  name[SoPlex::POWERSCALING] = "powerscaling";
99  description[SoPlex::POWERSCALING] = "round scaling factors for iterative refinement to powers of two?";
101 
102  // continue iterative refinement with exact basic solution if not optimal?
103  name[SoPlex::RATFACJUMP] = "ratfacjump";
104  description[SoPlex::RATFACJUMP] = "continue iterative refinement with exact basic solution if not optimal?";
106 
107  // use bound flipping also for row representation?
108  name[SoPlex::ROWBOUNDFLIPS] = "rowboundflips";
109  description[SoPlex::ROWBOUNDFLIPS] = "use bound flipping also for row representation?";
111 
112  // use persistent scaling?
113  name[SoPlex::PERSISTENTSCALING] = "persistentscaling";
114  description[SoPlex::PERSISTENTSCALING] = "should persistent scaling be used?";
116 
117  // perturb the entire problem or only the relevant bounds of s single pivot?
118  name[SoPlex::FULLPERTURBATION] = "fullperturbation";
119  description[SoPlex::FULLPERTURBATION] = "should perturbation be applied to the entire problem?";
121  }
122 
124  // objective sense
125  name[SoPlex::OBJSENSE] = "objsense";
126  description[SoPlex::OBJSENSE] = "objective sense (-1 - minimize, +1 - maximize)";
127  lower[SoPlex::OBJSENSE] = -1;
128  upper[SoPlex::OBJSENSE] = 1;
130 
131  // type of computational form, i.e., column or row representation
132  name[SoPlex::REPRESENTATION] = "representation";
133  description[SoPlex::REPRESENTATION] = "type of computational form (0 - auto, 1 - column representation, 2 - row representation)";
134  lower[SoPlex::REPRESENTATION] = 0;
135  upper[SoPlex::REPRESENTATION] = 2;
137 
138  // type of algorithm, i.e., primal or dual
139  name[SoPlex::ALGORITHM] = "algorithm";
140  description[SoPlex::ALGORITHM] = "type of algorithm (0 - primal, 1 - dual)";
141  lower[SoPlex::ALGORITHM] = 0;
142  upper[SoPlex::ALGORITHM] = 1;
144 
145  // type of LU update
146  name[SoPlex::FACTOR_UPDATE_TYPE] = "factor_update_type";
147  description[SoPlex::FACTOR_UPDATE_TYPE] = "type of LU update (0 - eta update, 1 - Forrest-Tomlin update)";
148  lower[SoPlex::FACTOR_UPDATE_TYPE] = 0;
149  upper[SoPlex::FACTOR_UPDATE_TYPE] = 1;
151 
152  // maximum number of updates without fresh factorization
153  name[SoPlex::FACTOR_UPDATE_MAX] = "factor_update_max";
154  description[SoPlex::FACTOR_UPDATE_MAX] = "maximum number of LU updates without fresh factorization";
155  lower[SoPlex::FACTOR_UPDATE_MAX] = 0;
156  upper[SoPlex::FACTOR_UPDATE_MAX] = INT_MAX;
158 
159  // iteration limit (-1 if unlimited)
160  name[SoPlex::ITERLIMIT] = "iterlimit";
161  description[SoPlex::ITERLIMIT] = "iteration limit (-1 - no limit)";
162  lower[SoPlex::ITERLIMIT] = -1;
163  upper[SoPlex::ITERLIMIT] = INT_MAX;
165 
166  // refinement limit (-1 if unlimited)
167  name[SoPlex::REFLIMIT] = "reflimit";
168  description[SoPlex::REFLIMIT] = "refinement limit (-1 - no limit)";
169  lower[SoPlex::REFLIMIT] = -1;
170  upper[SoPlex::REFLIMIT] = INT_MAX;
172 
173  // stalling refinement limit (-1 if unlimited)
174  name[SoPlex::STALLREFLIMIT] = "stallreflimit";
175  description[SoPlex::STALLREFLIMIT] = "stalling refinement limit (-1 - no limit)";
176  lower[SoPlex::STALLREFLIMIT] = -1;
177  upper[SoPlex::STALLREFLIMIT] = INT_MAX;
179 
180  // display frequency
181  name[SoPlex::DISPLAYFREQ] = "displayfreq";
182  description[SoPlex::DISPLAYFREQ] = "display frequency";
183  lower[SoPlex::DISPLAYFREQ] = 1;
184  upper[SoPlex::DISPLAYFREQ] = INT_MAX;
186 
187  // verbosity level
188  name[SoPlex::VERBOSITY] = "verbosity";
189  description[SoPlex::VERBOSITY] = "verbosity level (0 - error, 1 - warning, 2 - debug, 3 - normal, 4 - high, 5 - full)";
190  lower[SoPlex::VERBOSITY] = 0;
191  upper[SoPlex::VERBOSITY] = 5;
193  //_intParamDefault[SoPlex::VERBOSITY] = SoPlex::VERBOSITY_FULL;
194 
195  // type of simplifier
196  name[SoPlex::SIMPLIFIER] = "simplifier";
197  description[SoPlex::SIMPLIFIER] = "simplifier (0 - off, 1 - auto)";
198  lower[SoPlex::SIMPLIFIER] = 0;
199  upper[SoPlex::SIMPLIFIER] = 1;
201 
202  // type of scaler
203  name[SoPlex::SCALER] = "scaler";
204  description[SoPlex::SCALER] = "scaling (0 - off, 1 - uni-equilibrium, 2 - bi-equilibrium, 3 - geometric, 4 - iterated geometric, 5 - least squares)";
205  lower[SoPlex::SCALER] = 0;
206  upper[SoPlex::SCALER] = 5;
208 
209  // type of starter used to create crash basis
210  name[SoPlex::STARTER] = "starter";
211  description[SoPlex::STARTER] = "crash basis generated when starting from scratch (0 - none, 1 - weight, 2 - sum, 3 - vector)";
212  lower[SoPlex::STARTER] = 0;
213  upper[SoPlex::STARTER] = 3;
215 
216  // type of pricer
217  name[SoPlex::PRICER] = "pricer";
218  description[SoPlex::PRICER] = "pricing method (0 - auto, 1 - dantzig, 2 - parmult, 3 - devex, 4 - quicksteep, 5 - steep)";
219  lower[SoPlex::PRICER] = 0;
220  upper[SoPlex::PRICER] = 5;
222 
223  // type of ratio test
224  name[SoPlex::RATIOTESTER] = "ratiotester";
225  description[SoPlex::RATIOTESTER] = "method for ratio test (0 - textbook, 1 - harris, 2 - fast, 3 - boundflipping)";
226  lower[SoPlex::RATIOTESTER] = 0;
227  upper[SoPlex::RATIOTESTER] = 3;
229 
230  // mode for synchronizing real and rational LP
231  name[SoPlex::SYNCMODE] = "syncmode";
232  description[SoPlex::SYNCMODE] = "mode for synchronizing real and rational LP (0 - store only real LP, 1 - auto, 2 - manual)";
233  lower[SoPlex::SYNCMODE] = 0;
234  upper[SoPlex::SYNCMODE] = 2;
236 
237  // mode for reading LP files
238  name[SoPlex::READMODE] = "readmode";
239  description[SoPlex::READMODE] = "mode for reading LP files (0 - floating-point, 1 - rational)";
240  lower[SoPlex::READMODE] = 0;
241  upper[SoPlex::READMODE] = 1;
243 
244  // mode for iterative refinement strategy
245  name[SoPlex::SOLVEMODE] = "solvemode";
246  description[SoPlex::SOLVEMODE] = "mode for iterative refinement strategy (0 - floating-point solve, 1 - auto, 2 - exact rational solve)";
247  lower[SoPlex::SOLVEMODE] = 0;
248  upper[SoPlex::SOLVEMODE] = 2;
250 
251  // mode for iterative refinement strategy
252  name[SoPlex::CHECKMODE] = "checkmode";
253  description[SoPlex::CHECKMODE] = "mode for a posteriori feasibility checks (0 - floating-point check, 1 - auto, 2 - exact rational check)";
254  lower[SoPlex::CHECKMODE] = 0;
255  upper[SoPlex::CHECKMODE] = 2;
257 
258  // type of timing
259  name[SoPlex::TIMER] = "timer";
260  description[SoPlex::TIMER] = "type of timer (1 - cputime, aka. usertime, 2 - wallclock time, 0 - no timing)";
261  lower[SoPlex::TIMER] = 0;
262  upper[SoPlex::TIMER] = 2;
264 
265  // mode for hyper sparse pricing
266  name[SoPlex::HYPER_PRICING] = "hyperpricing";
267  description[SoPlex::HYPER_PRICING] = "mode for hyper sparse pricing (0 - off, 1 - auto, 2 - always)";
268  lower[SoPlex::HYPER_PRICING] = 0;
269  upper[SoPlex::HYPER_PRICING] = 2;
271 
272  // minimum number of stalling refinements since last pivot to trigger rational factorization
273  name[SoPlex::RATFAC_MINSTALLS] = "ratfac_minstalls";
274  description[SoPlex::RATFAC_MINSTALLS] = "minimum number of stalling refinements since last pivot to trigger rational factorization";
275  lower[SoPlex::RATFAC_MINSTALLS] = 0;
276  upper[SoPlex::RATFAC_MINSTALLS] = INT_MAX;
278 
279  // maximum number of conjugate gradient iterations in least square scaling
280  name[SoPlex::LEASTSQ_MAXROUNDS] = "leastsq_maxrounds";
281  description[SoPlex::LEASTSQ_MAXROUNDS] = "maximum number of conjugate gradient iterations in least square scaling";
282  lower[SoPlex::LEASTSQ_MAXROUNDS] = 0;
283  upper[SoPlex::LEASTSQ_MAXROUNDS] = INT_MAX;
285 
286  // mode for solution polishing
287  name[SoPlex::SOLUTION_POLISHING] = "solution_polishing";
288  description[SoPlex::SOLUTION_POLISHING] = "mode for solution polishing (0 - off, 1 - max basic slack, 2 - min basic slack)";
289  lower[SoPlex::SOLUTION_POLISHING] = 0;
290  upper[SoPlex::SOLUTION_POLISHING] = 2;
292 
293  // the number of iterations before the decomposition simplex initialisation is terminated.
294  name[SoPlex::DECOMP_ITERLIMIT] = "decomp_iterlimit";
295  description[SoPlex::DECOMP_ITERLIMIT] = "the number of iterations before the decomposition simplex initialisation solve is terminated";
296  lower[SoPlex::DECOMP_ITERLIMIT] = 1;
297  upper[SoPlex::DECOMP_ITERLIMIT] = INT_MAX;
299 
300  // maximum number of violated rows added in each iteration of the decomposition simplex
301  name[SoPlex::DECOMP_MAXADDEDROWS] = "decomp_maxaddedrows";
302  description[SoPlex::DECOMP_MAXADDEDROWS] = "maximum number of rows that are added to the reduced problem when using the decomposition based simplex";
303  lower[SoPlex::DECOMP_MAXADDEDROWS] = 1;
304  upper[SoPlex::DECOMP_MAXADDEDROWS] = INT_MAX;
306 
307  // maximum number of violated rows added in each iteration of the decomposition simplex
308  name[SoPlex::DECOMP_DISPLAYFREQ] = "decomp_displayfreq";
309  description[SoPlex::DECOMP_DISPLAYFREQ] = "the frequency that the decomposition based simplex status output is displayed.";
310  lower[SoPlex::DECOMP_DISPLAYFREQ] = 1;
311  upper[SoPlex::DECOMP_DISPLAYFREQ] = INT_MAX;
313 
314  // the verbosity of the decomposition based simplex
315  name[SoPlex::DECOMP_VERBOSITY] = "decomp_verbosity";
316  description[SoPlex::DECOMP_VERBOSITY] = "the verbosity of decomposition based simplex (0 - error, 1 - warning, 2 - debug, 3 - normal, 4 - high, 5 - full).";
317  lower[SoPlex::DECOMP_VERBOSITY] = 1;
318  upper[SoPlex::DECOMP_VERBOSITY] = 5;
320  }
321 
323  // primal feasibility tolerance
324  name[SoPlex::FEASTOL] = "feastol";
325  description[SoPlex::FEASTOL] = "primal feasibility tolerance";
326  lower[SoPlex::FEASTOL] = 0.0;
327  upper[SoPlex::FEASTOL] = 1.0;
329 
330  // dual feasibility tolerance
331  name[SoPlex::OPTTOL] = "opttol";
332  description[SoPlex::OPTTOL] = "dual feasibility tolerance";
333  lower[SoPlex::OPTTOL] = 0.0;
334  upper[SoPlex::OPTTOL] = 1.0;
336 
337  ///@todo define suitable values depending on Real type
338  // general zero tolerance
339  name[SoPlex::EPSILON_ZERO] = "epsilon_zero";
340  description[SoPlex::EPSILON_ZERO] = "general zero tolerance";
341  lower[SoPlex::EPSILON_ZERO] = 0.0;
342  upper[SoPlex::EPSILON_ZERO] = 1.0;
344 
345  ///@todo define suitable values depending on Real type
346  // zero tolerance used in factorization
347  name[SoPlex::EPSILON_FACTORIZATION] = "epsilon_factorization";
348  description[SoPlex::EPSILON_FACTORIZATION] = "zero tolerance used in factorization";
349  lower[SoPlex::EPSILON_FACTORIZATION] = 0.0;
350  upper[SoPlex::EPSILON_FACTORIZATION] = 1.0;
352 
353  ///@todo define suitable values depending on Real type
354  // zero tolerance used in update of the factorization
355  name[SoPlex::EPSILON_UPDATE] = "epsilon_update";
356  description[SoPlex::EPSILON_UPDATE] = "zero tolerance used in update of the factorization";
357  lower[SoPlex::EPSILON_UPDATE] = 0.0;
358  upper[SoPlex::EPSILON_UPDATE] = 1.0;
360 
361  ///@todo define suitable values depending on Real type
362  // pivot zero tolerance used in factorization
363  name[SoPlex::EPSILON_PIVOT] = "epsilon_pivot";
364  description[SoPlex::EPSILON_PIVOT] = "pivot zero tolerance used in factorization";
365  lower[SoPlex::EPSILON_PIVOT] = 0.0;
366  upper[SoPlex::EPSILON_PIVOT] = 1.0;
368 
369  ///@todo define suitable values depending on Real type
370  // infinity threshold
371  name[SoPlex::INFTY] = "infty";
372  description[SoPlex::INFTY] = "infinity threshold";
373  lower[SoPlex::INFTY] = 1e10;
374  upper[SoPlex::INFTY] = 1e100;
376 
377  // time limit in seconds (INFTY if unlimited)
378  name[SoPlex::TIMELIMIT] = "timelimit";
379  description[SoPlex::TIMELIMIT] = "time limit in seconds";
380  lower[SoPlex::TIMELIMIT] = 0.0;
383 
384  // lower limit on objective value
385  name[SoPlex::OBJLIMIT_LOWER] = "objlimit_lower";
386  description[SoPlex::OBJLIMIT_LOWER] = "lower limit on objective value";
390 
391  // upper limit on objective value
392  name[SoPlex::OBJLIMIT_UPPER] = "objlimit_upper";
393  description[SoPlex::OBJLIMIT_UPPER] = "upper limit on objective value";
397 
398  // working tolerance for feasibility in floating-point solver during iterative refinement
399  name[SoPlex::FPFEASTOL] = "fpfeastol";
400  description[SoPlex::FPFEASTOL] = "working tolerance for feasibility in floating-point solver during iterative refinement";
401  lower[SoPlex::FPFEASTOL] = 1e-12;
402  upper[SoPlex::FPFEASTOL] = 1.0;
404 
405  // working tolerance for optimality in floating-point solver during iterative refinement
406  name[SoPlex::FPOPTTOL] = "fpopttol";
407  description[SoPlex::FPOPTTOL] = "working tolerance for optimality in floating-point solver during iterative refinement";
408  lower[SoPlex::FPOPTTOL] = 1e-12;
409  upper[SoPlex::FPOPTTOL] = 1.0;
411 
412  // maximum increase of scaling factors between refinements
413  name[SoPlex::MAXSCALEINCR] = "maxscaleincr";
414  description[SoPlex::MAXSCALEINCR] = "maximum increase of scaling factors between refinements";
415  lower[SoPlex::MAXSCALEINCR] = 1.0;
418 
419  // lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)
420  name[SoPlex::LIFTMINVAL] = "liftminval";
421  description[SoPlex::LIFTMINVAL] = "lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)";
422  lower[SoPlex::LIFTMINVAL] = 0.0;
423  upper[SoPlex::LIFTMINVAL] = 0.1;
424  defaultValue[SoPlex::LIFTMINVAL] = 0.000976562; // = 1/1024
425 
426  // upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulated)
427  name[SoPlex::LIFTMAXVAL] = "liftmaxval";
428  description[SoPlex::LIFTMAXVAL] = "lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)";
429  lower[SoPlex::LIFTMAXVAL] = 10.0;
432 
433  // threshold for using sparse pricing (no. of violations need to be smaller than threshold * dimension of problem)
434  name[SoPlex::SPARSITY_THRESHOLD] = "sparsity_threshold";
435  description[SoPlex::SPARSITY_THRESHOLD] = "sparse pricing threshold (#violations < dimension * SPARSITY_THRESHOLD activates sparse pricing)";
436  lower[SoPlex::SPARSITY_THRESHOLD] = 0.0;
437  upper[SoPlex::SPARSITY_THRESHOLD] = 1.0;
439 
440  // threshold on number of rows vs. number of columns for switching from column to row representations in auto mode
441  name[SoPlex::REPRESENTATION_SWITCH] = "representation_switch";
442  description[SoPlex::REPRESENTATION_SWITCH] = "threshold on number of rows vs. number of columns for switching from column to row representations in auto mode";
443  lower[SoPlex::REPRESENTATION_SWITCH] = 0.0;
446 
447  // geometric frequency at which to apply rational reconstruction
448  name[SoPlex::RATREC_FREQ] = "ratrec_freq";
449  description[SoPlex::RATREC_FREQ] = "geometric frequency at which to apply rational reconstruction";
450  lower[SoPlex::RATREC_FREQ] = 1.0;
453 
454  // minimal reduction (sum of removed rows/cols) to continue simplification
455  name[SoPlex::MINRED] = "minred";
456  description[SoPlex::MINRED] = "minimal reduction (sum of removed rows/cols) to continue simplification";
457  lower[SoPlex::MINRED] = 0.0;
458  upper[SoPlex::MINRED] = 1.0;
460 
461  // refactor threshold for nonzeros in last factorized basis matrix compared to updated basis matrix
462  name[SoPlex::REFAC_BASIS_NNZ] = "refac_basis_nnz";
463  description[SoPlex::REFAC_BASIS_NNZ] = "refactor threshold for nonzeros in last factorized basis matrix compared to updated basis matrix";
464  lower[SoPlex::REFAC_BASIS_NNZ] = 1.0;
465  upper[SoPlex::REFAC_BASIS_NNZ] = 100.0;
467 
468  // refactor threshold for fill-in in current factor update compared to fill-in in last factorization
469  name[SoPlex::REFAC_UPDATE_FILL] = "refac_update_fill";
470  description[SoPlex::REFAC_UPDATE_FILL] = "refactor threshold for fill-in in current factor update compared to fill-in in last factorization";
471  lower[SoPlex::REFAC_UPDATE_FILL] = 1.0;
472  upper[SoPlex::REFAC_UPDATE_FILL] = 100.0;
474 
475  // refactor threshold for memory growth in factorization since last refactorization
476  name[SoPlex::REFAC_MEM_FACTOR] = "refac_mem_factor";
477  description[SoPlex::REFAC_MEM_FACTOR] = "refactor threshold for memory growth in factorization since last refactorization";
478  lower[SoPlex::REFAC_MEM_FACTOR] = 1.0;
479  upper[SoPlex::REFAC_MEM_FACTOR] = 10.0;
481 
482  // accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations)
483  name[SoPlex::LEASTSQ_ACRCY] = "leastsq_acrcy";
484  description[SoPlex::LEASTSQ_ACRCY] = "accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations)";
485  lower[SoPlex::LEASTSQ_ACRCY] = 1.0;
488 
489  // objective offset
490  name[SoPlex::OBJ_OFFSET] = "obj_offset";
491  description[SoPlex::OBJ_OFFSET] = "objective offset to be used";
495  }
496 
497 #ifdef SOPLEX_WITH_RATIONALPARAM
498  SoPlex::Settings::RationalParam::RationalParam() {}
499 #endif
500 
502  {
503  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
505 
506  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
508 
509  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
511 
512 #ifdef SOPLEX_WITH_RATIONALPARAM
513  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
514  _rationalParamValues[i] = rationalParam.defaultValue[i];
515 #endif
516  }
517 
519  {
520  *this = settings;
521  }
522 
524  {
525  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
526  _boolParamValues[i] = settings._boolParamValues[i];
527 
528  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
529  _intParamValues[i] = settings._intParamValues[i];
530 
531  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
532  _realParamValues[i] = settings._realParamValues[i];
533 
534 #ifdef SOPLEX_WITH_RATIONALPARAM
535  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
536  _rationalParamValues[i] = settings._rationalParamValues[i];
537 #endif
538 
539  return *this;
540  }
541 
545 #ifdef SOPLEX_WITH_RATIONALPARAM
546  SoPlex::Settings::RationalParam SoPlex::Settings::rationalParam;
547 #endif
548 
549  /// default constructor
551  : _statistics(0)
552  , _currentSettings(0)
553  , _scalerUniequi(false)
554  , _scalerBiequi(true)
555  , _scalerGeo1(1)
556  , _scalerGeo8(8)
557  , _scalerLeastsq()
558  , _simplifier(0)
559  , _scaler(0)
560  , _starter(0)
561  , _rationalLP(0)
563  , _status(SPxSolver::UNKNOWN)
564  , _hasBasis(false)
565  , _hasSolReal(false)
566  , _hasSolRational(false)
567  , _rationalPosone(1)
568  , _rationalNegone(-1)
569  , _rationalZero(0)
570  {
571  // transfer message handler
578 
579  // give lu factorization to solver
581 
582  // the real LP is initially stored in the solver; the rational LP is constructed, when the parameter SYNCMODE is
583  // initialized in setSettings() below
584  _realLP = &_solver;
585  _isRealLPLoaded = true;
586  _isRealLPScaled = false;
587  _applyPolishing = false;
588  _optimizeCalls = 0;
589  _unscaleCalls = 0;
592 
593  // initialize statistics
596 
597  // initialize parameter settings to default
601 
603 
604  assert(_isConsistent());
605  }
606 
607 
608 
609  /// assignment operator
611  {
612  if( this != &rhs )
613  {
614  // copy message handler
615  spxout = rhs.spxout;
616 
617  // copy statistics
618  *_statistics = *(rhs._statistics);
619 
620  // copy settings
622 
623  // copy solver components
624  _solver = rhs._solver;
625  _slufactor = rhs._slufactor;
629  _scalerGeo1 = rhs._scalerGeo1;
630  _scalerGeo8 = rhs._scalerGeo8;
633  _starterSum = rhs._starterSum;
635  _pricerAuto = rhs._pricerAuto;
645 
646  // copy solution data
647  _status = rhs._status;
651 
652  if( rhs._hasSolReal )
653  _solReal = rhs._solReal;
654 
655  if( rhs._hasSolRational )
657 
658  // set message handlers in members
665 
666  // transfer the lu solver
668 
669  // initialize pointers for simplifier, scaler, and starter
673 
674  // copy real LP if different from the LP in the solver
675  if( rhs._realLP != &(rhs._solver) )
676  {
677  _realLP = 0;
679  _realLP = new (_realLP) SPxLPReal(*(rhs._realLP));
680  }
681  else
682  _realLP = &_solver;
683 
684  // copy rational LP
685  if( rhs._rationalLP == 0 )
686  {
688  _rationalLP = 0;
689  }
690  else
691  {
693  _rationalLP = 0;
696  }
697 
698  // copy rational factorization
701 
702  // copy boolean flags
705  _hasSolReal = rhs._hasSolReal;
707  _hasBasis = rhs._hasBasis;
709 
710  // rational constants do not need to be assigned
711  _rationalPosone = 1;
712  _rationalNegone = -1;
713  _rationalZero = 0;
714  }
715 
716  assert(_isConsistent());
717 
718  return *this;
719  }
720 
721 
722 
723  /// copy constructor
724  ///@todo improve performance by implementing a separate copy constructor
725  SoPlex::SoPlex(const SoPlex& rhs)
726  {
727  // allocate memory as in default constructor
728  _statistics = 0;
731 
732  _currentSettings = 0;
735 
736  // call assignment operator
737  *this = rhs;
738  }
739 
740 
741 
742  /// destructor
744  {
745  assert(_isConsistent());
746 
747  // free settings
748  _currentSettings->~Settings();
750 
751  // free statistics
754 
755  // free real LP if different from the LP in the solver
756  assert(_realLP != 0);
757  if( _realLP != &_solver )
758  {
759  _realLP->~SPxLPReal();
760  spx_free(_realLP);
761  }
762 
763  // free rational LP
764  if( _rationalLP != 0 )
765  {
766  _rationalLP->~SPxLPRational();
768  }
769 
770  // free unit vectors
771  for( int i = 0; i < _unitMatrixRational.size(); i++ )
772  {
773  if( _unitMatrixRational[i] != 0 )
774  {
775  _unitMatrixRational[i]->~UnitVectorRational();
777  }
778  }
779  }
780 
781 
782 
783  /// returns number of rows
785  {
786  assert(_realLP != 0);
787  return _realLP->nRows();
788  }
789 
790 
791 
792  /// returns number of columns
794  {
795  assert(_realLP != 0);
796  return _realLP->nCols();
797  }
798 
799 
800 
801  /// returns number of nonzeros
803  {
804  assert(_realLP != 0);
805  return _realLP->nNzos();
806  }
807 
808 
809 
810  /// returns smallest non-zero element in absolute value
812  {
813  assert(_realLP != 0);
814  return _realLP->minAbsNzo();
815  }
816 
817 
818 
819  /// returns biggest non-zero element in absolute value
821  {
822  assert(_realLP != 0);
823  return _realLP->maxAbsNzo();
824  }
825 
826 
827 
828  /// returns (unscaled) coefficient
829  Real SoPlex::coefReal(int row, int col) const
830  {
831  if( _realLP->isScaled() )
832  {
833  assert(_scaler);
834  return _scaler->getCoefUnscaled(*_realLP, row, col);
835  }
836  else
837  return colVectorRealInternal(col)[row];
838  }
839 
840 
841 
842  /// returns vector of row \p i, ignoring scaling
844  {
845  assert(_realLP != 0);
846  return _realLP->rowVector(i);
847  }
848 
849 
850 
851  /// gets vector of row \p i
852  void SoPlex::getRowVectorReal(int i, DSVectorReal& row) const
853  {
854  assert(_realLP);
855 
856  if( _realLP->isScaled() )
857  {
858  assert(_scaler);
859  row.setMax(_realLP->rowVector(i).size());
860  _scaler->getRowUnscaled(*_realLP, i, row);
861  }
862  else
863  row = _realLP->rowVector(i);
864  }
865 
866 
867 
868  /// returns right-hand side vector, ignoring scaling
870  {
871  assert(_realLP != 0);
872  return _realLP->rhs();
873  }
874 
875 
876 
877  /// gets right-hand side vector
879  {
880  assert(_realLP);
881  _realLP->getRhsUnscaled(rhs);
882  }
883 
884 
885 
886  /// returns right-hand side of row \p i
887  Real SoPlex::rhsReal(int i) const
888  {
889  assert(_realLP != 0);
890  return _realLP->rhsUnscaled(i);
891  }
892 
893 
894 
895  /// returns left-hand side vector, ignoring scaling
897  {
898  assert(_realLP != 0);
899  return _realLP->lhs();
900  }
901 
902 
903 
904  /// gets left-hand side vector
906  {
907  assert(_realLP);
908  _realLP->getLhsUnscaled(lhs);
909  }
910 
911 
912 
913  /// returns left-hand side of row \p i
914  Real SoPlex::lhsReal(int i) const
915  {
916  assert(_realLP != 0);
917  return _realLP->lhsUnscaled(i);
918  }
919 
920 
921 
922  /// returns inequality type of row \p i
924  {
925  assert(_realLP != 0);
926  return _realLP->rowType(i);
927  }
928 
929 
930 
931  /// returns vector of col \p i, ignoring scaling
933  {
934  assert(_realLP != 0);
935  return _realLP->colVector(i);
936  }
937 
938 
939 
940  /// gets vector of col \p i
941  void SoPlex::getColVectorReal(int i, DSVectorReal& col) const
942  {
943  assert(_realLP);
944  _realLP->getColVectorUnscaled(i, col);
945  }
946 
947 
948 
949  /// returns upper bound vector
951  {
952  assert(_realLP != 0);
953  return _realLP->upper();
954  }
955 
956 
957 
958  /// returns upper bound of column \p i
959  Real SoPlex::upperReal(int i) const
960  {
961  assert(_realLP != 0);
962  return _realLP->upperUnscaled(i);
963  }
964 
965 
966 
967  /// gets upper bound vector
969  {
970  assert(_realLP != 0);
971  return _realLP->getUpperUnscaled(upper);
972  }
973 
974 
975 
976  /// returns lower bound vector
978  {
979  assert(_realLP != 0);
980  return _realLP->lower();
981  }
982 
983 
984 
985  /// returns lower bound of column \p i
986  Real SoPlex::lowerReal(int i) const
987  {
988  assert(_realLP != 0);
989  return _realLP->lowerUnscaled(i);
990  }
991 
992 
993 
994  /// gets lower bound vector
996  {
997  assert(_realLP != 0);
998  return _realLP->getLowerUnscaled(lower);
999  }
1000 
1001 
1002 
1003 
1004  /// gets objective function vector
1006  {
1007  assert(_realLP != 0);
1008  _realLP->getObjUnscaled(obj);
1009  }
1010 
1011 
1012 
1013  /// returns objective value of column \p i
1014  Real SoPlex::objReal(int i) const
1015  {
1016  assert(_realLP != 0);
1017  return _realLP->objUnscaled(i);
1018  }
1019 
1020 
1021 
1022  /// returns objective function vector after transformation to a maximization problem; since this is how it is stored
1023  /// internally, this is generally faster
1025  {
1026  assert(_realLP != 0);
1027  return _realLP->maxObj();
1028  }
1029 
1030 
1031 
1032  /// returns objective value of column \p i after transformation to a maximization problem; since this is how it is
1033  /// stored internally, this is generally faster
1035  {
1036  assert(_realLP != 0);
1037  return _realLP->maxObjUnscaled(i);
1038  }
1039 
1040 
1041 
1042  /// gets number of available dual norms
1043  void SoPlex::getNdualNorms(int& nnormsRow, int& nnormsCol) const
1044  {
1045  _solver.getNdualNorms(nnormsRow, nnormsCol);
1046  }
1047 
1048 
1049 
1050  /// gets steepest edge norms and returns false if they are not available
1051  bool SoPlex::getDualNorms(int& nnormsRow, int& nnormsCol, Real* norms) const
1052  {
1053  return _solver.getDualNorms(nnormsRow, nnormsCol, norms);
1054  }
1055 
1056 
1057 
1058  /// sets steepest edge norms and returns false if that's not possible
1059  bool SoPlex::setDualNorms(int nnormsRow, int nnormsCol, Real* norms)
1060  {
1061  return _solver.setDualNorms(nnormsRow, nnormsCol, norms);
1062  }
1063 
1064 
1065 
1066  /// pass integrality information about the variables to the solver
1067  void SoPlex::setIntegralityInformation( int ncols, int* intInfo)
1068  {
1069  assert(ncols == _solver.nCols() || (ncols == 0 && intInfo == NULL));
1070  _solver.setIntegralityInformation(ncols, intInfo);
1071  }
1072 
1073 
1074 
1075  /// returns number of rows
1077  {
1078  assert(_rationalLP != 0);
1079  return _rationalLP->nRows();
1080  }
1081 
1082 
1083 
1084  /// returns number of columns
1086  {
1087  assert(_rationalLP != 0);
1088  return _rationalLP->nCols();
1089  }
1090 
1091 
1092 
1093  /// returns number of nonzeros
1095  {
1096  assert(_rationalLP != 0);
1097  return _rationalLP->nNzos();
1098  }
1099 
1100 
1101 
1102  /// returns smallest non-zero element in absolute value
1104  {
1105  assert(_rationalLP != 0);
1106  return _rationalLP->minAbsNzo();
1107  }
1108 
1109 
1110 
1111  /// returns biggest non-zero element in absolute value
1113  {
1114  assert(_rationalLP != 0);
1115  return _rationalLP->maxAbsNzo();
1116  }
1117 
1118 
1119 
1120  /// gets row \p i
1121  void SoPlex::getRowRational(int i, LPRowRational& lprow) const
1122  {
1123  assert(_rationalLP != 0);
1124  _rationalLP->getRow(i, lprow);
1125  }
1126 
1127 
1128 
1129  /// gets rows \p start, ..., \p end.
1130  void SoPlex::getRowsRational(int start, int end, LPRowSetRational& lprowset) const
1131  {
1132  assert(_rationalLP != 0);
1133  _rationalLP->getRows(start, end, lprowset);
1134  }
1135 
1136 
1137 
1138  /// returns vector of row \p i
1140  {
1141  assert(_rationalLP != 0);
1142  return _rationalLP->rowVector(i);
1143  }
1144 
1145 
1146 
1147  /// returns right-hand side vector
1149  {
1150  assert(_rationalLP != 0);
1151  return _rationalLP->rhs();
1152  }
1153 
1154 
1155 
1156  /// returns right-hand side of row \p i
1157  const Rational& SoPlex::rhsRational(int i) const
1158  {
1159  assert(_rationalLP != 0);
1160  return _rationalLP->rhs(i);
1161  }
1162 
1163 
1164 
1165  /// returns left-hand side vector
1167  {
1168  assert(_rationalLP != 0);
1169  return _rationalLP->lhs();
1170  }
1171 
1172 
1173 
1174  /// returns left-hand side of row \p i
1175  const Rational& SoPlex::lhsRational(int i) const
1176  {
1177  assert(_rationalLP != 0);
1178  return _rationalLP->lhs(i);
1179  }
1180 
1181 
1182 
1183  /// returns inequality type of row \p i
1185  {
1186  assert(_rationalLP != 0);
1187  return _rationalLP->rowType(i);
1188  }
1189 
1190 
1191 
1192  /// gets column \p i
1193  void SoPlex::getColRational(int i, LPColRational& lpcol) const
1194  {
1195  assert(_rationalLP != 0);
1196  return _rationalLP->getCol(i, lpcol);
1197  }
1198 
1199 
1200 
1201  /// gets columns \p start, ..., \p end
1202  void SoPlex::getColsRational(int start, int end, LPColSetRational& lpcolset) const
1203  {
1204  assert(_rationalLP != 0);
1205  return _rationalLP->getCols(start, end, lpcolset);
1206  }
1207 
1208 
1209 
1210  /// returns vector of column \p i
1212  {
1213  assert(_rationalLP != 0);
1214  return _rationalLP->colVector(i);
1215  }
1216 
1217 
1218 
1219  /// returns upper bound vector
1221  {
1222  assert(_rationalLP != 0);
1223  return _rationalLP->upper();
1224  }
1225 
1226 
1227 
1228  /// returns upper bound of column \p i
1229  const Rational& SoPlex::upperRational(int i) const
1230  {
1231  assert(_rationalLP != 0);
1232  return _rationalLP->upper(i);
1233  }
1234 
1235 
1236 
1237  /// returns lower bound vector
1239  {
1240  assert(_rationalLP != 0);
1241  return _rationalLP->lower();
1242  }
1243 
1244 
1245 
1246  /// returns lower bound of column \p i
1247  const Rational& SoPlex::lowerRational(int i) const
1248  {
1249  assert(_rationalLP != 0);
1250  return _rationalLP->lower(i);
1251  }
1252 
1253 
1254 
1255  /// gets objective function vector
1257  {
1258  assert(_rationalLP != 0);
1259  _rationalLP->getObj(obj);
1260  }
1261 
1262 
1263 
1264  /// gets objective value of column \p i
1265  void SoPlex::getObjRational(int i, Rational& obj) const
1266  {
1267  obj = maxObjRational(i);
1269  obj *= -1;
1270  }
1271 
1272 
1273 
1274  /// returns objective value of column \p i
1276  {
1277  assert(_rationalLP != 0);
1278  return _rationalLP->obj(i);
1279  }
1280 
1281 
1282 
1283  /// returns objective function vector after transformation to a maximization problem; since this is how it is stored
1284  /// internally, this is generally faster
1286  {
1287  assert(_rationalLP != 0);
1288  return _rationalLP->maxObj();
1289  }
1290 
1291 
1292 
1293  /// returns objective value of column \p i after transformation to a maximization problem; since this is how it is
1294  /// stored internally, this is generally faster
1295  const Rational& SoPlex::maxObjRational(int i) const
1296  {
1297  assert(_rationalLP != 0);
1298  return _rationalLP->maxObj(i);
1299  }
1300 
1301 
1302 
1303  /// adds a single row
1304  void SoPlex::addRowReal(const LPRowReal& lprow)
1305  {
1306  assert(_realLP != 0);
1307 
1308  _addRowReal(lprow);
1309 
1311  {
1312  _rationalLP->addRow(lprow);
1314  }
1315 
1317  }
1318 
1319 
1320 
1321  /// adds multiple rows
1322  void SoPlex::addRowsReal(const LPRowSetReal& lprowset)
1323  {
1324  assert(_realLP != 0);
1325 
1326  _addRowsReal(lprowset);
1327 
1329  {
1330  _rationalLP->addRows(lprowset);
1332  }
1333 
1335  }
1336 
1337 
1338 
1339  /// adds a single column
1340  void SoPlex::addColReal(const LPColReal& lpcol)
1341  {
1342  assert(_realLP != 0);
1343 
1344  _addColReal(lpcol);
1345 
1347  {
1348  _rationalLP->addCol(lpcol);
1350  }
1351 
1353  }
1354 
1355 
1356 
1357  /// adds multiple columns
1358  void SoPlex::addColsReal(const LPColSetReal& lpcolset)
1359  {
1360  assert(_realLP != 0);
1361 
1362  _addColsReal(lpcolset);
1363 
1365  {
1366  _rationalLP->addCols(lpcolset);
1368  }
1369 
1371  }
1372 
1373 
1374 
1375  /// replaces row \p i with \p lprow
1376  void SoPlex::changeRowReal(int i, const LPRowReal& lprow)
1377  {
1378  assert(_realLP != 0);
1379 
1380  _changeRowReal(i, lprow);
1381 
1383  {
1384  _rationalLP->changeRow(i, lprow);
1385  _rowTypes[i] = _rangeTypeReal(lprow.lhs(), lprow.rhs());
1387  }
1388 
1390  }
1391 
1392 
1393 
1394  /// changes left-hand side vector for constraints to \p lhs
1396  {
1397  assert(_realLP != 0);
1398 
1399  _changeLhsReal(lhs);
1400 
1402  {
1404  for( int i = 0; i < numRowsRational(); i++ )
1406  }
1407 
1409  }
1410 
1411 
1412 
1413  /// changes left-hand side of row \p i to \p lhs
1414  void SoPlex::changeLhsReal(int i, const Real& lhs)
1415  {
1416  assert(_realLP != 0);
1417 
1418  _changeLhsReal(i, lhs);
1419 
1421  {
1422  _rationalLP->changeLhs(i, lhs);
1424  }
1425 
1427  }
1428 
1429 
1430 
1431  /// changes right-hand side vector to \p rhs
1433  {
1434  assert(_realLP != 0);
1435 
1436  _changeRhsReal(rhs);
1437 
1439  {
1441  for( int i = 0; i < numRowsRational(); i++ )
1443  }
1444 
1446  }
1447 
1448 
1449 
1450  /// changes right-hand side of row \p i to \p rhs
1451  void SoPlex::changeRhsReal(int i, const Real& rhs)
1452  {
1453  assert(_realLP != 0);
1454 
1455  _changeRhsReal(i, rhs);
1456 
1458  {
1459  _rationalLP->changeRhs(i, rhs);
1461  }
1462 
1464  }
1465 
1466 
1467 
1468  /// changes left- and right-hand side vectors
1469  void SoPlex::changeRangeReal(const VectorReal& lhs, const VectorReal& rhs)
1470  {
1471  assert(_realLP != 0);
1472 
1473  _changeRangeReal(lhs, rhs);
1474 
1476  {
1478  for( int i = 0; i < numRowsRational(); i++ )
1479  _rowTypes[i] = _rangeTypeReal(lhs[i], rhs[i]);
1480  }
1481 
1483  }
1484 
1485 
1486 
1487  /// changes left- and right-hand side of row \p i
1488  void SoPlex::changeRangeReal(int i, const Real& lhs, const Real& rhs)
1489  {
1490  assert(_realLP != 0);
1491 
1492  _changeRangeReal(i,lhs, rhs);
1493 
1495  {
1496  _rationalLP->changeRange(i, lhs, rhs);
1497  _rowTypes[i] = _rangeTypeReal(lhs, rhs);
1498  }
1499 
1501  }
1502 
1503 
1504 
1505  /// replaces column \p i with \p lpcol
1506  void SoPlex::changeColReal(int i, const LPColReal& lpcol)
1507  {
1508  assert(_realLP != 0);
1509 
1510  _changeColReal(i, lpcol);
1511 
1513  {
1514  _rationalLP->changeCol(i, lpcol);
1515  _colTypes[i] = _rangeTypeReal(lpcol.lower(), lpcol.upper());
1517  }
1518 
1520  }
1521 
1522 
1523 
1524  /// changes vector of lower bounds to \p lower
1526  {
1527  assert(_realLP != 0);
1528 
1529  _changeLowerReal(lower);
1530 
1532  {
1534  for( int i = 0; i < numColsRational(); i++ )
1536  }
1537 
1538 
1540  }
1541 
1542 
1543 
1544  /// changes lower bound of column i to \p lower
1545  void SoPlex::changeLowerReal(int i, const Real& lower)
1546  {
1547  assert(_realLP != 0);
1548 
1549  _changeLowerReal(i, lower);
1550 
1552  {
1553  _rationalLP->changeLower(i, lower);
1555  }
1556 
1558  }
1559 
1560 
1561 
1562  /// changes vector of upper bounds to \p upper
1564  {
1565  assert(_realLP != 0);
1566 
1567  _changeUpperReal(upper);
1568 
1570  {
1572  for( int i = 0; i < numColsRational(); i++ )
1574  }
1575 
1577  }
1578 
1579 
1580 
1581  /// changes \p i 'th upper bound to \p upper
1582  void SoPlex::changeUpperReal(int i, const Real& upper)
1583  {
1584  assert(_realLP != 0);
1585 
1586  _changeUpperReal(i, upper);
1587 
1589  {
1590  _rationalLP->changeUpper(i, upper);
1592  }
1593 
1595  }
1596 
1597 
1598 
1599  /// changes vectors of column bounds to \p lower and \p upper
1600  void SoPlex::changeBoundsReal(const VectorReal& lower, const VectorReal& upper)
1601  {
1602  assert(_realLP != 0);
1603 
1604  _changeBoundsReal(lower, upper);
1605 
1607  {
1609  for( int i = 0; i < numColsRational(); i++ )
1610  _colTypes[i] = _rangeTypeReal(lower[i], upper[i]);
1611  }
1612 
1614  }
1615 
1616 
1617 
1618  /// changes bounds of column \p i to \p lower and \p upper
1619  void SoPlex::changeBoundsReal(int i, const Real& lower, const Real& upper)
1620  {
1621  assert(_realLP != 0);
1622 
1623  _changeBoundsReal(i, lower, upper);
1624 
1626  {
1627  _rationalLP->changeBounds(i, lower, upper);
1628  _colTypes[i] = _rangeTypeReal(lower, upper);
1629  }
1631  }
1632 
1633 
1634 
1635  /// changes objective function vector to \p obj
1637  {
1638  assert(_realLP != 0);
1639 
1640  bool scale = _realLP->isScaled();
1641  _realLP->changeObj(obj, scale);
1642 
1645 
1647  }
1648 
1649 
1650 
1651  /// changes objective coefficient of column i to \p obj
1652  void SoPlex::changeObjReal(int i, const Real& obj)
1653  {
1654  assert(_realLP != 0);
1655 
1656  bool scale = _realLP->isScaled();
1657  _realLP->changeObj(i, obj, scale);
1658 
1660  _rationalLP->changeObj(i, obj);
1661 
1663  }
1664 
1665 
1666 
1667  /// changes matrix entry in row \p i and column \p j to \p val
1668  void SoPlex::changeElementReal(int i, int j, const Real& val)
1669  {
1670  assert(_realLP != 0);
1671 
1672  _changeElementReal(i, j, val);
1673 
1675  _rationalLP->changeElement(i, j, val);
1676 
1678  }
1679 
1680 
1681 
1682  /// removes row \p i
1684  {
1685  assert(_realLP != 0);
1686 
1687  _removeRowReal(i);
1688 
1690  {
1691  _rationalLP->removeRow(i);
1692  // only swap elements if not the last one was removed
1693  if( i < _rationalLP->nRows() )
1694  {
1696  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
1697  }
1699  }
1700 
1702  }
1703 
1704 
1705 
1706  /// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
1707  /// new index where row \p i has been moved to; note that \p perm must point to an array of size at least
1708  /// #numRowsReal()
1709  void SoPlex::removeRowsReal(int perm[])
1710  {
1711  assert(_realLP != 0);
1712 
1713  const int oldsize = numRowsReal();
1714  _removeRowsReal(perm);
1715 
1717  {
1718  _rationalLP->removeRows(perm);
1719  for( int i = 0; i < oldsize; i++ )
1720  {
1721  if( perm[i] >= 0 )
1722  _rowTypes[perm[i]] = _rowTypes[i];
1723  }
1725  for( int i = 0; i < numRowsRational(); i++ )
1726  {
1727  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
1728  }
1729  }
1730 
1732  }
1733 
1734 
1735 
1736  /// remove all rows with indices in array \p idx of size \p n; an array \p perm of size #numRowsReal() may be passed
1737  /// as buffer memory
1738  void SoPlex::removeRowsReal(int idx[], int n, int perm[])
1739  {
1740  if( perm == 0 )
1741  {
1743  _idxToPerm(idx, n, p.get_ptr(), numRowsReal());
1745  }
1746  else
1747  {
1748  _idxToPerm(idx, n, perm, numRowsReal());
1749  SoPlex::removeRowsReal(perm);
1750  }
1751  }
1752 
1753 
1754 
1755  /// removes rows \p start to \p end including both; an array \p perm of size #numRowsReal() may be passed as buffer
1756  /// memory
1757  void SoPlex::removeRowRangeReal(int start, int end, int perm[])
1758  {
1759  if( perm == 0 )
1760  {
1762  _rangeToPerm(start, end, p.get_ptr(), numRowsReal());
1764  }
1765  else
1766  {
1767  _rangeToPerm(start, end, perm, numRowsReal());
1768  SoPlex::removeRowsReal(perm);
1769  }
1770  }
1771 
1772 
1773 
1774  /// removes column i
1776  {
1777  assert(_realLP != 0);
1778 
1779  _removeColReal(i);
1780 
1782  {
1783  _rationalLP->removeCol(i);
1784  // only swap elements if not the last one was removed
1785  if( i < _rationalLP->nCols() )
1786  {
1789  }
1791  }
1792 
1794  }
1795 
1796 
1797 
1798  /// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
1799  /// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
1800  /// #numColsReal()
1801  void SoPlex::removeColsReal(int perm[])
1802  {
1803  assert(_realLP != 0);
1804 
1805  const int oldsize = numColsReal();
1806  _removeColsReal(perm);
1807 
1809  {
1810  _rationalLP->removeCols(perm);
1811  for( int i = 0; i < oldsize; i++ )
1812  {
1813  if( perm[i] >= 0 )
1814  _colTypes[perm[i]] = _colTypes[i];
1815  }
1817  for( int i = 0; i < numColsRational(); i++ )
1818  {
1820  }
1821  }
1822 
1824  }
1825 
1826 
1827 
1828  /// remove all columns with indices in array \p idx of size \p n; an array \p perm of size #numColsReal() may be
1829  /// passed as buffer memory
1830  void SoPlex::removeColsReal(int idx[], int n, int perm[])
1831  {
1832  if( perm == 0 )
1833  {
1835  _idxToPerm(idx, n, p.get_ptr(), numColsReal());
1837  }
1838  else
1839  {
1840  _idxToPerm(idx, n, perm, numColsReal());
1841  SoPlex::removeColsReal(perm);
1842  }
1843  }
1844 
1845 
1846 
1847  /// removes columns \p start to \p end including both; an array \p perm of size #numColsReal() may be passed as
1848  /// buffer memory
1849  void SoPlex::removeColRangeReal(int start, int end, int perm[])
1850  {
1851  if( perm == 0 )
1852  {
1854  _rangeToPerm(start, end, p.get_ptr(), numColsReal());
1856  }
1857  else
1858  {
1859  _rangeToPerm(start, end, perm, numColsReal());
1860  SoPlex::removeColsReal(perm);
1861  }
1862  }
1863 
1864 
1865 
1866  /// clears the LP
1868  {
1869  assert(_realLP != 0);
1870 
1871  _realLP->clear();
1872  _hasBasis = false;
1874 
1876  {
1877  _rationalLP->clear();
1878  _rowTypes.clear();
1879  _colTypes.clear();
1880  }
1881 
1883  }
1884 
1885 
1886 
1887  /// synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP, if sync mode is manual
1889  {
1890  assert(_isConsistent());
1891 
1893  _syncLPReal();
1894  }
1895 
1896 
1897 
1898  /// adds a single row
1900  {
1901  assert(_rationalLP != 0);
1902 
1904  return;
1905 
1906  _rationalLP->addRow(lprow);
1908 
1910  _addRowReal(lprow);
1911 
1913  }
1914 
1915 
1916 
1917 #ifdef SOPLEX_WITH_GMP
1918  /// adds a single row
1919  void SoPlex::addRowRational(const mpq_t* lhs, const mpq_t* rowValues, const int* rowIndices, const int rowSize, const mpq_t* rhs)
1920  {
1921  assert(_rationalLP != 0);
1922 
1924  return;
1925 
1926  _rationalLP->addRow(lhs, rowValues, rowIndices, rowSize, rhs);
1928 
1929  int i = numRowsRational() - 1;
1932 
1934  }
1935 
1936 
1937 
1938  /// adds a set of rows
1939  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)
1940  {
1941  assert(_rationalLP != 0);
1942 
1944  return;
1945 
1946  _rationalLP->addRows(lhs, rowValues, rowIndices, rowStarts, rowLengths, numRows, numValues, rhs);
1948 
1950  {
1951  LPRowSetReal lprowset;
1952  for( int i = numRowsRational() - numRows; i < numRowsRational(); i++ )
1954  _addRowsReal(lprowset);
1955  }
1956 
1958  }
1959 #endif
1960 
1961 
1962 
1963  /// adds multiple rows
1965  {
1966  assert(_rationalLP != 0);
1967 
1969  return;
1970 
1971  _rationalLP->addRows(lprowset);
1973 
1975  _addRowsReal(lprowset);
1976 
1978  }
1979 
1980 
1981 
1982  /// adds a single column
1984  {
1985  assert(_rationalLP != 0);
1986 
1988  return;
1989 
1990  _rationalLP->addCol(lpcol);
1992 
1994  _addColReal(lpcol);
1995 
1997  }
1998 
1999 
2000 
2001 #ifdef SOPLEX_WITH_GMP
2002  /// adds a single column
2003  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)
2004  {
2005  assert(_rationalLP != 0);
2006 
2008  return;
2009 
2010  _rationalLP->addCol(obj, lower, colValues, colIndices, colSize, upper);
2011  int i = numColsRational() - 1;
2013 
2017 
2019  }
2020 
2021 
2022 
2023  /// adds a set of columns
2024  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)
2025  {
2026  assert(_rationalLP != 0);
2027 
2029  return;
2030 
2031  _rationalLP->addCols(obj, lower, colValues, colIndices, colStarts, colLengths, numCols, numValues, upper);
2033 
2035  {
2036  LPColSetReal lpcolset;
2037  for( int i = numColsRational() - numCols; i < numColsRational(); i++ )
2038  lpcolset.add(Real(maxObjRational(i)) * (intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MAXIMIZE ? 1.0 : -1.0),
2040  _addColsReal(lpcolset);
2041  }
2042 
2044  }
2045 #endif
2046 
2047 
2048 
2049  /// adds multiple columns
2051  {
2052  assert(_rationalLP != 0);
2053 
2055  return;
2056 
2057  _rationalLP->addCols(lpcolset);
2059 
2061  _addColsReal(lpcolset);
2062 
2064  }
2065 
2066 
2067 
2068  /// replaces row \p i with \p lprow
2069  void SoPlex::changeRowRational(int i, const LPRowRational& lprow)
2070  {
2071  assert(_rationalLP != 0);
2072 
2074  return;
2075 
2076  _rationalLP->changeRow(i, lprow);
2077  _rowTypes[i] = _rangeTypeRational(lprow.lhs(), lprow.rhs());
2079 
2081  _changeRowReal(i, lprow);
2082 
2084  }
2085 
2086 
2087 
2088  /// changes left-hand side vector for constraints to \p lhs
2090  {
2091  assert(_rationalLP != 0);
2092 
2094  return;
2095 
2096  _rationalLP->changeLhs(lhs);
2097  for( int i = 0; i < numRowsRational(); i++ )
2098  _rowTypes[i] = _rangeTypeRational(lhs[i], _rationalLP->rhs(i));
2099 
2102 
2104  }
2105 
2106 
2107 
2108  /// changes left-hand side of row \p i to \p lhs
2109  void SoPlex::changeLhsRational(int i, const Rational& lhs)
2110  {
2111  assert(_rationalLP != 0);
2112 
2114  return;
2115 
2116  _rationalLP->changeLhs(i, lhs);
2118 
2120  _changeLhsReal(i, Real(lhs));
2121 
2123  }
2124 
2125 
2126 
2127 #ifdef SOPLEX_WITH_GMP
2128  /// changes left-hand side of row \p i to \p lhs
2129  void SoPlex::changeLhsRational(int i, const mpq_t* lhs)
2130  {
2131  assert(_rationalLP != 0);
2132 
2134  return;
2135 
2136  _rationalLP->changeLhs(i, lhs);
2138 
2141 
2143  }
2144 #endif
2145 
2146 
2147 
2148  /// changes right-hand side vector to \p rhs
2150  {
2151  assert(_rationalLP != 0);
2152 
2154  return;
2155 
2156  _rationalLP->changeRhs(rhs);
2157  for( int i = 0; i < numRowsRational(); i++ )
2158  _rowTypes[i] = _rangeTypeRational(_rationalLP->lhs(i), rhs[i]);
2159 
2162 
2164  }
2165 
2166 
2167 
2168 #ifdef SOPLEX_WITH_GMP
2169  /// changes right-hand side vector to \p rhs
2170  void SoPlex::changeRhsRational(const mpq_t* rhs, int rhsSize)
2171  {
2172  assert(_rationalLP != 0);
2173 
2175  return;
2176 
2177  for( int i = 0; i < rhsSize; i++ )
2178  {
2179  _rationalLP->changeRhs(i, rhs[i]);
2181  }
2182 
2185 
2187  }
2188 #endif
2189 
2190 
2191 
2192  /// changes right-hand side of row \p i to \p rhs
2193  void SoPlex::changeRhsRational(int i, const Rational& rhs)
2194  {
2195  assert(_rationalLP != 0);
2196 
2198  return;
2199 
2200  _rationalLP->changeRhs(i, rhs);
2202 
2204  _changeRhsReal(i, Real(rhs));
2205 
2207  }
2208 
2209 
2210 
2211  /// changes left- and right-hand side vectors
2213  {
2214  assert(_rationalLP != 0);
2215 
2217  return;
2218 
2219  _rationalLP->changeRange(lhs, rhs);
2220  for( int i = 0; i < numRowsRational(); i++ )
2221  _rowTypes[i] = _rangeTypeRational(lhs[i], rhs[i]);
2222 
2225 
2227  }
2228 
2229 
2230 
2231  /// changes left- and right-hand side of row \p i
2232  void SoPlex::changeRangeRational(int i, const Rational& lhs, const Rational& rhs)
2233  {
2234  assert(_rationalLP != 0);
2235 
2237  return;
2238 
2239  _rationalLP->changeRange(i, lhs, rhs);
2240  _rowTypes[i] = _rangeTypeRational(lhs, rhs);
2241 
2243  _changeRangeReal(i, Real(lhs), Real(rhs));
2244 
2246  }
2247 
2248 
2249 
2250 #ifdef SOPLEX_WITH_GMP
2251  /// changes left-hand side of row \p i to \p lhs
2252  void SoPlex::changeRangeRational(int i, const mpq_t* lhs, const mpq_t* rhs)
2253  {
2254  assert(_rationalLP != 0);
2255 
2257  return;
2258 
2259  _rationalLP->changeRange(i, lhs, rhs);
2261 
2264 
2266  }
2267 #endif
2268 
2269 
2270 
2271  /// replaces column \p i with \p lpcol
2272  void SoPlex::changeColRational(int i, const LPColRational& lpcol)
2273  {
2274  assert(_rationalLP != 0);
2275 
2277  return;
2278 
2279  _rationalLP->changeCol(i, lpcol);
2280  _colTypes[i] = _rangeTypeRational(lpcol.lower(), lpcol.upper());
2282 
2284  _changeColReal(i, lpcol);
2285 
2287  }
2288 
2289 
2290 
2291  /// changes vector of lower bounds to \p lower
2293  {
2294  assert(_rationalLP != 0);
2295 
2297  return;
2298 
2299  _rationalLP->changeLower(lower);
2300  for( int i = 0; i < numColsRational(); i++ )
2301  _colTypes[i] = _rangeTypeRational(lower[i], _rationalLP->upper(i));
2302 
2304  _changeLowerReal(DVectorReal(lower));
2305 
2307  }
2308 
2309 
2310 
2311  /// changes lower bound of column i to \p lower
2312  void SoPlex::changeLowerRational(int i, const Rational& lower)
2313  {
2314  assert(_rationalLP != 0);
2315 
2317  return;
2318 
2319  _rationalLP->changeLower(i, lower);
2320  _colTypes[i] = _rangeTypeRational(lower, _rationalLP->upper(i));
2321 
2323  _changeLowerReal(i, Real(lower));
2324 
2326  }
2327 
2328 
2329 
2330 #ifdef SOPLEX_WITH_GMP
2331  /// changes lower bound of column i to \p lower
2332  void SoPlex::changeLowerRational(int i, const mpq_t* lower)
2333  {
2334  assert(_rationalLP != 0);
2335 
2337  return;
2338 
2339  _rationalLP->changeLower(i, lower);
2341 
2344 
2346  }
2347 #endif
2348 
2349 
2350 
2351  /// changes vector of upper bounds to \p upper
2353  {
2354  assert(_rationalLP != 0);
2355 
2357  return;
2358 
2359  _rationalLP->changeUpper(upper);
2360  for( int i = 0; i < numColsRational(); i++ )
2361  _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), upper[i]);
2362 
2364  _changeUpperReal(DVectorReal(upper));
2365 
2367  }
2368 
2369 
2370 
2371  /// changes \p i 'th upper bound to \p upper
2372  void SoPlex::changeUpperRational(int i, const Rational& upper)
2373  {
2374  assert(_rationalLP != 0);
2375 
2377  return;
2378 
2379  _rationalLP->changeUpper(i, upper);
2380  _colTypes[i] = _rangeTypeRational(_rationalLP->lower(i), upper);
2381 
2383  _changeUpperReal(i, Real(upper));
2384 
2386  }
2387 
2388 
2389 
2390 #ifdef SOPLEX_WITH_GMP
2391  /// changes upper bound of column i to \p upper
2392  void SoPlex::changeUpperRational(int i, const mpq_t* upper)
2393  {
2394  assert(_rationalLP != 0);
2395 
2397  return;
2398 
2399  _rationalLP->changeUpper(i, upper);
2401 
2404 
2406  }
2407 #endif
2408 
2409 
2410 
2411  /// changes vectors of column bounds to \p lower and \p upper
2413  {
2414  assert(_rationalLP != 0);
2415 
2417  return;
2418 
2419  _rationalLP->changeBounds(lower, upper);
2420  for( int i = 0; i < numColsRational(); i++ )
2421  _colTypes[i] = _rangeTypeRational(lower[i], upper[i]);
2422 
2424  _changeBoundsReal(DVectorReal(lower), DVectorReal(upper));
2425 
2427  }
2428 
2429 
2430 
2431  /// changes bounds of column \p i to \p lower and \p upper
2432  void SoPlex::changeBoundsRational(int i, const Rational& lower, const Rational& upper)
2433  {
2434  assert(_rationalLP != 0);
2435 
2437  return;
2438 
2439  _rationalLP->changeBounds(i, lower, upper);
2440  _colTypes[i] = _rangeTypeRational(lower, upper);
2441 
2443  _changeBoundsReal(i, Real(lower), Real(upper));
2444 
2446  }
2447 
2448 
2449 
2450 #ifdef SOPLEX_WITH_GMP
2451  /// changes bounds of column \p i to \p lower and \p upper
2452  void SoPlex::changeBoundsRational(int i, const mpq_t* lower, const mpq_t* upper)
2453  {
2454  assert(_rationalLP != 0);
2455 
2457  return;
2458 
2459  _rationalLP->changeBounds(i, lower, upper);
2461 
2464 
2466  }
2467 #endif
2468 
2469 
2470 
2471  /// changes objective function vector to \p obj
2473  {
2474  assert(_rationalLP != 0);
2475 
2477  return;
2478 
2479  _rationalLP->changeObj(obj);
2480 
2482  _realLP->changeObj(DVectorReal(obj));
2483 
2485  }
2486 
2487 
2488 
2489  /// changes objective coefficient of column i to \p obj
2490  void SoPlex::changeObjRational(int i, const Rational& obj)
2491  {
2492  assert(_rationalLP != 0);
2493 
2495  return;
2496 
2497  _rationalLP->changeObj(i, obj);
2498 
2500  _realLP->changeObj(i, Real(obj));
2501 
2503  }
2504 
2505 
2506 
2507 #ifdef SOPLEX_WITH_GMP
2508  /// changes objective coefficient of column i to \p obj
2509  void SoPlex::changeObjRational(int i, const mpq_t* obj)
2510  {
2511  assert(_rationalLP != 0);
2512 
2514  return;
2515 
2516  _rationalLP->changeObj(i, obj);
2517 
2519  _realLP->changeObj(i, Real(objRational(i)));
2520 
2522  }
2523 #endif
2524 
2525 
2526 
2527  /// changes matrix entry in row \p i and column \p j to \p val
2528  void SoPlex::changeElementRational(int i, int j, const Rational& val)
2529  {
2530  assert(_rationalLP != 0);
2531 
2533  return;
2534 
2535  _rationalLP->changeElement(i, j, val);
2536 
2538  _changeElementReal(i, j, Real(val));
2539 
2541  }
2542 
2543 
2544 #ifdef SOPLEX_WITH_GMP
2545  /// changes matrix entry in row \p i and column \p j to \p val
2546  void SoPlex::changeElementRational(int i, int j, const mpq_t* val)
2547  {
2548  assert(_rationalLP != 0);
2549 
2551  return;
2552 
2553  _rationalLP->changeElement(i, j, val);
2554 
2556  _changeElementReal(i, j, mpq_get_d(*val));
2557 
2559  }
2560 #endif
2561 
2562 
2563  /// removes row \p i
2565  {
2566  assert(_rationalLP != 0);
2567 
2569  return;
2570 
2571  _rationalLP->removeRow(i);
2572  // only swap elements if not the last one was removed
2573  if( i < _rationalLP->nRows() )
2574  {
2576  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
2577  }
2579 
2581  _removeRowReal(i);
2582 
2584  }
2585 
2586 
2587 
2588  /// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the new
2589  /// index where row \p i has been moved to; note that \p perm must point to an array of size at least
2590  /// #numRowsRational()
2592  {
2593  assert(_rationalLP != 0);
2594 
2596  return;
2597 
2598  const int oldsize = numRowsRational();
2599  _rationalLP->removeRows(perm);
2600  for( int i = 0; i < oldsize; i++ )
2601  {
2602  if( perm[i] >= 0 )
2603  _rowTypes[perm[i]] = _rowTypes[i];
2604  }
2606  for( int i = 0; i < numRowsRational(); i++ )
2607  {
2608  assert(_rowTypes[i] == _rangeTypeRational(lhsRational(i), rhsRational(i)));
2609  }
2610 
2611 
2613  _removeRowsReal(perm);
2614 
2616  }
2617 
2618 
2619 
2620  /// remove all rows with indices in array \p idx of size \p n; an array \p perm of size #numRowsRational() may be
2621  /// passed as buffer memory
2622  void SoPlex::removeRowsRational(int idx[], int n, int perm[])
2623  {
2624  if( perm == 0 )
2625  {
2627  _idxToPerm(idx, n, p.get_ptr(), numRowsRational());
2629  }
2630  else
2631  {
2632  _idxToPerm(idx, n, perm, numRowsRational());
2634  }
2635  }
2636 
2637 
2638 
2639  /// removes rows \p start to \p end including both; an array \p perm of size #numRowsRational() may be passed as
2640  /// buffer memory
2641  void SoPlex::removeRowRangeRational(int start, int end, int perm[])
2642  {
2643  if( perm == 0 )
2644  {
2646  _rangeToPerm(start, end, p.get_ptr(), numRowsRational());
2648  }
2649  else
2650  {
2651  _rangeToPerm(start, end, perm, numRowsRational());
2653  }
2654  }
2655 
2656 
2657 
2658  /// removes column i
2660  {
2661  assert(_rationalLP != 0);
2662 
2664  return;
2665 
2666  _rationalLP->removeCol(i);
2667  // only swap elements if not the last one was removed
2668  if( i < _rationalLP->nCols() )
2669  {
2672  }
2674 
2676  _removeColReal(i);
2677 
2679  }
2680 
2681 
2682 
2683  /// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
2684  /// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
2685  /// #numColsRational()
2687  {
2688  assert(_rationalLP != 0);
2689 
2691  return;
2692 
2693  const int oldsize = numColsRational();
2694  _rationalLP->removeCols(perm);
2695  for( int i = 0; i < oldsize; i++ )
2696  {
2697  if( perm[i] >= 0 )
2698  _colTypes[perm[i]] = _colTypes[i];
2699  }
2701  for( int i = 0; i < numColsRational(); i++ )
2702  {
2704  }
2705 
2707  _removeColsReal(perm);
2708 
2710  }
2711 
2712 
2713 
2714  /// remove all columns with indices in array \p idx of size \p n; an array \p perm of size #numColsRational() may be
2715  /// passed as buffer memory
2716  void SoPlex::removeColsRational(int idx[], int n, int perm[])
2717  {
2718  if( perm == 0 )
2719  {
2721  _idxToPerm(idx, n, p.get_ptr(), numColsRational());
2723  }
2724  else
2725  {
2726  _idxToPerm(idx, n, perm, numColsRational());
2728  }
2729  }
2730 
2731 
2732 
2733  /// removes columns \p start to \p end including both; an array \p perm of size #numColsRational() may be passed as
2734  /// buffer memory
2735  void SoPlex::removeColRangeRational(int start, int end, int perm[])
2736  {
2737  if( perm == 0 )
2738  {
2740  _rangeToPerm(start, end, p.get_ptr(), numColsRational());
2742  }
2743  else
2744  {
2745  _rangeToPerm(start, end, perm, numColsRational());
2747  }
2748  }
2749 
2750 
2751 
2752  /// clears the LP
2754  {
2755  assert(_rationalLP != 0);
2756 
2758  return;
2759 
2760  _rationalLP->clear();
2762  _rowTypes.clear();
2763  _colTypes.clear();
2764 
2766  {
2767  _realLP->clear();
2768  _hasBasis = false;
2769  }
2770 
2772  }
2773 
2774 
2775 
2776  /// synchronizes rational LP with real LP, i.e., copies real LP to rational LP, if sync mode is manual
2778  {
2779  assert(_isConsistent());
2780 
2782  _syncLPRational();
2783  }
2784 
2785 
2786 
2787  /// solves the LP
2789  {
2790  assert(_isConsistent());
2791 
2792  // clear statistics
2794 
2795  // the solution is no longer valid
2797 
2798  // if the decomposition based dual simplex flag is set to true
2800  {
2804  //setBoolParam(SoPlex::PERSISTENTSCALING, false);
2805 
2807 
2809  }
2810  // decide whether to solve the rational LP with iterative refinement or call the standard floating-point solver
2812  && GE(realParam(SoPlex::FEASTOL), 1e-9) && GE(realParam(SoPlex::OPTTOL), 1e-9)) )
2813  {
2814  // ensure that tolerances are reasonable for the floating-point solver
2816  {
2817  MSG_WARNING( spxout, spxout << "Cannot call floating-point solver with feasibility tolerance below "
2818  << _currentSettings->realParam.lower[SoPlex::FPFEASTOL] << " - relaxing tolerance\n");
2820  }
2821  else
2823 
2825  {
2826  MSG_WARNING( spxout, spxout << "Cannot call floating-point solver with optimality tolerance below "
2827  << _currentSettings->realParam.lower[SoPlex::FPOPTTOL] << " - relaxing tolerance\n");
2829  }
2830  else
2832 
2834 
2835  _optimizeReal();
2836 #ifdef SOPLEX_DEBUG // this check will remove scaling of the realLP
2838 #endif
2839  }
2841  {
2842  _syncLPRational();
2844  }
2846  {
2847 #ifdef ENABLE_ADDITIONAL_CHECKS
2848  assert(areLPsInSync(true, true, false));
2849 #else
2850  assert(areLPsInSync(true, false, false));
2851 #endif
2852 
2854 
2855 #ifdef ENABLE_ADDITIONAL_CHECKS
2856  assert(areLPsInSync(true, true, false));
2857 #else
2858  assert(areLPsInSync(true, false, false));
2859 #endif
2860  }
2861  else
2862  {
2863 #ifdef ENABLE_ADDITIONAL_CHECKS
2864  assert(areLPsInSync(true, true, false));
2865 #else
2866  assert(areLPsInSync(true, false, false));
2867 #endif
2868 
2870  }
2871 
2872  MSG_INFO1( spxout, spxout << "\n";
2874  spxout << "\n" );
2875 
2876  return status();
2877  }
2878 
2879 
2880 
2881  /// returns the current solver status
2883  {
2884  return _status;
2885  }
2886 
2887 
2888 
2889  /// is a primal feasible solution available?
2890  bool SoPlex::hasPrimal() const
2891  {
2893  }
2894 
2895 
2896 
2897  /// is a primal unbounded ray available?
2899  {
2901  }
2902 
2903 
2904 
2905  /// is a dual feasible solution available?
2906  bool SoPlex::hasDual() const
2907  {
2909  }
2910 
2911 
2912 
2913  /// is Farkas proof of infeasibility available?
2915  {
2917  }
2918 
2919 
2920 
2921  /// returns the objective value if a primal or dual solution is available
2923  {
2924  assert(OBJSENSE_MAXIMIZE == 1);
2925  assert(OBJSENSE_MINIMIZE == -1);
2926 
2927  if( status() == SPxSolver::UNBOUNDED )
2929  else if( status() == SPxSolver::INFEASIBLE )
2931  else if( hasPrimal() )
2932  {
2935  }
2936  else if( hasDual() )
2937  {
2940  }
2941  else
2942  return 0.0;
2943  }
2944 
2945 
2946 
2947  /// gets the primal solution vector if available; returns true on success
2949  {
2950  if( hasPrimal() && vector.dim() >= numColsReal() )
2951  {
2953  _solReal.getPrimal(vector);
2954  return true;
2955  }
2956  else
2957  return false;
2958  }
2959 
2960 
2961 
2962  /// gets the vector of slack values if available; returns true on success
2964  {
2965  if( hasPrimal() && vector.dim() >= numRowsReal() )
2966  {
2968  _solReal.getSlacks(vector);
2969  return true;
2970  }
2971  else
2972  return false;
2973  }
2974 
2975 
2976 
2977  /// gets the primal ray if available; returns true on success
2979  {
2980  if( hasPrimalRay() && vector.dim() >= numColsReal() )
2981  {
2983  _solReal.getPrimalRay(vector);
2984  return true;
2985  }
2986  else
2987  return false;
2988  }
2989 
2990 
2991 
2992  /// gets the dual solution vector if available; returns true on success
2994  {
2995  if( hasDual() && vector.dim() >= numRowsReal() )
2996  {
2998  _solReal.getDual(vector);
2999  return true;
3000  }
3001  else
3002  return false;
3003  }
3004 
3005 
3006 
3007  /// gets the vector of reduced cost values if available; returns true on success
3009  {
3010  if( hasDual() && vector.dim() >= numColsReal() )
3011  {
3013  _solReal.getRedCost(vector);
3014  return true;
3015  }
3016  else
3017  return false;
3018  }
3019 
3020 
3021 
3022  /// gets the Farkas proof if available; returns true on success
3024  {
3025  if( hasDualFarkas() && vector.dim() >= numRowsReal() )
3026  {
3028  _solReal.getDualFarkas(vector);
3029  return true;
3030  }
3031  else
3032  return false;
3033  }
3034 
3035 
3036 
3037  /// gets violation of bounds; returns true on success
3038  bool SoPlex::getBoundViolationReal(Real& maxviol, Real& sumviol)
3039  {
3040  if( !hasPrimal() )
3041  return false;
3042 
3044  VectorReal& primal = _solReal._primal;
3045  assert(primal.dim() == numColsReal());
3046 
3047  maxviol = 0.0;
3048  sumviol = 0.0;
3049 
3050  for( int i = numColsReal() - 1; i >= 0; i-- )
3051  {
3052  Real lower = _realLP->lowerUnscaled(i);
3053  Real upper = _realLP->upperUnscaled(i);
3054  Real viol = lower - primal[i];
3055  if( viol > 0.0 )
3056  {
3057  sumviol += viol;
3058  if( viol > maxviol )
3059  maxviol = viol;
3060  }
3061 
3062  viol = primal[i] - upper;
3063  if( viol > 0.0 )
3064  {
3065  sumviol += viol;
3066  if( viol > maxviol )
3067  maxviol = viol;
3068  }
3069  }
3070 
3071  return true;
3072  }
3073 
3074 
3075 
3076  /// gets violation of constraints; returns true on success
3077  bool SoPlex::getRowViolationReal(Real& maxviol, Real& sumviol)
3078  {
3079  if( !hasPrimal() )
3080  return false;
3081 
3083  VectorReal& primal = _solReal._primal;
3084  assert(primal.dim() == numColsReal());
3085 
3086  DVectorReal activity(numRowsReal());
3087  _realLP->computePrimalActivity(primal, activity, true);
3088  maxviol = 0.0;
3089  sumviol = 0.0;
3090 
3091  for( int i = numRowsReal() - 1; i >= 0; i-- )
3092  {
3093  Real lhs = _realLP->lhsUnscaled(i);
3094  Real rhs = _realLP->rhsUnscaled(i);
3095 
3096  Real viol = lhs - activity[i];
3097  if( viol > 0.0 )
3098  {
3099  sumviol += viol;
3100  if( viol > maxviol )
3101  maxviol = viol;
3102  }
3103 
3104  viol = activity[i] - rhs;
3105  if( viol > 0.0 )
3106  {
3107  sumviol += viol;
3108  if( viol > maxviol )
3109  maxviol = viol;
3110  }
3111  }
3112 
3113  return true;
3114  }
3115 
3116 
3117 
3118  /// gets violation of reduced costs; returns true on success
3119  bool SoPlex::getRedCostViolationReal(Real& maxviol, Real& sumviol)
3120  {
3121  if( !hasDual() || !hasBasis() )
3122  return false;
3123 
3125  VectorReal& redcost = _solReal._redCost;
3126  assert(redcost.dim() == numColsReal());
3127 
3128  maxviol = 0.0;
3129  sumviol = 0.0;
3130 
3131  for( int c = numColsReal() - 1; c >= 0; c-- )
3132  {
3133  SPxSolver::VarStatus colStatus = basisColStatus(c);
3134 
3136  {
3137  if( colStatus != SPxSolver::ON_UPPER && colStatus != SPxSolver::FIXED && redcost[c] < 0.0 )
3138  {
3139  sumviol += -redcost[c];
3140  if( redcost[c] < -maxviol )
3141  maxviol = -redcost[c];
3142  }
3143  if( colStatus != SPxSolver::ON_LOWER && colStatus != SPxSolver::FIXED && redcost[c] > 0.0 )
3144  {
3145  sumviol += redcost[c];
3146  if( redcost[c] > maxviol )
3147  maxviol = redcost[c];
3148  }
3149  }
3150  else
3151  {
3152  if( colStatus != SPxSolver::ON_UPPER && colStatus != SPxSolver::FIXED && redcost[c] > 0.0 )
3153  {
3154  sumviol += redcost[c];
3155  if( redcost[c] > maxviol )
3156  maxviol = redcost[c];
3157  }
3158  if( colStatus != SPxSolver::ON_LOWER && colStatus != SPxSolver::FIXED && redcost[c] < 0.0 )
3159  {
3160  sumviol += -redcost[c];
3161  if( redcost[c] < -maxviol )
3162  maxviol = -redcost[c];
3163  }
3164  }
3165  }
3166 
3167  return true;
3168  }
3169 
3170 
3171 
3172  /// gets violation of dual multipliers; returns true on success
3173  bool SoPlex::getDualViolationReal(Real& maxviol, Real& sumviol)
3174  {
3175  if( !hasDual() || !hasBasis() )
3176  return false;
3177 
3179  VectorReal& dual = _solReal._dual;
3180  assert(dual.dim() == numRowsReal());
3181 
3182  maxviol = 0.0;
3183  sumviol = 0.0;
3184 
3185  for( int r = numRowsReal() - 1; r >= 0; r-- )
3186  {
3187  SPxSolver::VarStatus rowStatus = basisRowStatus(r);
3188 
3190  {
3191  if( rowStatus != SPxSolver::ON_UPPER && rowStatus != SPxSolver::FIXED && dual[r] < 0.0 )
3192  {
3193  sumviol += -dual[r];
3194  if( dual[r] < -maxviol )
3195  maxviol = -dual[r];
3196  }
3197  if( rowStatus != SPxSolver::ON_LOWER && rowStatus != SPxSolver::FIXED && dual[r] > 0.0 )
3198  {
3199  sumviol += dual[r];
3200  if( dual[r] > maxviol )
3201  maxviol = dual[r];
3202  }
3203  }
3204  else
3205  {
3206  if( rowStatus != SPxSolver::ON_UPPER && rowStatus != SPxSolver::FIXED && dual[r] > 0.0 )
3207  {
3208  sumviol += dual[r];
3209  if( dual[r] > maxviol )
3210  maxviol = dual[r];
3211  }
3212  if( rowStatus != SPxSolver::ON_LOWER && rowStatus != SPxSolver::FIXED && dual[r] < 0.0 )
3213  {
3214  sumviol += -dual[r];
3215  if( dual[r] < -maxviol )
3216  maxviol = -dual[r];
3217  }
3218  }
3219  }
3220 
3221  return true;
3222  }
3223 
3224 
3225 
3226  /// returns the objective value if a primal or dual solution is available
3228  {
3229  assert(OBJSENSE_MAXIMIZE == 1);
3230  assert(OBJSENSE_MINIMIZE == -1);
3231 
3232  if( status() == SPxSolver::UNBOUNDED )
3233  {
3235  return _rationalPosInfty;
3236  else
3237  return _rationalNegInfty;
3238  }
3239  else if( status() == SPxSolver::INFEASIBLE )
3240  {
3242  return _rationalNegInfty;
3243  else
3244  return _rationalPosInfty;
3245  }
3246  else if( hasPrimal() )
3247  {
3249  return _solRational._primalObjVal;
3250  }
3251  else if( hasDual() )
3252  {
3254  return _solRational._dualObjVal;
3255  }
3256  else
3257  return _rationalZero;
3258  }
3259 
3260 
3261 
3262  /// gets the primal solution vector if available; returns true on success
3264  {
3265  if( _rationalLP != 0 && hasPrimal() && vector.dim() >= numColsRational() )
3266  {
3268  _solRational.getPrimal(vector);
3269  return true;
3270  }
3271  else
3272  return false;
3273  }
3274 
3275 
3276 
3277  /// gets the vector of slack values if available; returns true on success
3279  {
3280  if( _rationalLP != 0 && hasPrimal() && vector.dim() >= numRowsRational() )
3281  {
3283  _solRational.getSlacks(vector);
3284  return true;
3285  }
3286  else
3287  return false;
3288  }
3289 
3290 
3291 
3292  /// gets the primal ray if LP is unbounded; returns true on success
3294  {
3295  if( _rationalLP != 0 && hasPrimalRay() && vector.dim() >= numColsRational() )
3296  {
3298  _solRational.getPrimalRay(vector);
3299  return true;
3300  }
3301  else
3302  return false;
3303  }
3304 
3305 
3306 
3307  /// gets the dual solution vector if available; returns true on success
3309  {
3310  if( _rationalLP != 0 && hasDual() && vector.dim() >= numRowsRational() )
3311  {
3313  _solRational.getDual(vector);
3314  return true;
3315  }
3316  else
3317  return false;
3318  }
3319 
3320 
3321 
3322  /// gets the vector of reduced cost values if available; returns true on success
3324  {
3325  if( _rationalLP != 0 && hasDual() && vector.dim() >= numColsRational() )
3326  {
3328  _solRational.getRedCost(vector);
3329  return true;
3330  }
3331  else
3332  return false;
3333  }
3334 
3335 
3336 
3337  /// gets the Farkas proof if LP is infeasible; returns true on success
3339  {
3340  if( _rationalLP != 0 && hasDualFarkas() && vector.dim() >= numRowsRational() )
3341  {
3343  _solRational.getDualFarkas(vector);
3344  return true;
3345  }
3346  else
3347  return false;
3348  }
3349 
3350 
3351 
3352  /// gets violation of bounds; returns true on success
3354  {
3355  if( !hasPrimal() )
3356  return false;
3357 
3358  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3360  _syncLPRational(false);
3361 
3364  assert(primal.dim() == numColsRational());
3365 
3366  maxviol = 0;
3367  sumviol = 0;
3368 
3369  for( int i = numColsRational() - 1; i >= 0; i-- )
3370  {
3371  Rational viol = lowerRational(i) - primal[i];
3372  if( viol > 0 )
3373  {
3374  sumviol += viol;
3375  if( viol > maxviol )
3376  {
3377  maxviol = viol;
3378  MSG_DEBUG( std::cout << "increased bound violation for column " << i << ": " << rationalToString(viol)
3379  << " lower: " << rationalToString(lowerRational(i))
3380  << ", primal: " << rationalToString(primal[i]) << "\n" );
3381  }
3382  }
3383 
3384  viol = primal[i] - upperRational(i);
3385  if( viol > 0 )
3386  {
3387  sumviol += viol;
3388  if( viol > maxviol )
3389  {
3390  maxviol = viol;
3391  MSG_DEBUG( std::cout << "increased bound violation for column " << i << ": " << rationalToString(viol)
3392  << " upper: " << rationalToString(upperRational(i))
3393  << ", primal: " << rationalToString(primal[i]) << "\n" );
3394  }
3395  }
3396  }
3397 
3398  return true;
3399  }
3400 
3401 
3402 
3403  /// gets violation of constraints; returns true on success
3405  {
3406  if( !hasPrimal() )
3407  return false;
3408 
3409  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3411  _syncLPRational(false);
3412 
3415  assert(primal.dim() == numColsRational());
3416 
3417  DVectorRational activity(numRowsRational());
3418  _rationalLP->computePrimalActivity(primal, activity);
3419  maxviol = 0;
3420  sumviol = 0;
3421 
3422  for( int i = numRowsRational() - 1; i >= 0; i-- )
3423  {
3424  Rational viol = lhsRational(i) - activity[i];
3425  if( viol > 0 )
3426  {
3427  sumviol += viol;
3428  if( viol > maxviol )
3429  {
3430  maxviol = viol;
3431  MSG_DEBUG( std::cout << "increased constraint violation for row " << i << ": " << rationalToString(viol)
3432  << " lhs: " << rationalToString(lhsRational(i))
3433  << ", activity: " << rationalToString(activity[i]) << "\n" );
3434  }
3435  }
3436 
3437  viol = activity[i] - rhsRational(i);
3438  if( viol > 0 )
3439  {
3440  sumviol += viol;
3441  if( viol > maxviol )
3442  {
3443  maxviol = viol;
3444  MSG_DEBUG( std::cout << "increased constraint violation for row " << i << ": " << rationalToString(viol)
3445  << " rhs: " << rationalToString(rhsRational(i))
3446  << ", activity: " << rationalToString(activity[i]) << "\n" );
3447  }
3448  }
3449  }
3450 
3451  return true;
3452  }
3453 
3454 
3455 
3456  /// gets violation of reduced costs; returns true on success
3458  {
3459  if( !hasDual() || !hasPrimal() )
3460  return false;
3461 
3462  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3464  _syncLPRational(false);
3465 
3468  assert(redcost.dim() == numColsRational());
3469 
3470  maxviol = 0;
3471  sumviol = 0;
3472 
3473  for( int c = numColsReal() - 1; c >= 0; c-- )
3474  {
3475  assert(!_hasBasis || basisColStatus(c) != SPxSolver::UNDEFINED);
3476 
3477  if( _colTypes[c] == RANGETYPE_FIXED )
3478  {
3479  assert(lowerRational(c) == upperRational(c));
3480  continue;
3481  }
3482 
3487 
3489  {
3490  if( _solRational._primal[c] != upperRational(c) && redcost[c] < 0 )
3491  {
3492  sumviol += -redcost[c];
3493  if( redcost[c] < -maxviol )
3494  {
3495  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on upper bound: " << rationalToString(-redcost[c]) << "\n" );
3496  maxviol = -redcost[c];
3497  }
3498  }
3499  if( _solRational._primal[c] != lowerRational(c) && redcost[c] > 0 )
3500  {
3501  sumviol += redcost[c];
3502  if( redcost[c] > maxviol )
3503  {
3504  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on lower bound: " << rationalToString(redcost[c]) << "\n" );
3505  maxviol = redcost[c];
3506  }
3507  }
3508  }
3509  else
3510  {
3511  if( _solRational._primal[c] != upperRational(c) && redcost[c] > 0 )
3512  {
3513  sumviol += redcost[c];
3514  if( redcost[c] > maxviol )
3515  {
3516  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on upper bound: " << rationalToString(redcost[c]) << "\n" );
3517  maxviol = redcost[c];
3518  }
3519  }
3520  if( _solRational._primal[c] != lowerRational(c) && redcost[c] < 0 )
3521  {
3522  sumviol += -redcost[c];
3523  if( redcost[c] < -maxviol )
3524  {
3525  MSG_DEBUG( std::cout << "increased reduced cost violation for column " << c << " not on lower bound: " << rationalToString(-redcost[c]) << "\n" );
3526  maxviol = -redcost[c];
3527  }
3528  }
3529  }
3530  }
3531 
3532  return true;
3533  }
3534 
3535 
3536 
3537  /// gets violation of dual multipliers; returns true on success
3539  {
3540  if( !hasDual() || !hasPrimal() )
3541  return false;
3542 
3543  // if we have to synchronize, we do not measure time, because this would affect the solving statistics
3545  _syncLPRational(false);
3546 
3549  assert(dual.dim() == numRowsRational());
3550 
3551  maxviol = 0;
3552  sumviol = 0;
3553 
3554  for( int r = numRowsReal() - 1; r >= 0; r-- )
3555  {
3556  assert(!_hasBasis || basisRowStatus(r) != SPxSolver::UNDEFINED);
3557 
3558  if( _rowTypes[r] == RANGETYPE_FIXED )
3559  {
3560  assert(lhsRational(r) == rhsRational(r));
3561  continue;
3562  }
3563 
3568 
3570  {
3571  if( _solRational._slacks[r] < rhsRational(r) - _rationalFeastol && dual[r] < 0 )
3572  {
3573  sumviol += -dual[r];
3574  if( dual[r] < -maxviol )
3575  {
3576  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on upper bound: " << rationalToString(-dual[r])
3577  << " (slack = " << rationalToString(_solRational._slacks[r])
3578  << ", status = " << basisRowStatus(r)
3579  << ", lhs = " << rationalToString(lhsRational(r))
3580  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3581  maxviol = -dual[r];
3582  }
3583  }
3584  if( _solRational._slacks[r] > lhsRational(r) + _rationalFeastol && dual[r] > 0 )
3585  {
3586  sumviol += dual[r];
3587  if( dual[r] > maxviol )
3588  {
3589  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on lower bound: " << rationalToString(dual[r])
3590  << " (slack = " << rationalToString(_solRational._slacks[r])
3591  << ", status = " << basisRowStatus(r)
3592  << ", lhs = " << rationalToString(lhsRational(r))
3593  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3594  maxviol = dual[r];
3595  }
3596  }
3597  }
3598  else
3599  {
3600  if( _solRational._slacks[r] < rhsRational(r) - _rationalFeastol && dual[r] > 0 )
3601  {
3602  sumviol += dual[r];
3603  if( dual[r] > maxviol )
3604  {
3605  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on upper bound: " << rationalToString(dual[r])
3606  << " (slack = " << rationalToString(_solRational._slacks[r])
3607  << ", status = " << basisRowStatus(r)
3608  << ", lhs = " << rationalToString(lhsRational(r))
3609  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3610  maxviol = dual[r];
3611  }
3612  }
3613  if( _solRational._slacks[r] > lhsRational(r) + _rationalFeastol && dual[r] < 0 )
3614  {
3615  sumviol += -dual[r];
3616  if( dual[r] < -maxviol )
3617  {
3618  MSG_DEBUG( std::cout << "increased dual violation for row " << r << " not on lower bound: " << rationalToString(-dual[r])
3619  << " (slack = " << rationalToString(_solRational._slacks[r])
3620  << ", status = " << basisRowStatus(r)
3621  << ", lhs = " << rationalToString(lhsRational(r))
3622  << ", rhs = " << rationalToString(rhsRational(r)) << ")\n" );
3623  maxviol = -dual[r];
3624  }
3625  }
3626  }
3627  }
3628 
3629  return true;
3630  }
3631 
3632 
3633 
3634 #ifdef SOPLEX_WITH_GMP
3635  /// gets the primal solution vector if available; returns true on success
3636  bool SoPlex::getPrimalRational(mpq_t* vector, const int size)
3637  {
3638  assert(size >= numColsRational());
3639 
3640  if( hasPrimal() )
3641  {
3643  for( int i = 0; i < numColsRational(); i++ )
3644  mpq_set(vector[i], _solRational._primal[i].getMpqRef());
3645  return true;
3646  }
3647  else
3648  return false;
3649  }
3650 
3651 
3652  /// gets the vector of slack values if available; returns true on success
3653  bool SoPlex::getSlacksRational(mpq_t* vector, const int size)
3654  {
3655  assert(size >= numRowsRational());
3656 
3657  if( hasPrimal() )
3658  {
3660  for( int i = 0; i < numRowsRational(); i++ )
3661  mpq_set(vector[i], _solRational._slacks[i].getMpqRef());
3662  return true;
3663  }
3664  else
3665  return false;
3666  }
3667 
3668 
3669 
3670  /// gets the primal ray if LP is unbounded; returns true on success
3671  bool SoPlex::getPrimalRayRational(mpq_t* vector, const int size)
3672  {
3673  assert(size >= numColsRational());
3674 
3675  if( hasPrimalRay() )
3676  {
3678  for( int i = 0; i < numColsRational(); i++ )
3679  mpq_set(vector[i], _solRational._primalRay[i].getMpqRef());
3680  return true;
3681  }
3682  else
3683  return false;
3684  }
3685 
3686 
3687 
3688  /// gets the dual solution vector if available; returns true on success
3689  bool SoPlex::getDualRational(mpq_t* vector, const int size)
3690  {
3691  assert(size >= numRowsRational());
3692 
3693  if( hasDual() )
3694  {
3696  for( int i = 0; i < numRowsRational(); i++ )
3697  mpq_set(vector[i], _solRational._dual[i].getMpqRef());
3698  return true;
3699  }
3700  else
3701  return false;
3702  }
3703 
3704 
3705 
3706  /// gets the vector of reduced cost values if available; returns true on success
3707  bool SoPlex::getRedCostRational(mpq_t* vector, const int size)
3708  {
3709  assert(size >= numColsRational());
3710 
3711  if( hasDual() )
3712  {
3714  for( int i = 0; i < numColsRational(); i++ )
3715  mpq_set(vector[i], _solRational._redCost[i].getMpqRef());
3716  return true;
3717  }
3718  else
3719  return false;
3720  }
3721 
3722 
3723 
3724  /// gets the Farkas proof if LP is infeasible; returns true on success
3725  bool SoPlex::getDualFarkasRational(mpq_t* vector, const int size)
3726  {
3727  assert(size >= numRowsRational());
3728 
3729  if( hasDualFarkas() )
3730  {
3732  for( int i = 0; i < numRowsRational(); i++ )
3733  mpq_set(vector[i], _solRational._dualFarkas[i].getMpqRef());
3734  return true;
3735  }
3736  else
3737  return false;
3738  }
3739 #endif
3740 
3741 
3742 
3743  /// get size of primal solution
3745  {
3746  if( hasPrimal() || hasPrimalRay() )
3747  {
3749  return _solRational.totalSizePrimal(base);
3750  }
3751  else
3752  return 0;
3753  }
3754 
3755 
3756 
3757  /// get size of dual solution
3758  int SoPlex::totalSizeDualRational(const int base)
3759  {
3760  if( hasDual() || hasDualFarkas() )
3761  {
3763  return _solRational.totalSizeDual(base);
3764  }
3765  else
3766  return 0;
3767  }
3768 
3769 
3770 
3771  /// get size of least common multiple of denominators in primal solution
3773  {
3774  if( hasPrimal() || hasPrimalRay() )
3775  {
3777  return _solRational.dlcmSizePrimal(base);
3778  }
3779  else
3780  return 0;
3781  }
3782 
3783 
3784 
3785  /// get size of least common multiple of denominators in dual solution
3786  int SoPlex::dlcmSizeDualRational(const int base)
3787  {
3788  if( hasDual() || hasDualFarkas() )
3789  {
3791  return _solRational.dlcmSizeDual(base);
3792  }
3793  else
3794  return 0;
3795  }
3796 
3797 
3798 
3799  /// get size of largest denominator in primal solution
3801  {
3802  if( hasPrimal() || hasPrimalRay() )
3803  {
3805  return _solRational.dmaxSizePrimal(base);
3806  }
3807  else
3808  return 0;
3809  }
3810 
3811 
3812 
3813  /// get size of largest denominator in dual solution
3814  int SoPlex::dmaxSizeDualRational(const int base)
3815  {
3816  if( hasDual() || hasDualFarkas() )
3817  {
3819  return _solRational.dmaxSizeDual(base);
3820  }
3821  else
3822  return 0;
3823  }
3824 
3825 
3826 
3827  /// is an advanced starting basis available?
3828  bool SoPlex::hasBasis() const
3829  {
3830  return _hasBasis;
3831  }
3832 
3833 
3834 
3835  /// returns the current basis status
3837  {
3838  if( !hasBasis() )
3839  return SPxBasis::NO_PROBLEM;
3840  else if( status() == SPxSolver::OPTIMAL )
3841  return SPxBasis::OPTIMAL;
3842  else if( status() == SPxSolver::UNBOUNDED )
3843  return SPxBasis::UNBOUNDED;
3844  else if( status() == SPxSolver::INFEASIBLE )
3845  return SPxBasis::INFEASIBLE;
3846  else if( hasPrimal() )
3847  return SPxBasis::PRIMAL;
3848  else if( hasDual() )
3849  return SPxBasis::DUAL;
3850  else
3851  return SPxBasis::REGULAR;
3852  }
3853 
3854 
3855 
3856  /// returns basis status for a single row
3858  {
3859  assert(row >= 0);
3860  assert(row < numRowsReal());
3861 
3862  // if no basis is available, return slack basis; if index is out of range, return basic status as for a newly
3863  // added row
3864  if( !hasBasis() || row < 0 || row >= numRowsReal() )
3865  return SPxSolver::BASIC;
3866  // if the real LP is loaded, ask solver
3867  else if( _isRealLPLoaded )
3868  {
3869  return _solver.getBasisRowStatus(row);
3870  }
3871  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3872  else
3873  {
3874  assert(row < _basisStatusRows.size());
3875  return _basisStatusRows[row];
3876  }
3877  }
3878 
3879 
3880 
3881  /// returns basis status for a single column
3883  {
3884  assert(col >= 0);
3885  assert(col < numColsReal());
3886 
3887  // if index is out of range, return nonbasic status as for a newly added unbounded column
3888  if( col < 0 || col >= numColsReal() )
3889  {
3890  return SPxSolver::ZERO;
3891  }
3892  // if no basis is available, return slack basis
3893  else if( !hasBasis() )
3894  {
3895  if( lowerReal(col) > -realParam(SoPlex::INFTY) )
3896  return SPxSolver::ON_LOWER;
3897  else if( upperReal(col) < realParam(SoPlex::INFTY) )
3898  return SPxSolver::ON_UPPER;
3899  else
3900  return SPxSolver::ZERO;
3901  }
3902  // if the real LP is loaded, ask solver
3903  else if( _isRealLPLoaded )
3904  {
3905  return _solver.getBasisColStatus(col);
3906  }
3907  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3908  else
3909  {
3910  assert(col < _basisStatusCols.size());
3911  return _basisStatusCols[col];
3912  }
3913  }
3914 
3915 
3916 
3917  /// gets current basis
3919  {
3920  // if no basis is available, return slack basis
3921  if( !hasBasis() )
3922  {
3923  for( int i = numRowsReal() - 1; i >= 0; i-- )
3924  rows[i] = SPxSolver::BASIC;
3925 
3926  for( int i = numColsReal() - 1; i >= 0; i-- )
3927  {
3928  if( lowerReal(i) > -realParam(SoPlex::INFTY) )
3929  cols[i] = SPxSolver::ON_LOWER;
3930  else if( upperReal(i) < realParam(SoPlex::INFTY) )
3931  cols[i] = SPxSolver::ON_UPPER;
3932  else
3933  cols[i] = SPxSolver::ZERO;
3934  }
3935  }
3936  // if the real LP is loaded, ask solver
3937  else if( _isRealLPLoaded )
3938  {
3939  (void)_solver.getBasis(rows, cols);
3940  }
3941  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3942  else
3943  {
3944  assert(numRowsReal() == _basisStatusRows.size());
3945  assert(numColsReal() == _basisStatusCols.size());
3946 
3947  for( int i = numRowsReal() - 1; i >= 0; i-- )
3948  rows[i] = _basisStatusRows[i];
3949 
3950  for( int i = numColsReal() - 1; i >= 0; i-- )
3951  cols[i] = _basisStatusCols[i];
3952  }
3953  }
3954 
3955 
3956 
3957  /// returns the indices of the basic columns and rows; basic column n gives value n, basic row m gives value -1-m
3958  void SoPlex::getBasisInd(int* bind) const
3959  {
3960  // if no basis is available, return slack basis
3961  if( !hasBasis() )
3962  {
3963  for( int i = 0; i < numRowsReal(); ++i )
3964  bind[i] = -1 - i;
3965  }
3966  // if the real LP is not loaded, the basis is stored in the basis arrays of this class
3967  else if( !_isRealLPLoaded )
3968  {
3969  int k = 0;
3970 
3971  assert(numRowsReal() == _basisStatusRows.size());
3972  assert(numColsReal() == _basisStatusCols.size());
3973 
3974  for( int i = 0; i < numRowsReal(); ++i )
3975  {
3977  {
3978  bind[k] = -1 - i;
3979  k++;
3980  }
3981  }
3982 
3983  for( int j = 0; j < numColsReal(); ++j )
3984  {
3986  {
3987  bind[k] = j;
3988  k++;
3989  }
3990  }
3991 
3992  assert(k == numRowsReal());
3993  }
3994  // if the real LP is loaded, the basis is stored in the solver and we need to distinguish between column and row
3995  // representation; ask the solver itself which representation it has, since the REPRESENTATION parameter of this
3996  // class might be set to automatic
3997  else if( _solver.rep() == SPxSolver::COLUMN )
3998  {
3999  for( int i = 0; i < numRowsReal(); ++i )
4000  {
4001  SPxId id = _solver.basis().baseId(i);
4002  bind[i] = (id.isSPxColId() ? _solver.number(id) : - 1 - _solver.number(id));
4003  }
4004  }
4005  // for row representation, return the complement of the row basis; for this, we need to loop through all rows and columns
4006  else
4007  {
4008  assert(_solver.rep() == SPxSolver::ROW);
4009 
4010  int k = 0;
4011 
4012  for( int i = 0; i < numRowsReal(); ++i )
4013  {
4014  if( !_solver.isRowBasic(i) )
4015  {
4016  bind[k] = -1 - i;
4017  k++;
4018  }
4019  }
4020 
4021  for( int j = 0; j < numColsReal(); ++j )
4022  {
4023  if( !_solver.isColBasic(j) )
4024  {
4025  bind[k] = j;
4026  k++;
4027  }
4028  }
4029 
4030  assert(k == numRowsReal());
4031  }
4032  }
4033 
4034 
4035 
4036  /// computes an estimated condition number for the current basis matrix using the power method; returns true on success
4038  {
4040  if( !_isRealLPLoaded )
4041  return false;
4042 
4044  return false;
4045 
4046  condition = _solver.basis().getEstimatedCondition();
4047 
4048  return true;
4049  }
4050 
4051  /// computes the exact condition number for the current basis matrix using the power method; returns true on success
4053  {
4055  if( !_isRealLPLoaded )
4056  return false;
4057 
4059  return false;
4060 
4061  condition = _solver.basis().getExactCondition();
4062 
4063  return true;
4064  }
4065 
4066  /// computes row r of basis inverse; returns true on success
4067  bool SoPlex::getBasisInverseRowReal(int r, Real* coef, int* inds, int* ninds, bool unscale)
4068  {
4069  assert(r >= 0);
4070  assert(r < numRowsReal());
4071  assert(coef != 0);
4072 
4073  if( !hasBasis() || r < 0 || r >= numRowsReal() )
4074  return false;
4075 
4077 
4078  if( !_isRealLPLoaded )
4079  return false;
4080 
4081  // we need to distinguish between column and row representation; ask the solver itself which representation it
4082  // has, since the REPRESENTATION parameter of this class might be set to automatic
4083  if( _solver.rep() == SPxSolver::COLUMN )
4084  {
4085  int idx;
4087  try
4088  {
4089  /* unscaling required? */
4090  if( unscale && _solver.isScaled())
4091  {
4092  /* for information on the unscaling procedure see spxscaler.h */
4093 
4094  int scaleExp;
4095  DSVector rhs(_solver.unitVector(r));
4096 
4097  if( _solver.basis().baseId(r).isSPxColId() )
4099  else
4100  scaleExp = - _scaler->getRowScaleExp(_solver.number(_solver.basis().baseId(r)));
4101 
4102  rhs *= spxLdexp(1.0, scaleExp);
4103 
4104  _solver.basis().coSolve(x, rhs);
4105  x.setup();
4106  int size = x.size();
4107 
4108  for( int i = 0; i < size; i++ )
4109  {
4110  scaleExp = _scaler->getRowScaleExp(x.index(i));
4111  x.scaleValue(x.index(i), scaleExp);
4112  }
4113  }
4114  else
4115  {
4117  }
4118  }
4119  catch( const SPxException& E )
4120  {
4121  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4122  return false;
4123  }
4124  // copy sparse data to dense result vector based on coef array
4125  if( ninds != 0 && inds != 0 )
4126  {
4127  // during solving SoPlex may have destroyed the sparsity structure so we need to restore it
4128  x.setup();
4129  *ninds = x.size();
4130  for( int i = 0; i < *ninds; ++i )
4131  {
4132  idx = x.index(i);
4133  coef[idx] = x[idx];
4134  // set sparsity pattern of coef array
4135  inds[i] = idx;
4136  }
4137  }
4138  else
4139  {
4140  VectorReal y(numRowsReal(), coef);
4141  y = x;
4142  if( ninds != NULL )
4143  *ninds = -1;
4144  }
4145  }
4146  else
4147  {
4148  assert(_solver.rep() == SPxSolver::ROW);
4149 
4150  // @todo should rhs be a reference?
4151  DSVector rhs(numColsReal());
4152  SSVector y(numColsReal());
4153  int* bind = 0;
4154  int index;
4155 
4156  // get ordering of column basis matrix
4157  spx_alloc(bind, numRowsReal());
4158  getBasisInd(bind);
4159 
4160  // get vector corresponding to requested index r
4161  index = bind[r];
4162 
4163  // r corresponds to a row vector
4164  if( index < 0 )
4165  {
4166  // transform index to actual row index
4167  index = -index - 1;
4168 
4169  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4170  assert(index >= 0);
4171  assert(index < numRowsReal());
4172  assert(!_solver.isRowBasic(index));
4173 
4174  // get row vector
4175  rhs = _solver.rowVector(index);
4176  rhs *= -1.0;
4177 
4178  if( unscale && _solver.isScaled() )
4179  {
4180  for( int i = 0; i < rhs.size(); ++i)
4181  rhs.value(i) = spxLdexp(rhs.value(i), -_scaler->getRowScaleExp(index));
4182  }
4183  }
4184  // r corresponds to a column vector
4185  else
4186  {
4187  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4188  assert(index < numColsReal());
4189  assert(!_solver.isColBasic(index));
4190 
4191  // get unit vector
4192  rhs = UnitVectorReal(index);
4193 
4194  if( unscale && _solver.isScaled() )
4195  rhs *= spxLdexp(1.0, _scaler->getColScaleExp(index));
4196  }
4197 
4198  // solve system "y B = rhs", where B is the row basis matrix
4199  try
4200  {
4201  _solver.basis().solve(y, rhs);
4202  }
4203  catch( const SPxException& E )
4204  {
4205  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4206  return false;
4207  }
4208 
4209  // initialize result vector x as zero
4210  memset(coef, 0, (unsigned int)numRowsReal() * sizeof(Real));
4211 
4212  // add nonzero entries
4213  for( int i = 0; i < numColsReal(); ++i )
4214  {
4215  SPxId id = _solver.basis().baseId(i);
4216 
4217  if( id.isSPxRowId() )
4218  {
4219  assert(_solver.number(id) >= 0);
4220  assert(_solver.number(id) < numRowsReal());
4221  assert(bind[r] >= 0 || _solver.number(id) != index);
4222 
4223  int rowindex = _solver.number(id);
4224  coef[rowindex] = y[i];
4225 
4226  if( unscale && _solver.isScaled() )
4227  coef[rowindex] = spxLdexp(y[i], _scaler->getRowScaleExp(rowindex));
4228  }
4229  }
4230 
4231  // if r corresponds to a row vector, we have to add a 1 at position r
4232  if( bind[r] < 0 )
4233  {
4234  assert(coef[index] == 0.0);
4235  coef[index] = 1.0;
4236  }
4237 
4238  // @todo implement returning of sparsity information like in column wise case
4239  if( ninds != NULL)
4240  *ninds = -1;
4241 
4242  // free memory
4243  spx_free(bind);
4244  }
4245 
4246  return true;
4247  }
4248 
4249 
4250 
4251  /// computes column c of basis inverse; returns true on success
4252  /// @todo does not work correctly for the row representation
4253  bool SoPlex::getBasisInverseColReal(int c, Real* coef, int* inds, int* ninds, bool unscale)
4254  {
4255  assert(c >= 0);
4256  assert(c < numRowsReal());
4257  assert(coef != 0);
4258 
4259  if( !hasBasis() || c < 0 || c >= numRowsReal() )
4260  return false;
4261 
4263 
4264  if( !_isRealLPLoaded )
4265  return false;
4266 
4267  // we need to distinguish between column and row representation; ask the solver itself which representation it
4268  // has, since the REPRESENTATION parameter of this class might be set to automatic
4269  if( _solver.rep() == SPxSolver::COLUMN )
4270  {
4271  int idx;
4273  try
4274  {
4275  /* unscaling required? */
4276  if( unscale && _solver.isScaled())
4277  {
4278  /* for information on the unscaling procedure see spxscaler.h */
4279 
4280  int scaleExp =_scaler->getRowScaleExp(c);
4281  DSVector rhs(_solver.unitVector(c));
4282  rhs *= spxLdexp(1.0, scaleExp);
4283 
4284  _solver.basis().solve(x, rhs);
4285 
4286  x.setup();
4287  int size = x.size();
4288 
4289  for( int i = 0; i < size; i++ )
4290  {
4291  if( _solver.basis().baseId(x.index(i)).isSPxColId() )
4292  {
4293  idx = _solver.number(_solver.basis().baseId(x.index(i)));
4294  scaleExp = _scaler->getColScaleExp(idx);
4295  x.scaleValue(x.index(i), scaleExp);
4296  }
4297  else
4298  {
4299  idx = _solver.number(_solver.basis().baseId(x.index(i)));
4300  scaleExp = - _scaler->getRowScaleExp(idx);
4301  x.scaleValue(x.index(i), scaleExp);
4302  }
4303  }
4304  }
4305  else
4306  {
4308  }
4309  }
4310  catch( const SPxException& E )
4311  {
4312  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4313  return false;
4314  }
4315  // copy sparse data to dense result vector based on coef array
4316  if( ninds != 0 && inds != 0 )
4317  {
4318  // SoPlex may have destroyed the sparsity structure so we need to restore it
4319  x.setup();
4320  *ninds = x.size();
4321  for( int i = 0; i < *ninds; ++i )
4322  {
4323  idx = x.index(i);
4324  coef[idx] = x[idx];
4325  // set sparsity pattern of coef array
4326  inds[i] = idx;
4327  }
4328  }
4329  else
4330  {
4331  VectorReal y(numRowsReal(), coef);
4332  y = x;
4333  if( ninds != 0 )
4334  *ninds = -1;
4335  }
4336  }
4337  else
4338  {
4339  assert(_solver.rep() == SPxSolver::ROW);
4340 
4341  // @todo should rhs be a reference?
4342  DSVectorReal rhs(numColsReal());
4344  int* bind = 0;
4345  int index;
4346 
4347  // get ordering of column basis matrix
4348  spx_alloc(bind, numRowsReal());
4349  getBasisInd(bind);
4350 
4351  // get vector corresponding to requested index c
4352  index = bind[c];
4353 
4354  // c corresponds to a row vector
4355  if( index < 0 )
4356  {
4357  // transform index to actual row index
4358  index = -index - 1;
4359 
4360  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4361  assert(index >= 0);
4362  assert(index < numRowsReal());
4363  assert(!_solver.isRowBasic(index));
4364 
4365  // get row vector
4366  rhs = _solver.rowVector(index);
4367  rhs *= -1.0;
4368  }
4369  // c corresponds to a column vector
4370  else
4371  {
4372  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4373  assert(index < numColsReal());
4374  assert(!_solver.isColBasic(index));
4375 
4376  // get unit vector
4377  rhs = UnitVectorReal(index);
4378  }
4379 
4380  // solve system "y B = rhs", where B is the row basis matrix
4381  try
4382  {
4383  /* unscaling required? */
4384  if( unscale && _solver.isScaled() )
4385  {
4386  int size = rhs.size();
4387  int scaleExp;
4388 
4389  for( int i = 0; i < size; i++ )
4390  {
4391  scaleExp = _scaler->getColScaleExp(i);
4392  rhs.value(i) *= spxLdexp(1.0, scaleExp);
4393  }
4394 
4395  _solver.basis().coSolve(y, rhs);
4396 
4397  int rowIdx;
4398  size = y.size();
4399 
4400  for( int i = 0; i < size; i++ )
4401  {
4402  assert(_solver.basis().baseId(y.index(i)).isSPxRowId());
4403  rowIdx = _solver.basis().baseId(y.index(i)).getIdx();
4404  scaleExp = _scaler->getRowScaleExp(rowIdx);
4405  y.setValue(i, y.value(i) * spxLdexp(1.0, scaleExp));
4406  }
4407  }
4408  else
4409  {
4410  _solver.basis().coSolve(y, rhs);
4411  }
4412  }
4413  catch( const SPxException& E )
4414  {
4415  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while computing basis inverse row.\n" );
4416  return false;
4417  }
4418 
4419  // initialize result vector x as zero
4420  memset(coef, 0, (unsigned int)numRowsReal() * sizeof(Real));
4421 
4422  // add nonzero entries
4423  for( int i = 0; i < numColsReal(); ++i )
4424  {
4425  SPxId id = _solver.basis().baseId(i);
4426 
4427  if( id.isSPxRowId() )
4428  {
4429  assert(_solver.number(id) >= 0);
4430  assert(_solver.number(id) < numRowsReal());
4431  assert(bind[c] >= 0 || _solver.number(id) != index);
4432 
4433  coef[_solver.number(id)] = y[i];
4434  }
4435  }
4436 
4437  // if c corresponds to a row vector, we have to add a 1 at position c
4438  if( bind[c] < 0 )
4439  {
4440  assert(coef[index] == 0.0);
4441  coef[index] = 1.0;
4442  }
4443 
4444  // @todo implement returning of sparsity information like in column wise case
4445  if( ninds != NULL)
4446  *ninds = -1;
4447 
4448  // free memory
4449  spx_free(bind);
4450  }
4451 
4452  return true;
4453  }
4454 
4455 
4456 
4457  /// computes dense solution of basis matrix B * sol = rhs; returns true on success
4458  bool SoPlex::getBasisInverseTimesVecReal(Real* rhs, Real* sol, bool unscale)
4459  {
4460  VectorReal v(numRowsReal(), rhs);
4461  VectorReal x(numRowsReal(), sol);
4462 
4463  if( !hasBasis() )
4464  return false;
4465 
4467 
4468  if( !_isRealLPLoaded )
4469  return false;
4470 
4471  // we need to distinguish between column and row representation; ask the solver itself which representation it
4472  // has, since the REPRESENTATION parameter of this class might be set to automatic; in the column case we can use
4473  // the existing factorization
4474  if( _solver.rep() == SPxSolver::COLUMN )
4475  {
4476  // solve system "x = B^-1 * v"
4477  try
4478  {
4479  /* unscaling required? */
4480  if( unscale && _solver.isScaled())
4481  {
4482  /* for information on the unscaling procedure see spxscaler.h */
4483  int scaleExp;
4484  int idx;
4485 
4486  for( int i = 0; i < v.dim(); ++i)
4487  {
4488  if( isNotZero(v[i]) )
4489  {
4490  scaleExp =_scaler->getRowScaleExp(i);
4491  v[i] = spxLdexp(v[i], scaleExp);
4492  }
4493  }
4494 
4495  _solver.basis().solve(x, v);
4496 
4497  for( int i = 0; i < x.dim(); i++ )
4498  {
4499  if( isNotZero(x[i]) )
4500  {
4501  idx = _solver.number(_solver.basis().baseId(i));
4502  if( _solver.basis().baseId(i).isSPxColId() )
4503  scaleExp = _scaler->getColScaleExp(idx);
4504  else
4505  scaleExp = - _scaler->getRowScaleExp(idx);
4506  x[i] = spxLdexp(x[i], scaleExp);
4507  }
4508  }
4509  }
4510  else
4511  {
4512  _solver.basis().solve(x, v);
4513  }
4514  }
4515  catch( const SPxException& E )
4516  {
4517  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while solving with basis matrix.\n" );
4518  return false;
4519  }
4520  }
4521  else
4522  {
4523  assert(_solver.rep() == SPxSolver::ROW);
4524 
4525  DSVectorReal rowrhs(numColsReal());
4527  int* bind = 0;
4528 
4529  bool adaptScaling = unscale && _realLP->isScaled();
4530  int scaleExp;
4531  int idx;
4532 
4533  // get ordering of column basis matrix
4534  spx_alloc(bind, numRowsReal());
4535  getBasisInd(bind);
4536 
4537  // fill right-hand side for row-based system
4538  for( int i = 0; i < numColsReal(); ++i )
4539  {
4540  SPxId id = _solver.basis().baseId(i);
4541 
4542  if( id.isSPxRowId() )
4543  {
4544  assert(_solver.number(id) >= 0);
4545  assert(_solver.number(id) < numRowsReal());
4546 
4547  if( adaptScaling )
4548  {
4549  idx = _solver.number(id);
4550  scaleExp = _scaler->getRowScaleExp(idx);
4551  rowrhs.add(i, spxLdexp(v[idx], scaleExp));
4552  }
4553  else
4554  rowrhs.add(i, v[_solver.number(id)]);
4555  }
4556  else
4557  {
4558  assert(rowrhs[i] == 0.0);
4559  }
4560  }
4561 
4562  // solve system "B y = rowrhs", where B is the row basis matrix
4563  try
4564  {
4565  _solver.basis().coSolve(y, rowrhs);
4566  }
4567  catch( const SPxException& E )
4568  {
4569  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while solving with basis matrix.\n" );
4570  return false;
4571  }
4572 
4573  // fill result w.r.t. order given by bind
4574  for( int i = 0; i < numRowsReal(); ++i )
4575  {
4576  int index;
4577 
4578  index = bind[i];
4579 
4580  if( index < 0 )
4581  {
4582  index = -index-1;
4583 
4584  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4585  assert(index >= 0);
4586  assert(index < numRowsReal());
4587  assert(!_solver.isRowBasic(index));
4588 
4589  x[i] = v[index] - (rowVectorRealInternal(index) * Vector(numColsReal(), y.get_ptr()));
4590 
4591  if( adaptScaling )
4592  {
4593  scaleExp = -_scaler->getRowScaleExp(index);
4594  x[i] = spxLdexp(x[i], scaleExp);
4595  }
4596  }
4597  else
4598  {
4599  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4600  assert(index >= 0);
4601  assert(index < numColsReal());
4602  assert(!_solver.isColBasic(index));
4603 
4604  if( adaptScaling )
4605  {
4606  scaleExp = _scaler->getColScaleExp(index);
4607  x[i] = spxLdexp(y[index], scaleExp);
4608  }
4609  else
4610  x[i] = y[index];
4611  }
4612  }
4613 
4614  // free memory
4615  spx_free(bind);
4616  }
4617  return true;
4618  }
4619 
4620 
4621 
4622  /// multiply with basis matrix; B * vec (inplace)
4623  bool SoPlex::multBasis(Real* vec, bool unscale)
4624  {
4625  if( !hasBasis() )
4626  return false;
4627 
4629 
4630  if( !_isRealLPLoaded )
4631  return false;
4632 
4633  if( _solver.rep() == SPxSolver::COLUMN )
4634  {
4635  int basisdim = numRowsReal();
4636 
4637  // create Vector from input values
4638  Vector x(basisdim, vec);
4639 
4640  if( unscale && _solver.isScaled() )
4641  {
4642  /* for information on the unscaling procedure see spxscaler.h */
4643 
4644  int scaleExp;
4645  for( int i = 0; i < basisdim; ++i)
4646  {
4647  if( isNotZero(vec[i]) )
4648  {
4649  if( _solver.basis().baseId(i).isSPxColId() )
4650  scaleExp = - _scaler->getColScaleExp(_solver.number(_solver.basis().baseId(i)));
4651  else
4653 
4654  vec[i] = spxLdexp(vec[i], scaleExp);
4655  }
4656  }
4657  _solver.basis().multBaseWith(x);
4658  for( int i = 0; i < basisdim; ++i)
4659  {
4660  scaleExp = _scaler->getRowScaleExp(i);
4661  vec[i] = spxLdexp(vec[i], -scaleExp);
4662  }
4663  }
4664  else
4665  _solver.basis().multBaseWith(x);
4666  }
4667  else
4668  {
4669  int colbasisdim = numRowsReal();
4670 
4671  DSVector y(colbasisdim);
4672 
4673  y.clear();
4674 
4675  // create Vector from input values
4676  Vector x(colbasisdim, vec);
4677 
4678  int* bind = 0;
4679  int index;
4680 
4681  // get ordering of column basis matrix
4682  spx_alloc(bind, colbasisdim);
4683  getBasisInd(bind);
4684 
4685  // temporarily create the column basis and multiply every column with x
4686  for( int i = 0; i < colbasisdim; ++i)
4687  {
4688  if( isNotZero(x[i]) )
4689  {
4690  // get vector corresponding to requested index i
4691  index = bind[i];
4692  // r corresponds to a row vector
4693  if( index < 0 )
4694  {
4695  // transform index to actual row index
4696  index = -index - 1;
4697 
4698  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4699  assert(index >= 0);
4700  assert(index < numRowsReal());
4701  assert(!_solver.isRowBasic(index));
4702 
4703  y.add(x[i] * UnitVectorReal(index));
4704  }
4705  // r corresponds to a column vector
4706  else
4707  {
4708  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4709  assert(index < numColsReal());
4710  assert(!_solver.isColBasic(index));
4711 
4712  if( unscale && _solver.isScaled() )
4713  {
4714  DSVector col;
4715  _solver.getColVectorUnscaled(index, col);
4716  y.add(x[i] * col);
4717  }
4718 
4719  y.add(x[i] * _solver.colVector(index));
4720  }
4721  }
4722  }
4723  spx_free(bind);
4724  x = y;
4725  }
4726 
4727  return true;
4728  }
4729 
4730 
4731 
4732  /// multiply with transpose of basis matrix; vec * B^T (inplace)
4733  bool SoPlex::multBasisTranspose(Real* vec, bool unscale)
4734  {
4735  if( !hasBasis() )
4736  return false;
4737 
4739 
4740  if( !_isRealLPLoaded )
4741  return false;
4742 
4743  if( _solver.rep() == SPxSolver::COLUMN )
4744  {
4745  int basisdim = numRowsReal();
4746 
4747  // create Vector from input values
4748  Vector x(basisdim, vec);
4749 
4750  if( unscale && _solver.isScaled() )
4751  {
4752  /* for information on the unscaling procedure see spxscaler.h */
4753 
4754  int scaleExp;
4755  for( int i = 0; i < basisdim; ++i)
4756  {
4757  if( isNotZero(vec[i]) )
4758  {
4759  scaleExp = - _scaler->getRowScaleExp(i);
4760  vec[i] = spxLdexp(vec[i], scaleExp);
4761  }
4762  }
4763  _solver.basis().multWithBase(x);
4764  for( int i = 0; i < basisdim; ++i)
4765  {
4766  if( isNotZero(vec[i]) )
4767  {
4768  if( _solver.basis().baseId(i).isSPxColId() )
4769  scaleExp = - _scaler->getColScaleExp(_solver.number(_solver.basis().baseId(i)));
4770  else
4772 
4773  vec[i] = spxLdexp(vec[i], scaleExp);
4774  }
4775  }
4776  }
4777  else
4778  _solver.basis().multWithBase(x);
4779  }
4780  else
4781  {
4782  int colbasisdim = numRowsReal();
4783 
4784  DSVector y(colbasisdim);
4785 
4786  // create Vector from input values
4787  Vector x(colbasisdim, vec);
4788 
4789  int* bind = 0;
4790  int index;
4791 
4792  // get ordering of column basis matrix
4793  spx_alloc(bind, colbasisdim);
4794  getBasisInd(bind);
4795 
4796  // temporarily create the column basis and multiply every column with x
4797  for( int i = 0; i < colbasisdim; ++i)
4798  {
4799  // get vector corresponding to requested index i
4800  index = bind[i];
4801  // r corresponds to a row vector
4802  if( index < 0 )
4803  {
4804  // transform index to actual row index
4805  index = -index - 1;
4806 
4807  // should be a valid row index and in the column basis matrix, i.e., not basic w.r.t. row representation
4808  assert(index >= 0);
4809  assert(index < numRowsReal());
4810  assert(!_solver.isRowBasic(index));
4811 
4812  y.add(i, x * UnitVectorReal(index));
4813  }
4814  // r corresponds to a column vector
4815  else
4816  {
4817  // should be a valid column index and in the column basis matrix, i.e., not basic w.r.t. row representation
4818  assert(index < numColsReal());
4819  assert(!_solver.isColBasic(index));
4820 
4821  if( unscale && _solver.isScaled() )
4822  {
4823  DSVector col;
4824  _solver.getColVectorUnscaled(index, col);
4825  y.add(i, x * col);
4826  }
4827  else
4828  y.add(i, x * _solver.colVector(index));
4829  }
4830  }
4831  spx_free(bind);
4832  x = y;
4833  }
4834 
4835  return true;
4836  }
4837 
4838 
4839 
4840  /// compute rational basis inverse; returns true on success
4842  {
4843  if( !hasBasis() )
4844  {
4847  return false;
4848  }
4849 
4852  {
4856  }
4857 
4859  return true;
4860 
4861  return false;
4862  }
4863 
4864 
4865 
4866  /// gets an array of indices for the columns of the rational basis matrix; bind[i] >= 0 means that the i-th column of
4867  /// the basis matrix contains variable bind[i]; bind[i] < 0 means that the i-th column of the basis matrix contains
4868  /// the slack variable for row -bind[i]-1; performs rational factorization if not available; returns true on success
4870  {
4873 
4875  return false;
4876 
4877  bind = _rationalLUSolverBind;
4878  assert(bind.size() == numRowsRational());
4879  return true;
4880  }
4881 
4882 
4883 
4884  /// computes row r of basis inverse; performs rational factorization if not available; returns true on success
4886  {
4889 
4891  return false;
4892 
4893  try
4894  {
4895  vec.reDim(numRowsRational());
4897  }
4898  catch( const SPxException& E )
4899  {
4900  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while computing rational basis inverse row.\n" );
4901  return false;
4902  }
4903  return true;
4904  }
4905 
4906 
4907 
4908  /// computes column c of basis inverse; performs rational factorization if not available; returns true on success
4910  {
4913 
4915  return false;
4916 
4917  try
4918  {
4919  vec.reDim(numRowsRational());
4921  }
4922  catch( const SPxException& E )
4923  {
4924  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while computing rational basis inverse column.\n" );
4925  return false;
4926  }
4927  return true;
4928  }
4929 
4930 
4931 
4932  /// computes solution of basis matrix B * sol = rhs; performs rational factorization if not available; returns true
4933  /// on success
4935  {
4938 
4940  return false;
4941 
4942  try
4943  {
4944  sol.reDim(numRowsRational());
4945  _rationalLUSolver.solveRight(sol, rhs);
4946  }
4947  catch( const SPxException& E )
4948  {
4949  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> during right solve with rational basis inverse.\n" );
4950  return false;
4951  }
4952  return true;
4953  }
4954 
4955 
4956 
4957  /// sets starting basis via arrays of statuses
4959  {
4961 
4962  if( _isRealLPLoaded )
4963  {
4964  assert(numRowsReal() == _solver.nRows());
4965  assert(numColsReal() == _solver.nCols());
4966 
4967  _solver.setBasis(rows, cols);
4969  }
4970  else
4971  {
4974 
4975  for( int i = numRowsReal() - 1; i >= 0; i-- )
4976  _basisStatusRows[i] = rows[i];
4977 
4978  for( int j = numColsReal() - 1; j >= 0; j-- )
4979  _basisStatusCols[j] = cols[j];
4980 
4981  _hasBasis = true;
4982  }
4983  }
4984 
4985 
4986 
4987  /// clears starting basis
4989  {
4990  _solver.reLoad();
4991  _status = _solver.status();
4992  _hasBasis = false;
4994  }
4995 
4996 
4997 
4998  /// number of iterations since last call to solve
5000  {
5001  return _statistics->iterations;
5002  }
5003 
5004 
5005 
5006  /// time spent in last call to solve
5008  {
5009  return _statistics->solvingTime->time();
5010  }
5011 
5012 
5013 
5014  /// statistical information in form of a string
5015  std::string SoPlex::statisticString() const
5016  {
5017  std::stringstream s;
5018  s << "Factorizations : " << std::setw(10) << _statistics->luFactorizationsReal << std::endl
5019  << " Time spent : " << std::setw(10) << std::fixed << std::setprecision(2) << _statistics->luFactorizationTimeReal << std::endl
5020  << "Solves : " << std::setw(10) << _statistics->luSolvesReal << std::endl
5021  << " Time spent : " << std::setw(10) << _statistics->luSolveTimeReal << std::endl
5022  << "Solution time : " << std::setw(10) << std::fixed << std::setprecision(2) << solveTime() << std::endl
5023  << "Iterations : " << std::setw(10) << numIterations() << std::endl;
5024 
5025  return s.str();
5026  }
5027 
5028 
5029 
5030  /// name of starter
5032  {
5033  if( _starter )
5034  return _starter->getName();
5035  else
5036  return "none";
5037  }
5038 
5039 
5040 
5041  /// name of simplifier
5043  {
5044  if( _simplifier )
5045  return _simplifier->getName();
5046  else
5047  return "none";
5048  }
5049 
5050 
5051 
5052  /// name of scaling method after simplifier
5054  {
5055  if( _scaler )
5056  return _scaler->getName();
5057  else
5058  return "none";
5059  }
5060 
5061 
5062 
5063  /// name of currently loaded pricer
5065  {
5066  return _solver.pricer()->getName();
5067  }
5068 
5069 
5070 
5071  /// name of currently loaded ratiotester
5073  {
5074  return _solver.ratiotester()->getName();
5075  }
5076 
5077 
5078 
5079  /// reads LP file in LP or MPS format according to READMODE parameter; gets row names, column names, and
5080  /// integer variables if desired; returns true on success
5081  bool SoPlex::readFile(const char* filename, NameSet* rowNames, NameSet* colNames, DIdxSet* intVars)
5082  {
5083  bool success = false;
5085  success = _readFileReal(filename, rowNames, colNames, intVars);
5086  else
5087  success = _readFileRational(filename, rowNames, colNames, intVars);
5088 
5089  // storing the row and column names for use in the DBDS print basis methods
5090  _rowNames = rowNames;
5091  _colNames = colNames;
5092 
5093  return success;
5094  }
5095 
5096  /// writes real LP to file; LP or MPS format is chosen from the extension in \p filename; if \p rowNames and \p
5097  /// colNames are \c NULL, default names are used; if \p intVars is not \c NULL, the variables contained in it are
5098  /// marked as integer; returns true on success
5099  bool SoPlex::writeFileReal(const char* filename, const NameSet* rowNames, const NameSet* colNames, const DIdxSet* intVars, const bool unscale) const
5100  {
5101  ///@todo implement return value
5102 
5103  if( unscale && _realLP->isScaled() )
5104  {
5105  SPxLPReal* origLP;
5106  origLP = 0;
5107  spx_alloc(origLP);
5108  origLP = new (origLP) SPxLPReal(*_realLP);
5109  origLP->unscaleLP();
5110  origLP->writeFile(filename, rowNames, colNames, intVars);
5111  origLP->~SPxLPReal();
5112  spx_free(origLP);
5113  }
5114  else
5115  _realLP->writeFile(filename, rowNames, colNames, intVars);
5116 
5117  return true;
5118  }
5119 
5120 
5121 
5122  /// writes rational LP to file; LP or MPS format is chosen from the extension in \p filename; if \p rowNames and \p
5123  /// colNames are \c NULL, default names are used; if \p intVars is not \c NULL, the variables contained in it are
5124  /// marked as integer; returns true on success
5125  bool SoPlex::writeFileRational(const char* filename, const NameSet* rowNames, const NameSet* colNames, const DIdxSet* intVars) const
5126  {
5128  return false;
5129  else
5130  {
5131  assert(_rationalLP != 0);
5132  _rationalLP->writeFile(filename, rowNames, colNames, intVars);
5133 
5134  ///@todo implement return value
5135  return true;
5136  }
5137  }
5138 
5139 
5140 
5141  /// writes the dual of the real LP to file; LP or MPS format is chosen from the extension in \p filename;
5142  /// if \p rowNames and \p colNames are \c NULL, default names are used; if \p intVars is not \c NULL,
5143  /// the variables contained in it are marked as integer; returns true on success
5144  bool SoPlex::writeDualFileReal(const char* filename, const NameSet* rowNames, const NameSet* colNames, const DIdxSet* intVars) const
5145  {
5146  SPxLPReal dualLP;
5147  _realLP->buildDualProblem(dualLP);
5148  dualLP.setOutstream(spxout);
5149 
5150  dualLP.writeFile(filename);
5151  return true;
5152  }
5153 
5154 
5155 
5156  /// reads basis information from \p filename and returns true on success; if \p rowNames and \p colNames are \c NULL,
5157  /// default names are assumed; returns true on success
5158  bool SoPlex::readBasisFile(const char* filename, const NameSet* rowNames, const NameSet* colNames)
5159  {
5160  clearBasis();
5161 
5162 #if 1
5163  assert(filename != 0);
5164  assert(_realLP != 0);
5165 
5166  // start timing
5168 
5169  // read
5170  if( !_isRealLPLoaded )
5171  {
5172  assert(_realLP != &_solver);
5173 
5175  _realLP->~SPxLPReal();
5176  spx_free(_realLP);
5177  _realLP = &_solver;
5178  _isRealLPLoaded = true;
5179  }
5180  _hasBasis = _solver.readBasisFile(filename, rowNames, colNames);
5181  assert(_hasBasis == (_solver.basis().status() > SPxBasis::NO_PROBLEM));
5182 
5183  // stop timing
5185 
5186  return _hasBasis;
5187 #else
5188  // this is alternative code for reading bases without the SPxSolver class
5189  assert(filename != 0);
5190 
5191  // start timing
5193 
5194  // read
5195  spxifstream file(filename);
5196 
5197  if( !file )
5198  return false;
5199 
5200  // get problem size
5201  int numRows = numRowsReal();
5202  int numCols = numColsReal();
5203 
5204  // prepare column names
5205  const NameSet* colNamesPtr = colNames;
5206  NameSet* tmpColNames = 0;
5207  if( colNames == 0 )
5208  {
5209  std::stringstream name;
5210 
5211  spx_alloc(tmpColNames);
5212  tmpColNames = new (tmpColNames) NameSet();
5213  tmpColNames->reMax(numCols);
5214 
5215  for( int j = 0; j < numCols; ++j )
5216  {
5217  name << "x" << j;
5218  tmpColNames->add(name.str().c_str());
5219  }
5220 
5221  colNamesPtr = tmpColNames;
5222  }
5223 
5224  // prepare row names
5225  const NameSet* rowNamesPtr = rowNames;
5226  NameSet* tmpRowNames = 0;
5227  if( rowNamesPtr == 0 )
5228  {
5229  std::stringstream name;
5230 
5231  spx_alloc(tmpRowNames);
5232  tmpRowNames = new (tmpRowNames) NameSet();
5233  tmpRowNames->reMax(numRows);
5234 
5235  for( int i = 0; i < numRows; ++i )
5236  {
5237  name << "C" << i;
5238  tmpRowNames->add(name.str().c_str());
5239  }
5240 
5241  rowNamesPtr = tmpRowNames;
5242  }
5243 
5244  // initialize with default slack basis
5245  _basisStatusRows.reSize(numRows);
5246  _basisStatusCols.reSize(numCols);
5247 
5248  for( int i = 0; i < numRows; i++ )
5250 
5251  for( int i = 0; i < numCols; i++ )
5252  {
5253  if( lowerRealInternal(i) == upperRealInternal(i) )
5255  else if( lowerRealInternal(i) <= double(-realParam(SoPlex::INFTY)) && upperRealInternal(i) >= double(realParam(SoPlex::INFTY)) )
5257  else if( lowerRealInternal(i) <= double(-realParam(SoPlex::INFTY)) )
5259  else
5261  }
5262 
5263  // read basis
5264  MPSInput mps(file);
5265  if( mps.readLine() && (mps.field0() != 0) && !strcmp(mps.field0(), "NAME") )
5266  {
5267  while( mps.readLine() )
5268  {
5269  int c = -1;
5270  int r = -1;
5271 
5272  if( mps.field0() != 0 && !strcmp(mps.field0(), "ENDATA") )
5273  {
5275  break;
5276  }
5277 
5278  if( mps.field1() == 0 || mps.field2() == 0 )
5279  break;
5280 
5281  if( (c = colNamesPtr->number(mps.field2())) < 0 )
5282  break;
5283 
5284  if( *mps.field1() == 'X' )
5285  {
5286  if( mps.field3() == 0 || (r = rowNamesPtr->number(mps.field3())) < 0 )
5287  break;
5288  }
5289 
5290  if( !strcmp(mps.field1(), "XU") )
5291  {
5295  else if( _rowTypes[r] == SoPlex::RANGETYPE_FIXED )
5297  else
5299  }
5300  else if( !strcmp(mps.field1(), "XL") )
5301  {
5305  else if( _rowTypes[r] == SoPlex::RANGETYPE_FIXED )
5307  else
5309  }
5310  else if( !strcmp(mps.field1(), "UL") )
5311  {
5313  }
5314  else if( !strcmp(mps.field1(), "LL") )
5315  {
5317  }
5318  else
5319  {
5320  mps.syntaxError();
5321  break;
5322  }
5323  }
5324  }
5325 
5326  if( rowNames == 0 )
5327  {
5328  tmpRowNames->~NameSet();
5329  spx_free(tmpRowNames);
5330  }
5331 
5332  if( colNames == 0 )
5333  {
5334  tmpColNames->~NameSet();
5335  spx_free(tmpColNames);
5336  }
5337 
5338  _hasBasis = !mps.hasError();
5339 
5340  // stop timing
5342 
5343  return _hasBasis;
5344 #endif
5345  }
5346 
5347 
5348 
5349  /// writes basis information to \p filename; if \p rowNames and \p colNames are \c NULL, default names are used;
5350  /// returns true on success
5351  bool SoPlex::writeBasisFile(const char* filename, const NameSet* rowNames, const NameSet* colNames, const bool cpxFormat) const
5352  {
5353  assert(filename != 0);
5354 
5355  if( _isRealLPLoaded )
5356  return _solver.writeBasisFile(filename, rowNames, colNames, cpxFormat);
5357  else
5358  {
5359  std::ofstream file(filename);
5360  if( !file.good() )
5361  return false;
5362 
5363  file.setf(std::ios::left);
5364  file << "NAME " << filename << "\n";
5365 
5366  // do not write basis if there is none
5367  if( !_hasBasis )
5368  {
5369  file << "ENDATA\n";
5370  return true;
5371  }
5372 
5373  // start writing
5374  int numRows = _basisStatusRows.size();
5375  int numCols = _basisStatusCols.size();
5376  int row = 0;
5377 
5378  for( int col = 0; col < numCols; col++ )
5379  {
5380  assert(_basisStatusCols[col] != SPxSolver::UNDEFINED);
5381 
5382  if( _basisStatusCols[col] == SPxSolver::BASIC )
5383  {
5384  // find nonbasic row
5385  for( ; row < numRows; row++ )
5386  {
5387  assert(_basisStatusRows[row] != SPxSolver::UNDEFINED);
5388  if( _basisStatusRows[row] != SPxSolver::BASIC )
5389  break;
5390  }
5391 
5392  assert(row != numRows);
5393 
5394  if( _basisStatusRows[row] == SPxSolver::ON_UPPER && (!cpxFormat || _rowTypes[row] == SoPlex::RANGETYPE_BOXED) )
5395  file << " XU ";
5396  else
5397  file << " XL ";
5398 
5399  file << std::setw(8);
5400  if( colNames != 0 && colNames->has(col) )
5401  file << (*colNames)[col];
5402  else
5403  file << "x" << col;
5404 
5405  file << " ";
5406  if( rowNames != 0 && rowNames->has(row) )
5407  file << (*rowNames)[row];
5408  else
5409  file << "C" << row;
5410 
5411  file << "\n";
5412  row++;
5413  }
5414  else
5415  {
5417  {
5418  file << " UL ";
5419 
5420  file << std::setw(8);
5421  if( colNames != 0 && colNames->has(col) )
5422  file << (*colNames)[col];
5423  else
5424  file << "x" << col;
5425 
5426  file << "\n";
5427  }
5428  }
5429  }
5430 
5431  file << "ENDATA\n";
5432 
5433 #ifndef NDEBUG
5434  // check that the remaining rows are basic
5435  for( ; row < numRows; row++ )
5436  {
5437  assert(_basisStatusRows[row] == SPxSolver::BASIC);
5438  }
5439 #endif
5440 
5441  return true;
5442  }
5443  }
5444 
5445 
5446 
5447  /// writes internal LP, basis information, and parameter settings; if \p rowNames and \p colNames are \c NULL,
5448  /// default names are used
5449  void SoPlex::writeStateReal(const char* filename, const NameSet* rowNames, const NameSet* colNames, const bool cpxFormat) const
5450  {
5451  std::string ofname;
5452 
5453  // write parameter settings
5454  ofname = std::string(filename) + ".set";
5455  saveSettingsFile(ofname.c_str());
5456 
5457  // write problem in MPS/LP format
5458  ofname = std::string(filename) + ((cpxFormat) ? ".lp" : ".mps");
5459  writeFileReal(ofname.c_str(), rowNames, colNames, 0);
5460 
5461  // write basis
5462  ofname = std::string(filename) + ".bas";
5463  writeBasisFile(ofname.c_str(), rowNames, colNames, cpxFormat);
5464  }
5465 
5466 
5467 
5468  /// writes internal LP, basis information, and parameter settings; if \p rowNames and \p colNames are \c NULL,
5469  /// default names are used
5470  void SoPlex::writeStateRational(const char* filename, const NameSet* rowNames, const NameSet* colNames, const bool cpxFormat) const
5471  {
5472  std::string ofname;
5473 
5474  // write parameter settings
5475  ofname = std::string(filename) + ".set";
5476  saveSettingsFile(ofname.c_str());
5477 
5478  // write problem in MPS/LP format
5479  ofname = std::string(filename) + ((cpxFormat) ? ".lp" : ".mps");
5480  writeFileRational(ofname.c_str(), rowNames, colNames, 0);
5481 
5482  // write basis
5483  ofname = std::string(filename) + ".bas";
5484  writeBasisFile(ofname.c_str(), rowNames, colNames, cpxFormat);
5485  }
5486 
5487 
5488 
5489  /// returns boolean parameter value
5490  bool SoPlex::boolParam(const BoolParam param) const
5491  {
5492  assert(param >= 0);
5493  assert(param < SoPlex::BOOLPARAM_COUNT);
5494  return _currentSettings->_boolParamValues[param];
5495  }
5496 
5497 
5498 
5499  /// returns integer parameter value
5500  int SoPlex::intParam(const IntParam param) const
5501  {
5502  assert(param >= 0);
5503  assert(param < INTPARAM_COUNT);
5504  return _currentSettings->_intParamValues[param];
5505  }
5506 
5507 
5508 
5509  /// returns real parameter value
5510  Real SoPlex::realParam(const RealParam param) const
5511  {
5512  assert(param >= 0);
5513  assert(param < REALPARAM_COUNT);
5514  return _currentSettings->_realParamValues[param];
5515  }
5516 
5517 
5518 
5519 #ifdef SOPLEX_WITH_RATIONALPARAM
5520  /// returns rational parameter value
5521  Rational SoPlex::rationalParam(const RationalParam param) const
5522  {
5523  assert(param >= 0);
5524  assert(param < RATIONALPARAM_COUNT);
5525  return _currentSettings->_rationalParamValues[param];
5526  }
5527 #endif
5528 
5529 
5530 
5531  /// returns current parameter settings
5533  {
5534  return *_currentSettings;
5535  }
5536 
5537 
5538 
5539  /// sets boolean parameter value; returns true on success
5540  bool SoPlex::setBoolParam(const BoolParam param, const bool value, const bool init)
5541  {
5542  assert(param >= 0);
5543  assert(param < SoPlex::BOOLPARAM_COUNT);
5544  assert(init || _isConsistent());
5545 
5546  if( !init && value == boolParam(param) )
5547  return true;
5548 
5549  switch( param )
5550  {
5551  case LIFTING:
5552  break;
5553  case EQTRANS:
5554  break;
5555  case TESTDUALINF:
5556  break;
5557  case RATFAC:
5558  break;
5559  case USEDECOMPDUALSIMPLEX:
5560  break;
5561  case COMPUTEDEGEN:
5562  break;
5563  case USECOMPDUAL:
5564  break;
5565  case EXPLICITVIOL:
5566  break;
5567  case ACCEPTCYCLING:
5568  break;
5569  case RATREC:
5570  break;
5571  case POWERSCALING:
5572  break;
5573  case RATFACJUMP:
5574  break;
5575  case ROWBOUNDFLIPS:
5577  break;
5578  case PERSISTENTSCALING:
5579  break;
5580  case FULLPERTURBATION:
5582  break;
5583  default:
5584  return false;
5585  }
5586 
5587  _currentSettings->_boolParamValues[param] = value;
5588  return true;
5589  }
5590 
5591 
5592 
5593  /// sets integer parameter value; returns true on success
5594  bool SoPlex::setIntParam(const IntParam param, const int value, const bool init)
5595  {
5596  assert(param >= 0);
5597  assert(param < INTPARAM_COUNT);
5598  assert(init || _isConsistent());
5599 
5600  if( !init && value == intParam(param) )
5601  return true;
5602 
5603  // check for a valid parameter value wrt bounds
5604  if( value < _currentSettings->intParam.lower[param] || value > _currentSettings->intParam.upper[param] )
5605  return false;
5606 
5607  switch( param )
5608  {
5609  // objective sense
5610  case SoPlex::OBJSENSE:
5611  if( value != SoPlex::OBJSENSE_MAXIMIZE && value != SoPlex::OBJSENSE_MINIMIZE )
5612  return false;
5614  if( _rationalLP != 0 )
5617  break;
5618 
5619  // type of computational form, i.e., column or row representation
5622  return false;
5623  break;
5624 
5625  // type of algorithm, i.e., primal or dual
5626  case SoPlex::ALGORITHM:
5627  // decide upon entering/leaving at solve time depending on representation
5628  break;
5629 
5630  // type of LU update
5633  return false;
5635  break;
5636 
5637  // maximum number of updates before fresh factorization
5639  _solver.basis().setMaxUpdates(value);
5640  break;
5641 
5642  // iteration limit (-1 if unlimited)
5643  case SoPlex::ITERLIMIT:
5644  break;
5645 
5646  // refinement limit (-1 if unlimited)
5647  case SoPlex::REFLIMIT:
5648  break;
5649 
5650  // stalling refinement limit (-1 if unlimited)
5651  case SoPlex::STALLREFLIMIT:
5652  break;
5653 
5654  // display frequency
5655  case SoPlex::DISPLAYFREQ:
5656  _solver.setDisplayFreq(value);
5657  break;
5658 
5659  // verbosity level
5660  case SoPlex::VERBOSITY:
5661  switch(value)
5662  {
5663  case 0:
5665  break;
5666  case 1:
5668  break;
5669  case 2:
5671  break;
5672  case 3:
5674  break;
5675  case 4:
5677  break;
5678  case 5:
5680  break;
5681  }
5682  break;
5683 
5684  // type of simplifier
5685  case SoPlex::SIMPLIFIER:
5686  switch( value )
5687  {
5688  case SIMPLIFIER_OFF:
5689  _simplifier = 0;
5690  break;
5691  case SIMPLIFIER_AUTO:
5693  assert(_simplifier != 0);
5694  break;
5695  default:
5696  return false;
5697  }
5698  break;
5699 
5700  // type of scaler
5701  case SoPlex::SCALER:
5702  switch( value )
5703  {
5704  case SCALER_OFF:
5705  _scaler = 0;
5706  break;
5707  case SCALER_UNIEQUI:
5709  break;
5710  case SCALER_BIEQUI:
5712  break;
5713  case SCALER_GEO1:
5714  _scaler = &_scalerGeo1;
5715  break;
5716  case SCALER_GEO8:
5717  _scaler = &_scalerGeo8;
5718  break;
5719  case SCALER_LEASTSQ:
5721  break;
5722  default:
5723  return false;
5724  }
5725  break;
5726 
5727  // type of starter used to create crash basis
5728  case SoPlex::STARTER:
5729  switch( value )
5730  {
5731  case STARTER_OFF:
5732  _starter = 0;
5733  break;
5734  case STARTER_WEIGHT:
5736  break;
5737  case STARTER_SUM:
5738  _starter = &_starterSum;
5739  break;
5740  case STARTER_VECTOR:
5742  break;
5743  default:
5744  return false;
5745  }
5746  break;
5747 
5748  // type of pricer
5749  case SoPlex::PRICER:
5750  switch( value )
5751  {
5752  case PRICER_AUTO:
5754  break;
5755  case PRICER_DANTZIG:
5757  break;
5758  case PRICER_PARMULT:
5760  break;
5761  case PRICER_DEVEX:
5763  break;
5764  case PRICER_QUICKSTEEP:
5766  break;
5767  case PRICER_STEEP:
5769  break;
5770  default:
5771  return false;
5772  }
5773  break;
5774 
5775  // mode for synchronizing real and rational LP
5776  case SoPlex::SYNCMODE:
5777  switch( value )
5778  {
5779  case SYNCMODE_ONLYREAL:
5780  if( _rationalLP != 0 )
5781  {
5782  _rationalLP->~SPxLPRational();
5784  }
5785  break;
5786  case SYNCMODE_AUTO:
5787  if( intParam(param) == SYNCMODE_ONLYREAL )
5788  _syncLPRational();
5789  break;
5790  case SYNCMODE_MANUAL:
5792  break;
5793  default:
5794  return false;
5795  }
5796  break;
5797 
5798  // mode for reading LP files; nothing to do but change the value if valid
5799  case SoPlex::READMODE:
5800  switch( value )
5801  {
5802  case READMODE_REAL:
5803  case READMODE_RATIONAL:
5804  break;
5805  default:
5806  return false;
5807  }
5808  break;
5809 
5810  // mode for iterative refinement strategy; nothing to do but change the value if valid
5811  case SoPlex::SOLVEMODE:
5812  switch( value )
5813  {
5814  case SOLVEMODE_REAL:
5815  case SOLVEMODE_AUTO:
5816  case SOLVEMODE_RATIONAL:
5817  break;
5818  default:
5819  return false;
5820  }
5821  break;
5822 
5823  // mode for a posteriori feasibility checks; nothing to do but change the value if valid
5824  case SoPlex::CHECKMODE:
5825  switch( value )
5826  {
5827  case CHECKMODE_REAL:
5828  case CHECKMODE_AUTO:
5829  case CHECKMODE_RATIONAL:
5830  break;
5831  default:
5832  return false;
5833  }
5834  break;
5835 
5836  // type of ratio test
5837  case SoPlex::RATIOTESTER:
5838  switch( value )
5839  {
5840  case RATIOTESTER_TEXTBOOK:
5842  break;
5843  case RATIOTESTER_HARRIS:
5845  break;
5846  case RATIOTESTER_FAST:
5848  break;
5851  break;
5852  default:
5853  return false;
5854  }
5855  break;
5856 
5857  // type of timer
5858  case SoPlex::TIMER:
5859  switch( value )
5860  {
5861  case TIMER_OFF:
5863  break;
5864  case TIMER_CPU:
5866  break;
5867  case TIMER_WALLCLOCK:
5869  break;
5870  default:
5871  return false;
5872  }
5873  break;
5874 
5875  // mode of hyper pricing
5876  case SoPlex::HYPER_PRICING:
5877  switch( value )
5878  {
5879  case HYPER_PRICING_OFF:
5880  case HYPER_PRICING_AUTO:
5881  case HYPER_PRICING_ON:
5882  break;
5883  default:
5884  return false;
5885  }
5886  break;
5887 
5888  // minimum number of stalling refinements since last pivot to trigger rational factorization
5890  break;
5891 
5892  // maximum number of conjugate gradient iterations in least square scaling
5894  if( _scaler )
5895  _scaler->setIntParam(value);
5896  break;
5897 
5898  // mode of solution polishing
5900  switch( value )
5901  {
5902  case POLISHING_OFF:
5903  _solver.setSolutionPolishing(SPxSolver::SolutionPolish::OFF);
5904  break;
5906  _solver.setSolutionPolishing(SPxSolver::SolutionPolish::MAXBASICSLACK);
5907  break;
5909  _solver.setSolutionPolishing(SPxSolver::SolutionPolish::MINBASICSLACK);
5910  break;
5911  default:
5912  return false;
5913  }
5914  break;
5915 
5916  // the decomposition based simplex parameter settings
5917  case DECOMP_ITERLIMIT:
5918  break;
5919  case DECOMP_MAXADDEDROWS:
5920  break;
5921  case DECOMP_DISPLAYFREQ:
5922  break;
5923  case DECOMP_VERBOSITY:
5924  break;
5925  default:
5926  return false;
5927  }
5928 
5929  _currentSettings->_intParamValues[param] = value;
5930  return true;
5931  }
5932 
5933 
5934 
5935  /// sets real parameter value; returns true on success
5936  bool SoPlex::setRealParam(const RealParam param, const Real value, const bool init)
5937  {
5938  assert(param >= 0);
5939  assert(param < REALPARAM_COUNT);
5940  assert(init || _isConsistent());
5941 
5942  if( !init && value == realParam(param) )
5943  return true;
5944 
5945  if( value < _currentSettings->realParam.lower[param] || value > _currentSettings->realParam.upper[param] )
5946  return false;
5947 
5948  switch( param )
5949  {
5950  // primal feasibility tolerance; passed to the floating point solver only when calling solve()
5951  case SoPlex::FEASTOL:
5952 #ifndef SOPLEX_WITH_GMP
5953  if( value < DEFAULT_EPS_ZERO )
5954  {
5955  MSG_WARNING( spxout, spxout << "Cannot set feasibility tolerance to small value " << value << " without GMP - using " << DEFAULT_EPS_ZERO << ".\n");
5957  break;
5958  }
5959 #endif
5960  _rationalFeastol = value;
5961  break;
5962 
5963  // dual feasibility tolerance; passed to the floating point solver only when calling solve()
5964  case SoPlex::OPTTOL:
5965 #ifndef SOPLEX_WITH_GMP
5966  if( value < DEFAULT_EPS_ZERO )
5967  {
5968  MSG_WARNING( spxout, spxout << "Cannot set optimality tolerance to small value " << value << " without GMP - using " << DEFAULT_EPS_ZERO << ".\n");
5970  break;
5971  }
5972 #endif
5973  _rationalOpttol = value;
5974  break;
5975 
5976  // general zero tolerance
5977  case SoPlex::EPSILON_ZERO:
5978  Param::setEpsilon(value);
5979  break;
5980 
5981  // zero tolerance used in factorization
5984  break;
5985 
5986  // zero tolerance used in update of the factorization
5988  Param::setEpsilonUpdate(value);
5989  break;
5990 
5991  // pivot zero tolerance used in factorization (declare numerical singularity for small LU pivots)
5992  case SoPlex::EPSILON_PIVOT:
5993  Param::setEpsilonPivot(value);
5994  break;
5995 
5996  // infinity threshold
5997  case SoPlex::INFTY:
5998  _rationalPosInfty = value;
5999  _rationalNegInfty = -value;
6002  break;
6003 
6004  // time limit in seconds (INFTY if unlimited)
6005  case SoPlex::TIMELIMIT:
6006  break;
6007 
6008  // lower limit on objective value is set in solveReal()
6010  break;
6011 
6012  // upper limit on objective value is set in solveReal()
6014  break;
6015 
6016  // working tolerance for feasibility in floating-point solver
6017  case SoPlex::FPFEASTOL:
6018  break;
6019 
6020  // working tolerance for optimality in floating-point solver
6021  case SoPlex::FPOPTTOL:
6022  break;
6023 
6024  // maximum increase of scaling factors between refinements
6025  case SoPlex::MAXSCALEINCR:
6026  _rationalMaxscaleincr = value;
6027  break;
6028 
6029  // lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformulated)
6030  case SoPlex::LIFTMINVAL:
6031  break;
6032 
6033  // upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulated)
6034  case SoPlex::LIFTMAXVAL:
6035  break;
6036 
6037  // threshold for sparse pricing
6039  break;
6040 
6041  // threshold on number of rows vs. number of columns for switching from column to row representations in auto mode
6043  break;
6044 
6045  // geometric frequency at which to apply rational reconstruction
6046  case SoPlex::RATREC_FREQ:
6047  break;
6048 
6049  // minimal reduction (sum of removed rows/cols) to continue simplification
6050  case SoPlex::MINRED:
6051  break;
6052 
6054  break;
6055 
6057  break;
6058 
6060  break;
6061 
6062  // accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations)
6063  case SoPlex::LEASTSQ_ACRCY:
6064  if( _scaler )
6065  _scaler->setRealParam(value);
6066  break;
6067 
6068  // objective offset
6069  case SoPlex::OBJ_OFFSET:
6070  if( _realLP )
6071  _realLP->changeObjOffset(value);
6072  if( _rationalLP )
6073  _rationalLP->changeObjOffset(value);
6074  break;
6075 
6076  default:
6077  return false;
6078  }
6079 
6080  _currentSettings->_realParamValues[param] = value;
6081  return true;
6082  }
6083 
6084 
6085 
6086 #ifdef SOPLEX_WITH_RATIONALPARAM
6087  /// sets rational parameter value; returns true on success
6088  bool SoPlex::setRationalParam(const RationalParam param, const Rational value, const bool init)
6089  {
6090  assert(param >= 0);
6091  assert(param < RATIONALPARAM_COUNT);
6092  assert(init || _isConsistent());
6093 
6094  if( !init && value == rationalParam(param) )
6095  return true;
6096 
6097  if( value < _currentSettings->rationalParam.lower[param] || value > _currentSettings->rationalParam.upper[param] )
6098  return false;
6099 
6100  switch( param )
6101  {
6102  default:
6103  // currently, there are no rational-valued parameters
6104  return false;
6105  }
6106 
6107  _currentSettings->_rationalParamValues[param] = value;
6108  return true;
6109  }
6110 #endif
6111 
6112 
6113 
6114  /// sets parameter settings; returns true on success
6115  bool SoPlex::setSettings(const Settings& newSettings, const bool init)
6116  {
6117  assert(init || _isConsistent());
6118 
6119  bool success = true;
6120 
6121  *_currentSettings = newSettings;
6122 
6123  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
6124  success &= setBoolParam((BoolParam)i, _currentSettings->_boolParamValues[i], init);
6125 
6126  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
6127  success &= setIntParam((IntParam)i, _currentSettings->_intParamValues[i], init);
6128 
6129  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
6130  success &= setRealParam((RealParam)i, _currentSettings->_realParamValues[i], init);
6131 
6132 #ifdef SOPLEX_WITH_RATIONALPARAM
6133  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
6134  success &= setRationalParam((RationalParam)i, _currentSettings->_rationalParamValues[i], init);
6135 #endif
6136 
6137  assert(_isConsistent());
6138 
6139  return success;
6140  }
6141 
6142  /// resets default parameter settings
6143  void SoPlex::resetSettings(const bool quiet, const bool init)
6144  {
6145  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
6147 
6148  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
6150 
6151  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
6153 
6154 #ifdef SOPLEX_WITH_RATIONALPARAM
6155  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
6156  success &= setRationalParam((RationalParam)i, _currentSettings->rationalParam.defaultValue[i], init);
6157 #endif
6158  }
6159 
6160 
6161  /// print non-default parameter values
6163  {
6164  bool printedValue = false;
6165 
6166  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
6167  {
6169  continue;
6170 
6171  spxout << "bool:" << _currentSettings->boolParam.name[i] << " = " << (_currentSettings->_boolParamValues[i] ? "true\n" : "false\n");
6172  printedValue = true;
6173  }
6174 
6175  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
6176  {
6178  continue;
6179 
6180  spxout << "int:" << _currentSettings->intParam.name[i] << " = " << _currentSettings->_intParamValues[i] << "\n";
6181  printedValue = true;
6182  }
6183 
6184  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
6185  {
6187  continue;
6188 
6189  spxout << "real:" << _currentSettings->realParam.name[i] << " = " << _currentSettings->_realParamValues[i] << "\n";
6190  printedValue = true;
6191  }
6192 
6193 #ifdef SOPLEX_WITH_RATIONALPARAM
6194  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
6195  {
6196  if( _currentSettings->_rationalParamValues[i] == _currentSettings->rationalParam.defaultValue[i] )
6197  continue;
6198 
6199  spxout << "rational:" << _currentSettings->rationalParam.name[i] << " = " << _currentSettings->_rationalParamValues[i] << "\n";
6200  printedValue = true;
6201  }
6202 #endif
6203 
6205  {
6206  spxout << "uint:random_seed = " << _solver.random.getSeed() << "\n";
6207  printedValue = true;
6208  }
6209 
6210  if( printedValue )
6211  spxout << std::endl;
6212  }
6213 
6214 
6215 
6216  /// writes settings file; returns true on success
6217  bool SoPlex::saveSettingsFile(const char* filename, const bool onlyChanged) const
6218  {
6219  assert(filename != 0);
6220 
6221  std::ofstream file(filename);
6222  if( !file.good() )
6223  return false;
6224 
6225  file.setf(std::ios::left);
6226  file << "# SoPlex version " << SOPLEX_VERSION / 100 << "." << (SOPLEX_VERSION / 10) % 10 << "." << SOPLEX_VERSION % 10;
6227 #if SOPLEX_SUBVERSION > 0
6228  file << "." << SOPLEX_SUBVERSION;
6229 #endif
6230  file << "\n";
6231 
6232  for( int i = 0; i < SoPlex::BOOLPARAM_COUNT; i++ )
6233  {
6235  continue;
6236 
6237  file << "\n";
6238  file << "# " << _currentSettings->boolParam.description[i] << "\n";
6239  file << "# range {true, false}, default " << (_currentSettings->boolParam.defaultValue[i] ? "true\n" : "false\n");
6240  file << "bool:" << _currentSettings->boolParam.name[i] << " = " << (_currentSettings->_boolParamValues[i] ? "true\n" : "false\n");
6241  }
6242 
6243  for( int i = 0; i < SoPlex::INTPARAM_COUNT; i++ )
6244  {
6246  continue;
6247 
6248  file << "\n";
6249  file << "# " << _currentSettings->intParam.description[i] << "\n";
6250  file << "# range [" << _currentSettings->intParam.lower[i] << "," << _currentSettings->intParam.upper[i]
6251  << "], default " << _currentSettings->intParam.defaultValue[i] << "\n";
6252  file << "int:" << _currentSettings->intParam.name[i] << " = " << _currentSettings->_intParamValues[i] << "\n";
6253  }
6254 
6255  for( int i = 0; i < SoPlex::REALPARAM_COUNT; i++ )
6256  {
6258  continue;
6259 
6260  file << "\n";
6261  file << "# " << _currentSettings->realParam.description[i] << "\n";
6262  file << "# range [" << _currentSettings->realParam.lower[i] << "," << _currentSettings->realParam.upper[i]
6263  << "], default " << _currentSettings->realParam.defaultValue[i] << "\n";
6264  file << "real:" << _currentSettings->realParam.name[i] << " = " << _currentSettings->_realParamValues[i] << "\n";
6265  }
6266 
6267 #ifdef SOPLEX_WITH_RATIONALPARAM
6268  for( int i = 0; i < SoPlex::RATIONALPARAM_COUNT; i++ )
6269  {
6270  if( onlyChanged && _currentSettings->_rationalParamValues[i] == _currentSettings->rationalParam.defaultValue[i] )
6271  continue;
6272 
6273  file << "\n";
6274  file << "# " << _currentSettings->rationalParam.description[i] << "\n";
6275  file << "# range [" << _currentSettings->rationalParam.lower[i] << "," << _currentSettings->rationalParam.upper[i]
6276  << "], default " << _currentSettings->rationalParam.defaultValue[i] << "\n";
6277  file << "rational:" << _currentSettings->rationalParam.name[i] << " = " << _currentSettings->_rationalParamValues[i] << "\n";
6278  }
6279 #endif
6280 
6281  if( !onlyChanged || _solver.random.getSeed() != DEFAULT_RANDOM_SEED )
6282  {
6283  file << "\n";
6284  file << "# initial random seed used for perturbation\n";
6285  file << "# range [0, " << UINT_MAX << "], default "<< DEFAULT_RANDOM_SEED << "\n";
6286  file << "uint:random_seed = " << _solver.random.getSeed() << "\n";
6287  }
6288 
6289  return true;
6290  }
6291 
6292 
6293 
6294  /// reads settings file; returns true on success
6295  bool SoPlex::loadSettingsFile(const char* filename)
6296  {
6297  assert(filename != 0);
6298 
6299  // start timing
6301 
6302  MSG_INFO1( spxout, spxout << "Loading settings file <" << filename << "> . . .\n" );
6303 
6304  // open file
6305  spxifstream file(filename);
6306 
6307  if( !file )
6308  {
6309  MSG_INFO1( spxout, spxout << "Error opening settings file.\n" );
6310  return false;
6311  }
6312 
6313  // read file
6314  char line[SET_MAX_LINE_LEN];
6315  int lineNumber = 0;
6316  bool readError = false;
6317  bool parseError = false;
6318 
6319  while( !readError && !parseError)
6320  {
6321  lineNumber++;
6322  readError = !file.getline(line, sizeof(line));
6323  if( !readError )
6324  parseError = !_parseSettingsLine(line, lineNumber);
6325  }
6326  readError = readError && !file.eof();
6327 
6328  if( readError && strlen(line) == SET_MAX_LINE_LEN - 1 )
6329  {
6330  MSG_INFO1( spxout, spxout << "Error reading settings file: line " << lineNumber << " in settings file exceeds " << SET_MAX_LINE_LEN - 2 << " characters.\n" );
6331  }
6332  else if( readError )
6333  {
6334  MSG_INFO1( spxout, spxout << "Error reading settings file: line " << lineNumber << ".\n" );
6335  }
6336 
6337  // stop timing
6339 
6340  return !readError;
6341  }
6342 
6343  /// parses one setting string and returns true on success
6344  bool SoPlex::parseSettingsString(char* string)
6345  {
6346  assert(string != 0);
6347  if( string == 0 )
6348  return false;
6349 
6350  char parseString[SET_MAX_LINE_LEN];
6351  strncpy(parseString, string, SET_MAX_LINE_LEN-1);
6352  parseString[SET_MAX_LINE_LEN-1] = '\0';
6353 
6354  char* line = parseString;
6355 
6356  // find the start of the parameter type
6357  while( *line == ' ' || *line == '\t' || *line == '\r' )
6358  line++;
6359  if( *line == '\0' || *line == '\n' || *line == '#' )
6360  return true;
6361  char* paramTypeString = line;
6362 
6363  // find the end of the parameter type
6364  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != ':' )
6365  line++;
6366  if( *line == ':' )
6367  {
6368  *line = '\0';
6369  line++;
6370  }
6371  else
6372  {
6373  *line = '\0';
6374  line++;
6375 
6376  // search for the ':' char in the line
6377  while( *line == ' ' || *line == '\t' || *line == '\r' )
6378  line++;
6379  if( *line != ':' )
6380  {
6381  MSG_INFO1( spxout, spxout << "Error parsing setting string: no ':' separating parameter type and name.\n" );
6382  return false;
6383  }
6384  line++;
6385  }
6386 
6387  // find the start of the parameter name
6388  while( *line == ' ' || *line == '\t' || *line == '\r' )
6389  line++;
6390  if( *line == '\0' || *line == '\n' || *line == '#' )
6391  {
6392  MSG_INFO1( spxout, spxout << "Error parsing setting string: no parameter name.\n");
6393  return false;
6394  }
6395  char* paramName = line;
6396 
6397  // find the end of the parameter name
6398  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != '=' )
6399  line++;
6400  if( *line == '=' )
6401  {
6402  *line = '\0';
6403  line++;
6404  }
6405  else
6406  {
6407  *line = '\0';
6408  line++;
6409 
6410  // search for the '=' char in the line
6411  while( *line == ' ' || *line == '\t' || *line == '\r' )
6412  line++;
6413  if( *line != '=' )
6414  {
6415  MSG_INFO1( spxout, spxout << "Error parsing setting string: no '=' after parameter name.\n" );
6416  return false;
6417  }
6418  line++;
6419  }
6420 
6421  // find the start of the parameter value string
6422  while( *line == ' ' || *line == '\t' || *line == '\r' )
6423  line++;
6424  if( *line == '\0' || *line == '\n' || *line == '#' )
6425  {
6426  MSG_INFO1( spxout, spxout << "Error parsing setting string: no parameter value.\n");
6427  return false;
6428  }
6429  char* paramValueString = line;
6430 
6431  // find the end of the parameter value string
6432  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' )
6433  line++;
6434  if( *line != '\0' )
6435  {
6436  // check, if the rest of the line is clean
6437  *line = '\0';
6438  line++;
6439  while( *line == ' ' || *line == '\t' || *line == '\r' )
6440  line++;
6441  if( *line != '\0' && *line != '\n' && *line != '#' )
6442  {
6443  MSG_INFO1( spxout, spxout << "Error parsing setting string: additional character '" << *line << "' after parameter value.\n" );
6444  return false;
6445  }
6446  }
6447 
6448  // check whether we have a bool parameter
6449  if( strncmp(paramTypeString, "bool", 4) == 0 )
6450  {
6451  for( int param = 0; ; param++ )
6452  {
6453  if( param >= SoPlex::BOOLPARAM_COUNT )
6454  {
6455  MSG_INFO1( spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
6456  return false;
6457  }
6458  else if( strncmp(paramName, _currentSettings->boolParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
6459  {
6460  if( strncasecmp(paramValueString, "true", 4) == 0
6461  || strncasecmp(paramValueString, "TRUE", 4) == 0
6462  || strncasecmp(paramValueString, "t", 4) == 0
6463  || strncasecmp(paramValueString, "T", 4) == 0
6464  || strtol(paramValueString, NULL, 4) == 1 )
6465  {
6466  setBoolParam((SoPlex::BoolParam)param, true);
6467  break;
6468  }
6469  else if( strncasecmp(paramValueString, "false", 5) == 0
6470  || strncasecmp(paramValueString, "FALSE", 5) == 0
6471  || strncasecmp(paramValueString, "f", 5) == 0
6472  || strncasecmp(paramValueString, "F", 5) == 0
6473  || strtol(paramValueString, NULL, 5) == 0 )
6474  {
6475  setBoolParam((SoPlex::BoolParam)param, false);
6476  break;
6477  }
6478  else
6479  {
6480  MSG_INFO1( spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString << "> for bool parameter <" << paramName << ">.\n" );
6481  return false;
6482  }
6483  }
6484  }
6485 
6486  return true;
6487  }
6488 
6489  // check whether we have an integer parameter
6490  if( strncmp(paramTypeString, "int", 3) == 0 )
6491  {
6492  for( int param = 0; ; param++ )
6493  {
6494  if( param >= SoPlex::INTPARAM_COUNT )
6495  {
6496  MSG_INFO1( spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
6497  return false;
6498  }
6499  else if( strncmp(paramName, _currentSettings->intParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
6500  {
6501  int value;
6502 
6503  if( sscanf(paramValueString, "%d", &value) == 1 && setIntParam((SoPlex::IntParam)param, value, false) )
6504  break;
6505  else
6506  {
6507  MSG_INFO1( spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString << "> for int parameter <" << paramName << ">.\n" );
6508  return false;
6509  }
6510  }
6511  }
6512 
6513  return true;
6514  }
6515 
6516  // check whether we have a real parameter
6517  if( strncmp(paramTypeString, "real", 4) == 0 )
6518  {
6519  for( int param = 0; ; param++ )
6520  {
6521  if( param >= SoPlex::REALPARAM_COUNT )
6522  {
6523  MSG_INFO1( spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
6524  return false;
6525  }
6526  else if( strncmp(paramName, _currentSettings->realParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
6527  {
6528  Real value;
6529 
6530  if( sscanf(paramValueString, "%" REAL_FORMAT, &value) == 1 && setRealParam((SoPlex::RealParam)param, value) )
6531  break;
6532  else
6533  {
6534  MSG_INFO1( spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString << "> for real parameter <" << paramName << ">.\n" );
6535  return false;
6536  }
6537  }
6538  }
6539 
6540  return true;
6541  }
6542 
6543 #ifdef SOPLEX_WITH_RATIONALPARAM
6544  // check whether we have a rational parameter
6545  if( strncmp(paramTypeString, "rational", 8) == 0 )
6546  {
6547  for( int param = 0; ; param++ )
6548  {
6549  if( param >= SoPlex::RATIONALPARAM_COUNT )
6550  {
6551  MSG_INFO1( spxout, spxout << "Error parsing setting string: unknown parameter name <" << paramName << ">.\n" );
6552  return false;
6553  }
6554  else if( strncmp(paramName, _currentSettings->rationalParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
6555  {
6556  Rational value;
6557 
6558  if( readStringRational(paramValueString, value) && setRationalParam((SoPlex::RationalParam)param, value) )
6559  break;
6560  else
6561  {
6562  MSG_INFO1( spxout, spxout << "Error parsing setting string: invalid value <" << paramValueString << "> for rational parameter <" << paramName << ">.\n" );
6563  return false;
6564  }
6565  }
6566  }
6567 
6568  return true;
6569  }
6570 #endif
6571 
6572  // check whether we have the random seed
6573  if( strncmp(paramTypeString, "uint", 4) == 0 )
6574  {
6575  if( strncmp(paramName, "random_seed", 11) == 0 )
6576  {
6577  unsigned int value;
6578 
6579  if( sscanf(paramValueString, "%u", &value) == 1 )
6580  {
6581  setRandomSeed(value);
6582  return true;
6583  }
6584  }
6585 
6586  MSG_INFO1( spxout, spxout << "Error parsing setting string for uint parameter <random_seed>.\n" );
6587  return false;
6588  }
6589 
6590  MSG_INFO1( spxout, spxout << "Error parsing setting string: invalid parameter type <" << paramTypeString << "> for parameter <" << paramName << ">.\n" );
6591 
6592  return false;
6593  }
6594 
6595 
6596 
6597 
6598  /// prints solution statistics
6599  void SoPlex::printSolutionStatistics(std::ostream& os)
6600  {
6601  int prec = (int) os.precision();
6603  {
6604  os << std::scientific << std::setprecision(8)
6605  << "Solution (real) : \n"
6606  << " Objective value : " << objValueReal() << "\n";
6607  }
6608  else if( _lastSolveMode == SOLVEMODE_RATIONAL )
6609  {
6610  os << "Solution (rational) : \n"
6611  << " Objective value : " << rationalToString(objValueRational()) << "\n";
6612  os << "Size (base 2/10) : \n"
6613  << " Total primal : " << totalSizePrimalRational() << " / " << totalSizePrimalRational(10) << "\n"
6614  << " Total dual : " << totalSizeDualRational() << " / " << totalSizeDualRational(10) << "\n"
6615  << " DLCM primal : " << dlcmSizePrimalRational() << " / " << dlcmSizePrimalRational(10) << "\n"
6616  << " DLCM dual : " << dlcmSizeDualRational() << " / " << dlcmSizeDualRational(10) << "\n"
6617  << " DMAX primal : " << dmaxSizePrimalRational() << " / " << dmaxSizePrimalRational(10) << "\n"
6618  << " DMAX dual : " << dmaxSizeDualRational() << " / " << dmaxSizeDualRational(10) << "\n";
6619  }
6620  else
6621  {
6622  os << "Solution : \n"
6623  << " Objective value : -\n";
6624  }
6625 
6628  {
6629  Rational maxviol;
6630  Rational sumviol;
6631 
6632  os << "Violation (rational): \n";
6633  if( getBoundViolationRational(maxviol, sumviol) )
6634  os << " Max/sum bound : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
6635  else
6636  os << " Max/sum bound : - / -\n";
6637  if( getRowViolationRational(maxviol, sumviol) )
6638  os << " Max/sum row : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
6639  else
6640  os << " Max/sum row : - / -\n";
6641  if( getRedCostViolationRational(maxviol, sumviol) )
6642  os << " Max/sum redcost : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
6643  else
6644  os << " Max/sum redcost : - / -\n";
6645  if( getDualViolationRational(maxviol, sumviol) )
6646  os << " Max/sum dual : " << rationalToString(maxviol) << " / " << rationalToString(sumviol) << "\n";
6647  else
6648  os << " Max/sum dual : - / -\n";
6649  }
6650  else
6651  {
6652  Real maxviol;
6653  Real sumviol;
6654 
6655  os << "Violations (real) : \n";
6656  if( getBoundViolationReal(maxviol, sumviol) )
6657  os << " Max/sum bound : " << maxviol << " / " << sumviol << "\n";
6658  else
6659  os << " Max/sum bound : - / -\n";
6660  if( getRowViolationReal(maxviol, sumviol) )
6661  os << " Max/sum row : " << maxviol << " / " << sumviol << "\n";
6662  else
6663  os << " Max/sum row : - / -\n";
6664  if( getRedCostViolationReal(maxviol, sumviol) )
6665  os << " Max/sum redcost : " << maxviol << " / " << sumviol << "\n";
6666  else
6667  os << " Max/sum redcost : - / -\n";
6668  if( getDualViolationReal(maxviol, sumviol) )
6669  os << " Max/sum dual : " << maxviol << " / " << sumviol << "\n";
6670  else
6671  os << " Max/sum dual : - / -\n";
6672  }
6673  os << std::setprecision(prec);
6674  }
6675 
6676 
6677 
6678  /// prints statistics on solving process
6679  void SoPlex::printSolvingStatistics(std::ostream& os)
6680  {
6681  assert(_statistics != 0);
6682  _statistics->print(os);
6683  }
6684 
6685 
6686 
6687  /// prints short statistics
6688  void SoPlex::printShortStatistics(std::ostream& os)
6689  {
6690  printStatus(os, _status);
6691  os << "Solving time (sec) : " << std::fixed << std::setprecision(2) << _statistics->solvingTime->time() << "\n"
6692  << "Iterations : " << _statistics->iterations << "\n"
6693  << "Objective value : " << std::scientific << std::setprecision(8) << objValueReal() << std::fixed << "\n";
6694  }
6695 
6696 
6697 
6698  /// prints complete statistics
6699  void SoPlex::printStatistics(std::ostream& os)
6700  {
6701  int prec = (int) os.precision();
6702  os << std::setprecision(2);
6703 
6704  printStatus(os, _status);
6705 
6706  os << "Original problem : \n";
6709  else
6710  {
6713  else
6715  }
6716 
6717  os << "Objective sense : " << (intParam(SoPlex::OBJSENSE) == SoPlex::OBJSENSE_MINIMIZE ? "minimize\n" : "maximize\n");
6720  os << std::setprecision(prec);
6721  }
6722 
6723 
6724 
6725  /// prints status
6726  void SoPlex::printStatus(std::ostream& os, SPxSolver::Status stat)
6727  {
6728  os << "SoPlex status : ";
6729 
6730  switch( stat )
6731  {
6732  case SPxSolver::ERROR:
6733  os << "error [unspecified]";
6734  break;
6736  os << "error [no ratiotester loaded]";
6737  break;
6738  case SPxSolver::NO_PRICER:
6739  os << "error [no pricer loaded]";
6740  break;
6741  case SPxSolver::NO_SOLVER:
6742  os << "error [no linear solver loaded]";
6743  break;
6744  case SPxSolver::NOT_INIT:
6745  os << "error [not initialized]";
6746  break;
6748  os << "solving aborted [cycling]";
6749  break;
6750  case SPxSolver::ABORT_TIME:
6751  os << "solving aborted [time limit reached]";
6752  break;
6753  case SPxSolver::ABORT_ITER:
6754  os << "solving aborted [iteration limit reached]";
6755  break;
6757  os << "solving aborted [objective limit reached]";
6758  break;
6759  case SPxSolver::NO_PROBLEM:
6760  os << "no problem loaded";
6761  break;
6762  case SPxSolver::REGULAR:
6763  os << "basis is regular";
6764  break;
6765  case SPxSolver::SINGULAR:
6766  os << "basis is singular";
6767  break;
6768  case SPxSolver::OPTIMAL:
6769  os << "problem is solved [optimal]";
6770  break;
6771  case SPxSolver::UNBOUNDED:
6772  os << "problem is solved [unbounded]";
6773  break;
6774  case SPxSolver::INFEASIBLE:
6775  os << "problem is solved [infeasible]";
6776  break;
6777  case SPxSolver::INForUNBD:
6778  os << "problem is solved [infeasible or unbounded]";
6779  break;
6780  default:
6781  case SPxSolver::UNKNOWN:
6782  os << "unknown";
6783  break;
6784  }
6785 
6786  os << "\n";
6787  }
6788 
6789 
6790 
6791  /// prints version and compilation options
6793  {
6794  // do not use preprocessor directives within the MSG_INFO1 macro
6795 #if (SOPLEX_SUBVERSION > 0)
6796  MSG_INFO1( spxout, spxout << "SoPlex version " << SOPLEX_VERSION/100
6797  << "." << (SOPLEX_VERSION % 100)/10
6798  << "." << SOPLEX_VERSION % 10
6799  << "." << SOPLEX_SUBVERSION );
6800 #else
6801  MSG_INFO1( spxout, spxout << "SoPlex version " << SOPLEX_VERSION/100
6802  << "." << (SOPLEX_VERSION % 100)/10
6803  << "." << SOPLEX_VERSION % 10 );
6804 #endif
6805 
6806 #ifndef NDEBUG
6807  MSG_INFO1( spxout, spxout << " [mode: debug]" );
6808 #else
6809  MSG_INFO1( spxout, spxout << " [mode: optimized]" );
6810 #endif
6811 
6812  MSG_INFO1( spxout, spxout << " [precision: " << (int)sizeof(Real) << " byte]" );
6813 
6814 #ifdef SOPLEX_WITH_GMP
6815 #ifdef mpir_version
6816  MSG_INFO1( spxout, spxout << " [rational: MPIR " << mpir_version << "]" );
6817 #else
6818  MSG_INFO1( spxout, spxout << " [rational: GMP " << gmp_version << "]" );
6819 #endif
6820 #else
6821  MSG_INFO1( spxout, spxout << " [rational: long double]" );
6822 #endif
6823 
6824  MSG_INFO1( spxout, spxout << " [githash: " << getGitHash() << "]\n" );
6825  }
6826 
6827 
6828 
6829  /// checks if real LP and rational LP are in sync; dimensions will always be compared,
6830  /// vector and matrix values only if the respective parameter is set to true.
6831  /// If quiet is set to true the function will only display which vectors are different.
6832  bool SoPlex::areLPsInSync(const bool checkVecVals, const bool checkMatVals, const bool quiet) const
6833  {
6834  bool result = true;
6835  bool nRowsMatch = true;
6836  bool nColsMatch = true;
6837  bool rhsDimMatch = true;
6838  bool lhsDimMatch = true;
6839  bool maxObjDimMatch = true;
6840  bool upperDimMatch = true;
6841  bool lowerDimMatch = true;
6842 
6843  // compare number of Rows
6844  if( _realLP->nRows() != _rationalLP->nRows() )
6845  {
6846  MSG_INFO1( spxout, spxout << "The number of Rows in the Real LP does not match the one in the Rational LP."
6847  << " Real LP: " << _realLP->nRows() << " Rational LP: " << _rationalLP->nRows() << std::endl);
6848  result = false;
6849  nRowsMatch = false;
6850  }
6851 
6852  // compare number of Columns
6853  if( _realLP->nCols() != _rationalLP->nCols() )
6854  {
6855  MSG_INFO1( spxout, spxout << "The number of Columns in the Real LP does not match the one in the Rational LP."
6856  << " Real LP: " << _realLP->nCols() << " Rational LP: " << _rationalLP->nCols() << std::endl);
6857  result = false;
6858  nColsMatch = false;
6859  }
6860 
6861  // compare number of nonZeros
6862  if( _realLP->nNzos() != _rationalLP->nNzos() )
6863  {
6864  MSG_INFO1( spxout, spxout << "The number of nonZeros in the Real LP does not match the one in the Rational LP."
6865  << " Real LP: " << _realLP->nNzos() << " Rational LP: " << _rationalLP->nNzos() << std::endl);
6866  result = false;
6867  }
6868 
6869  // compare the dimensions of the right hand side vectors
6870  if( _realLP->rhs().dim() != _rationalLP->rhs().dim() )
6871  {
6872  MSG_INFO1( spxout, spxout << "The dimension of the right hand side vector of the Real LP does not match the one of the Rational LP."
6873  << " Real LP: " << _realLP->rhs().dim() << " Rational LP: " << _rationalLP->rhs().dim() << std::endl);
6874  result = false;
6875  rhsDimMatch = false;
6876 
6877  }
6878 
6879  // compare the dimensions of the left hand side vectors
6880  if( _realLP->lhs().dim() != _rationalLP->lhs().dim() )
6881  {
6882  MSG_INFO1( spxout, spxout << "The dimension of the left hand side vector of the Real LP does not match the one of the Rational LP."
6883  << " Real LP: " << _realLP->lhs().dim() << " Rational LP: " << _rationalLP->lhs().dim() << std::endl);
6884  result = false;
6885  lhsDimMatch = false;
6886  }
6887 
6888  // compare the dimensions of the objective function vectors
6889  if( _realLP->maxObj().dim() != _rationalLP->maxObj().dim() )
6890  {
6891  MSG_INFO1( spxout, spxout << "The dimension of the objective function vector of the Real LP does not match the one of the Rational LP."
6892  << " Real LP: " << _realLP->maxObj().dim() << " Rational LP: " << _rationalLP->maxObj().dim() << std::endl);
6893  result = false;
6894  maxObjDimMatch = false;
6895  }
6896 
6897  // compare the sense
6898  if( (int)_realLP->spxSense() != (int)_rationalLP->spxSense() )
6899  {
6900  MSG_INFO1( spxout, spxout << "The objective function sense of the Real LP does not match the one of the Rational LP."
6901  << " Real LP: " << (_realLP->spxSense() == SPxLPReal::MINIMIZE ? "MIN" : "MAX")
6902  << " Rational LP: " << (_rationalLP->spxSense() == SPxLPRational::MINIMIZE ? "MIN" : "MAX") << std::endl);
6903  result = false;
6904  }
6905 
6906  // compare the dimensions of upper bound vectors
6907  if( _realLP->upper().dim() != _rationalLP->upper().dim() )
6908  {
6909  MSG_INFO1( spxout, spxout << "The dimension of the upper bound vector of the Real LP does not match the one of the Rational LP."
6910  << " Real LP: " << _realLP->upper().dim() << " Rational LP: " << _rationalLP->upper().dim() << std::endl);
6911  result = false;
6912  upperDimMatch = false;
6913  }
6914 
6915  // compare the dimensions of the objective function vectors
6916  if( _realLP->lower().dim() != _rationalLP->lower().dim() )
6917  {
6918  MSG_INFO1( spxout, spxout << "The dimension of the lower bound vector of the Real LP does not match the one of the Rational LP."
6919  << " Real LP: " << _realLP->lower().dim() << " Rational LP: " << _rationalLP->lower().dim() << std::endl);
6920  result = false;
6921  lowerDimMatch = false;
6922  }
6923 
6924  // compares the values of the rhs, lhs, maxObj, upper, lower vectors
6925  if( checkVecVals )
6926  {
6927  bool rhsValMatch = true;
6928  bool lhsValMatch = true;
6929  bool maxObjValMatch = true;
6930  bool upperValMatch = true;
6931  bool lowerValMatch = true;
6932 
6933  // compares the values of the right hand side vectors
6934  if( rhsDimMatch )
6935  {
6936  for( int i = 0; i < _realLP->rhs().dim(); i++ )
6937  {
6938  if( (GE(_realLP->rhs()[i], realParam(SoPlex::INFTY)) != (_rationalLP->rhs()[i] >= _rationalPosInfty))
6940  && !_rationalLP->rhs()[i].isAdjacentTo((double)_realLP->rhs()[i])) )
6941  {
6942  if( !quiet )
6943  {
6944  MSG_INFO1( spxout, spxout << "Entries number " << i << " of the right hand side vectors don't match."
6945  << " Real LP: " << _realLP->rhs()[i] << " Rational LP: " << _rationalLP->rhs()[i] << std::endl);
6946  }
6947  rhsValMatch = false;
6948  result = false;
6949  }
6950  }
6951 
6952  if( !rhsValMatch && quiet )
6953  {
6954  MSG_INFO1( spxout, spxout << "The values of the right hand side vectors don't match." << std::endl );
6955  }
6956  }
6957 
6958  // compares the values of the left hand side vectors
6959  if( lhsDimMatch )
6960  {
6961  for( int i = 0; i < _realLP->lhs().dim(); i++ )
6962  {
6963  if( (LE(_realLP->lhs()[i], -realParam(SoPlex::INFTY)) != (_rationalLP->lhs()[i] <= _rationalNegInfty))
6965  && !_rationalLP->lhs()[i].isAdjacentTo((double)_realLP->lhs()[i])) )
6966  {
6967  if( !quiet )
6968  {
6969  MSG_INFO1( spxout, spxout << "Entries number " << i << " of the left hand side vectors don't match."
6970  << " Real LP: " << _realLP->lhs()[i] << " Rational LP: " << _rationalLP->lhs()[i] << std::endl);
6971  }
6972  lhsValMatch = false;
6973  result = false;
6974  }
6975  }
6976 
6977  if( !lhsValMatch && quiet )
6978  {
6979  MSG_INFO1( spxout, spxout << "The values of the left hand side vectors don't match." << std::endl );
6980  }
6981  }
6982 
6983  // compares the values of the objective function vectors
6984  if( maxObjDimMatch )
6985  {
6986  for( int i = 0; i < _realLP->maxObj().dim(); i++ )
6987  {
6988  if( !_rationalLP->maxObj()[i].isAdjacentTo((double)_realLP->maxObj()[i]) )
6989  {
6990  if( !quiet )
6991  {
6992  MSG_INFO1( spxout, spxout << "Entries number " << i << " of the objective function vectors don't match."
6993  << " Real LP: " << _realLP->maxObj()[i] << " Rational LP: " << _rationalLP->maxObj()[i] << std::endl);
6994  }
6995  maxObjValMatch = false;
6996  result = false;
6997  }
6998  }
6999 
7000  if( !maxObjValMatch && quiet )
7001  {
7002  MSG_INFO1( spxout, spxout << "The values of the objective function vectors don't match." << std::endl );
7003  }
7004  }
7005 
7006  // compares the values of the upper bound vectors
7007  if( upperDimMatch )
7008  {
7009  for( int i = 0; i < _realLP->upper().dim(); i++ )
7010  {
7013  && !_rationalLP->upper()[i].isAdjacentTo((double)_realLP->upper()[i])) )
7014  {
7015  if( !quiet )
7016  {
7017  MSG_INFO1( spxout, spxout << "Entries number " << i << " of the upper bound vectors don't match."
7018  << " Real LP: " << _realLP->upper()[i] << " Rational LP: " << _rationalLP->upper()[i] << std::endl);
7019  }
7020  upperValMatch = false;
7021  result = false;
7022  }
7023  }
7024 
7025  if( !upperValMatch && quiet )
7026  {
7027  MSG_INFO1( spxout, spxout << "The values of the upper bound vectors don't match." << std::endl );
7028  }
7029  }
7030 
7031  // compares the values of the lower bound vectors
7032  if( lowerDimMatch )
7033  {
7034  for( int i = 0; i < _realLP->lower().dim(); i++ )
7035  {
7038  && !_rationalLP->lower()[i].isAdjacentTo((double)_realLP->lower()[i])) )
7039  {
7040  if( !quiet )
7041  {
7042  MSG_INFO1( spxout, spxout << "Entries number " << i << " of the lower bound vectors don't match."
7043  << " Real LP: " << _realLP->lower()[i] << " Rational LP: " << _rationalLP->lower()[i] << std::endl);
7044  }
7045  lowerValMatch = false;
7046  result = false;
7047  }
7048  }
7049 
7050  if( !lowerValMatch && quiet )
7051  {
7052  MSG_INFO1( spxout, spxout << "The values of the lower bound vectors don't match." << std::endl );
7053  }
7054  }
7055  }
7056 
7057  // compare the values of the matrix
7058  if( checkMatVals && nRowsMatch && nColsMatch )
7059  {
7060  bool matrixValMatch = true;
7061 
7062  for( int i = 0; i < _realLP->nCols() ; i++ )
7063  {
7064  for( int j = 0;j < _realLP->nRows() ; j++ )
7065  {
7066  if( !_rationalLP->colVector(i)[j].isAdjacentTo((double)_realLP->colVector(i)[j]) )
7067  {
7068  if( !quiet )
7069  {
7070  MSG_INFO1( spxout, spxout << "Entries number " << j << " of column number " << i << " don't match."
7071  << " Real LP: " << _realLP->colVector(i)[j] << " Rational LP: " << _rationalLP->colVector(i)[j] << std::endl);
7072  }
7073  matrixValMatch = false;
7074  result = false;
7075  }
7076  }
7077  }
7078 
7079  if( !matrixValMatch && quiet )
7080  {
7081  MSG_INFO1( spxout, spxout << "The values of the matrices don't match." << std::endl );
7082  }
7083  }
7084 
7085  return result;
7086  }
7087 
7088 
7089 
7090  /// set the random seed of the solver instance
7091  void SoPlex::setRandomSeed(unsigned int seed)
7092  {
7093  _solver.random.setSeed(seed);
7094  }
7095 
7096 
7097 
7098  /// returns the current random seed of the solver instance or the one stored in the settings
7099  unsigned int SoPlex::randomSeed() const
7100  {
7101  return _solver.random.getSeed();
7102  }
7103 
7104 
7105 
7106  /// extends sparse vector to hold newmax entries if and only if it holds no more free entries
7107  void SoPlex::_ensureDSVectorRationalMemory(DSVectorRational& vec, const int newmax) const
7108  {
7109  assert(newmax > vec.size());
7110  if( vec.size() >= vec.max() )
7111  vec.setMax(newmax);
7112  }
7113 
7114 
7115 
7116  /// creates a permutation for removing rows/columns from an array of indices
7117  void SoPlex::_idxToPerm(int* idx, int idxSize, int* perm, int permSize) const
7118  {
7119  assert(idx != 0);
7120  assert(idxSize >= 0);
7121  assert(perm != 0);
7122  assert(permSize >= 0);
7123 
7124  for( int i = 0; i < permSize; i++ )
7125  perm[i] = i;
7126 
7127  for( int i = 0; i < idxSize; i++ )
7128  {
7129  assert(idx[i] >= 0);
7130  assert(idx[i] < permSize);
7131  perm[idx[i]] = -1;
7132  }
7133  }
7134 
7135 
7136 
7137  /// creates a permutation for removing rows/columns from a range of indices
7138  void SoPlex::_rangeToPerm(int start, int end, int* perm, int permSize) const
7139  {
7140  assert(perm != 0);
7141  assert(permSize >= 0);
7142 
7143  for( int i = 0; i < permSize; i++ )
7144  perm[i] = (i < start || i > end) ? i : -1;
7145  }
7146 
7147 
7148 
7149  /// checks consistency
7151  {
7152  assert(_statistics != 0);
7153  assert(_currentSettings != 0);
7154 
7155  assert(_realLP != 0);
7157 
7158  assert(_realLP != &_solver || _isRealLPLoaded);
7159  assert(_realLP == &_solver || !_isRealLPLoaded);
7160 
7166 
7167  assert(_rationalLP == 0 || _colTypes.size() == numColsRational());
7168  assert(_rationalLP == 0 || _rowTypes.size() == numRowsRational());
7169 
7170  return true;
7171  }
7172 
7173 
7174 
7175  /// should solving process be stopped?
7176  bool SoPlex::_isSolveStopped(bool& stoppedTime, bool& stoppedIter) const
7177  {
7178  assert(_statistics != 0);
7179 
7181  stoppedIter = (intParam(ITERLIMIT) >= 0 && _statistics->iterations >= intParam(ITERLIMIT))
7184 
7185  return stoppedTime || stoppedIter;
7186  }
7187 
7188 
7189 
7190  /// determines RangeType from real bounds
7191  SoPlex::RangeType SoPlex::_rangeTypeReal(const Real& lower, const Real& upper) const
7192  {
7193  assert(lower <= upper);
7194 
7195  if( lower <= -infinity )
7196  {
7197  if( upper >= infinity )
7198  return RANGETYPE_FREE;
7199  else
7200  return RANGETYPE_UPPER;
7201  }
7202  else
7203  {
7204  if( upper >= infinity )
7205  return RANGETYPE_LOWER;
7206  else if( lower == upper )
7207  return RANGETYPE_FIXED;
7208  else
7209  return RANGETYPE_BOXED;
7210  }
7211  }
7212 
7213 
7214 
7215  /// determines RangeType from rational bounds
7217  {
7218  assert(lower <= upper);
7219 
7220  if( lower <= _rationalNegInfty )
7221  {
7222  if( upper >= _rationalPosInfty )
7223  return RANGETYPE_FREE;
7224  else
7225  return RANGETYPE_UPPER;
7226  }
7227  else
7228  {
7229  if( upper >= _rationalPosInfty )
7230  return RANGETYPE_LOWER;
7231  else if( lower == upper )
7232  return RANGETYPE_FIXED;
7233  else
7234  return RANGETYPE_BOXED;
7235  }
7236  }
7237 
7238 
7239 
7240  /// switches RANGETYPE_LOWER to RANGETYPE_UPPER and vice versa
7242  {
7243  if( rangeType == RANGETYPE_LOWER )
7244  return RANGETYPE_UPPER;
7245  else if( rangeType == RANGETYPE_UPPER )
7246  return RANGETYPE_LOWER;
7247  else
7248  return rangeType;
7249  }
7250 
7251 
7252 
7253  /// checks whether RangeType corresponds to finite lower bound
7254  bool SoPlex::_lowerFinite(const RangeType& rangeType) const
7255  {
7256  return (rangeType == RANGETYPE_LOWER || rangeType == RANGETYPE_BOXED || rangeType == RANGETYPE_FIXED);
7257  }
7258 
7259 
7260 
7261  /// checks whether RangeType corresponds to finite upper bound
7262  bool SoPlex::_upperFinite(const RangeType& rangeType) const
7263  {
7264  return (rangeType == RANGETYPE_UPPER || rangeType == RANGETYPE_BOXED || rangeType == RANGETYPE_FIXED);
7265  }
7266 
7267 
7268 
7269  /// adds a single row to the real LP and adjusts basis
7270  void SoPlex::_addRowReal(const LPRowReal& lprow)
7271  {
7272  assert(_realLP != 0);
7273 
7274  bool scale = _realLP->isScaled();
7275  _realLP->addRow(lprow, scale);
7276 
7277  if( _isRealLPLoaded )
7279  else if( _hasBasis )
7281 
7283  }
7284 
7285 
7286 
7287  /// adds a single row to the real LP and adjusts basis
7288  void SoPlex::_addRowReal(Real lhs, const SVectorReal& lprow, Real rhs)
7289  {
7290  assert(_realLP != 0);
7291 
7292  bool scale = _realLP->isScaled();
7293  _realLP->addRow(lhs, lprow, rhs, scale);
7294 
7295  if( _isRealLPLoaded )
7297  else if( _hasBasis )
7299 
7301  }
7302 
7303 
7304 
7305  /// adds multiple rows to the real LP and adjusts basis
7306  void SoPlex::_addRowsReal(const LPRowSetReal& lprowset)
7307  {
7308  assert(_realLP != 0);
7309 
7310  bool scale = _realLP->isScaled();
7311  _realLP->addRows(lprowset, scale);
7312 
7313  if( _isRealLPLoaded )
7315  else if( _hasBasis )
7317 
7319  }
7320 
7321 
7322  /// adds a single column to the real LP and adjusts basis
7323  void SoPlex::_addColReal(const LPColReal& lpcol)
7324  {
7325  assert(_realLP != 0);
7326 
7327  bool scale = _realLP->isScaled();
7328  _realLP->addCol(lpcol, scale);
7329 
7330  if( _isRealLPLoaded )
7332  else if( _hasBasis )
7333  {
7334  if( lpcol.lower() > -realParam(SoPlex::INFTY) )
7336  else if( lpcol.upper() < realParam(SoPlex::INFTY) )
7338  else
7340  }
7341 
7343  }
7344 
7345 
7346 
7347  /// adds a single column to the real LP and adjusts basis
7348  void SoPlex::_addColReal(Real obj, Real lower, const SVectorReal& lpcol, Real upper)
7349  {
7350  assert(_realLP != 0);
7351 
7352  bool scale = _realLP->isScaled();
7353  _realLP->addCol(obj, lower, lpcol, upper, scale);
7354 
7355  if( _isRealLPLoaded )
7357  else if( _hasBasis )
7359 
7361  }
7362 
7363 
7364 
7365  /// adds multiple columns to the real LP and adjusts basis
7366  void SoPlex::_addColsReal(const LPColSetReal& lpcolset)
7367  {
7368  assert(_realLP != 0);
7369 
7370  bool scale = _realLP->isScaled();
7371  _realLP->addCols(lpcolset, scale);
7372 
7373  if( _isRealLPLoaded )
7375  else if( _hasBasis )
7376  {
7377  for( int i = 0; i < lpcolset.num(); i++ )
7378  {
7379  if( lpcolset.lower(i) > -realParam(SoPlex::INFTY) )
7381  else if( lpcolset.upper(i) < realParam(SoPlex::INFTY) )
7383  else
7385  }
7386  }
7387 
7389  }
7390 
7391 
7392  /// replaces row \p i with \p lprow and adjusts basis
7393  void SoPlex::_changeRowReal(int i, const LPRowReal& lprow)
7394  {
7395  assert(_realLP != 0);
7396 
7397  bool scale = _realLP->isScaled();
7398  _realLP->changeRow(i, lprow, scale);
7399 
7400  if( _isRealLPLoaded )
7402  else if( _hasBasis )
7403  {
7405  _hasBasis = false;
7406  else if( _basisStatusRows[i] == SPxSolver::ON_LOWER && lprow.lhs() <= -realParam(SoPlex::INFTY) )
7408  else if( _basisStatusRows[i] == SPxSolver::ON_UPPER && lprow.rhs() >= realParam(SoPlex::INFTY) )
7410  }
7411 
7413  }
7414 
7415 
7416 
7417  /// changes left-hand side vector for constraints to \p lhs and adjusts basis
7419  {
7420  assert(_realLP != 0);
7421 
7422  bool scale = _realLP->isScaled();
7423  _realLP->changeLhs(lhs, scale);
7424 
7425  if( _isRealLPLoaded )
7427  else if( _hasBasis )
7428  {
7429  for( int i = numRowsReal() - 1; i >= 0; i-- )
7430  {
7431  if( _basisStatusRows[i] == SPxSolver::ON_LOWER && lhs[i] <= -realParam(SoPlex::INFTY) )
7433  }
7434  }
7435  }
7436 
7437 
7438 
7439  /// changes left-hand side of row \p i to \p lhs and adjusts basis
7440  void SoPlex::_changeLhsReal(int i, const Real& lhs)
7441  {
7442  assert(_realLP != 0);
7443 
7444  bool scale = _realLP->isScaled();
7445  _realLP->changeLhs(i, lhs, scale);
7446 
7447  if( _isRealLPLoaded )
7448  {
7450  }
7451  else if( _hasBasis && _basisStatusRows[i] == SPxSolver::ON_LOWER && lhs <= -realParam(SoPlex::INFTY) )
7453 
7454  }
7455 
7456 
7457 
7458  /// changes right-hand side vector to \p rhs and adjusts basis
7460  {
7461  assert(_realLP != 0);
7462 
7463  bool scale = _realLP->isScaled();
7464  _realLP->changeRhs(rhs, scale);
7465 
7466  if( _isRealLPLoaded )
7467  {
7469  }
7470  else if( _hasBasis )
7471  {
7472  for( int i = numRowsReal() - 1; i >= 0; i-- )
7473  {
7476  }
7477  }
7478  }
7479 
7480 
7481 
7482  /// changes right-hand side of row \p i to \p rhs and adjusts basis
7483  void SoPlex::_changeRhsReal(int i, const Real& rhs)
7484  {
7485  assert(_realLP != 0);
7486 
7487  bool scale = _realLP->isScaled();
7488  _realLP->changeRhs(i, rhs, scale);
7489 
7490  if( _isRealLPLoaded )
7491  {
7493  }
7496  }
7497 
7498 
7499 
7500  /// changes left- and right-hand side vectors and adjusts basis
7501  void SoPlex::_changeRangeReal(const VectorReal& lhs, const VectorReal& rhs)
7502  {
7503  assert(_realLP != 0);
7504 
7505  bool scale = _realLP->isScaled();
7506  _realLP->changeRange(lhs, rhs, scale);
7507 
7508  if( _isRealLPLoaded )
7509  {
7511  }
7512  else if( _hasBasis )
7513  {
7514  for( int i = numRowsReal() - 1; i >= 0; i-- )
7515  {
7516  if( _basisStatusRows[i] == SPxSolver::ON_LOWER && lhs[i] <= -realParam(SoPlex::INFTY) )
7518  else if( _basisStatusRows[i] == SPxSolver::ON_UPPER && rhs[i] >= realParam(SoPlex::INFTY) )
7520  }
7521  }
7522  }
7523 
7524 
7525 
7526  /// changes left- and right-hand side of row \p i and adjusts basis
7527  void SoPlex::_changeRangeReal(int i, const Real& lhs, const Real& rhs)
7528  {
7529  assert(_realLP != 0);
7530 
7531  bool scale = _realLP->isScaled();
7532  _realLP->changeRange(i, lhs, rhs, scale);
7533 
7534  if( _isRealLPLoaded )
7535  {
7537  }
7538  else if( _hasBasis )
7539  {
7542  else if( _basisStatusRows[i] == SPxSolver::ON_UPPER && rhs >= realParam(SoPlex::INFTY) )
7544  }
7545  }
7546 
7547 
7548 
7549  /// replaces column \p i with \p lpcol and adjusts basis
7550  void SoPlex::_changeColReal(int i, const LPColReal& lpcol)
7551  {
7552  assert(_realLP != 0);
7553 
7554  bool scale = _realLP->isScaled();
7555  _realLP->changeCol(i, lpcol, scale);
7556 
7557  if( _isRealLPLoaded )
7558  {
7560  }
7561  else if( _hasBasis )
7562  {
7564  _hasBasis = false;
7565  else if( _basisStatusCols[i] == SPxSolver::ON_LOWER && lpcol.lower() <= -realParam(SoPlex::INFTY) )
7567  else if( _basisStatusCols[i] == SPxSolver::ON_UPPER && lpcol.upper() >= realParam(SoPlex::INFTY) )
7569  }
7570 
7572  }
7573 
7574 
7575 
7576  /// changes vector of lower bounds to \p lower and adjusts basis
7578  {
7579  assert(_realLP != 0);
7580 
7581  bool scale = _realLP->isScaled();
7582  _realLP->changeLower(lower, scale);
7583 
7584  if( _isRealLPLoaded )
7585  {
7587  }
7588  else if( _hasBasis )
7589  {
7590  for( int i = numColsReal() - 1; i >= 0; i-- )
7591  {
7592  if( _basisStatusCols[i] == SPxSolver::ON_LOWER && lower[i] <= -realParam(SoPlex::INFTY) )
7594  }
7595  }
7596  }
7597 
7598 
7599 
7600  /// changes lower bound of column i to \p lower and adjusts basis
7601  void SoPlex::_changeLowerReal(int i, const Real& lower)
7602  {
7603  assert(_realLP != 0);
7604 
7605  bool scale = _realLP->isScaled();
7606  _realLP->changeLower(i, lower, scale);
7607 
7608  if( _isRealLPLoaded )
7609  {
7611  }
7612  else if( _hasBasis && _basisStatusCols[i] == SPxSolver::ON_LOWER && lower <= -realParam(SoPlex::INFTY) )
7614  }
7615 
7616 
7617 
7618  /// changes vector of upper bounds to \p upper and adjusts basis
7620  {
7621  assert(_realLP != 0);
7622 
7623  bool scale = _realLP->isScaled();
7624  _realLP->changeUpper(upper, scale);
7625 
7626  if( _isRealLPLoaded )
7627  {
7629  }
7630  else if( _hasBasis )
7631  {
7632  for( int i = numColsReal() - 1; i >= 0; i-- )
7633  {
7634  if( _basisStatusCols[i] == SPxSolver::ON_UPPER && upper[i] >= realParam(SoPlex::INFTY) )
7636  }
7637  }
7638  }
7639 
7640 
7641 
7642  /// changes \p i 'th upper bound to \p upper and adjusts basis
7643  void SoPlex::_changeUpperReal(int i, const Real& upper)
7644  {
7645  assert(_realLP != 0);
7646 
7647  bool scale = _realLP->isScaled();
7648  _realLP->changeUpper(i, upper, scale);
7649 
7650  if( _isRealLPLoaded )
7651  {
7653  }
7654  else if( _hasBasis && _basisStatusCols[i] == SPxSolver::ON_UPPER && upper >= realParam(SoPlex::INFTY) )
7656  }
7657 
7658 
7659 
7660  /// changes vectors of column bounds to \p lower and \p upper and adjusts basis
7661  void SoPlex::_changeBoundsReal(const VectorReal& lower, const VectorReal& upper)
7662  {
7663  assert(_realLP != 0);
7664 
7665  bool scale = _realLP->isScaled();
7666  _realLP->changeBounds(lower, upper, scale);
7667 
7668  if( _isRealLPLoaded )
7669  {
7671  }
7672  else if( _hasBasis )
7673  {
7674  for( int i = numColsReal() - 1; i >= 0; i-- )
7675  {
7676  if( _basisStatusCols[i] == SPxSolver::ON_LOWER && lower[i] <= -realParam(SoPlex::INFTY) )
7678  else if( _basisStatusCols[i] == SPxSolver::ON_UPPER && upper[i] >= realParam(SoPlex::INFTY) )
7680  }
7681  }
7682  }
7683 
7684 
7685 
7686  /// changes bounds of column \p i to \p lower and \p upper and adjusts basis
7687  void SoPlex::_changeBoundsReal(int i, const Real& lower, const Real& upper)
7688  {
7689  assert(_realLP != 0);
7690 
7691  bool scale = _realLP->isScaled();
7692  _realLP->changeBounds(i, lower, upper, scale);
7693 
7694  if( _isRealLPLoaded )
7695  {
7697  }
7698  else if( _hasBasis )
7699  {
7702  else if( _basisStatusCols[i] == SPxSolver::ON_UPPER && upper >= realParam(SoPlex::INFTY) )
7704  }
7705  }
7706 
7707 
7708 
7709  /// changes matrix entry in row \p i and column \p j to \p val and adjusts basis
7710  void SoPlex::_changeElementReal(int i, int j, const Real& val)
7711  {
7712  assert(_realLP != 0);
7713 
7714  bool scale = _realLP->isScaled();
7715  _realLP->changeElement(i, j, val, scale);
7716 
7717  if( _isRealLPLoaded )
7718  {
7720  }
7721  else if( _hasBasis )
7722  {
7724  _hasBasis = false;
7725  }
7726 
7728  }
7729 
7730 
7731 
7732  /// removes row \p i and adjusts basis
7734  {
7735  assert(_realLP != 0);
7736 
7737  _realLP->removeRow(i);
7738 
7739  if( _isRealLPLoaded )
7740  {
7742  }
7743  else if( _hasBasis )
7744  {
7746  _hasBasis = false;
7747  else
7748  {
7751  }
7752  }
7753 
7755  }
7756 
7757 
7758 
7759  /// removes all rows with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
7760  /// new index where row \p i has been moved to; note that \p perm must point to an array of size at least
7761  /// #numRowsReal()
7762  void SoPlex::_removeRowsReal(int perm[])
7763  {
7764  assert(_realLP != 0);
7765 
7766  _realLP->removeRows(perm);
7767 
7768  if( _isRealLPLoaded )
7769  {
7771  }
7772  else if( _hasBasis )
7773  {
7774  for( int i = numRowsReal() - 1; i >= 0 && _hasBasis; i-- )
7775  {
7776  if( perm[i] < 0 && _basisStatusRows[i] != SPxSolver::BASIC )
7777  _hasBasis = false;
7778  else if( perm[i] >= 0 && perm[i] != i )
7779  {
7780  assert(perm[i] < numRowsReal());
7781  assert(perm[perm[i]] < 0);
7782 
7783  _basisStatusRows[perm[i]] = _basisStatusRows[i];
7784  }
7785  }
7786 
7787  if( _hasBasis )
7789  }
7790 
7792  }
7793 
7794 
7795 
7796  /// removes column i
7798  {
7799  assert(_realLP != 0);
7800 
7801  _realLP->removeCol(i);
7802 
7803  if( _isRealLPLoaded )
7804  {
7806  }
7807  else if( _hasBasis )
7808  {
7810  _hasBasis = false;
7811  else
7812  {
7815  }
7816  }
7817 
7819  }
7820 
7821 
7822 
7823  /// removes all columns with an index \p i such that \p perm[i] < 0; upon completion, \p perm[i] >= 0 indicates the
7824  /// new index where column \p i has been moved to; note that \p perm must point to an array of size at least
7825  /// #numColsReal()
7826  void SoPlex::_removeColsReal(int perm[])
7827  {
7828  assert(_realLP != 0);
7829 
7830  _realLP->removeCols(perm);
7831 
7832  if( _isRealLPLoaded )
7833  {
7835  }
7836  else if( _hasBasis )
7837  {
7838  for( int i = numColsReal() - 1; i >= 0 && _hasBasis; i-- )
7839  {
7840  if( perm[i] < 0 && _basisStatusCols[i] == SPxSolver::BASIC )
7841  _hasBasis = false;
7842  else if( perm[i] >= 0 && perm[i] != i )
7843  {
7844  assert(perm[i] < numColsReal());
7845  assert(perm[perm[i]] < 0);
7846 
7847  _basisStatusCols[perm[i]] = _basisStatusCols[i];
7848  }
7849  }
7850 
7851  if( _hasBasis )
7853  }
7854 
7856  }
7857 
7858 
7859 
7860  /// invalidates solution
7862  {
7863  ///@todo maybe this should be done individually at the places when this method is called
7865 
7866  _solReal.invalidate();
7867  _hasSolReal = false;
7868 
7870  _hasSolRational = false;
7871  }
7872 
7873 
7874 
7875  /// enables simplifier and scaler
7877  {
7878  // type of simplifier
7879  switch( intParam(SoPlex::SIMPLIFIER) )
7880  {
7881  case SIMPLIFIER_OFF:
7882  _simplifier = 0;
7883  break;
7884  case SIMPLIFIER_AUTO:
7886  assert(_simplifier != 0);
7888  break;
7889  default:
7890  break;
7891  }
7892 
7893  // type of scaler
7894  switch( intParam(SoPlex::SCALER) )
7895  {
7896  case SCALER_OFF:
7897  _scaler = 0;
7898  break;
7899  case SCALER_UNIEQUI:
7901  break;
7902  case SCALER_BIEQUI:
7904  break;
7905  case SCALER_GEO1:
7906  _scaler = &_scalerGeo1;
7907  break;
7908  case SCALER_GEO8:
7909  _scaler = &_scalerGeo8;
7910  break;
7911  case SCALER_LEASTSQ:
7913  break;
7914  default:
7915  break;
7916  }
7917  }
7918 
7919 
7920 
7921  /// disables simplifier and scaler
7923  {
7924  _simplifier = 0;
7925 
7926  // preserve scaler when persistent scaling is used
7927  if( !_isRealLPScaled )
7928  _scaler = 0;
7929  else
7931  }
7932 
7933 
7934 
7935  /// ensures that the rational LP is available; performs no sync
7937  {
7938  if( _rationalLP == 0 )
7939  {
7943  }
7944  }
7945 
7946 
7947 
7948  /// ensures that the real LP and the basis are loaded in the solver; performs no sync
7950  {
7951  if( !_isRealLPLoaded )
7952  {
7953  assert(_realLP != &_solver);
7954 
7956  _realLP->~SPxLPReal();
7957  spx_free(_realLP);
7958  _realLP = &_solver;
7959  _isRealLPLoaded = true;
7960 
7961  if( _hasBasis )
7962  {
7963  ///@todo this should not fail even if the basis is invalid (wrong dimension or wrong number of basic
7964  /// entries); fix either in SPxSolver or in SPxBasis
7965  assert(_basisStatusRows.size() == numRowsReal());
7966  assert(_basisStatusCols.size() == numColsReal());
7969  }
7970  }
7971  }
7972 
7973 
7974 
7975  /// call floating-point solver and update statistics on iterations etc.
7977  {
7978  bool _hadBasis = _hasBasis;
7979 
7980  // set time and iteration limit
7983  else
7987  else
7989 
7990  // ensure that tolerances are not too small
7991  if( _solver.feastol() < 1e-12 )
7992  _solver.setFeastol(1e-12);
7993  if( _solver.opttol() < 1e-12 )
7994  _solver.setOpttol(1e-12);
7995 
7996  // set correct representation
7999  && _solver.rep() != SPxSolver::COLUMN )
8000  {
8002  }
8005  &&_solver.rep() != SPxSolver::ROW )
8006  {
8008  }
8009 
8010  // set correct type
8013  && _solver.type() != SPxSolver::ENTER )
8014  {
8016  }
8019  && _solver.type() != SPxSolver::LEAVE )
8020  {
8022  }
8023 
8024  // set pricing modes
8029  _solver.hyperPricing(true);
8031  _solver.hyperPricing(false);
8032 
8036 
8037  // call floating-point solver and catch exceptions
8039  try
8040  {
8041  _solver.solve();
8042  }
8043  catch( const SPxException& E )
8044  {
8045  MSG_INFO1( spxout, spxout << "Caught exception <" << E.what() << "> while solving real LP.\n" );
8047  }
8048  catch( ... )
8049  {
8050  MSG_INFO1( spxout, spxout << "Caught unknown exception while solving real LP.\n" );
8052  }
8054 
8055  // invalidate rational factorization of basis if pivots have been performed
8056  if( _solver.iterations() > 0 )
8058 
8059  // record statistics
8062  _statistics->iterationsFromBasis += _hadBasis ? _solver.iterations() : 0;
8070 
8075  }
8076 
8077 
8078 
8079  /// reads real LP in LP or MPS format from file and returns true on success; gets row names, column names, and
8080  /// integer variables if desired
8081  bool SoPlex::_readFileReal(const char* filename, NameSet* rowNames, NameSet* colNames, DIdxSet* intVars)
8082  {
8083  assert(_realLP != 0);
8084 
8085  // clear statistics
8087 
8088  // update status
8089  clearBasis();
8092 
8093  // start timing
8095 
8096  // read
8097  bool success = _realLP->readFile(filename, rowNames, colNames, intVars);
8098 
8099  // stop timing
8101 
8102  if( success )
8103  {
8106 
8107  // if sync mode is auto, we have to copy the (rounded) real LP to the rational LP; this is counted to sync time
8108  // and not to reading time
8110  _syncLPRational();
8111  }
8112  else
8113  clearLPReal();
8114 
8115  return success;
8116  }
8117 
8118 
8119 
8120  /// reads rational LP in LP or MPS format from file and returns true on success; gets row names, column names, and
8121  /// integer variables if desired
8122  bool SoPlex::_readFileRational(const char* filename, NameSet* rowNames, NameSet* colNames, DIdxSet* intVars)
8123  {
8124  // clear statistics
8126 
8127  // start timing
8129 
8130  // update status
8131  clearBasis();
8134 
8135  // read
8137  bool success = _rationalLP->readFile(filename, rowNames, colNames, intVars);
8138 
8139  // stop timing
8141 
8142  if( success )
8143  {
8147 
8148  // if sync mode is auto, we have to copy the (rounded) real LP to the rational LP; this is counted to sync time
8149  // and not to reading time
8151  _syncLPReal();
8152  // if a rational LP file is read, but only the (rounded) real LP should be kept, we have to free the rational LP
8154  {
8155  _syncLPReal();
8156  _rationalLP->~SPxLPRational();
8158  }
8159  }
8160  else
8161  clearLPRational();
8162 
8163  return success;
8164  }
8165 
8166 
8167 
8168  /// completes range type arrays after adding columns and/or rows
8170  {
8171  // we use one method for bot columns and rows, because during column/row addition, rows/columns can be added
8172  // implicitly
8173  for( int i = _colTypes.size(); i < numColsRational(); i++ )
8175  for( int i = _rowTypes.size(); i < numRowsRational(); i++ )
8177  }
8178 
8179 
8180 
8181  /// recomputes range types from scratch using real LP
8183  {
8185  for( int i = 0; i < numRowsReal(); i++ )
8186  _rowTypes[i] = _rangeTypeReal(_realLP->lhs(i), _realLP->rhs(i));
8188  for( int i = 0; i < numColsReal(); i++ )
8190  }
8191 
8192 
8193 
8194  /// recomputes range types from scratch using rational LP
8196  {
8198  for( int i = 0; i < numRowsRational(); i++ )
8201  for( int i = 0; i < numColsRational(); i++ )
8203  }
8204 
8205 
8206 
8207  /// synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP, without looking at the sync mode
8208  void SoPlex::_syncLPReal(bool time)
8209  {
8210  // start timing
8211  if( time )
8213 
8214  // copy LP
8215  if( _isRealLPLoaded )
8217  else
8218  *_realLP = *_rationalLP;
8219 
8220  ///@todo try loading old basis
8221  _hasBasis = false;
8223 
8224  // stop timing
8225  if( time )
8227  }
8228 
8229 
8230 
8231  /// synchronizes rational LP with real LP, i.e., copies real LP to rational LP, without looking at the sync mode
8232  void SoPlex::_syncLPRational(bool time)
8233  {
8234  // start timing
8235  if( time )
8237 
8238  // copy LP
8240  *_rationalLP = *_realLP;
8242 
8243  // stop timing
8244  if( time )
8246  }
8247 
8248 
8249 
8250  /// synchronizes real solution with rational solution, i.e., copies real solution to rational solution
8252  {
8253  if( _hasSolRational && !_hasSolReal )
8254  {
8256  _hasSolReal = true;
8257  }
8258  }
8259 
8260 
8261 
8262  /// synchronizes rational solution with real solution, i.e., copies (rounded) rational solution to real solution
8264  {
8265  if( _hasSolReal && !_hasSolRational )
8266  {
8268  _hasSolRational = true;
8269  }
8270  }
8271 
8272 
8273 
8274  /// returns pointer to a constant unit vector available until destruction of the SoPlex class
8276  {
8277  assert(i >= 0);
8278 
8279  if( i < 0 )
8280  return 0;
8281  else if( i >= _unitMatrixRational.size() )
8282  _unitMatrixRational.append(i + 1 - _unitMatrixRational.size(), (UnitVectorRational*)0);
8283  assert(i < _unitMatrixRational.size());
8284 
8285  if( _unitMatrixRational[i] == 0 )
8286  {
8289  }
8290  assert(_unitMatrixRational[i] != 0);
8291 
8292  return _unitMatrixRational[i];
8293  }
8294 
8295 
8296 
8297  /// parses one line in a settings file and returns true on success; note that the string is modified
8298  bool SoPlex::_parseSettingsLine(char* line, const int lineNumber)
8299  {
8300  assert(line != 0);
8301 
8302  // find the start of the parameter type
8303  while( *line == ' ' || *line == '\t' || *line == '\r' )
8304  line++;
8305  if( *line == '\0' || *line == '\n' || *line == '#' )
8306  return true;
8307  char* paramTypeString = line;
8308 
8309  // find the end of the parameter type
8310  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != ':' )
8311  line++;
8312  if( *line == ':' )
8313  {
8314  *line = '\0';
8315  line++;
8316  }
8317  else
8318  {
8319  *line = '\0';
8320  line++;
8321 
8322  // search for the ':' char in the line
8323  while( *line == ' ' || *line == '\t' || *line == '\r' )
8324  line++;
8325  if( *line != ':' )
8326  {
8327  MSG_INFO1( spxout, spxout << "Error parsing settings file: no ':' separating parameter type and name in line " << lineNumber << ".\n" );
8328  return false;
8329  }
8330  line++;
8331  }
8332 
8333  // find the start of the parameter name
8334  while( *line == ' ' || *line == '\t' || *line == '\r' )
8335  line++;
8336  if( *line == '\0' || *line == '\n' || *line == '#' )
8337  {
8338  MSG_INFO1( spxout, spxout << "Error parsing settings file: no parameter name in line " << lineNumber << ".\n");
8339  return false;
8340  }
8341  char* paramName = line;
8342 
8343  // find the end of the parameter name
8344  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' && *line != '=' )
8345  line++;
8346  if( *line == '=' )
8347  {
8348  *line = '\0';
8349  line++;
8350  }
8351  else
8352  {
8353  *line = '\0';
8354  line++;
8355 
8356  // search for the '=' char in the line
8357  while( *line == ' ' || *line == '\t' || *line == '\r' )
8358  line++;
8359  if( *line != '=' )
8360  {
8361  MSG_INFO1( spxout, spxout << "Error parsing settings file: no '=' after parameter name in line " << lineNumber << ".\n" );
8362  return false;
8363  }
8364  line++;
8365  }
8366 
8367  // find the start of the parameter value string
8368  while( *line == ' ' || *line == '\t' || *line == '\r' )
8369  line++;
8370  if( *line == '\0' || *line == '\n' || *line == '#' )
8371  {
8372  MSG_INFO1( spxout, spxout << "Error parsing settings file: no parameter value in line " << lineNumber << ".\n");
8373  return false;
8374  }
8375  char* paramValueString = line;
8376 
8377  // find the end of the parameter value string
8378  while( *line != ' ' && *line != '\t' && *line != '\r' && *line != '\n' && *line != '#' && *line != '\0' )
8379  line++;
8380  if( *line != '\0' )
8381  {
8382  // check, if the rest of the line is clean
8383  *line = '\0';
8384  line++;
8385  while( *line == ' ' || *line == '\t' || *line == '\r' )
8386  line++;
8387  if( *line != '\0' && *line != '\n' && *line != '#' )
8388  {
8389  MSG_INFO1( spxout, spxout << "Error parsing settings file: additional character '" << *line << "' after parameter value in line " << lineNumber << ".\n" );
8390  return false;
8391  }
8392  }
8393 
8394  // check whether we have a bool parameter
8395  if( strncmp(paramTypeString, "bool", 4) == 0 )
8396  {
8397  for( int param = 0; ; param++ )
8398  {
8399  if( param >= SoPlex::BOOLPARAM_COUNT )
8400  {
8401  MSG_INFO1( spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
8402  return false;
8403  }
8404  else if( strncmp(paramName, _currentSettings->boolParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
8405  {
8406  if( strncasecmp(paramValueString, "true", 4) == 0
8407  || strncasecmp(paramValueString, "TRUE", 4) == 0
8408  || strncasecmp(paramValueString, "t", 4) == 0
8409  || strncasecmp(paramValueString, "T", 4) == 0
8410  || strtol(paramValueString, NULL, 4) == 1 )
8411  {
8412  setBoolParam((SoPlex::BoolParam)param, true);
8413  break;
8414  }
8415  else if( strncasecmp(paramValueString, "false", 5) == 0
8416  || strncasecmp(paramValueString, "FALSE", 5) == 0
8417  || strncasecmp(paramValueString, "f", 5) == 0
8418  || strncasecmp(paramValueString, "F", 5) == 0
8419  || strtol(paramValueString, NULL, 5) == 0 )
8420  {
8421  setBoolParam((SoPlex::BoolParam)param, false);
8422  break;
8423  }
8424  else
8425  {
8426  MSG_INFO1( spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString << "> for bool parameter <" << paramName << "> in line " << lineNumber << ".\n" );
8427  return false;
8428  }
8429  }
8430  }
8431 
8432  return true;
8433  }
8434 
8435  // check whether we have an integer parameter
8436  if( strncmp(paramTypeString, "int", 3) == 0 )
8437  {
8438  for( int param = 0; ; param++ )
8439  {
8440  if( param >= SoPlex::INTPARAM_COUNT )
8441  {
8442  MSG_INFO1( spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
8443  return false;
8444  }
8445  else if( strncmp(paramName, _currentSettings->intParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
8446  {
8447  int value;
8448 
8449  if( sscanf(paramValueString, "%d", &value) == 1 && setIntParam((SoPlex::IntParam)param, value, false) )
8450  break;
8451  else
8452  {
8453  MSG_INFO1( spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString << "> for int parameter <" << paramName << "> in line " << lineNumber << ".\n" );
8454  return false;
8455  }
8456  }
8457  }
8458 
8459  return true;
8460  }
8461 
8462  // check whether we have a real parameter
8463  if( strncmp(paramTypeString, "real", 4) == 0 )
8464  {
8465  for( int param = 0; ; param++ )
8466  {
8467  if( param >= SoPlex::REALPARAM_COUNT )
8468  {
8469  MSG_INFO1( spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
8470  return false;
8471  }
8472  else if( strncmp(paramName, _currentSettings->realParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
8473  {
8474  Real value;
8475 
8476  if( sscanf(paramValueString, "%" REAL_FORMAT, &value) == 1 && setRealParam((SoPlex::RealParam)param, value) )
8477  break;
8478  else
8479  {
8480  MSG_INFO1( spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString << "> for real parameter <" << paramName << "> in line " << lineNumber << ".\n" );
8481  return false;
8482  }
8483  }
8484  }
8485 
8486  return true;
8487  }
8488 
8489 #ifdef SOPLEX_WITH_RATIONALPARAM
8490  // check whether we have a rational parameter
8491  if( strncmp(paramTypeString, "rational", 8) == 0 )
8492  {
8493  for( int param = 0; ; param++ )
8494  {
8495  if( param >= SoPlex::RATIONALPARAM_COUNT )
8496  {
8497  MSG_INFO1( spxout, spxout << "Error parsing settings file: unknown parameter name <" << paramName << "> in line " << lineNumber << ".\n" );
8498  return false;
8499  }
8500  else if( strncmp(paramName, _currentSettings->rationalParam.name[param].c_str(), SET_MAX_LINE_LEN) == 0 )
8501  {
8502  Rational value;
8503 
8504  if( readStringRational(paramValueString, value) && setRationalParam((SoPlex::RationalParam)param, value) )
8505  break;
8506  else
8507  {
8508  MSG_INFO1( spxout, spxout << "Error parsing settings file: invalid value <" << paramValueString << "> for rational parameter <" << paramName << "> in line " << lineNumber << ".\n" );
8509  return false;
8510  }
8511  }
8512  }
8513 
8514  return true;
8515  }
8516 #endif
8517 
8518  // check whether we have the random seed
8519  if( strncmp(paramTypeString, "uint", 4) == 0 )
8520  {
8521  if( strncmp(paramName, "random_seed", 11) == 0 )
8522  {
8523  unsigned int value;
8524 
8525  if( sscanf(paramValueString, "%u", &value) == 1 )
8526  {
8527  setRandomSeed(value);
8528  return true;
8529  }
8530  }
8531 
8532  MSG_INFO1( spxout, spxout << "Error parsing settings file for uint parameter <random_seed>.\n" );
8533  return false;
8534  }
8535 
8536  MSG_INFO1( spxout, spxout << "Error parsing settings file: invalid parameter type <" << paramTypeString << "> for parameter <" << paramName << "> in line " << lineNumber << ".\n" );
8537 
8538  return false;
8539  }
8540 } // namespace soplex
8541 #endif
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:219
void changeLhsRational(const VectorRational &lhs)
changes left-hand side vector for constraints to lhs
Definition: soplex.cpp:2089
virtual void buildDualProblem(SPxLPBase< R > &dualLP, SPxRowId primalRowIds[]=0, SPxColId primalColIds[]=0, SPxRowId dualRowIds[]=0, SPxColId dualColIds[]=0, int *nprimalrows=0, int *nprimalcols=0, int *ndualrows=0, int *ndualcols=0)
Building the dual problem from a given LP.
int _lastSolveMode
Definition: soplex.h:1784
const VectorRational & rhsRational() const
returns right-hand side vector
Definition: soplex.cpp:1148
floating-point check
Definition: soplex.h:1194
bool isNotZero(Real a, Real eps=Param::epsilon())
returns true iff |a| > eps
Definition: spxdefines.h:428
RangeType
type of bounds and sides
Definition: soplex.h:1616
SPxLPBase< Real > SPxLPReal
Definition: spxlp.h:36
const char * getRatiotesterName()
name of currently loaded ratiotester
Definition: soplex.cpp:5072
DVectorBase< R > _slacks
Definition: solbase.h:219
textbook ratio test without stabilization
Definition: soplex.h:1142
void getRowsRational(int start, int end, LPRowSetRational &lprowset) const
gets rows start, ..., end.
Definition: soplex.cpp:1130
const VectorReal & maxObjRealInternal() const
returns objective function vector after transformation to a maximization problem; since this is how i...
Definition: soplex.cpp:1024
void _computeBasisInverseRational()
computes rational inverse of basis matrix as defined by _rationalLUSolverBind
int getSolveCount() const
number of solves performed
Definition: slufactor.h:251
bool multBasisTranspose(Real *vec, bool unscale=true)
multiply with transpose of basis matrix; vec * B^T (inplace)
Definition: soplex.cpp:4733
void _changeUpperReal(const VectorReal &upper)
changes vector of upper bounds to upper and adjusts basis
Definition: soplex.cpp:7619
bool getDual(VectorBase< R > &vector) const
gets the dual solution vector; returns true on success
Definition: solbase.h:94
void getRhsUnscaled(VectorBase< Real > &vec) const
Gets unscaled right hand side vector.
accuracy of conjugate gradient method in least squares scaling (higher value leads to more iterations...
Definition: soplex.h:1312
Vector & multWithBase(Vector &x) const
Vector-basis product.
Definition: spxbasis.cpp:937
virtual void removeRow(int i)
Removes i &#39;th row.
Definition: spxlpbase.h:884
int iterations() const
get number of iterations of current solution.
Definition: spxsolver.h:2070
zero tolerance used in factorization
Definition: soplex.h:1255
void getRow(int i, LPRowBase< R > &row) const
Gets i &#39;th row.
Definition: spxlpbase.h:180
void getUpperReal(DVectorReal &upper) const
gets upper bound vector
Definition: soplex.cpp:968
Rational _rationalMaxscaleincr
Definition: soplex.h:1533
Basis is dual feasible.
Definition: spxbasis.h:95
free variable fixed to zero.
Definition: spxsolver.h:194
int totalSizeDual(const int base=2) const
returns total size of dual solution
Definition: solbase.h:139
#define DEFAULT_EPS_FACTOR
Definition: spxdefines.h:229
void printVersion() const
prints version and compilation options
Definition: soplex.cpp:6792
SoPlex()
default constructor
Definition: soplex.cpp:550
not initialised error
Definition: spxsolver.h:208
bool getDualViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of dual multipliers; returns true on success
Definition: soplex.cpp:3538
bool GE(Real a, Real b, Real eps=Param::epsilon())
returns true iff a >= b + eps
Definition: spxdefines.h:416
void printSolutionStatistics(std::ostream &os)
prints solution statistics
Definition: soplex.cpp:6599
refactor threshold for memory growth in factorization since last refactorization
Definition: soplex.h:1309
DVectorBase< R > _dualFarkas
Definition: solbase.h:223
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:258
Basis is not known to be dual nor primal feasible.
Definition: spxbasis.h:94
No matrix has yet been loaded.
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:712
bool getDualNorms(int &nnormsRow, int &nnormsCol, Real *norms) const
gets steepest edge norms and returns false if they are not available
Definition: soplex.cpp:1051
const VectorBase< R > & lower() const
Definition: lpcolsetbase.h:130
void _addColReal(const LPColReal &lpcol)
adds a single column to the real LP and adjusts basis
Definition: soplex.cpp:7323
int numRowsReal() const
returns number of rows
Definition: soplex.cpp:784
bool getBasisInverseRowReal(int r, Real *coef, int *inds=NULL, int *ninds=NULL, bool unscale=true)
computes row r of basis inverse; returns true on success
Definition: soplex.cpp:4067
Rational minAbsNonzeroRational() const
returns smallest non-zero element in absolute value
Definition: soplex.cpp:1103
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:2591
type of starter used to create crash basis
Definition: soplex.h:952
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:1801
bool getDualNorms(int &nnormsRow, int &nnormsCol, Real *norms) const
get dual norms
Definition: spxsolver.cpp:1952
The time limit has been hit.
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:456
void _optimizeReal()
solves real LP
Definition: solvereal.cpp:29
const Settings & settings() const
returns current parameter settings
Definition: soplex.cpp:5532
upper limit on objective value
Definition: soplex.h:1273
void getNdualNorms(int &nnormsRow, int &nnormsCol) const
get number of dual norms
Definition: spxsolver.cpp:1880
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:7710
virtual R minAbsNzo(bool unscaled=true) const
Absolute smallest non-zero element in (possibly scaled) LP.
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
general zero tolerance
Definition: soplex.h:1252
void getRows(int start, int end, LPRowSetBase< R > &set) const
Gets rows start, ... end.
Definition: spxlpbase.h:195
mode for solution polishing
Definition: soplex.h:985
void setOutstream(SPxOut &newOutstream)
Definition: spxlpbase.h:125
Real _realParamValues[SoPlex::REALPARAM_COUNT]
array of current real parameter values
Definition: soplex.h:1399
void _changeRangeReal(const VectorReal &lhs, const VectorReal &rhs)
changes left- and right-hand side vectors and adjusts basis
Definition: soplex.cpp:7501
const SPxRatioTester * ratiotester() const
return loaded SPxRatioTester.
Definition: spxsolver.h:1735
type of ratio test
Definition: soplex.h:958
void removeColReal(int i)
removes column i
Definition: soplex.cpp:1775
maximum increase of scaling factors between refinements
Definition: soplex.h:1282
virtual void getRowUnscaled(const SPxLPBase< Real > &lp, int i, DSVector &vec) const
returns unscaled row i
Definition: spxscaler.cpp:461
SPxMainSM _simplifierMainSM
Definition: soplex.h:1543
Real maxAbsNonzeroReal() const
returns biggest non-zero element in absolute value
Definition: soplex.cpp:820
verbosity level
Definition: soplex.h:943
continue iterative refinement with exact basic solution if not optimal?
Definition: soplex.h:897
void setBasis(const VarStatus rows[], const VarStatus cols[])
set the lp solver&#39;s basis.
Definition: spxsolver.cpp:1862
const SVectorReal & colVectorRealInternal(int i) const
returns vector of col i, ignoring scaling
Definition: soplex.cpp:932
type of timer
Definition: soplex.h:973
void setMaxUpdates(int maxUp)
change maximum number of iterations until a refactorization is performed
Definition: spxbasis.h:450
void resetCounters()
reset timers and counters
Definition: slufactor.h:256
Read MPS format files.
number of real parameters
Definition: soplex.h:1318
apply standard floating-point algorithm
Definition: soplex.h:1181
type of computational form, i.e., column or row representation
Definition: soplex.h:919
int stallRefinements
number of refinement steps without pivots
Definition: statistics.h:111
int totalSizePrimal(const int base=2) const
returns total size of primal solution
Definition: solbase.h:125
void changeColRational(int i, const LPColRational &lpcol)
replaces column i with lpcol
Definition: soplex.cpp:2272
bool getBasisIndRational(DataArray< int > &bind)
gets an array of indices for the columns of the rational basis matrix; bind[i] >= 0 means that the i-...
Definition: soplex.cpp:4869
bool getPrimalReal(VectorReal &vector)
gets the primal solution vector if available; returns true on success
Definition: soplex.cpp:2948
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 size() const
Number of used indices.
Definition: svectorbase.h:152
equilibrium scaling on rows or columns
Definition: soplex.h:1085
pivot zero tolerance used in factorization
Definition: soplex.h:1261
int numRowsRational() const
returns number of rows
Definition: soplex.cpp:1076
bool writeDualFileReal(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0) const
writes the dual of the real LP to file; LP or MPS format is chosen from the extension in filename; if...
Definition: soplex.cpp:5144
objective offset
Definition: soplex.h:1315
bool getDualRational(VectorRational &vector)
gets the dual solution vector if available; returns true on success
Definition: soplex.cpp:3308
refinement limit (-1 if unlimited)
Definition: soplex.h:934
void setSolutionPolishing(SolutionPolish _polishObj)
set objective of solution polishing (0: off, 1: max_basic_slack, 2: min_basic_slack) ...
Definition: spxsolver.h:606
class of parameter settings
Definition: soplex.h:1331
SPxLPRational * _rationalLP
Definition: soplex.h:1587
void printShortStatistics(std::ostream &os)
prints short statistics
Definition: soplex.cpp:6688
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:1789
Real coefReal(int row, int col) const
returns (unscaled) coefficient
Definition: soplex.cpp:829
bool getSlacksRational(VectorRational &vector)
gets the vector of slack values if available; returns true on success
Definition: soplex.cpp:3278
standard Harris ratio test
Definition: soplex.h:1145
bool multBasis(Real *vec, bool unscale=true)
multiply with basis matrix; B * vec (inplace)
Definition: soplex.cpp:4623
void getColsRational(int start, int end, LPColSetRational &lpcolset) const
gets columns start, ..., end
Definition: soplex.cpp:1202
bool getSlacks(VectorBase< R > &vector) const
gets the vector of slack values; returns true on success
Definition: solbase.h:65
int totalSizePrimalRational(const int base=2)
get size of primal solution
Definition: soplex.cpp:3744
void _addColsReal(const LPColSetReal &lpcolset)
adds multiple columns to the real LP and adjusts basis
Definition: soplex.cpp:7366
Basis is optimal, i.e. dual and primal feasible.
Definition: spxbasis.h:97
Real feastol() const
allowed primal feasibility tolerance.
Definition: spxsolver.h:776
unsigned int randomSeed() const
returns the current random seed of the solver instance
Definition: soplex.cpp:7099
virtual void setBasisSolver(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
Real sumDualDegeneracy()
get the sum of dual degeneracy
Definition: spxsolver.h:2058
time limit in seconds (INFTY if unlimited)
Definition: soplex.h:1267
mode for iterative refinement strategy
Definition: soplex.h:967
SPxGeometSC _scalerGeo8
Definition: soplex.h:1547
void changeRangeReal(const VectorReal &lhs, const VectorReal &rhs)
changes left- and right-hand side vectors
Definition: soplex.cpp:1469
virtual bool readFile(const char *filename, NameSet *rowNames=0, NameSet *colNames=0, DIdxSet *intVars=0)
Reads LP from a file.
Definition: spxlpbase.h:1134
Rational _rationalFeastol
Definition: soplex.h:1531
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:5449
DVectorBase< R > _primalRay
Definition: solbase.h:220
bool isScaled() const
Returns true if and only if the LP is scaled.
Definition: spxlpbase.h:139
void setUtype(UpdateType tp)
sets update type.
Definition: slufactor.h:122
R rhsUnscaled(int i) const
Returns unscaled right hand side of row number i.
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:7826
modified Harris ratio test
Definition: soplex.h:1148
virtual void changeCol(int n, const LPColBase< R > &newCol, bool scale=false)
Replaces i &#39;th column of LP with newCol. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1586
virtual ~SoPlex()
destructor
Definition: soplex.cpp:743
virtual void removeCols(int perm[])
Removes multiple columns.
Definition: spxlpbase.h:1000
bool getRedCostRational(VectorRational &vector)
gets the vector of reduced cost values if available; returns true on success
Definition: soplex.cpp:3323
bool LE(Real a, Real b, Real eps=Param::epsilon())
returns true iff a <= b + eps
Definition: spxdefines.h:404
DVectorBase< R > _redCost
Definition: solbase.h:222
int _unscaleCalls
Definition: soplex.h:1803
crash basis from a greedy solution
Definition: soplex.h:1110
Real getFactorTime() const
time spent in factorizations
Definition: slufactor.h:226
primal feasibility tolerance
Definition: soplex.h:1246
static struct soplex::SoPlex::Settings::RealParam realParam
Definition: soplex.cpp:544
void getObj(VectorBase< R > &pobj) const
Gets objective vector.
Definition: spxlpbase.h:394
bool LT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a < b + eps
Definition: spxdefines.h:398
standard verbosity level
Definition: soplex.h:1059
void setType(Type tp)
set LEAVE or ENTER algorithm.
Definition: spxsolver.cpp:171
bound flipping ratio test for long steps in the dual simplex
Definition: soplex.h:1151
void setFillFactor(Real f)
set refactor threshold for fill-in in current factor update compared to fill-in in last factorization...
Definition: spxsolver.h:444
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:5351
void _addRowReal(const LPRowReal &lprow)
adds a single row to the real LP and adjusts basis
Definition: soplex.cpp:7270
bool defaultValue[SoPlex::BOOLPARAM_COUNT]
array of default values for boolean parameters
Definition: soplex.h:1342
solve() aborted due to iteration limit.
Definition: spxsolver.h:213
R rhs() const
Right-hand side value.
Definition: lprowbase.h:215
SPxScaler * _scaler
Definition: soplex.h:1566
std::string name[SoPlex::BOOLPARAM_COUNT]
array of names for boolean parameters
Definition: soplex.h:1338
cpu or user time
Definition: soplex.h:1210
#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:5158
void changeRangeRational(const VectorRational &lhs, const VectorRational &rhs)
changes left- and right-hand side vectors
Definition: soplex.cpp:2212
mode for reading LP files
Definition: soplex.h:964
mode for synchronizing real and rational LP
Definition: soplex.h:961
void _syncLPReal(bool time=true)
synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP...
Definition: soplex.cpp:8208
bool hasDualFarkas() const
is a dual farkas ray available?
Definition: solbase.h:110
void _optimizeRational()
solves rational LP
No Problem has been loaded.
Definition: spxsolver.h:216
bool getDualFarkasReal(VectorReal &vector)
gets the Farkas proof if available; returns true on success
Definition: soplex.cpp:3023
void resetSettings(const bool quiet=false, const bool init=true)
resets default parameter settings
Definition: soplex.cpp:6143
automatic sync of real and rational LP
Definition: soplex.h:1161
void setValue(int i, R x)
Sets i &#39;th element to x.
Definition: ssvectorbase.h:218
void _recomputeRangeTypesRational()
recomputes range types from scratch using rational LP
Definition: soplex.cpp:8195
void syntaxError()
Definition: mpsinput.h:198
iteration limit (-1 if unlimited)
Definition: soplex.h:931
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:522
void changeObjReal(const VectorReal &obj)
changes objective function vector to obj
Definition: soplex.cpp:1636
void changeRowRational(int i, const LPRowRational &lprow)
replaces row i with lprow
Definition: soplex.cpp:2069
bool getRowViolationReal(Real &maxviol, Real &sumviol)
gets violation of constraints; returns true on success
Definition: soplex.cpp:3077
SPxFastRT _ratiotesterFast
Definition: soplex.h:1560
should cycling solutions be accepted during iterative refinement?
Definition: soplex.h:888
void _disableSimplifierAndScaler()
disables simplifier and scaler
Definition: soplex.cpp:7922
bool getRowViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of constraints; returns true on success
Definition: soplex.cpp:3404
static struct soplex::SoPlex::Settings::IntParam intParam
Definition: soplex.cpp:543
should the decomposition based dual simplex be used to solve the LP? Setting this to true forces the ...
Definition: soplex.h:876
void add(const LPColBase< R > &pcol)
Definition: lpcolsetbase.h:255
Real lowerReal(int i) const
returns lower bound of column i
Definition: soplex.cpp:986
#define DEFAULT_INFINITY
Definition: spxdefines.h:237
bool getBasisInverseRowRational(const int r, SSVectorRational &vec)
computes row r of basis inverse; performs rational factorization if not available; returns true on su...
Definition: soplex.cpp:4885
NameSet * _rowNames
Definition: soplex.h:1748
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:976
void _removeRowReal(int i)
removes row i and adjusts basis
Definition: soplex.cpp:7733
lower bound is finite, upper bound is infinite
Definition: soplex.h:1622
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:8081
decide according to problem size
Definition: soplex.h:1223
UnitVectorBase< Rational > UnitVectorRational
Definition: unitvector.h:31
bool getRedCost(VectorBase< R > &vector) const
gets the vector of reduced cost values if available; returns true on success
Definition: solbase.h:102
Timer * simplexTime
simplex time
Definition: statistics.h:91
void addColsRational(const LPColSetRational &lpcolset)
adds multiple columns
Definition: soplex.cpp:2050
int luSolvesReal
number of (forward and backward) solves with basis matrix in real precision
Definition: statistics.h:107
Real upperReal(int i) const
returns upper bound of column i
Definition: soplex.cpp:959
void getColRational(int i, LPColRational &lpcol) const
gets column i
Definition: soplex.cpp:1193
int refinements
number of refinement steps
Definition: statistics.h:110
const char * getStarterName()
name of starter
Definition: soplex.cpp:5031
void clear()
remove all elements.
Definition: dataarray.h:205
variable fixed to identical bounds.
Definition: spxsolver.h:193
int luFactorizationsReal
number of basis matrix factorizations in real precision
Definition: statistics.h:106
objective sense
Definition: soplex.h:916
bool hasError() const
Definition: mpsinput.h:162
int getFactorCount() const
number of factorizations performed
Definition: slufactor.h:236
#define DEFAULT_EPS_UPDATE
Definition: spxdefines.h:232
virtual void removeCol(int i)
Removes i &#39;th column.
Definition: spxlpbase.h:981
LP has been proven to be primal infeasible.
Definition: spxsolver.h:222
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:254
void setComputeDegenFlag(bool computeDegen)
sets whether the degeneracy is computed at each iteration
Definition: spxsolver.h:2184
Real defaultValue[SoPlex::REALPARAM_COUNT]
array of default values for real parameters
Definition: soplex.h:1368
void _checkBasisScaling()
check correctness of (un)scaled basis matrix operations
Definition: testsoplex.cpp:89
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:5081
void setSparsePricingFactor(Real fac)
Definition: spxsolver.h:831
display frequency
Definition: soplex.h:940
int intParam(const IntParam param) const
returns integer parameter value
Definition: soplex.cpp:5500
void setOpttol(Real d)
set parameter opttol.
Definition: spxsolver.cpp:942
void _ensureRationalLP()
ensures that the rational LP is available; performs no sync
Definition: soplex.cpp:7936
minimum number of stalling refinements since last pivot to trigger rational factorization ...
Definition: soplex.h:979
minimal reduction (sum of removed rows/cols) to continue simplification
Definition: soplex.h:1300
void getRowVectorReal(int i, DSVectorReal &row) const
gets vector of row i
Definition: soplex.cpp:852
bool writeFileReal(const char *filename, const NameSet *rowNames=0, const NameSet *colNames=0, const DIdxSet *intvars=0, const bool unscale=false) const
writes real LP to file; LP or MPS format is chosen from the extension in filename; if rowNames and co...
Definition: soplex.cpp:5099
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
bool setSettings(const Settings &newSettings, const bool init=true)
sets parameter settings; returns true on success
Definition: soplex.cpp:6115
void _changeRhsReal(const VectorReal &rhs)
changes right-hand side vector to rhs and adjusts basis
Definition: soplex.cpp:7459
void changeElementReal(int i, int j, const Real &val)
changes matrix entry in row i and column j to val
Definition: soplex.cpp:1668
disable timing
Definition: soplex.h:1207
void printStatistics(std::ostream &os)
prints complete statistics
Definition: soplex.cpp:6699
std::string name[SoPlex::REALPARAM_COUNT]
array of names for real parameters
Definition: soplex.h:1364
Real rhsReal(int i) const
returns right-hand side of row i
Definition: soplex.cpp:887
std::ostream & getStream(const Verbosity &verbosity) const
Returns the stream for the specified verbosity level.
Definition: spxout.h:157
should a rational factorization be performed after iterative refinement?
Definition: soplex.h:872
const SPxPricer * pricer() const
return loaded SPxPricer.
Definition: spxsolver.h:1725
#define REAL_FORMAT
Definition: spxdefines.h:218
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:976
void getRhsReal(DVectorReal &rhs) const
gets right-hand side vector
Definition: soplex.cpp:878
void add(const LPRowBase< R > &row)
Definition: lprowsetbase.h:321
bool setDualNorms(int nnormsRow, int nnormsCol, Real *norms)
set dual norms
Definition: spxsolver.cpp:1958
maximum number of updates without fresh factorization
Definition: soplex.h:928
int dlcmSizeDual(const int base=2) const
returns size of least common multiple of denominators in dual solution
Definition: solbase.h:167
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:2735
virtual void setTerminationTime(Real time=infinity)
set time limit.
Definition: spxsolver.cpp:1545
void changeUpperRational(const VectorRational &upper)
changes vector of upper bounds to upper
Definition: soplex.cpp:2352
bool _boolParamValues[SoPlex::BOOLPARAM_COUNT]
array of current boolean parameter values
Definition: soplex.h:1393
Rational _rationalPosInfty
Definition: soplex.h:1529
number of integer parameters
Definition: soplex.h:1000
Rational _rationalOpttol
Definition: soplex.h:1532
bool getPrimal(VectorBase< R > &vector) const
gets the primal solution vector; returns true on success
Definition: solbase.h:57
RealParam
real parameters
Definition: soplex.h:1243
virtual void changeObjOffset(const R &o)
Definition: spxlpbase.h:1716
bool setDualNorms(int nnormsRow, int nnormsCol, Real *norms)
sets steepest edge norms and returns false if that&#39;s not possible
Definition: soplex.cpp:1059
static struct soplex::SoPlex::Settings::BoolParam boolParam
Definition: soplex.cpp:542
const VectorRational & lhsRational() const
returns left-hand side vector
Definition: soplex.cpp:1166
virtual void removeRows(int perm[])
Removes multiple rows.
Definition: spxlpbase.h:903
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:5125
void removeLast(int m=1)
remove m last elements.
Definition: dataarray.h:199
SPxEquiliSC _scalerBiequi
Definition: soplex.h:1545
int numNonzerosRational() const
returns number of nonzeros
Definition: soplex.cpp:1094
steepest edge pricer with exact initialization of norms
Definition: soplex.h:1135
void getObjUnscaled(VectorBase< Real > &pobj) const
Gets unscaled objective vector.
virtual const std::string what() const
returns exception message
Definition: exceptions.h:57
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:1849
void addColReal(const LPCol &lpcol)
adds a single column
Definition: soplex.cpp:1340
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
Rational objRational(int i) const
returns objective value of column i
Definition: soplex.cpp:1275
void add(const SVectorBase< S > &vec)
Append nonzeros of sv.
Definition: dsvectorbase.h:216
void clearLPRational()
clears the LP
Definition: soplex.cpp:2753
No ratiotester loaded.
Definition: spxsolver.h:205
R lower() const
Gets lower bound.
Definition: lpcolbase.h:137
No pricer loaded.
Definition: spxsolver.h:206
void addRowsRational(const LPRowSetRational &lprowset)
adds multiple rows
Definition: soplex.cpp:1964
void printOriginalProblemStatistics(std::ostream &os)
stores the problem statistics of the original problem
Definition: solvedbds.cpp:3532
SPxSolver::Status optimize()
optimize the given LP
Definition: soplex.cpp:2788
void getObjReal(VectorReal &obj) const
gets objective function vector
Definition: soplex.cpp:1005
void getLowerReal(DVectorReal &lower) const
gets lower bound vector
Definition: soplex.cpp:995
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:1899
void addColRational(const LPColRational &lpcol)
adds a single column
Definition: soplex.cpp:1983
virtual Real stop()=0
stop timer, return accounted user time.
int dualDegeneratePivots()
get number of dual degenerate pivots
Definition: spxsolver.h:2046
void spx_alloc(T &p, int n=1)
Allocate memory.
Definition: spxalloc.h:48
Real getExactCondition()
Definition: spxbasis.h:613
const UnitVectorRational * _unitVectorRational(const int i)
returns pointer to a constant unit vector available until destruction of the SoPlex class ...
Definition: soplex.cpp:8275
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:7138
bool readLine()
reads an MPS format data line and parse the fields.
Definition: mpsinput.cpp:57
void _syncRealSolution()
synchronizes real solution with rational solution, i.e., copies real solution to rational solution ...
Definition: soplex.cpp:8251
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
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:2686
LP is primal infeasible or unbounded.
Definition: spxsolver.h:223
R objUnscaled(int i) const
Returns unscaled objective value of column i.
refactor threshold for fill-in in current factor update compared to fill-in in last factorization ...
Definition: soplex.h:1306
int nNzos() const
Returns number of nonzeros in LP.
Definition: spxlpbase.h:163
void changeRhsRational(const VectorRational &rhs)
changes right-hand side vector to rhs
Definition: soplex.cpp:2149
virtual void setOutstream(SPxOut &newOutstream)
set message handler
Definition: spxscaler.h:137
Leaving Simplex.
Definition: spxsolver.h:143
standard floating-point parsing
Definition: soplex.h:1171
int dmaxSizeDualRational(const int base=2)
get size of largest denominator in dual solution
Definition: soplex.cpp:3814
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:7107
Real luFactorizationTimeReal
time for factorizing bases matrices in real precision
Definition: statistics.h:97
void getLowerUnscaled(DVector &vec) const
Gets unscaled lower bound vector.
Real spxLdexp(Real x, int exp)
returns x * 2^exp
Definition: spxdefines.h:358
int dlcmSizePrimalRational(const int base=2)
get size of least common multiple of denominators in primal solution
Definition: soplex.cpp:3772
Rational objValueRational()
returns the objective value if a primal solution is available
Definition: soplex.cpp:3227
void getBasis(SPxSolver::VarStatus rows[], SPxSolver::VarStatus cols[]) const
gets current basis via arrays of statuses
Definition: soplex.cpp:3918
void setNonzeroFactor(Real f)
set refactor threshold for nonzeros in last factorized basis matrix compared to updated basis matrix ...
Definition: spxsolver.h:438
DataArray< SPxSolver::VarStatus > _basisStatusCols
Definition: soplex.h:1787
nothing known about basis status (possibly due to a singular basis in transformed problem) ...
Definition: spxsolver.h:196
decide depending on tolerances whether to apply iterative refinement
Definition: soplex.h:1184
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:1155
void getLhsReal(DVectorReal &lhs) const
gets left-hand side vector
Definition: soplex.cpp:905
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:425
Real upper[SoPlex::REALPARAM_COUNT]
array of upper bounds for real parameter values
Definition: soplex.h:1372
decompStatus _currentProb
Definition: soplex.h:1775
declaration of types for file output
DataArray< RangeType > _colTypes
Definition: soplex.h:1634
type of scaler
Definition: soplex.h:949
automatic choice according to number of rows and columns
Definition: soplex.h:1017
void maxObjUnscaled(VectorBase< Real > &vec) const
Returns unscaled objective vector for maximization problem.
double Real
Definition: spxdefines.h:214
Rational _rationalPosone
Definition: soplex.h:1805
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:1757
SPxBoundFlippingRT _ratiotesterBoundFlipping
Definition: soplex.h:1561
bool _isRealLPLoaded
Definition: soplex.h:1569
SLUFactorRational _rationalLUSolver
Definition: soplex.h:1588
geometric mean scaling on rows and columns, max 8 rounds
Definition: soplex.h:1094
bool isColBasic(int i) const
is the i &#39;th column vector basic ?
Definition: spxsolver.h:1256
void getRowRational(int i, LPRowRational &lprow) const
gets row i
Definition: soplex.cpp:1121
void _solveRealLPAndRecordStatistics()
call floating-point solver and update statistics on iterations etc.
Definition: soplex.cpp:7976
DVectorBase< R > _primal
Definition: solbase.h:218
number of boolean parameters
Definition: soplex.h:909
SPxEquiliSC _scalerUniequi
Definition: soplex.h:1544
#define MSG_DEBUG(x)
Definition: spxdefines.h:128
Status status() const
Status of solution process.
Definition: spxsolve.cpp:1868
Real sumPrimalDegeneracy()
get the sum of primal degeneracy
Definition: spxsolver.h:2064
void printSolvingStatistics(std::ostream &os)
prints statistics on solving process
Definition: soplex.cpp:6679
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:8122
lower threshold in lifting (nonzero matrix coefficients with smaller absolute value will be reformula...
Definition: soplex.h:1285
bool getPrimalRayReal(VectorReal &vector)
gets the primal ray if available; returns true on success
Definition: soplex.cpp:2978
void getColVectorUnscaled(int i, DSVectorBase< Real > &vec) const
Gets column vector of column i.
bool hasPrimal() const
is a primal feasible solution available?
Definition: soplex.cpp:2890
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
Definition: spxdefines.h:410
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:510
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:1395
DVectorBase< Real > DVectorReal
Definition: dvector.h:29
greedy crash basis weighted by objective, bounds, and sides
Definition: soplex.h:1107
bool hasDualFarkas() const
is Farkas proof of infeasibility available?
Definition: soplex.cpp:2914
virtual const char * getName() const
get name of simplifier.
std::string description[SoPlex::INTPARAM_COUNT]
array of descriptions for integer parameters
Definition: soplex.h:1351
bool _isConsistent() const
checks consistency
Definition: soplex.cpp:7150
void _changeLowerReal(const VectorReal &lower)
changes vector of lower bounds to lower and adjusts basis
Definition: soplex.cpp:7577
R upperUnscaled(int i) const
Returns unscaled upper bound of column i.
R lhs() const
Left-hand side value.
Definition: lprowbase.h:203
the iteration frequency at which the decomposition solve output is displayed.
Definition: soplex.h:994
dual simplex algorithm, i.e., leaving for column and entering for row representation ...
Definition: soplex.h:1033
steepest edge pricer with initialization to unit norms
Definition: soplex.h:1132
LP has been solved to optimality.
Definition: spxsolver.h:220
Rational maxAbsNonzeroRational() const
returns biggest non-zero element in absolute value
Definition: soplex.cpp:1112
use persistent scaling?
Definition: soplex.h:903
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:103
bool computeBasisInverseRational()
compute rational basis inverse; returns true on success
Definition: soplex.cpp:4841
bool _upperFinite(const RangeType &rangeType) const
checks whether RangeType corresponds to finite upper bound
Definition: soplex.cpp:7262
bool _hasBasis
Definition: soplex.h:1793
use bound flipping also for row representation?
Definition: soplex.h:900
bool hasBasis() const
is an advanced starting basis available?
Definition: soplex.cpp:3828
void _invalidateSolution()
invalidates solution
Definition: soplex.cpp:7861
bool getBasisInverseColReal(int c, Real *coef, int *inds=NULL, int *ninds=NULL, bool unscale=true)
computes column c of basis inverse; returns true on success
Definition: soplex.cpp:4253
bool getDualViolationReal(Real &maxviol, Real &sumviol)
gets violation of dual multipliers; returns true on success
Definition: soplex.cpp:3173
bool getBasisInverseColRational(const int c, SSVectorRational &vec)
computes column c of basis inverse; performs rational factorization if not available; returns true on...
Definition: soplex.cpp:4909
Real sumPrimalDegen
the sum of the rate of primal degeneracy at each iteration
Definition: statistics.h:128
void append(const T &t)
append element t.
Definition: dataarray.h:121
const char * getSimplifierName()
name of simplifier
Definition: soplex.cpp:5042
void changeLowerReal(const VectorReal &lower)
changes vector of lower bounds to lower
Definition: soplex.cpp:1525
DVectorBase< Rational > DVectorRational
Definition: dvector.h:30
virtual void addRows(const LPRowSetBase< R > &pset, bool scale=false)
Definition: spxlpbase.h:615
const char * getPricerName()
name of currently loaded pricer
Definition: soplex.cpp:5064
Class for collecting statistical information.
bool isSPxColId() const
is id a column id?
Definition: spxid.h:165
void setDisplayFreq(int freq)
set display frequency
Definition: spxsolver.h:819
solve() aborted due to time limit.
Definition: spxsolver.h:212
Rational _rationalNegone
Definition: soplex.h:1806
an error occured.
Definition: spxsolver.h:204
round scaling factors for iterative refinement to powers of two?
Definition: soplex.h:894
const T * get_const_ptr() const
get a const C pointer to the data.
Definition: dataarray.h:115
SPxBasis::SPxStatus basisStatus() const
returns the current basis status
Definition: soplex.cpp:3836
virtual void setMinReduction(const Real minRed)
set minimal reduction threshold to continue simplification
void removeRowReal(int i)
removes row i
Definition: soplex.cpp:1683
Forrest-Tomlin type update.
Definition: soplex.h:1043
#define DEFAULT_EPS_ZERO
default allowed additive zero: 1.0 + EPS_ZERO == 1.0
Definition: spxdefines.h:226
bool getBasisInverseTimesVecReal(Real *rhs, Real *sol, bool unscale=true)
computes dense solution of basis matrix B * sol = rhs; returns true on success
Definition: soplex.cpp:4458
int dlcmSizeDualRational(const int base=2)
get size of least common multiple of denominators in dual solution
Definition: soplex.cpp:3786
virtual void changeLower(const VectorBase< R > &newLower, bool scale=false)
Changes vector of lower bounds to newLower. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1325
virtual void setVerbosity(const Verbosity &v)
Definition: spxout.h:111
LPRowBase< R >::Type rowType(int i) const
Returns the inequality type of the i&#39;th LPRow.
Definition: spxlpbase.h:324
SPxWeightST _starterWeight
Definition: soplex.h:1549
Statistics * _statistics
statistics since last call to solveReal() or solveRational()
Definition: soplex.h:1516
#define DEFAULT_EPS_PIVOT
Definition: spxdefines.h:235
virtual void changeRhs(const VectorBase< R > &newRhs, bool scale=false)
Changes right hand side vector for constraints to newRhs. scale determines whether the new data shoul...
Definition: spxlpbase.h:1460
type of simplifier
Definition: soplex.h:946
bool isPrimalFeasible() const
is the stored solution primal feasible?
Definition: solbase.h:51
R obj(int i) const
Returns objective value of column i.
Definition: spxlpbase.h:403
void getColVectorReal(int i, DSVectorReal &col) const
gets vector of col i
Definition: soplex.cpp:941
void solveRight(VectorRational &x, const VectorRational &b)
Solves .
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:253
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:7762
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:8232
void printUserSettings()
print non-default parameter values
Definition: soplex.cpp:6162
void changeBoundsReal(const VectorReal &lower, const VectorReal &upper)
changes vectors of column bounds to lower and upper
Definition: soplex.cpp:1600
const char * field3() const
Definition: mpsinput.h:150
RangeType _rangeTypeRational(const Rational &lower, const Rational &upper) const
determines RangeType from rational bounds
Definition: soplex.cpp:7216
SPxSteepPR _pricerQuickSteep
Definition: soplex.h:1556
virtual int getColScaleExp(int i) const
returns scaling factor for column i
Definition: spxscaler.cpp:287
Real getEstimatedCondition()
Definition: spxbasis.h:607
int numColsRational() const
returns number of columns
Definition: soplex.cpp:1085
void syncLPReal()
synchronizes real LP with rational LP, i.e., copies (rounded) rational LP into real LP...
Definition: soplex.cpp:1888
SPxDantzigPR _pricerDantzig
Definition: soplex.h:1553
SPxParMultPR _pricerParMult
Definition: soplex.h:1554
bool getPrimalRational(VectorRational &vector)
gets the primal solution vector if available; returns true on success
Definition: soplex.cpp:3263
void changeObjRational(const VectorRational &obj)
changes objective function vector to obj
Definition: soplex.cpp:2472
std::string statisticString() const
statistical information in form of a string
Definition: soplex.cpp:5015
RangeType _switchRangeType(const RangeType &rangeType) const
switches RANGETYPE_LOWER to RANGETYPE_UPPER and vice versa
Definition: soplex.cpp:7241
SLUFactor _slufactor
Definition: soplex.h:1542
variable set to its upper bound.
Definition: spxsolver.h:191
int primalDegeneratePivots()
get number of primal degenerate pivots
Definition: spxsolver.h:2052
Dynamic index set.Class DIdxSet provides dynamic IdxSet in the sense, that no restrictions are posed ...
Definition: didxset.h:42
void clearBasis()
clears starting basis
Definition: soplex.cpp:4988
const SVectorReal & rowVectorRealInternal(int i) const
returns vector of row i, ignoring scaling
Definition: soplex.cpp:843
void syncLPRational()
synchronizes rational LP with real LP, i.e., copies real LP to rational LP, if sync mode is manual ...
Definition: soplex.cpp:2777
virtual void setRealParam(Real param, const char *name="realparam")
set real parameter
Definition: spxscaler.cpp:118
bool getRedCostReal(VectorReal &vector)
gets the vector of reduced cost values if available; returns true on success
Definition: soplex.cpp:3008
virtual void changeBounds(const VectorBase< R > &newLower, const VectorBase< R > &newUpper, bool scale=false)
Changes variable bounds to newLower and newUpper. scale determines whether the new data should be sca...
Definition: spxlpbase.h:1397
void add(const char *str)
Definition: nameset.cpp:25
int polishIterations()
return number of iterations done with primal algorithm
Definition: spxsolver.h:2089
void getCol(int i, LPColBase< R > &col) const
Gets i &#39;th column.
Definition: spxlpbase.h:336
Real realParam(const RealParam param) const
returns real parameter value
Definition: soplex.cpp:5510
virtual Real time() const =0
~Statistics()
destructor
Definition: statistics.h:52
user sync of real and rational LP
Definition: soplex.h:1164
SPxSteepExPR _pricerSteep
Definition: soplex.h:1557
int boundFlips() const
get number of bound flips.
Definition: spxsolver.h:2040
const char * field0() const
Definition: mpsinput.h:144
int degenPivotsDual
number of dual degenerate pivots
Definition: statistics.h:124
bool hasDual() const
is a dual feasible solution available?
Definition: soplex.cpp:2906
void useFullPerturbation(bool full)
perturb entire problem or only the bounds relevant to the current pivot
Definition: spxsolver.h:860
bool parseSettingsString(char *line)
parses one setting string and returns true on success; note that string is modified ...
Definition: soplex.cpp:6344
const VectorReal & upperRealInternal() const
returns upper bound vector
Definition: soplex.cpp:950
SPxLPBase< Rational > SPxLPRational
Definition: spxlp.h:37
SPxOut spxout
Definition: soplex.h:1416
infinity threshold
Definition: soplex.h:1264
void changeBoundsRational(const VectorRational &lower, const VectorRational &upper)
changes vectors of column bounds to lower and upper
Definition: soplex.cpp:2412
const SVectorRational & colVectorRational(int i) const
returns vector of column i
Definition: soplex.cpp:1211
R lhsUnscaled(int i) const
Returns unscaled left hand side of row number i.
int index(int n) const
Returns index of the n &#39;th nonzero element.
Definition: ssvectorbase.h:174
int numIterations() const
number of iterations since last call to solve
Definition: soplex.cpp:4999
SPxDefaultRT _ratiotesterTextbook
Definition: soplex.h:1558
bool getPrimalRay(VectorBase< R > &vector) const
gets the primal unbounded ray if available; returns true on success
Definition: solbase.h:79
(In)equality for LPs.Class LPRowBase provides constraints for linear programs in the form where a is...
Definition: lprowbase.h:45
int dmaxSizeDual(const int base=2) const
returns size of largest denominator in dual solution
Definition: solbase.h:195
virtual void loadLP(const SPxLP &LP, bool initSlackBasis=true)
copy LP.
Definition: spxsolver.cpp:68
void setSection(Section p_section)
Definition: mpsinput.h:171
variable set to its lower bound.
Definition: spxsolver.h:192
Settings * _currentSettings
Definition: soplex.h:1527
bool getBasisInverseTimesVecRational(const SVectorRational &rhs, SSVectorRational &sol)
computes solution of basis matrix B * sol = rhs; performs rational factorization if not available; re...
Definition: soplex.cpp:4934
SPxId & baseId(int i)
Definition: spxbasis.h:503
virtual const char * getName() const
get name of ratio tester.
Real lhsReal(int i) const
returns left-hand side of row i
Definition: soplex.cpp:914
LPRowReal::Type rowTypeReal(int i) const
returns inequality type of row i
Definition: soplex.cpp:923
Preconfigured SoPlex LP solver.
Sparse vector .A UnitVectorBase is an SVectorBase that can take only one nonzero value with value 1 b...
void _syncRationalSolution()
synchronizes rational solution with real solution, i.e., copies (rounded) rational solution to real s...
Definition: soplex.cpp:8263
int _intParamValues[SoPlex::INTPARAM_COUNT]
array of current integer parameter values
Definition: soplex.h:1396
virtual void changeRow(int n, const LPRowBase< R > &newRow, bool scale=false)
Replaces i &#39;th row of LP with newRow. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1546
virtual void changeUpper(const VectorBase< R > &newUpper, bool scale=false)
Changes vector of upper bounds to newUpper. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1361
void reDim(int newdim)
Resets dimension to newdim.
Definition: ssvectorbase.h:565
virtual const char * getName() const
get name of scaler
Definition: spxscaler.cpp:100
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:6832
Set of strings.Class NameSet implements a symbol or name table. It allows to store or remove names (i...
Definition: nameset.h:61
partial multiple pricer based on Dantzig pricing
Definition: soplex.h:1126
lower and upper bound finite, but different
Definition: soplex.h:1628
bool isDualFeasible() const
is a dual solution available?
Definition: solbase.h:88
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:84
virtual bool writeBasisFile(const char *filename, const NameSet *rowNames, const NameSet *colNames, const bool cpxFormat=false) const
Definition: spxfileio.cpp:39
equilibrium scaling on rows and columns
Definition: soplex.h:1088
Real luSolveTimeReal
time for solving linear systems in real precision
Definition: statistics.h:98
virtual void changeObj(const VectorBase< R > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1257
R * get_ptr()
Only used in slufactor.cpp.
Definition: ssvectorbase.h:99
Rational _rationalNegInfty
Definition: soplex.h:1530
const SVectorRational & rowVectorRational(int i) const
returns vector of row i
Definition: soplex.cpp:1139
int dlcmSizePrimal(const int base=2) const
returns size of least common multiple of denominators in primal solution
Definition: solbase.h:153
void printStatus(std::ostream &os, SPxSolver::Status status)
prints status
Definition: soplex.cpp:6726
virtual void setTerminationIter(int iteration=-1)
set iteration limit.
Definition: spxsolver.cpp:1557
threshold on number of rows vs. number of columns for switching from column to row representations in...
Definition: soplex.h:1294
lower bound equals upper bound
Definition: soplex.h:1631
virtual void addCol(const LPColBase< R > &col, bool scale=false)
Definition: spxlpbase.h:721
std::string description[SoPlex::REALPARAM_COUNT]
array of descriptions for real parameters
Definition: soplex.h:1366
column representation Ax - s = 0, lower <= x <= upper, lhs <= s <= rhs
Definition: soplex.h:1020
bool getSlacksReal(VectorReal &vector)
gets the vector of slack values if available; returns true on success
Definition: soplex.cpp:2963
#define DEFAULT_RANDOM_SEED
Definition: soplex.h:64
int dim() const
Dimension of vector.
Definition: vectorbase.h:215
automatic pricer
Definition: soplex.h:1120
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:199
Everything should be within this namespace.
bool setRealParam(const RealParam param, const Real value, const bool init=true)
sets real parameter value; returns true on success
Definition: soplex.cpp:5936
void _changeLhsReal(const VectorReal &lhs)
changes left-hand side vector for constraints to lhs and adjusts basis
Definition: soplex.cpp:7418
working tolerance for feasibility in floating-point solver during iterative refinement ...
Definition: soplex.h:1276
SPxLPReal * _realLP
Definition: soplex.h:1563
int max() const
Maximal number of indices.
Definition: svectorbase.h:159
bool _lowerFinite(const RangeType &rangeType) const
checks whether RangeType corresponds to finite lower bound
Definition: soplex.cpp:7254
returns the current git hash of SoPlex
void getCols(int start, int end, LPColSetBase< R > &set) const
Gets columns start, ..., end.
Definition: spxlpbase.h:351
the maximum number of rows that are added in each iteration of the decomposition based simplex ...
Definition: soplex.h:991
bool loadSettingsFile(const char *filename)
reads settings file; returns true on success
Definition: soplex.cpp:6295
SPxGeometSC _scalerGeo1
Definition: soplex.h:1546
virtual void changeRange(const VectorBase< R > &newLhs, const VectorBase< R > &newRhs, bool scale=false)
Changes left and right hand side vectors. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1484
int numNonzerosReal() const
returns number of nonzeros
Definition: soplex.cpp:802
SoPlex & operator=(const SoPlex &rhs)
assignment operator
Definition: soplex.cpp:610
bool getRedCostViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of reduced costs; returns true on success
Definition: soplex.cpp:3457
SPxDevexPR _pricerDevex
Definition: soplex.h:1555
void clear()
Remove all indices.
Definition: svectorbase.h:396
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:130
Real objReal(int i) const
returns objective value of column i
Definition: soplex.cpp:1014
DataArray< RangeType > _rowTypes
Definition: soplex.h:1635
void _removeColReal(int i)
removes column i
Definition: soplex.cpp:7797
void _changeRowReal(int i, const LPRowReal &lprow)
replaces row i with lprow and adjusts basis
Definition: soplex.cpp:7393
void setIntegralityInformation(int ncols, int *intInfo)
pass integrality information about the variables to the solver
Definition: soplex.cpp:1067
SPxSumST _starterSum
Definition: soplex.h:1550
bool readStringRational(const char *s, Rational &value)
read Rational from string
Definition: rational.cpp:3462
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:3958
row representation (lower,lhs) <= (x,Ax) <= (upper,rhs)
Definition: soplex.h:1023
apply rational reconstruction after each iterative refinement?
Definition: soplex.h:891
void _changeColReal(int i, const LPColReal &lpcol)
replaces column i with lpcol and adjusts basis
Definition: soplex.cpp:7550
solve() aborted due to detection of cycling.
Definition: spxsolver.h:211
Real minAbsNonzeroReal() const
returns smallest non-zero element in absolute value
Definition: soplex.cpp:811
type of pricer
Definition: soplex.h:955
Saving LPs in a form suitable for SoPlex.Class SPxLPBase provides the data structures required for sa...
Definition: spxlpbase.h:80
const VectorReal & lowerRealInternal() const
returns lower bound vector
Definition: soplex.cpp:977
bool getDualReal(VectorReal &vector)
gets the dual solution vector if available; returns true on success
Definition: soplex.cpp:2993
SPxHarrisRT _ratiotesterHarris
Definition: soplex.h:1559
DSVectorBase< Real > DSVectorReal
Definition: dsvector.h:29
void changeColReal(int i, const LPColReal &lpcol)
replaces column i with lpcol
Definition: soplex.cpp:1506
working tolerance for optimality in floating-point solver during iterative refinement ...
Definition: soplex.h:1279
void clearLPReal()
clears the LP
Definition: soplex.cpp:1867
Preconfigured SoPlex LP-solver.
Definition: soplex.h:90
should the dual of the complementary problem be used in the decomposition simplex?
Definition: soplex.h:882
void removeRowRational(int i)
removes row i
Definition: soplex.cpp:2564
R lowerUnscaled(int i) const
Returns unscaled lower bound of column i.
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:112
Type
(In)Equality type of an LP row.
Definition: lprowbase.h:72
int iterations
number of iterations/pivots
Definition: statistics.h:101
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:429
virtual const char * getName() const
get name of pricer.
Definition: spxpricer.h:109
R upper() const
Gets upper bound.
Definition: lpcolbase.h:125
minimize number of basic slack variables, i.e. more variables between bounds
Definition: soplex.h:1239
int upper[SoPlex::INTPARAM_COUNT]
array of upper bounds for int parameter values
Definition: soplex.h:1357
Real lower[SoPlex::REALPARAM_COUNT]
array of lower bounds for real parameter values
Definition: soplex.h:1370
SPxVectorST _starterVector
Definition: soplex.h:1551
void setIntegralityInformation(int ncols, int *intInfo)
pass integrality information about the variables to the solver
Definition: spxsolver.cpp:1964
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
bool getBoundViolationReal(Real &maxviol, Real &sumviol)
gets violation of bounds; returns true on success
Definition: soplex.cpp:3038
const VectorRational & upperRational() const
returns upper bound vector
Definition: soplex.cpp:1220
NameSet * _colNames
Definition: soplex.h:1749
int boundflips
number of dual bound flips
Definition: statistics.h:105
decide according to READMODE
Definition: soplex.h:1197
void clearAllData()
clears all statistics
Definition: statistics.cpp:90
SPxSolver _solver
Definition: soplex.h:1541
const char * getGitHash()
Definition: spxgithash.cpp:23
mode for a posteriori feasibility checks
Definition: soplex.h:970
refactor threshold for nonzeros in last factorized basis matrix compared to updated basis matrix ...
Definition: soplex.h:1303
nothing known on loaded problem.
Definition: spxsolver.h:219
VarStatus getBasisRowStatus(int row) const
gets basis status for a single row
Definition: spxsolver.cpp:1777
int _optimizeCalls
Definition: soplex.h:1802
variable is basic.
Definition: spxsolver.h:195
LPRowRational::Type rowTypeRational(int i) const
returns inequality type of row i
Definition: soplex.cpp:1184
type of algorithm, i.e., primal or dual
Definition: soplex.h:922
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:204
VarStatus getBasisColStatus(int col) const
gets basis status for a single column
Definition: spxsolver.cpp:1783
void print(std::ostream &os)
prints statistics
Definition: statistics.cpp:148
void clearSolvingData()
clears statistics on solving process
Definition: statistics.cpp:97
void _recomputeRangeTypesReal()
recomputes range types from scratch using real LP
Definition: soplex.cpp:8182
virtual void addRow(const LPRowBase< R > &row, bool scale=false)
Definition: spxlpbase.h:560
std::string name[SoPlex::INTPARAM_COUNT]
array of names for integer parameters
Definition: soplex.h:1349
DataArray< UnitVectorRational *> _unitMatrixRational
Definition: soplex.h:1610
bool getDualFarkasRational(VectorRational &vector)
gets the Farkas proof if LP is infeasible; returns true on success
Definition: soplex.cpp:3338
stalling refinement limit (-1 if unlimited)
Definition: soplex.h:937
int lower[SoPlex::INTPARAM_COUNT]
array of lower bounds for int parameter values
Definition: soplex.h:1355
DataArray< SPxSolver::VarStatus > _basisStatusRows
Definition: soplex.h:1786
std::ifstream spxifstream
Definition: spxfileio.h:43
Set of LP rows.Class LPRowSetBase implements a set of LPRowBase%s. Unless for memory limitations...
Definition: lprowsetbase.h:44
Timer * readingTime
reading time not included in solving time
Definition: statistics.h:88
int iterationsFromBasis
number of iterations from Basis
Definition: statistics.h:103
int iterationsPolish
number of iterations during solution polishing
Definition: statistics.h:104
SPxSolver::VarStatus basisColStatus(int col) const
returns basis status for a single column
Definition: soplex.cpp:3882
void _solveDecompositionDualSimplex()
solves LP using the decomposition based dual simplex
Definition: solvedbds.cpp:48
void getNdualNorms(int &nnormsRow, int &nnormsCol) const
gets number of available dual norms
Definition: soplex.cpp:1043
should dual infeasibility be tested in order to try to return a dual solution even if primal infeasib...
Definition: soplex.h:869
int defaultValue[SoPlex::INTPARAM_COUNT]
array of default values for integer parameters
Definition: soplex.h:1353
virtual void changeSense(SPxSense sns)
Changes optimization sense to sns.
Definition: spxlpbase.h:1706
void getUpperUnscaled(DVector &vec) const
Gets unscaled upper bound vector.
uint32_t getSeed() const
returns the initial seed shift
Definition: random.h:113
Timer * solvingTime
solving time
Definition: statistics.h:89
int size() const
return nr. of elements.
Definition: dataarray.h:211
generic solution-based crash basis
Definition: soplex.h:1113
std::string description[SoPlex::BOOLPARAM_COUNT]
array of descriptions for boolean parameters
Definition: soplex.h:1340
Type type() const
return current Type.
Definition: spxsolver.h:474
const VectorReal & rhsRealInternal() const
returns right-hand side vector, ignoring scaling
Definition: soplex.cpp:869
bool boolParam(const BoolParam param) const
returns boolean parameter value
Definition: soplex.cpp:5490
void setSeed(uint32_t initshift)
initialize all seeds of the random number generator.
Definition: random.h:124
void unscaleLP()
unscales the lp and clears basis
virtual const char * getName() const
get name of starter.
Definition: spxstarter.h:88
the verbosity of the decomposition based simplex
Definition: soplex.h:997
const VectorBase< R > & upper() const
Definition: lpcolsetbase.h:166
Real getSolveTime() const
time spent in solves
Definition: slufactor.h:241
should lifting be used to reduce range of nonzero matrix coefficients?
Definition: soplex.h:863
void printProblemStatistics(std::ostream &os)
Definition: spxlpbase.h:1172
int dmaxSizePrimalRational(const int base=2)
get size of largest denominator in primal solution
Definition: soplex.cpp:3800
bool getEstimatedCondition(Real &condition)
computes an estimated condition number for the current basis matrix using the power method; returns t...
Definition: soplex.cpp:4037
int dmaxSizePrimal(const int base=2) const
returns size of largest denominator in primal solution
Definition: solbase.h:181
Real maxObjReal(int i) const
returns objective value of column i after transformation to a maximization problem; since this is how...
Definition: soplex.cpp:1034
void setRandomSeed(unsigned int seed)
set the random seeds of the solver instance
Definition: soplex.cpp:7091
DataArray< int > _rationalLUSolverBind
Definition: soplex.h:1589
should the degeneracy be computed for each basis?
Definition: soplex.h:879
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:114
bool _applyPolishing
Definition: soplex.h:1572
bool getExactCondition(Real &condition)
computes the exact condition number for the current basis matrix using the power method; returns true...
Definition: soplex.cpp:4052
SPxStatus
basis status.
Definition: spxbasis.h:90
virtual int getRowScaleExp(int i) const
returns scaling factor for row i
Definition: spxscaler.cpp:294
const char * getScalerName()
name of scaling method
Definition: soplex.cpp:5053
Real solveTime() const
time spent in last call to solve
Definition: soplex.cpp:5007
void addColsReal(const LPColSetReal &lpcolset)
adds multiple columns
Definition: soplex.cpp:1358
const SVectorBase< R > & colVector(int i) const
Returns column vector of column i.
Definition: spxlpbase.h:373
Random random
The random number generator used throughout the whole computation. Its seed can be modified...
Definition: spxsolver.h:394
const char * field1() const
Definition: mpsinput.h:146
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
virtual void changeElement(int i, int j, const R &val, bool scale=false)
Changes LP element (i, j) to val. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1626
SPxSolver::Status status() const
returns the current solver status
Definition: soplex.cpp:2882
SolReal _solReal
Definition: soplex.h:1789
zero tolerance used in update of the factorization
Definition: soplex.h:1258
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:2292
lower limit on objective value
Definition: soplex.h:1270
both bounds are infinite
Definition: soplex.h:1619
bool getRedCostViolationReal(Real &maxviol, Real &sumviol)
gets violation of reduced costs; returns true on success
Definition: soplex.cpp:3119
BoolParam
boolean parameters
Definition: soplex.h:860
bool _hasSolReal
Definition: soplex.h:1794
bool _isSolveStopped(bool &stoppedTime, bool &stoppedIter) const
should solving process be stopped?
Definition: soplex.cpp:7176
virtual void changeLhs(const VectorBase< R > &newLhs, bool scale=false)
Changes left hand side vector for constraints to newLhs. scale determines whether the new data should...
Definition: spxlpbase.h:1428
virtual Real getCoefUnscaled(const SPxLPBase< Real > &lp, int row, int col) const
returns unscaled coefficient of LP
Definition: spxscaler.cpp:595
void _changeBoundsReal(const VectorReal &lower, const VectorReal &upper)
changes vectors of column bounds to lower and upper and adjusts basis
Definition: soplex.cpp:7661
#define SOPLEX_SUBVERSION
Definition: spxdefines.h:43
Settings()
default constructor initializing default settings
Definition: soplex.cpp:501
maximum number of conjugate gradient iterations in least square scaling
Definition: soplex.h:982
sparse pricing threshold (#violations < dimension * SPARSITY_THRESHOLD activates sparse pricing) ...
Definition: soplex.h:1291
Settings & operator=(const Settings &settings)
assignment operator
Definition: soplex.cpp:523
void setFeastol(Real d)
set parameter feastol.
Definition: spxsolver.cpp:930
bool getDualFarkas(VectorBase< R > &vector) const
gets the Farkas proof if available; returns true on success
Definition: solbase.h:116
void addRowReal(const LPRowReal &lprow)
adds a single row
Definition: soplex.cpp:1304
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:3293
dual feasibility tolerance
Definition: soplex.h:1249
void _ensureRealLPLoaded()
ensures that the real LP and the basis are loaded in the solver; performs no sync ...
Definition: soplex.cpp:7949
void invalidate()
invalidate solution
Definition: solbase.h:209
no solution polishing
Definition: soplex.h:1233
void changeRowReal(int i, const LPRowReal &lprow)
replaces row i with lprow
Definition: soplex.cpp:1376
void setBasis(const SPxSolver::VarStatus rows[], const SPxSolver::VarStatus cols[])
sets starting basis via arrays of statuses
Definition: soplex.cpp:4958
bool hasPrimalRay() const
is a primal unbounded ray available?
Definition: solbase.h:73
bool setIntParam(const IntParam param, const int value, const bool init=true)
sets integer parameter value; returns true on success
Definition: soplex.cpp:5594
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:624
SolRational _solRational
Definition: soplex.h:1790
void getLhsUnscaled(VectorBase< Real > &vec) const
Returns unscaled left hand side vector.
bool saveSettingsFile(const char *filename, const bool onlyChanged=false) const
writes settings file; returns true on success
Definition: soplex.cpp:6217
UnitVectorBase< Real > UnitVectorReal
Definition: unitvector.h:30
std::string rationalToString(const Rational &r, const int precision)
convert rational number to string
Definition: rational.cpp:3452
Real objValueReal()
returns the objective value if a primal solution is available
Definition: soplex.cpp:2922
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:8298
void changeRhsReal(const VectorReal &rhs)
changes right-hand side vector to rhs
Definition: soplex.cpp:1432
SPxLeastSqSC _scalerLeastsq
Definition: soplex.h:1548
geometric frequency at which to apply rational reconstruction
Definition: soplex.h:1297
Real opttol() const
allowed optimality, i.e., dual feasibility tolerance.
Definition: spxsolver.h:784
void changeElementRational(int i, int j, const Rational &val)
changes matrix entry in row i and column j to val
Definition: soplex.cpp:2528
bool isRowBasic(int i) const
is the i &#39;th row vector basic ?
Definition: spxsolver.h:1250
SPxStarter * _starter
Definition: soplex.h:1567
bool _hasSolRational
Definition: soplex.h:1795
void hyperPricing(bool h)
enable or disable hyper sparse pricing
Definition: spxsolver.cpp:964
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:5470
void _enableSimplifierAndScaler()
enables simplifier and scaler according to current parameters
Definition: soplex.cpp:7876
primal simplex algorithm, i.e., entering for column and leaving for row representation ...
Definition: soplex.h:1030
bool setBoolParam(const BoolParam param, const bool value, const bool init=true)
sets boolean parameter value; returns true on success
Definition: soplex.cpp:5540
should LP be transformed to equality form before a rational solve?
Definition: soplex.h:866
void setOutstream(SPxOut &newOutstream)
Definition: spxsolver.h:431
const char * field2() const
Definition: mpsinput.h:148
Real sumDualDegen
the sum of the rate of dual degeneracy at each iteration
Definition: statistics.h:127
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:7117
DVectorBase< R > _dual
Definition: solbase.h:221
virtual void clear()
clears the LP.
Definition: spxlpbase.h:1078
void setMemFactor(Real f)
set refactor threshold for memory growth in current factor update compared to the last factorization ...
Definition: spxsolver.h:450
void solveLeft(VectorRational &x, const VectorRational &b)
Solves .
int number(const DataKey &pkey) const
returns number of name with DataKey pkey in NameSet.
Definition: nameset.h:212
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1715
SPxSolver::VarStatus basisRowStatus(int row) const
returns basis status for a single row
Definition: soplex.cpp:3857
the number of iterations before the decomposition simplex initialisation is terminated.
Definition: soplex.h:988
store only real LP
Definition: soplex.h:1158
virtual void reLoad()
reload LP.
Definition: spxsolver.cpp:55
const VectorRational & maxObjRational() const
returns objective function vector after transformation to a maximization problem; since this is how i...
Definition: soplex.cpp:1285
upper threshold in lifting (nonzero matrix coefficients with larger absolute value will be reformulat...
Definition: soplex.h:1288
void _addRowsReal(const LPRowSetReal &lprowset)
adds multiple rows to the real LP and adjusts basis
Definition: soplex.cpp:7306
int numColsReal() const
returns number of columns
Definition: soplex.cpp:793
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:1563
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:223
bool hasPrimalRay() const
is a primal unbounded ray available?
Definition: soplex.cpp:2898
void removeColRational(int i)
removes column i
Definition: soplex.cpp:2659
bool _isRealLPScaled
Definition: soplex.h:1571
IntParam
integer parameters
Definition: soplex.h:913
force iterative refinement
Definition: soplex.h:1187
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:483
~NameSet()
destructor.
Definition: nameset.cpp:259
SPxSolver::Status _status
Definition: soplex.h:1783
void setTiming(Timer::TYPE ttype)
set timing type
Definition: spxsolver.h:806
virtual R maxAbsNzo(bool unscaled=true) const
Absolute biggest non-zero element in (in rational case possibly scaled) LP.
void getObjRational(VectorRational &obj) const
gets objective function vector
Definition: soplex.cpp:1256
int num() const
Returns the number of LPColBases currently in LPColSetBase.
Definition: lpcolsetbase.h:82
virtual void setIntParam(int param, const char *name="intparam")
set int parameter
Definition: spxscaler.cpp:121
virtual void computePrimalActivity(const VectorBase< R > &primal, VectorBase< R > &activity, const bool unscaled=true) const
Computes activity of the rows for a given primal vector; activity does not need to be zero...
Rational _rationalZero
Definition: soplex.h:1807
LP column.Class LPColBase provides a datatype for storing the column of an LP a the form similar to ...
Definition: lpcolbase.h:45
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:468
RangeType _rangeTypeReal(const Real &lower, const Real &upper) const
determines RangeType from real bounds
Definition: soplex.cpp:7191
void _completeRangeTypesRational()
completes range type arrays after adding columns and/or rows
Definition: soplex.cpp:8169
const VectorReal & lhsRealInternal() const
returns left-hand side vector, ignoring scaling
Definition: soplex.cpp:896
solve() aborted due to objective limit.
Definition: spxsolver.h:214
columnwise representation.
Definition: spxsolver.h:108
void spx_free(T &p)
Release memory.
Definition: spxalloc.h:109
SPxSimplifier * _simplifier
Definition: soplex.h:1565
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:2641
void addRowsReal(const LPRowSetReal &lprowset)
adds multiple rows
Definition: soplex.cpp:1322
bool has(int pnum) const
does NameSet has a name with number pnum?
Definition: nameset.h:231
geometric mean scaling on rows and columns, max 1 round
Definition: soplex.h:1091
virtual void addCols(const LPColSetBase< R > &pset, bool scale=false)
Definition: spxlpbase.h:773
void scaleValue(int i, int scaleExp)
Scale i &#39;th element by a.
Definition: ssvectorbase.h:242
perturb the entire problem or only the relevant bounds of s single pivot?
Definition: soplex.h:906
Basis is singular, numerical troubles?
Definition: spxsolver.h:215
R value(int n) const
Returns value of the n &#39;th nonzero element.
Definition: ssvectorbase.h:182
const SVector & unitVector(int i) const
return i &#39;th unit vector.
Definition: spxsolver.h:1196
maximize number of basic slack variables, i.e. more variables on bounds
Definition: soplex.h:1236
should row and bound violations be computed explicitly in the update of reduced problem in the decomp...
Definition: soplex.h:885
Basis is primal feasible.
Definition: spxbasis.h:96
upper bound is finite, lower bound is infinite
Definition: soplex.h:1625
bool getBoundViolationRational(Rational &maxviol, Rational &sumviol)
gets violation of bounds; returns true on success
Definition: soplex.cpp:3353
LP has a usable Basis (maybe LP is changed).
Definition: spxsolver.h:217
SPxAutoPR _pricerAuto
Definition: soplex.h:1552
int num() const
Returns the number of LPRowBases in LPRowSetBase.
Definition: lprowsetbase.h:83
int primalIterations()
return number of iterations done with primal algorithm
Definition: spxsolver.h:2076
least square scaling
Definition: soplex.h:1097
only error output
Definition: soplex.h:1050
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:221
int totalSizeDualRational(const int base=2)
get size of dual solution
Definition: soplex.cpp:3758
int degenPivotsPrimal
number of primal degenerate pivots
Definition: statistics.h:123
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:207
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:1709
const VectorRational & lowerRational() const
returns lower bound vector
Definition: soplex.cpp:1238