1 /* $Id: AbcSimplex.hpp 2385 2019-01-06 19:43:06Z unxusr $ */
2 // Copyright (C) 2002, International Business Machines
3 // Corporation and others, Copyright (C) 2012, FasterCoin.  All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5 /*
6   Authors
7 
8   John Forrest
9 
10 */
11 #ifndef AbcSimplex_H
12 #define AbcSimplex_H
13 
14 #include <iostream>
15 #include <cfloat>
16 #include "ClpModel.hpp"
17 #include "ClpMatrixBase.hpp"
18 #include "CoinIndexedVector.hpp"
19 #include "AbcCommon.hpp"
20 class AbcSimplex;
21 #include "ClpSolve.hpp"
22 #include "CoinAbcCommon.hpp"
23 #include "ClpSimplex.hpp"
24 class AbcDualRowPivot;
25 class AbcPrimalColumnPivot;
26 class AbcSimplexFactorization;
27 class AbcNonLinearCost;
28 class OsiAbcSolverInterface;
29 class CoinWarmStartBasis;
30 class ClpDisasterHandler;
31 class AbcSimplexProgress;
32 class AbcMatrix;
33 class AbcTolerancesEtc;
34 
35 /** This solves LPs using the simplex method
36 
37     It inherits from ClpModel and all its arrays are created at
38     algorithm time. Originally I tried to work with model arrays
39     but for simplicity of coding I changed to single arrays with
40     structural variables then row variables.  Some coding is still
41     based on old style and needs cleaning up.
42 
43     For a description of algorithms:
44 
45     for dual see AbcSimplexDual.hpp and at top of AbcSimplexDual.cpp
46     for primal see AbcSimplexPrimal.hpp and at top of AbcSimplexPrimal.cpp
47 
48     There is an algorithm data member.  + for primal variations
49     and - for dual variations
50 
51 */
52 #define PAN
53 #if ABC_NORMAL_DEBUG > 0
54 #define PRINT_PAN 1
55 #endif
56 #define TRY_ABC_GUS
57 #define HEAVY_PERTURBATION 57
58 #if ABC_PARALLEL == 1
59 // Use pthreads
60 #include <pthread.h>
61 #endif
62 class AbcSimplex : public ClpSimplex {
63   friend void AbcSimplexUnitTest(const std::string &mpsDir);
64 
65 public:
66   /** enums for status of various sorts.
67       ClpModel order (and warmstart) is
68       isFree = 0x00,
69       basic = 0x01,
70       atUpperBound = 0x02,
71       atLowerBound = 0x03,
72       isFixed means fixed at lower bound and out of basis
73   */
74   enum Status {
75     atLowerBound = 0x00, // so we can use bottom two bits to sort and swap signs
76     atUpperBound = 0x01,
77     isFree = 0x04,
78     superBasic = 0x05,
79     basic = 0x06,
80     isFixed = 0x07
81   };
82   // For Dual
83   enum FakeBound {
84     noFake = 0x00,
85     lowerFake = 0x01,
86     upperFake = 0x02,
87     bothFake = 0x03
88   };
89 
90   /**@name Constructors and destructor and copy */
91   //@{
92   /// Default constructor
93   AbcSimplex(bool emptyMessages = false);
94 
95   /** Copy constructor.
96   */
97   AbcSimplex(const AbcSimplex &rhs);
98   /** Copy constructor from model.
99   */
100   AbcSimplex(const ClpSimplex &rhs);
101   /** Subproblem constructor.  A subset of whole model is created from the
102       row and column lists given.  The new order is given by list order and
103       duplicates are allowed.  Name and integer information can be dropped
104       Can optionally modify rhs to take into account variables NOT in list
105       in this case duplicates are not allowed (also see getbackSolution)
106   */
107   AbcSimplex(const ClpSimplex *wholeModel,
108     int numberRows, const int *whichRows,
109     int numberColumns, const int *whichColumns,
110     bool dropNames = true, bool dropIntegers = true,
111     bool fixOthers = false);
112   /** Subproblem constructor.  A subset of whole model is created from the
113       row and column lists given.  The new order is given by list order and
114       duplicates are allowed.  Name and integer information can be dropped
115       Can optionally modify rhs to take into account variables NOT in list
116       in this case duplicates are not allowed (also see getbackSolution)
117   */
118   AbcSimplex(const AbcSimplex *wholeModel,
119     int numberRows, const int *whichRows,
120     int numberColumns, const int *whichColumns,
121     bool dropNames = true, bool dropIntegers = true,
122     bool fixOthers = false);
123   /** This constructor modifies original AbcSimplex and stores
124       original stuff in created AbcSimplex.  It is only to be used in
125       conjunction with originalModel */
126   AbcSimplex(AbcSimplex *wholeModel,
127     int numberColumns, const int *whichColumns);
128   /** This copies back stuff from miniModel and then deletes miniModel.
129       Only to be used with mini constructor */
130   void originalModel(AbcSimplex *miniModel);
131   /** This constructor copies from ClpSimplex */
132   AbcSimplex(const ClpSimplex *clpSimplex);
133   /// Put back solution into ClpSimplex
134   void putBackSolution(ClpSimplex *simplex);
135   /** Array persistence flag
136       If 0 then as now (delete/new)
137       1 then only do arrays if bigger needed
138       2 as 1 but give a bit extra if bigger needed
139   */
140   //void setPersistenceFlag(int value);
141   /// Save a copy of model with certain state - normally without cuts
142   void makeBaseModel();
143   /// Switch off base model
144   void deleteBaseModel();
145   /// See if we have base model
baseModel() const146   inline AbcSimplex *baseModel() const
147   {
148     return abcBaseModel_;
149   }
150   /** Reset to base model (just size and arrays needed)
151       If model NULL use internal copy
152   */
153   void setToBaseModel(AbcSimplex *model = NULL);
154   /// Assignment operator. This copies the data
155   AbcSimplex &operator=(const AbcSimplex &rhs);
156   /// Destructor
157   ~AbcSimplex();
158   //@}
159 
160   /**@name Functions most useful to user */
161   //@{
162   /** Dual algorithm - see AbcSimplexDual.hpp for method.
163   */
164   int dual();
165   int doAbcDual();
166   /** Primal algorithm - see AbcSimplexPrimal.hpp for method.
167   */
168   int primal(int ifValuesPass);
169   int doAbcPrimal(int ifValuesPass);
170   /// Returns a basis (to be deleted by user)
171   CoinWarmStartBasis *getBasis() const;
172   /// Passes in factorization
173   void setFactorization(AbcSimplexFactorization &factorization);
174   /// Swaps factorization
175   AbcSimplexFactorization *swapFactorization(AbcSimplexFactorization *factorization);
176   /// Gets clean and emptyish factorization
177   AbcSimplexFactorization *getEmptyFactorization();
178   /** Tightens primal bounds to make dual faster.  Unless
179       fixed or doTight>10, bounds are slightly looser than they could be.
180       This is to make dual go faster and is probably not needed
181       with a presolve.  Returns non-zero if problem infeasible.
182 
183       Fudge for branch and bound - put bounds on columns of factor *
184       largest value (at continuous) - should improve stability
185       in branch and bound on infeasible branches (0.0 is off)
186   */
187   int tightenPrimalBounds();
188   /// Sets row pivot choice algorithm in dual
189   void setDualRowPivotAlgorithm(AbcDualRowPivot &choice);
190   /// Sets column pivot choice algorithm in primal
191   void setPrimalColumnPivotAlgorithm(AbcPrimalColumnPivot &choice);
192   //@}
193   /// If user left factorization frequency then compute
194   void defaultFactorizationFrequency();
195   //@}
196 
197   /**@name most useful gets and sets */
198   //@{
199   /// factorization
factorization() const200   inline AbcSimplexFactorization *factorization() const
201   {
202     return reinterpret_cast< AbcSimplexFactorization * >(abcFactorization_);
203   }
204 #ifdef EARLY_FACTORIZE
205   /// Early factorization
earlyFactorization() const206   inline AbcSimplexFactorization *earlyFactorization() const
207   {
208     return reinterpret_cast< AbcSimplexFactorization * >(abcEarlyFactorization_);
209   }
210 #endif
211   /// Factorization frequency
212   int factorizationFrequency() const;
213   void setFactorizationFrequency(int value);
214   /// Maximum rows
maximumAbcNumberRows() const215   inline int maximumAbcNumberRows() const
216   {
217     return maximumAbcNumberRows_;
218   }
219   /// Maximum Total
maximumNumberTotal() const220   inline int maximumNumberTotal() const
221   {
222     return maximumNumberTotal_;
223   }
maximumTotal() const224   inline int maximumTotal() const
225   {
226     return maximumNumberTotal_;
227   }
228   /// Return true if the objective limit test can be relied upon
229   bool isObjectiveLimitTestValid() const;
230   /// Number of variables (includes spare rows)
numberTotal() const231   inline int numberTotal() const
232   {
233     return numberTotal_;
234   }
235   /// Number of variables without fixed to zero (includes spare rows)
numberTotalWithoutFixed() const236   inline int numberTotalWithoutFixed() const
237   {
238     return numberTotalWithoutFixed_;
239   }
240   /// Useful arrays (0,1,2,3,4,5,6,7)
usefulArray(int index)241   inline CoinPartitionedVector *usefulArray(int index)
242   {
243     return &usefulArray_[index];
244   }
usefulArray(int index) const245   inline CoinPartitionedVector *usefulArray(int index) const
246   {
247     return const_cast< CoinPartitionedVector * >(&usefulArray_[index]);
248   }
249   //@}
250 
251   /******************** End of most useful part **************/
252   /**@name Functions less likely to be useful to casual user */
253   //@{
254   /** Given an existing factorization computes and checks
255       primal and dual solutions.  Uses current problem arrays for
256       bounds.  Returns feasibility states */
257   int getSolution();
258   /// Sets objectiveValue_ from rawObjectiveValue_
259   void setClpSimplexObjectiveValue();
260   /** Sets dual values pass djs using unscaled duals
261       type 1 - values pass
262       type 2 - just use as infeasibility weights
263       type 3 - as 2 but crash
264   */
265   void setupDualValuesPass(const double *fakeDuals,
266     const double *fakePrimals,
267     int type);
268   /// Gets objective value with all offsets but as for minimization
minimizationObjectiveValue() const269   inline double minimizationObjectiveValue() const
270   {
271     return objectiveValue_ - dblParam_[ClpObjOffset];
272   }
273   /// Current dualTolerance (will end up as dualTolerance_)
currentDualTolerance() const274   inline double currentDualTolerance() const
275   {
276     return currentDualTolerance_;
277   }
setCurrentDualTolerance(double value)278   inline void setCurrentDualTolerance(double value)
279   {
280     currentDualTolerance_ = value;
281   }
282   /// Return pointer to details of costs
abcNonLinearCost() const283   inline AbcNonLinearCost *abcNonLinearCost() const
284   {
285     return abcNonLinearCost_;
286   }
287   /// Perturbation (fixed) - is just scaled random numbers
perturbationSaved() const288   double *perturbationSaved() const
289   {
290     return perturbationSaved_;
291   }
292   /// Acceptable pivot for this iteration
acceptablePivot() const293   inline double acceptablePivot() const
294   {
295     return acceptablePivot_;
296   }
297   /// Set to 1 if no free or super basic
ordinaryVariables() const298   inline int ordinaryVariables() const
299   {
300     return ordinaryVariables_;
301   }
302   /// Number of ordinary (lo/up) in tableau row
numberOrdinary() const303   inline int numberOrdinary() const
304   {
305     return numberOrdinary_;
306   }
307   /// Set number of ordinary (lo/up) in tableau row
setNumberOrdinary(int number)308   inline void setNumberOrdinary(int number)
309   {
310     numberOrdinary_ = number;
311   }
312   /// Current dualBound (will end up as dualBound_)
currentDualBound() const313   inline double currentDualBound() const
314   {
315     return currentDualBound_;
316   }
317   /// dual row pivot choice
dualRowPivot() const318   inline AbcDualRowPivot *dualRowPivot() const
319   {
320     return abcDualRowPivot_;
321   }
322   /// primal column pivot choice
primalColumnPivot() const323   inline AbcPrimalColumnPivot *primalColumnPivot() const
324   {
325     return abcPrimalColumnPivot_;
326   }
327   /// Abc Matrix
abcMatrix() const328   inline AbcMatrix *abcMatrix() const
329   {
330     return abcMatrix_;
331   }
332   /** Factorizes using current basis.
333       solveType - 1 iterating, 0 initial, -1 external
334       If 10 added then in primal values pass
335       Return codes are as from AbcSimplexFactorization unless initial factorization
336       when total number of singularities is returned.
337       Special case is numberRows_+1 -> all slack basis.
338       if initial should be before permute in
339       pivotVariable may be same as toExternal
340   */
341   int internalFactorize(int solveType);
342   /**
343      Permutes in from ClpModel data - assumes scale factors done
344      and AbcMatrix exists but is in original order (including slacks)
345      For now just add basicArray at end
346      ==
347      But could partition into
348      normal (i.e. reasonable lower/upper)
349      abnormal - free, odd bounds
350      fixed
351      ==
352      sets a valid pivotVariable
353      Slacks always shifted by offset
354      Fixed variables always shifted by offset
355      Recode to allow row objective so can use pi from idiot etc
356   */
357   void permuteIn();
358   /// deals with new basis and puts in abcPivotVariable_
359   void permuteBasis();
360   /// Permutes out - bit settings same as stateOfProblem
361   void permuteOut(int whatsWanted);
362   /// Save data
363   ClpDataSave saveData();
364   /// Restore data
365   void restoreData(ClpDataSave saved);
366   /// Clean up status - make sure no superbasic etc
367   void cleanStatus(bool valuesPass = false);
368   /** Computes duals from scratch. If givenDjs then
369       allows for nonzero basic djs.  Returns number of refinements  */
370   int computeDuals(double *givenDjs, CoinIndexedVector *array1, CoinIndexedVector *array2);
371   /// Computes primals from scratch.  Returns number of refinements
372   int computePrimals(CoinIndexedVector *array1, CoinIndexedVector *array2);
373   /// Computes nonbasic cost and total cost
374   void computeObjective();
375   /// set multiple sequence in
376   void setMultipleSequenceIn(int sequenceIn[4]);
377   /**
378      Unpacks one column of the matrix into indexed array
379      Uses sequenceIn_
380   */
unpack(CoinIndexedVector & rowArray) const381   inline void unpack(CoinIndexedVector &rowArray) const
382   {
383     unpack(rowArray, sequenceIn_);
384   }
385   /**
386      Unpacks one column of the matrix into indexed array
387   */
388   void unpack(CoinIndexedVector &rowArray, int sequence) const;
389   /**
390      This does basis housekeeping and does values for in/out variables.
391      Can also decide to re-factorize
392   */
393   int housekeeping(/*double objectiveChange*/);
394   /** This sets largest infeasibility and most infeasible and sum
395       and number of infeasibilities (Primal) */
396   void checkPrimalSolution(bool justBasic);
397   /** This sets largest infeasibility and most infeasible and sum
398       and number of infeasibilities (Dual) */
399   void checkDualSolution();
400   /** This sets largest infeasibility and most infeasible and sum
401       and number of infeasibilities AND sumFakeInfeasibilites_ (Dual) */
402   void checkDualSolutionPlusFake();
403   /** This sets sum and number of infeasibilities (Dual and Primal) */
404   void checkBothSolutions();
405   /// Computes solutions - 1 do duals, 2 do primals, 3 both (returns number of refinements)
406   int gutsOfSolution(int type);
407   /// Computes solutions - 1 do duals, 2 do primals, 3 both (returns number of refinements)
408   int gutsOfPrimalSolution(int type);
409   /// Saves good status etc
410   void saveGoodStatus();
411   /// Restores previous good status and says trouble
412   void restoreGoodStatus(int type);
413 #define rowUseScale_ scaleFromExternal_
414 #define inverseRowUseScale_ scaleToExternal_
415   /// After modifying first copy refreshes second copy and marks as updated
416   void refreshCosts();
417   void refreshLower(unsigned int type = ~(ROW_LOWER_SAME | COLUMN_UPPER_SAME));
418   void refreshUpper(unsigned int type = ~(ROW_LOWER_SAME | COLUMN_LOWER_SAME));
419   /// Sets up all extra pointers
420   void setupPointers(int maxRows, int maxColumns);
421   /// Copies all saved versions to working versions and may do something for perturbation
422   void copyFromSaved(int type = 31);
423   /// fills in perturbationSaved_ from start with 0.5+random
424   void fillPerturbation(int start, int number);
425   /// For debug - prints summary of arrays which are out of kilter
426   void checkArrays(int ignoreEmpty = 0) const;
427   /// For debug - summarizes dj situation (1 recomputes duals first, 2 checks duals as well)
428   void checkDjs(int type = 1) const;
429   /// For debug - checks solutionBasic
430   void checkSolutionBasic() const;
431   /// For debug - moves solution back to external and computes stuff (always checks djs)
432   void checkMoveBack(bool checkDuals);
433 
434 public:
435   /** For advanced use.  When doing iterative solves things can get
436       nasty so on values pass if incoming solution has largest
437       infeasibility < incomingInfeasibility throw out variables
438       from basis until largest infeasibility < allowedInfeasibility
439       or incoming largest infeasibility.
440       If allowedInfeasibility>= incomingInfeasibility this is
441       always possible altough you may end up with an all slack basis.
442 
443       Defaults are 1.0,10.0
444   */
445   void setValuesPassAction(double incomingInfeasibility,
446     double allowedInfeasibility);
447   /** Get a clean factorization - i.e. throw out singularities
448       may do more later */
449   int cleanFactorization(int ifValuesPass);
450   /// Move status and solution to ClpSimplex
451   void moveStatusToClp(ClpSimplex *clpModel);
452   /// Move status and solution from ClpSimplex
453   void moveStatusFromClp(ClpSimplex *clpModel);
454   //@}
455   /**@name most useful gets and sets */
456   //@{
457 public:
458   /// Objective value
clpObjectiveValue() const459   inline double clpObjectiveValue() const
460   {
461     return (objectiveValue_ + objectiveOffset_ - bestPossibleImprovement_) * optimizationDirection_ - dblParam_[ClpObjOffset];
462   }
463   /** Basic variables pivoting on which rows
464       may be same as toExternal but may be as at invert */
pivotVariable() const465   inline int *pivotVariable() const
466   {
467     return abcPivotVariable_;
468   }
469   /// State of problem
stateOfProblem() const470   inline int stateOfProblem() const
471   {
472     return stateOfProblem_;
473   }
474   /// State of problem
setStateOfProblem(int value)475   inline void setStateOfProblem(int value)
476   {
477     stateOfProblem_ = value;
478   }
479   /// Points from external to internal
480   //inline int * fromExternal() const
481   //{ return fromExternal_;}
482   /// Points from internal to external
483   //inline int * toExternal() const
484   //{return toExternal_;}
485   /** Scale from primal external to internal (in external order) Or other way for dual
486    */
scaleFromExternal() const487   inline double *scaleFromExternal() const
488   {
489     return scaleFromExternal_;
490   }
491   /** Scale from primal internal to external (in external order) Or other way for dual
492    */
scaleToExternal() const493   inline double *scaleToExternal() const
494   {
495     return scaleToExternal_;
496   }
497   /// corresponds to rowScale etc
rowScale2() const498   inline double *rowScale2() const
499   {
500     return rowUseScale_;
501   }
inverseRowScale2() const502   inline double *inverseRowScale2() const
503   {
504     return inverseRowUseScale_;
505   }
inverseColumnScale2() const506   inline double *inverseColumnScale2() const
507   {
508     return inverseColumnUseScale_;
509   }
columnScale2() const510   inline double *columnScale2() const
511   {
512     return columnUseScale_;
513   }
arrayForDualColumn() const514   inline int arrayForDualColumn() const
515   {
516     return arrayForDualColumn_;
517   }
518   /// upper theta from dual column
upperTheta() const519   inline double upperTheta() const
520   {
521     return upperTheta_;
522   }
arrayForReplaceColumn() const523   inline int arrayForReplaceColumn() const
524   {
525     return arrayForReplaceColumn_;
526   }
arrayForFlipBounds() const527   inline int arrayForFlipBounds() const
528   {
529     return arrayForFlipBounds_;
530   }
arrayForFlipRhs() const531   inline int arrayForFlipRhs() const
532   {
533     return arrayForFlipRhs_;
534   }
arrayForBtran() const535   inline int arrayForBtran() const
536   {
537     return arrayForBtran_;
538   }
arrayForFtran() const539   inline int arrayForFtran() const
540   {
541     return arrayForFtran_;
542   }
arrayForTableauRow() const543   inline int arrayForTableauRow() const
544   {
545     return arrayForTableauRow_;
546   }
547   /// value of incoming variable (in Dual)
548   double valueIncomingDual() const;
549   /// Get pointer to array[getNumCols()] of primal solution vector
550   const double *getColSolution() const;
551 
552   /// Get pointer to array[getNumRows()] of dual prices
553   const double *getRowPrice() const;
554 
555   /// Get a pointer to array[getNumCols()] of reduced costs
556   const double *getReducedCost() const;
557 
558   /** Get pointer to array[getNumRows()] of row activity levels (constraint
559       matrix times the solution vector */
560   const double *getRowActivity() const;
561   //@}
562 
563   /**@name protected methods */
564   //@{
565   /** May change basis and then returns number changed.
566       Computation of solutions may be overriden by given pi and solution
567   */
568   int gutsOfSolution(double *givenDuals,
569     const double *givenPrimals,
570     bool valuesPass = false);
571   /// Does most of deletion for arrays etc(0 just null arrays, 1 delete first)
572   void gutsOfDelete(int type);
573   /// Does most of copying
574   void gutsOfCopy(const AbcSimplex &rhs);
575   /// Initializes arrays
576   void gutsOfInitialize(int numberRows, int numberColumns, bool doMore);
577   /// resizes arrays
578   void gutsOfResize(int numberRows, int numberColumns);
579   /** Translates ClpModel to AbcSimplex
580       See DO_ bits in stateOfProblem_ for type e.g. DO_BASIS_AND_ORDER
581   */
582   void translate(int type);
583   /// Moves basic stuff to basic area
584   void moveToBasic(int which = 15);
585   //@}
586 public:
587   /**@name public methods */
588   //@{
589   /// Return region
solutionRegion() const590   inline double *solutionRegion() const
591   {
592     return abcSolution_;
593   }
djRegion() const594   inline double *djRegion() const
595   {
596     return abcDj_;
597   }
lowerRegion() const598   inline double *lowerRegion() const
599   {
600     return abcLower_;
601   }
upperRegion() const602   inline double *upperRegion() const
603   {
604     return abcUpper_;
605   }
costRegion() const606   inline double *costRegion() const
607   {
608     return abcCost_;
609   }
610   /// Return region
solutionRegion(int which) const611   inline double *solutionRegion(int which) const
612   {
613     return abcSolution_ + which * maximumAbcNumberRows_;
614   }
djRegion(int which) const615   inline double *djRegion(int which) const
616   {
617     return abcDj_ + which * maximumAbcNumberRows_;
618   }
lowerRegion(int which) const619   inline double *lowerRegion(int which) const
620   {
621     return abcLower_ + which * maximumAbcNumberRows_;
622   }
upperRegion(int which) const623   inline double *upperRegion(int which) const
624   {
625     return abcUpper_ + which * maximumAbcNumberRows_;
626   }
costRegion(int which) const627   inline double *costRegion(int which) const
628   {
629     return abcCost_ + which * maximumAbcNumberRows_;
630   }
631   /// Return region
solutionBasic() const632   inline double *solutionBasic() const
633   {
634     return solutionBasic_;
635   }
djBasic() const636   inline double *djBasic() const
637   {
638     return djBasic_;
639   }
lowerBasic() const640   inline double *lowerBasic() const
641   {
642     return lowerBasic_;
643   }
upperBasic() const644   inline double *upperBasic() const
645   {
646     return upperBasic_;
647   }
costBasic() const648   inline double *costBasic() const
649   {
650     return costBasic_;
651   }
652   /// Perturbation
abcPerturbation() const653   inline double *abcPerturbation() const
654   {
655     return abcPerturbation_;
656   }
657   /// Fake djs
fakeDjs() const658   inline double *fakeDjs() const
659   {
660     return djSaved_;
661   }
internalStatus() const662   inline unsigned char *internalStatus() const
663   {
664     return internalStatus_;
665   }
getInternalStatus(int sequence) const666   inline AbcSimplex::Status getInternalStatus(int sequence) const
667   {
668     return static_cast< Status >(internalStatus_[sequence] & 7);
669   }
getInternalColumnStatus(int sequence) const670   inline AbcSimplex::Status getInternalColumnStatus(int sequence) const
671   {
672     return static_cast< Status >(internalStatus_[sequence + maximumAbcNumberRows_] & 7);
673   }
setInternalStatus(int sequence,AbcSimplex::Status newstatus)674   inline void setInternalStatus(int sequence, AbcSimplex::Status newstatus)
675   {
676     unsigned char &st_byte = internalStatus_[sequence];
677     st_byte = static_cast< unsigned char >(st_byte & ~7);
678     st_byte = static_cast< unsigned char >(st_byte | newstatus);
679   }
setInternalColumnStatus(int sequence,AbcSimplex::Status newstatus)680   inline void setInternalColumnStatus(int sequence, AbcSimplex::Status newstatus)
681   {
682     unsigned char &st_byte = internalStatus_[sequence + maximumAbcNumberRows_];
683     st_byte = static_cast< unsigned char >(st_byte & ~7);
684     st_byte = static_cast< unsigned char >(st_byte | newstatus);
685   }
686   /** Normally the first factorization does sparse coding because
687       the factorization could be singular.  This allows initial dense
688       factorization when it is known to be safe
689   */
690   void setInitialDenseFactorization(bool onOff);
691   bool initialDenseFactorization() const;
692   /** Return sequence In or Out */
sequenceIn() const693   inline int sequenceIn() const
694   {
695     return sequenceIn_;
696   }
sequenceOut() const697   inline int sequenceOut() const
698   {
699     return sequenceOut_;
700   }
701   /** Set sequenceIn or Out */
setSequenceIn(int sequence)702   inline void setSequenceIn(int sequence)
703   {
704     sequenceIn_ = sequence;
705   }
setSequenceOut(int sequence)706   inline void setSequenceOut(int sequence)
707   {
708     sequenceOut_ = sequence;
709   }
710 #if 0
711   /** Return sequenceInternal In or Out */
712   inline int sequenceInternalIn() const {
713     return sequenceInternalIn_;
714   }
715   inline int sequenceInternalOut() const {
716     return sequenceInternalOut_;
717   }
718   /** Set sequenceInternalIn or Out */
719   inline void  setSequenceInternalIn(int sequence) {
720     sequenceInternalIn_ = sequence;
721   }
722   inline void  setSequenceInternalOut(int sequence) {
723     sequenceInternalOut_ = sequence;
724   }
725 #endif
726   /// Returns 1 if sequence indicates column
isColumn(int sequence) const727   inline int isColumn(int sequence) const
728   {
729     return sequence >= maximumAbcNumberRows_ ? 1 : 0;
730   }
731   /// Returns sequence number within section
sequenceWithin(int sequence) const732   inline int sequenceWithin(int sequence) const
733   {
734     return sequence < maximumAbcNumberRows_ ? sequence : sequence - maximumAbcNumberRows_;
735   }
736   /// Current/last pivot row (set after END of choosing pivot row in dual)
lastPivotRow() const737   inline int lastPivotRow() const
738   {
739     return lastPivotRow_;
740   }
741   /// First Free_
firstFree() const742   inline int firstFree() const
743   {
744     return firstFree_;
745   }
746   /// Last firstFree_
lastFirstFree() const747   inline int lastFirstFree() const
748   {
749     return lastFirstFree_;
750   }
751   /// Free chosen vector
freeSequenceIn() const752   inline int freeSequenceIn() const
753   {
754     return freeSequenceIn_;
755   }
756   /// Acceptable pivot for this iteration
currentAcceptablePivot() const757   inline double currentAcceptablePivot() const
758   {
759     return currentAcceptablePivot_;
760   }
761 #ifdef PAN
762   /** Returns
763       1 if fake superbasic
764       0 if free or true superbasic
765       -1 if was fake but has cleaned itself up (sets status)
766       -2 if wasn't fake
767    */
fakeSuperBasic(int iSequence)768   inline int fakeSuperBasic(int iSequence)
769   {
770     if ((internalStatus_[iSequence] & 7) == 4)
771       return 0; // free
772     if ((internalStatus_[iSequence] & 7) != 5)
773       return -2;
774     double value = abcSolution_[iSequence];
775     if (value < abcLower_[iSequence] + primalTolerance_) {
776       if (abcDj_[iSequence] >= -currentDualTolerance_) {
777         setInternalStatus(iSequence, atLowerBound);
778 #if PRINT_PAN > 1
779         printf("Pansetting %d to lb\n", iSequence);
780 #endif
781         return -1;
782       } else {
783         return 1;
784       }
785     } else if (value > abcUpper_[iSequence] - primalTolerance_) {
786       if (abcDj_[iSequence] <= currentDualTolerance_) {
787         setInternalStatus(iSequence, atUpperBound);
788 #if PRINT_PAN > 1
789         printf("Pansetting %d to ub\n", iSequence);
790 #endif
791         return -1;
792       } else {
793         return 1;
794       }
795     } else {
796       return 0;
797     }
798   }
799 #endif
800   /// Return row or column values
solution(int sequence)801   inline double solution(int sequence)
802   {
803     return abcSolution_[sequence];
804   }
805   /// Return address of row or column values
solutionAddress(int sequence)806   inline double &solutionAddress(int sequence)
807   {
808     return abcSolution_[sequence];
809   }
reducedCost(int sequence)810   inline double reducedCost(int sequence)
811   {
812     return abcDj_[sequence];
813   }
reducedCostAddress(int sequence)814   inline double &reducedCostAddress(int sequence)
815   {
816     return abcDj_[sequence];
817   }
lower(int sequence)818   inline double lower(int sequence)
819   {
820     return abcLower_[sequence];
821   }
822   /// Return address of row or column lower bound
lowerAddress(int sequence)823   inline double &lowerAddress(int sequence)
824   {
825     return abcLower_[sequence];
826   }
upper(int sequence)827   inline double upper(int sequence)
828   {
829     return abcUpper_[sequence];
830   }
831   /// Return address of row or column upper bound
upperAddress(int sequence)832   inline double &upperAddress(int sequence)
833   {
834     return abcUpper_[sequence];
835   }
cost(int sequence)836   inline double cost(int sequence)
837   {
838     return abcCost_[sequence];
839   }
840   /// Return address of row or column cost
costAddress(int sequence)841   inline double &costAddress(int sequence)
842   {
843     return abcCost_[sequence];
844   }
845   /// Return original lower bound
originalLower(int iSequence) const846   inline double originalLower(int iSequence) const
847   {
848     if (iSequence < numberColumns_)
849       return columnLower_[iSequence];
850     else
851       return rowLower_[iSequence - numberColumns_];
852   }
853   /// Return original lower bound
originalUpper(int iSequence) const854   inline double originalUpper(int iSequence) const
855   {
856     if (iSequence < numberColumns_)
857       return columnUpper_[iSequence];
858     else
859       return rowUpper_[iSequence - numberColumns_];
860   }
861   /// For dealing with all issues of cycling etc
abcProgress()862   inline AbcSimplexProgress *abcProgress()
863   {
864     return &abcProgress_;
865   }
866 #ifdef ABC_SPRINT
867   /// Overwrite to create sub problem (just internal arrays) - save full stuff
868   AbcSimplex *createSubProblem(int numberColumns, const int *whichColumn);
869   /// Restore stuff from sub problem (and delete sub problem)
870   void restoreFromSubProblem(AbcSimplex *fullProblem, const int *whichColumn);
871 #endif
872 public:
873   /** Clears an array and says available (-1 does all)
874       when no possibility of going parallel */
clearArraysPublic(int which)875   inline void clearArraysPublic(int which)
876   {
877     clearArrays(which);
878   }
879   /** Returns first available empty array (and sets flag)
880       when no possibility of going parallel */
getAvailableArrayPublic() const881   inline int getAvailableArrayPublic() const
882   {
883     return getAvailableArray();
884   }
885 #if ABC_PARALLEL
886   /// get parallel mode
parallelMode() const887   inline int parallelMode() const
888   {
889     return parallelMode_;
890   }
891   /// set parallel mode
setParallelMode(int value)892   inline void setParallelMode(int value)
893   {
894     parallelMode_ = value;
895   }
896   /// Number of cpus
numberCpus() const897   inline int numberCpus() const
898   {
899     return parallelMode_ + 1;
900   }
901 #if ABC_PARALLEL == 1
902   /// set stop start
setStopStart(int value)903   inline void setStopStart(int value)
904   {
905     stopStart_ = value;
906   }
907 #endif
908 #endif
909   //protected:
910   /// Clears an array and says available (-1 does all)
911   void clearArrays(int which);
912   /// Clears an array and says available
913   void clearArrays(CoinPartitionedVector *which);
914   /// Returns first available empty array (and sets flag)
915   int getAvailableArray() const;
916   /// Say array going to be used
setUsedArray(int which) const917   inline void setUsedArray(int which) const
918   {
919     int check = 1 << which;
920     assert((stateOfProblem_ & check) == 0);
921     stateOfProblem_ |= check;
922   }
923   /// Say array going available
setAvailableArray(int which) const924   inline void setAvailableArray(int which) const
925   {
926     int check = 1 << which;
927     assert((stateOfProblem_ & check) != 0);
928     assert(!usefulArray_[which].getNumElements());
929     stateOfProblem_ &= ~check;
930   }
931   /// Swaps primal stuff
932   void swapPrimalStuff();
933   /// Swaps dual stuff
934   void swapDualStuff(int lastSequenceOut, int lastDirectionOut);
935 
936 protected:
937   //@}
938   /**@name status methods */
939   //@{
940   /// Swaps two variables and does status
941   void swap(int pivotRow, int nonBasicPosition, Status newStatus);
setFakeBound(int sequence,FakeBound fakeBound)942   inline void setFakeBound(int sequence, FakeBound fakeBound)
943   {
944     unsigned char &st_byte = internalStatus_[sequence];
945     st_byte = static_cast< unsigned char >(st_byte & ~24);
946     st_byte = static_cast< unsigned char >(st_byte | (fakeBound << 3));
947   }
getFakeBound(int sequence) const948   inline FakeBound getFakeBound(int sequence) const
949   {
950     return static_cast< FakeBound >((internalStatus_[sequence] >> 3) & 3);
951   }
952   bool atFakeBound(int sequence) const;
setPivoted(int sequence)953   inline void setPivoted(int sequence)
954   {
955     internalStatus_[sequence] = static_cast< unsigned char >(internalStatus_[sequence] | 32);
956   }
clearPivoted(int sequence)957   inline void clearPivoted(int sequence)
958   {
959     internalStatus_[sequence] = static_cast< unsigned char >(internalStatus_[sequence] & ~32);
960   }
pivoted(int sequence) const961   inline bool pivoted(int sequence) const
962   {
963     return (((internalStatus_[sequence] >> 5) & 1) != 0);
964   }
965 
966 public:
967   /// Swaps two variables
968   void swap(int pivotRow, int nonBasicPosition);
969   /// To flag a variable
970   void setFlagged(int sequence);
clearFlagged(int sequence)971   inline void clearFlagged(int sequence)
972   {
973     internalStatus_[sequence] = static_cast< unsigned char >(internalStatus_[sequence] & ~64);
974   }
flagged(int sequence) const975   inline bool flagged(int sequence) const
976   {
977     return ((internalStatus_[sequence] & 64) != 0);
978   }
979 
980 protected:
981   /// To say row active in primal pivot row choice
setActive(int iRow)982   inline void setActive(int iRow)
983   {
984     internalStatus_[iRow] = static_cast< unsigned char >(internalStatus_[iRow] | 128);
985   }
clearActive(int iRow)986   inline void clearActive(int iRow)
987   {
988     internalStatus_[iRow] = static_cast< unsigned char >(internalStatus_[iRow] & ~128);
989   }
active(int iRow) const990   inline bool active(int iRow) const
991   {
992     return ((internalStatus_[iRow] & 128) != 0);
993   }
994 
995 public:
996   /** Set up status array (can be used by OsiAbc).
997       Also can be used to set up all slack basis */
998   void createStatus();
999   /// Does sort of crash
1000   void crash(int type);
1001   /** Puts more stuff in basis
1002       1 bit set - do even if basis exists
1003       2 bit set - don't bother staying triangular
1004    */
1005   void putStuffInBasis(int type);
1006   /** Sets up all slack basis and resets solution to
1007       as it was after initial load or readMps */
1008   void allSlackBasis();
1009   /// For debug - check pivotVariable consistent
1010   void checkConsistentPivots() const;
1011   /// Print stuff
1012   void printStuff() const;
1013   /// Common bits of coding for dual and primal
1014   int startup(int ifValuesPass);
1015 
1016   /// Raw objective value (so always minimize in primal)
rawObjectiveValue() const1017   inline double rawObjectiveValue() const
1018   {
1019     return objectiveValue_;
1020   }
1021   /// Compute objective value from solution and put in objectiveValue_
1022   void computeObjectiveValue(bool useWorkingSolution = false);
1023   /// Compute minimization objective value from internal solution without perturbation
1024   double computeInternalObjectiveValue();
1025   /// Move status and solution across
1026   void moveInfo(const AbcSimplex &rhs, bool justStatus = false);
1027 #ifndef NUMBER_THREADS
1028 #define NUMBER_THREADS 3
1029 #endif
1030 #if ABC_PARALLEL == 1
1031   // For waking up thread
mutexPointer(int which,int thread=0)1032   inline pthread_mutex_t *mutexPointer(int which, int thread = 0)
1033   {
1034     return mutex_ + which + 3 * thread;
1035   }
barrierPointer()1036   inline pthread_barrier_t *barrierPointer()
1037   {
1038     return &barrier_;
1039   }
whichLocked(int thread=0) const1040   inline int whichLocked(int thread = 0) const
1041   {
1042     return locked_[thread];
1043   }
threadInfoPointer(int thread=0)1044   inline CoinThreadInfo *threadInfoPointer(int thread = 0)
1045   {
1046     return threadInfo_ + thread;
1047   }
1048   void startParallelStuff(int type);
1049   int stopParallelStuff(int type);
1050   /// so thread can find out which one it is
1051   int whichThread() const;
1052 #elif ABC_PARALLEL == 2
1053   //inline CoinThreadInfo * threadInfoPointer(int thread=0)
1054   //{ return threadInfo_+thread;}
1055 #endif
1056   //@}
1057 
1058   //-------------------------------------------------------------------------
1059   /**@name Changing bounds on variables and constraints */
1060   //@{
1061   /** Set an objective function coefficient */
1062   void setObjectiveCoefficient(int elementIndex, double elementValue);
1063   /** Set an objective function coefficient */
setObjCoeff(int elementIndex,double elementValue)1064   inline void setObjCoeff(int elementIndex, double elementValue)
1065   {
1066     setObjectiveCoefficient(elementIndex, elementValue);
1067   }
1068 
1069   /** Set a single column lower bound<br>
1070       Use -DBL_MAX for -infinity. */
1071   void setColumnLower(int elementIndex, double elementValue);
1072 
1073   /** Set a single column upper bound<br>
1074       Use DBL_MAX for infinity. */
1075   void setColumnUpper(int elementIndex, double elementValue);
1076 
1077   /** Set a single column lower and upper bound */
1078   void setColumnBounds(int elementIndex,
1079     double lower, double upper);
1080 
1081   /** Set the bounds on a number of columns simultaneously<br>
1082       The default implementation just invokes setColLower() and
1083       setColUpper() over and over again.
1084       @param indexFirst,indexLast pointers to the beginning and after the
1085       end of the array of the indices of the variables whose
1086       <em>either</em> bound changes
1087       @param boundList the new lower/upper bound pairs for the variables
1088   */
1089   void setColumnSetBounds(const int *indexFirst,
1090     const int *indexLast,
1091     const double *boundList);
1092 
1093   /** Set a single column lower bound<br>
1094       Use -DBL_MAX for -infinity. */
setColLower(int elementIndex,double elementValue)1095   inline void setColLower(int elementIndex, double elementValue)
1096   {
1097     setColumnLower(elementIndex, elementValue);
1098   }
1099   /** Set a single column upper bound<br>
1100       Use DBL_MAX for infinity. */
setColUpper(int elementIndex,double elementValue)1101   inline void setColUpper(int elementIndex, double elementValue)
1102   {
1103     setColumnUpper(elementIndex, elementValue);
1104   }
1105 
1106   /** Set a single column lower and upper bound */
setColBounds(int elementIndex,double newlower,double newupper)1107   inline void setColBounds(int elementIndex,
1108     double newlower, double newupper)
1109   {
1110     setColumnBounds(elementIndex, newlower, newupper);
1111   }
1112 
1113   /** Set the bounds on a number of columns simultaneously<br>
1114       @param indexFirst,indexLast pointers to the beginning and after the
1115       end of the array of the indices of the variables whose
1116       <em>either</em> bound changes
1117       @param boundList the new lower/upper bound pairs for the variables
1118   */
setColSetBounds(const int * indexFirst,const int * indexLast,const double * boundList)1119   inline void setColSetBounds(const int *indexFirst,
1120     const int *indexLast,
1121     const double *boundList)
1122   {
1123     setColumnSetBounds(indexFirst, indexLast, boundList);
1124   }
1125 
1126   /** Set a single row lower bound<br>
1127       Use -DBL_MAX for -infinity. */
1128   void setRowLower(int elementIndex, double elementValue);
1129 
1130   /** Set a single row upper bound<br>
1131       Use DBL_MAX for infinity. */
1132   void setRowUpper(int elementIndex, double elementValue);
1133 
1134   /** Set a single row lower and upper bound */
1135   void setRowBounds(int elementIndex,
1136     double lower, double upper);
1137 
1138   /** Set the bounds on a number of rows simultaneously<br>
1139       @param indexFirst,indexLast pointers to the beginning and after the
1140       end of the array of the indices of the constraints whose
1141       <em>either</em> bound changes
1142       @param boundList the new lower/upper bound pairs for the constraints
1143   */
1144   void setRowSetBounds(const int *indexFirst,
1145     const int *indexLast,
1146     const double *boundList);
1147   /// Resizes rim part of model
1148   void resize(int newNumberRows, int newNumberColumns);
1149 
1150   //@}
1151 
1152   ////////////////// data //////////////////
1153 protected:
1154   /**@name data.  Many arrays have a row part and a column part.
1155      There is a single array with both - columns then rows and
1156      then normally two arrays pointing to rows and columns.  The
1157      single array is the owner of memory
1158   */
1159   //@{
1160   /// Sum of nonbasic costs
1161   double sumNonBasicCosts_;
1162   /// Sum of costs (raw objective value)
1163   double rawObjectiveValue_;
1164   /// Objective offset (from offset_)
1165   double objectiveOffset_;
1166   /**  Perturbation factor
1167        If <0.0 then virtual
1168        if 0.0 none
1169        if >0.0 use this as factor */
1170   double perturbationFactor_;
1171   /// Current dualTolerance (will end up as dualTolerance_)
1172   double currentDualTolerance_;
1173   /// Current dualBound (will end up as dualBound_)
1174   double currentDualBound_;
1175   /// Largest gap
1176   double largestGap_;
1177   /// Last dual bound
1178   double lastDualBound_;
1179   /// Sum of infeasibilities when using fake perturbation tolerance
1180   double sumFakeInfeasibilities_;
1181   /// Last primal error
1182   double lastPrimalError_;
1183   /// Last dual error
1184   double lastDualError_;
1185   /// Acceptable pivot for this iteration
1186   double currentAcceptablePivot_;
1187   /// Movement of variable
1188   double movement_;
1189   /// Objective change
1190   double objectiveChange_;
1191   /// Btran alpha
1192   double btranAlpha_;
1193   /// FT alpha
1194 #ifdef ABC_LONG_FACTORIZATION
1195   long
1196 #endif
1197     double ftAlpha_;
1198   /// Minimum theta movement
1199   double minimumThetaMovement_;
1200   /// Initial sum of infeasibilities
1201   double initialSumInfeasibilities_;
1202 
1203 public:
1204   /// Where we are in iteration
1205   int stateOfIteration_;
1206 
1207 protected:
1208   /// Last firstFree_
1209   int lastFirstFree_;
1210   /// Free chosen vector
1211   int freeSequenceIn_;
1212   /// Maximum number rows
1213   int maximumAbcNumberRows_;
1214   /// Maximum number columns
1215   int maximumAbcNumberColumns_;
1216   /// Maximum numberTotal
1217   int maximumNumberTotal_;
1218   /// Current number of variables flagged
1219   int numberFlagged_;
1220   /// Iteration at which to do relaxed dualColumn
1221   int normalDualColumnIteration_;
1222   /** State of dual waffle
1223       -2 - in initial large tolerance phase
1224       -1 - in medium tolerance phase
1225       n - in correct tolerance phase and thought optimal n times
1226    */
1227   int stateDualColumn_;
1228   /*
1229     May want to put some arrays into struct
1230     Two arrays point to/from external
1231     Order is basic,unused basic, at lower, at upper, superbasic, free, fixed with starts
1232   */
1233   /// Number of variables (includes spare rows)
1234   int numberTotal_;
1235   /// Number of variables without fixed to zero (includes spare rows)
1236   int numberTotalWithoutFixed_;
1237   /// Start of variables at lower bound with no upper
1238 #define startAtLowerNoOther_ maximumAbcNumberRows_
1239   /// Start of variables at lower bound with upper
1240   int startAtLowerOther_;
1241   /// Start of variables at upper bound with no lower
1242   int startAtUpperNoOther_;
1243   /// Start of variables at upper bound with lower
1244   int startAtUpperOther_;
1245   /// Start of superBasic, free or awkward bounds variables
1246   int startOther_;
1247   /// Start of fixed variables
1248   int startFixed_;
1249 #ifdef EARLY_FACTORIZE
1250   /// Number of iterations to try factorizing early
1251   int numberEarly_;
1252 #endif
1253   /**
1254      State of problem
1255      State of external arrays
1256      2048 - status OK
1257      4096 - row primal solution OK
1258      8192 - row dual solution OK
1259      16384 - column primal solution OK
1260      32768 - column dual solution OK
1261      65536 - Everything not going smoothly (when smooth we forget about tiny bad djs)
1262      131072 - when increasing rows add a bit
1263      262144 - scale matrix and create new one
1264      524288 - do basis and order
1265      1048576 - just status (and check if order needed)
1266      2097152 - just solution
1267      4194304 - just redo bounds (and offset)
1268      Bottom bits say if usefulArray in use
1269    */
1270 #define ALL_STATUS_OK 2048
1271 #define ROW_PRIMAL_OK 4096
1272 #define ROW_DUAL_OK 8192
1273 #define COLUMN_PRIMAL_OK 16384
1274 #define COLUMN_DUAL_OK 32768
1275 #define PESSIMISTIC 65536
1276 #define ADD_A_BIT 131072
1277 #define DO_SCALE_AND_MATRIX 262144
1278 #define DO_BASIS_AND_ORDER 524288
1279 #define DO_STATUS 1048576
1280 #define DO_SOLUTION 2097152
1281 #define DO_JUST_BOUNDS 0x400000
1282 #define NEED_BASIS_SORT 0x800000
1283 #define FAKE_SUPERBASIC 0x1000000
1284 #define VALUES_PASS 0x2000000
1285 #define VALUES_PASS2 0x4000000
1286   mutable int stateOfProblem_;
1287 #if ABC_PARALLEL
1288 public:
1289   /// parallel mode
1290   int parallelMode_;
1291 
1292 protected:
1293 #endif
1294   /// Number of ordinary (lo/up) in tableau row
1295   int numberOrdinary_;
1296   /// Set to 1 if no free or super basic
1297   int ordinaryVariables_;
1298   /// Number of free nonbasic variables
1299   int numberFreeNonBasic_;
1300   /// Last time cleaned up
1301   int lastCleaned_;
1302   /// Current/last pivot row (set after END of choosing pivot row in dual)
1303   int lastPivotRow_;
1304   /// Nonzero (probably 10) if swapped algorithms
1305   int swappedAlgorithm_;
1306   /// Initial number of infeasibilities
1307   int initialNumberInfeasibilities_;
1308   /// Points from external to internal
1309   //int * fromExternal_;
1310   /// Points from internal to external
1311   //int * toExternal_;
1312   /** Scale from primal external to internal (in external order) Or other way for dual
1313    */
1314   double *scaleFromExternal_;
1315   /** Scale from primal internal to external (in external order) Or other way for dual
1316    */
1317   double *scaleToExternal_;
1318   /// use this instead of columnScale
1319   double *columnUseScale_;
1320   /// use this instead of inverseColumnScale
1321   double *inverseColumnUseScale_;
1322   /** Primal offset (in external order)
1323       So internal value is (external-offset)*scaleFromExternal
1324    */
1325   double *offset_;
1326   /// Offset for accumulated offsets*matrix
1327   double *offsetRhs_;
1328   /// Useful array of numberTotal length
1329   double *tempArray_;
1330   /** Working status
1331       ? may be signed
1332       ? link pi_ to an indexed array?
1333       may have saved from last factorization at end */
1334   unsigned char *internalStatus_;
1335   /// Saved status
1336   unsigned char *internalStatusSaved_;
1337   /** Perturbation (fixed) - is just scaled random numbers
1338       If perturbationFactor_<0 then virtual perturbation */
1339   double *abcPerturbation_;
1340   /// saved perturbation
1341   double *perturbationSaved_;
1342   /// basic perturbation
1343   double *perturbationBasic_;
1344   /// Working matrix
1345   AbcMatrix *abcMatrix_;
1346   /** Working scaled copy of lower bounds
1347       has original scaled copy at end */
1348   double *abcLower_;
1349   /** Working scaled copy of upper bounds
1350       has original scaled copy at end */
1351   double *abcUpper_;
1352   /** Working scaled copy of objective
1353       ? where perturbed copy or can we
1354       always work with perturbed copy (in B&B) if we adjust increments/cutoffs
1355       ? should we save a fixed perturbation offset array
1356       has original scaled copy at end */
1357   double *abcCost_;
1358   /** Working scaled primal solution
1359       may have saved from last factorization at end */
1360   double *abcSolution_;
1361   /** Working scaled dual solution
1362       may have saved from last factorization at end */
1363   double *abcDj_;
1364   /// Saved scaled copy of  lower bounds
1365   double *lowerSaved_;
1366   /// Saved scaled copy of  upper bounds
1367   double *upperSaved_;
1368   /// Saved scaled copy of  objective
1369   double *costSaved_;
1370   /// Saved scaled  primal solution
1371   double *solutionSaved_;
1372   /// Saved scaled  dual solution
1373   double *djSaved_;
1374   /// Working scaled copy of basic lower bounds
1375   double *lowerBasic_;
1376   /// Working scaled copy of basic upper bounds
1377   double *upperBasic_;
1378   /// Working scaled copy of basic objective
1379   double *costBasic_;
1380   /// Working scaled basic primal solution
1381   double *solutionBasic_;
1382   /// Working scaled basic dual solution (want it to be zero)
1383   double *djBasic_;
1384   /// dual row pivot choice
1385   AbcDualRowPivot *abcDualRowPivot_;
1386   /// primal column pivot choice
1387   AbcPrimalColumnPivot *abcPrimalColumnPivot_;
1388   /** Basic variables pivoting on which rows
1389       followed by atLo/atUp then free/superbasic then fixed
1390   */
1391   int *abcPivotVariable_;
1392   /// Reverse abcPivotVariable_ for moving around
1393   int *reversePivotVariable_;
1394   /// factorization
1395   AbcSimplexFactorization *abcFactorization_;
1396 #ifdef EARLY_FACTORIZE
1397   /// Alternative factorization
1398   AbcSimplexFactorization *abcEarlyFactorization_;
1399 #endif
1400 #ifdef TEMPORARY_FACTORIZATION
1401   /// Alternative factorization
1402   AbcSimplexFactorization *abcOtherFactorization_;
1403 #endif
1404   /// Saved version of solution
1405   //double * savedSolution_;
1406   /// A copy of model with certain state - normally without cuts
1407   AbcSimplex *abcBaseModel_;
1408   /// A copy of model as ClpSimplex with certain state
1409   ClpSimplex *clpModel_;
1410   /** Very wasteful way of dealing with infeasibilities in primal.
1411       However it will allow non-linearities and use of dual
1412       analysis.  If it doesn't work it can easily be replaced.
1413   */
1414   AbcNonLinearCost *abcNonLinearCost_;
1415   /// Useful arrays (all of row+column+2 length)
1416   /* has secondary offset and counts so row goes first then column
1417      Probably back to CoinPartitionedVector as AbcMatrix has slacks
1418      also says if in use - so we can just get next available one */
1419 #define ABC_NUMBER_USEFUL 8
1420   mutable CoinPartitionedVector usefulArray_[ABC_NUMBER_USEFUL];
1421   /// For dealing with all issues of cycling etc
1422   AbcSimplexProgress abcProgress_;
1423   /// For saving stuff at beginning
1424   ClpDataSave saveData_;
1425   /// upper theta from dual column
1426   double upperTheta_;
1427   /// Multiple sequence in
1428   int multipleSequenceIn_[4];
1429 
1430 public:
1431   int arrayForDualColumn_;
1432   int arrayForReplaceColumn_;
1433   int arrayForFlipBounds_; //2
1434   int arrayForFlipRhs_; // if sequential can re-use
1435   int arrayForBtran_; // 0
1436   int arrayForFtran_; // 1
1437   int arrayForTableauRow_; //3
1438 protected:
1439   int numberFlipped_;
1440   int numberDisasters_;
1441   //int nextCleanNonBasicIteration_;
1442 #if ABC_PARALLEL == 1
1443   // For waking up thread
1444   pthread_mutex_t mutex_[3 * NUMBER_THREADS];
1445   pthread_barrier_t barrier_;
1446   CoinThreadInfo threadInfo_[NUMBER_THREADS];
1447   pthread_t abcThread_[NUMBER_THREADS];
1448   int locked_[NUMBER_THREADS];
1449   int stopStart_;
1450 #elif ABC_PARALLEL == 2
1451   //CoinThreadInfo threadInfo_[NUMBER_THREADS];
1452 #endif
1453   //@}
1454 };
1455 //#############################################################################
1456 /** A function that tests the methods in the AbcSimplex class. The
1457     only reason for it not to be a member method is that this way it doesn't
1458     have to be compiled into the library. And that's a gain, because the
1459     library should be compiled with optimization on, but this method should be
1460     compiled with debugging.
1461 
1462     It also does some testing of AbcSimplexFactorization class
1463 */
1464 void AbcSimplexUnitTest(const std::string &mpsDir);
1465 #endif
1466 
1467 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1468 */
1469