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