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