1 // $Id$ 2 // Copyright (C) 2000, International Business Machines 3 // Corporation and others. All Rights Reserved. 4 // This code is licensed under the terms of the Eclipse Public License (EPL). 5 6 7 #ifndef OsiClpSolverInterface_H 8 #define OsiClpSolverInterface_H 9 10 #include <string> 11 #include <cfloat> 12 #include <map> 13 14 #include "ClpSimplex.hpp" 15 #include "ClpLinearObjective.hpp" 16 #include "CoinPackedMatrix.hpp" 17 #include "OsiSolverInterface.hpp" 18 #include "CoinWarmStartBasis.hpp" 19 #include "ClpEventHandler.hpp" 20 #include "ClpNode.hpp" 21 #include "CoinIndexedVector.hpp" 22 #include "CoinFinite.hpp" 23 24 class OsiRowCut; 25 class OsiClpUserSolver; 26 class OsiClpDisasterHandler; 27 class CoinSet; 28 static const double OsiClpInfinity = COIN_DBL_MAX; 29 30 //############################################################################# 31 32 /** Clp Solver Interface 33 34 Instantiation of OsiClpSolverInterface for the Model Algorithm. 35 36 */ 37 38 class OsiClpSolverInterface : 39 virtual public OsiSolverInterface { 40 friend void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); 41 42 public: 43 //--------------------------------------------------------------------------- 44 /**@name Solve methods */ 45 //@{ 46 /// Solve initial LP relaxation 47 virtual void initialSolve() override; 48 49 /// Resolve an LP relaxation after problem modification 50 virtual void resolve() override; 51 52 /// Resolve an LP relaxation after problem modification (try GUB) 53 virtual void resolveGub(int needed); 54 55 /// Invoke solver's built-in enumeration algorithm 56 virtual void branchAndBound() override; 57 58 /** Solve when primal column and dual row solutions are near-optimal 59 options - 0 no presolve (use primal and dual) 60 1 presolve (just use primal) 61 2 no presolve (just use primal) 62 basis - 0 use all slack basis 63 1 try and put some in basis 64 */ 65 void crossover(int options,int basis); 66 //@} 67 68 /*! @name OsiSimplexInterface methods 69 \brief Methods for the Osi Simplex API. 70 71 The current implementation should work for both minimisation and 72 maximisation in mode 1 (tableau access). In mode 2 (single pivot), only 73 minimisation is supported as of 100907. 74 */ 75 //@{ 76 /** \brief Simplex API capability. 77 78 Returns 79 - 0 if no simplex API 80 - 1 if can just do getBInv etc 81 - 2 if has all OsiSimplex methods 82 */ 83 virtual int canDoSimplexInterface() const override; 84 85 /*! \brief Enables simplex mode 1 (tableau access) 86 87 Tells solver that calls to getBInv etc are about to take place. 88 Underlying code may need mutable as this may be called from 89 CglCut::generateCuts which is const. If that is too horrific then 90 each solver e.g. BCP or CBC will have to do something outside 91 main loop. 92 */ 93 virtual void enableFactorization() const override; 94 95 /*! \brief Undo any setting changes made by #enableFactorization */ 96 virtual void disableFactorization() const override; 97 98 /** Returns true if a basis is available 99 AND problem is optimal. This should be used to see if 100 the BInvARow type operations are possible and meaningful. 101 */ 102 virtual bool basisIsAvailable() const override; 103 104 /** The following two methods may be replaced by the 105 methods of OsiSolverInterface using OsiWarmStartBasis if: 106 1. OsiWarmStartBasis resize operation is implemented 107 more efficiently and 108 2. It is ensured that effects on the solver are the same 109 110 Returns a basis status of the structural/artificial variables 111 At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower 112 113 NOTE artificials are treated as +1 elements so for <= rhs 114 artificial will be at lower bound if constraint is tight 115 116 This means that Clpsimplex flips artificials as it works 117 in terms of row activities 118 */ 119 virtual void getBasisStatus(int* cstat, int* rstat) const override; 120 121 /** Set the status of structural/artificial variables and 122 factorize, update solution etc 123 124 NOTE artificials are treated as +1 elements so for <= rhs 125 artificial will be at lower bound if constraint is tight 126 127 This means that Clpsimplex flips artificials as it works 128 in terms of row activities 129 Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ... 130 */ 131 virtual int setBasisStatus(const int* cstat, const int* rstat) override; 132 133 ///Get the reduced gradient for the cost vector c 134 virtual void getReducedGradient(double* columnReducedCosts, 135 double * duals, 136 const double * c) const override ; 137 138 ///Get a row of the tableau (slack part in slack if not NULL) 139 virtual void getBInvARow(int row, double* z, double * slack=nullptr) const override; 140 141 /** Get a row of the tableau (slack part in slack if not NULL) 142 If keepScaled is true then scale factors not applied after so 143 user has to use coding similar to what is in this method 144 */ 145 virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=nullptr, 146 bool keepScaled=false) const; 147 148 ///Get a row of the basis inverse 149 virtual void getBInvRow(int row, double* z) const override; 150 151 ///Get a column of the tableau 152 virtual void getBInvACol(int col, double* vec) const override ; 153 154 ///Get a column of the tableau 155 virtual void getBInvACol(int col, CoinIndexedVector * vec) const ; 156 157 /** Update (i.e. ftran) the vector passed in. 158 Unscaling is applied after - can't be applied before 159 */ 160 161 virtual void getBInvACol(CoinIndexedVector * vec) const ; 162 163 ///Get a column of the basis inverse 164 virtual void getBInvCol(int col, double* vec) const override ; 165 166 /** Get basic indices (order of indices corresponds to the 167 order of elements in a vector retured by getBInvACol() and 168 getBInvCol()). 169 */ 170 virtual void getBasics(int* index) const override; 171 172 /*! \brief Enables simplex mode 2 (individual pivot control) 173 174 This method is supposed to ensure that all typical things (like 175 reduced costs, etc.) are updated when individual pivots are executed 176 and can be queried by other methods. 177 */ 178 virtual void enableSimplexInterface(bool doingPrimal) override; 179 180 /*! \brief Undo setting changes made by #enableSimplexInterface */ 181 virtual void disableSimplexInterface() override; 182 183 /** Perform a pivot by substituting a colIn for colOut in the basis. 184 The status of the leaving variable is given in statOut. Where 185 1 is to upper bound, -1 to lower bound 186 Return code is 0 for okay, 187 1 if inaccuracy forced re-factorization (should be okay) and 188 -1 for singular factorization 189 */ 190 virtual int pivot(int colIn, int colOut, int outStatus) override; 191 192 /** Obtain a result of the primal pivot 193 Outputs: colOut -- leaving column, outStatus -- its status, 194 t -- step size, and, if dx!=NULL, *dx -- primal ray direction. 195 Inputs: colIn -- entering column, sign -- direction of its change (+/-1). 196 Both for colIn and colOut, artificial variables are index by 197 the negative of the row index minus 1. 198 Return code (for now): 0 -- leaving variable found, 199 -1 -- everything else? 200 Clearly, more informative set of return values is required 201 Primal and dual solutions are updated 202 */ 203 virtual int primalPivotResult(int colIn, int sign, 204 int& colOut, int& outStatus, 205 double& t, CoinPackedVector* dx) override; 206 207 /** Obtain a result of the dual pivot (similar to the previous method) 208 Differences: entering variable and a sign of its change are now 209 the outputs, the leaving variable and its statuts -- the inputs 210 If dx!=NULL, then *dx contains dual ray 211 Return code: same 212 */ 213 virtual int dualPivotResult(int& colIn, int& sign, 214 int colOut, int outStatus, 215 double& t, CoinPackedVector* dx) override; 216 217 218 //@} 219 //--------------------------------------------------------------------------- 220 /**@name Parameter set/get methods 221 222 The set methods return true if the parameter was set to the given value, 223 false otherwise. There can be various reasons for failure: the given 224 parameter is not applicable for the solver (e.g., refactorization 225 frequency for the clp algorithm), the parameter is not yet implemented 226 for the solver or simply the value of the parameter is out of the range 227 the solver accepts. If a parameter setting call returns false check the 228 details of your solver. 229 230 The get methods return true if the given parameter is applicable for the 231 solver and is implemented. In this case the value of the parameter is 232 returned in the second argument. Otherwise they return false. 233 */ 234 //@{ 235 // Set an integer parameter 236 bool setIntParam(OsiIntParam key, int value) override; 237 // Set an double parameter 238 bool setDblParam(OsiDblParam key, double value) override; 239 // Set a string parameter 240 bool setStrParam(OsiStrParam key, const std::string & value) override; 241 // Get an integer parameter 242 bool getIntParam(OsiIntParam key, int& value) const override; 243 // Get an double parameter 244 bool getDblParam(OsiDblParam key, double& value) const override; 245 // Get a string parameter 246 bool getStrParam(OsiStrParam key, std::string& value) const override; 247 // Set a hint parameter - overrides OsiSolverInterface 248 virtual bool setHintParam(OsiHintParam key, bool yesNo=true, 249 OsiHintStrength strength=OsiHintTry, 250 void * otherInformation=nullptr) override; 251 //@} 252 253 //--------------------------------------------------------------------------- 254 ///@name Methods returning info on how the solution process terminated 255 //@{ 256 /// Are there a numerical difficulties? 257 virtual bool isAbandoned() const override; 258 /// Is optimality proven? 259 virtual bool isProvenOptimal() const override; 260 /// Is primal infeasiblity proven? 261 virtual bool isProvenPrimalInfeasible() const override; 262 /// Is dual infeasiblity proven? 263 virtual bool isProvenDualInfeasible() const override; 264 /// Is the given primal objective limit reached? 265 virtual bool isPrimalObjectiveLimitReached() const override; 266 /// Is the given dual objective limit reached? 267 virtual bool isDualObjectiveLimitReached() const override; 268 /// Iteration limit reached? 269 virtual bool isIterationLimitReached() const override; 270 //@} 271 272 //--------------------------------------------------------------------------- 273 /**@name WarmStart related methods */ 274 //@{ 275 276 /*! \brief Get an empty warm start object 277 278 This routine returns an empty CoinWarmStartBasis object. Its purpose is 279 to provide a way to give a client a warm start basis object of the 280 appropriate type, which can resized and modified as desired. 281 */ 282 283 virtual CoinWarmStart *getEmptyWarmStart () const override; 284 285 /// Get warmstarting information 286 virtual CoinWarmStart* getWarmStart() const override; 287 /// Get warmstarting information getPointerToWarmStart()288 inline CoinWarmStartBasis* getPointerToWarmStart() 289 { return &basis_;} 290 /// Get warmstarting information getConstPointerToWarmStart() const291 inline const CoinWarmStartBasis* getConstPointerToWarmStart() const 292 { return &basis_;} 293 /** Set warmstarting information. Return true/false depending on whether 294 the warmstart information was accepted or not. */ 295 virtual bool setWarmStart(const CoinWarmStart* warmstart) override; 296 /** \brief Get warm start information. 297 298 Return warm start information for the current state of the solver 299 interface. If there is no valid warm start information, an empty warm 300 start object wil be returned. This does not necessarily create an 301 object - may just point to one. must Delete set true if user 302 should delete returned object. 303 OsiClp version always returns pointer and false. 304 */ 305 virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) override ; 306 307 //@} 308 309 //--------------------------------------------------------------------------- 310 /**@name Hotstart related methods (primarily used in strong branching). 311 The user can create a hotstart (a snapshot) of the optimization process 312 then reoptimize over and over again always starting from there.<br> 313 <strong>NOTE</strong>: between hotstarted optimizations only 314 bound changes are allowed. */ 315 //@{ 316 /// Create a hotstart point of the optimization process 317 virtual void markHotStart() override; 318 /// Optimize starting from the hotstart 319 virtual void solveFromHotStart() override; 320 /// Delete the snapshot 321 virtual void unmarkHotStart() override; 322 /** Start faster dual - returns negative if problems 1 if infeasible, 323 Options to pass to solver 324 1 - create external reduced costs for columns 325 2 - create external reduced costs for rows 326 4 - create external row activity (columns always done) 327 Above only done if feasible 328 When set resolve does less work 329 */ 330 int startFastDual(int options); 331 /// Stop fast dual 332 void stopFastDual(); 333 /// Sets integer tolerance and increment 334 void setStuff(double tolerance,double increment); 335 //@} 336 337 //--------------------------------------------------------------------------- 338 /**@name Problem information methods 339 340 These methods call the solver's query routines to return 341 information about the problem referred to by the current object. 342 Querying a problem that has no data associated with it result in 343 zeros for the number of rows and columns, and NULL pointers from 344 the methods that return vectors. 345 346 Const pointers returned from any data-query method are valid as 347 long as the data is unchanged and the solver is not called. 348 */ 349 //@{ 350 /**@name Methods related to querying the input data */ 351 //@{ 352 /// Get number of columns getNumCols() const353 virtual int getNumCols() const override { 354 return modelPtr_->numberColumns(); } 355 356 /// Get number of rows getNumRows() const357 virtual int getNumRows() const override { 358 return modelPtr_->numberRows(); } 359 360 /// Get number of nonzero elements getNumElements() const361 virtual int getNumElements() const override { 362 int retVal = 0; 363 const CoinPackedMatrix * matrix =modelPtr_->matrix(); 364 if ( matrix != nullptr ) retVal=matrix->getNumElements(); 365 return retVal; } 366 367 /// Return name of row if one exists or Rnnnnnnn 368 /// maxLen is currently ignored and only there to match the signature from the base class! 369 virtual std::string getRowName(int rowIndex, 370 #pragma warning(suppress: 4309) 371 unsigned maxLen = static_cast<unsigned>(std::string::npos)) const override; 372 373 /// Return name of column if one exists or Cnnnnnnn 374 /// maxLen is currently ignored and only there to match the signature from the base class! 375 virtual std::string getColName(int colIndex, 376 #pragma warning(suppress: 4309) 377 unsigned maxLen = static_cast<unsigned>(std::string::npos)) const override; 378 379 380 /// Get pointer to array[getNumCols()] of column lower bounds getColLower() const381 virtual const double * getColLower() const override { return modelPtr_->columnLower(); } 382 383 /// Get pointer to array[getNumCols()] of column upper bounds getColUpper() const384 virtual const double * getColUpper() const override { return modelPtr_->columnUpper(); } 385 386 /** Get pointer to array[getNumRows()] of row constraint senses. 387 <ul> 388 <li>'L' <= constraint 389 <li>'E' = constraint 390 <li>'G' >= constraint 391 <li>'R' ranged constraint 392 <li>'N' free constraint 393 </ul> 394 */ 395 virtual const char * getRowSense() const override; 396 397 /** Get pointer to array[getNumRows()] of rows right-hand sides 398 <ul> 399 <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] 400 <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] 401 <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] 402 <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 403 </ul> 404 */ 405 virtual const double * getRightHandSide() const override ; 406 407 /** Get pointer to array[getNumRows()] of row ranges. 408 <ul> 409 <li> if rowsense()[i] == 'R' then 410 rowrange()[i] == rowupper()[i] - rowlower()[i] 411 <li> if rowsense()[i] != 'R' then 412 rowrange()[i] is undefined 413 </ul> 414 */ 415 virtual const double * getRowRange() const override ; 416 417 /// Get pointer to array[getNumRows()] of row lower bounds getRowLower() const418 virtual const double * getRowLower() const override { return modelPtr_->rowLower(); } 419 420 /// Get pointer to array[getNumRows()] of row upper bounds getRowUpper() const421 virtual const double * getRowUpper() const override { return modelPtr_->rowUpper(); } 422 423 /// Get pointer to array[getNumCols()] of objective function coefficients getObjCoefficients() const424 virtual const double * getObjCoefficients() const override 425 { if (fakeMinInSimplex_) 426 return linearObjective_ ; 427 else 428 return modelPtr_->objective(); } 429 430 /// Get objective function sense (1 for min (default), -1 for max) getObjSense() const431 virtual double getObjSense() const override 432 { return ((fakeMinInSimplex_)?-modelPtr_->optimizationDirection(): 433 modelPtr_->optimizationDirection()); } 434 435 /// Return true if column is continuous 436 virtual bool isContinuous(int colNumber) const override; 437 /// Return true if variable is binary 438 virtual bool isBinary(int colIndex) const override; 439 440 /** Return true if column is integer. 441 Note: This function returns true if the the column 442 is binary or a general integer. 443 */ 444 virtual bool isInteger(int colIndex) const override; 445 446 /// Return true if variable is general integer 447 virtual bool isIntegerNonBinary(int colIndex) const override; 448 449 /// Return true if variable is binary and not fixed at either bound 450 virtual bool isFreeBinary(int colIndex) const override; 451 /** Return array of column length 452 0 - continuous 453 1 - binary (may get fixed later) 454 2 - general integer (may get fixed later) 455 */ 456 virtual const char * getColType(bool refresh=false) const override; 457 458 /** Return true if column is integer but does not have to 459 be declared as such. 460 Note: This function returns true if the the column 461 is binary or a general integer. 462 */ 463 bool isOptionalInteger(int colIndex) const; 464 /** Set the index-th variable to be an optional integer variable */ 465 void setOptionalInteger(int index); 466 467 /// Get pointer to row-wise copy of matrix 468 virtual const CoinPackedMatrix * getMatrixByRow() const override; 469 470 /// Get pointer to column-wise copy of matrix 471 virtual const CoinPackedMatrix * getMatrixByCol() const override; 472 473 /// Get pointer to mutable column-wise copy of matrix 474 virtual CoinPackedMatrix * getMutableMatrixByCol() const override; 475 476 /// Get solver's value for infinity getInfinity() const477 virtual double getInfinity() const override { return OsiClpInfinity; } 478 //@} 479 480 /**@name Methods related to querying the solution */ 481 //@{ 482 /// Get pointer to array[getNumCols()] of primal solution vector 483 virtual const double * getColSolution() const override; 484 485 /// Get pointer to array[getNumRows()] of dual prices 486 virtual const double * getRowPrice() const override; 487 488 /// Get a pointer to array[getNumCols()] of reduced costs 489 virtual const double * getReducedCost() const override; 490 491 /** Get pointer to array[getNumRows()] of row activity levels (constraint 492 matrix times the solution vector */ 493 virtual const double * getRowActivity() const override; 494 495 /// Get objective function value 496 virtual double getObjValue() const override; 497 498 /** Get how many iterations it took to solve the problem (whatever 499 "iteration" mean to the solver. */ getIterationCount() const500 virtual int getIterationCount() const override 501 { return modelPtr_->numberIterations(); } 502 503 /** Get as many dual rays as the solver can provide. (In case of proven 504 primal infeasibility there should be at least one.) 505 506 The first getNumRows() ray components will always be associated with 507 the row duals (as returned by getRowPrice()). If \c fullRay is true, 508 the final getNumCols() entries will correspond to the ray components 509 associated with the nonbasic variables. If the full ray is requested 510 and the method cannot provide it, it will throw an exception. 511 512 <strong>NOTE for implementers of solver interfaces:</strong> <br> 513 The double pointers in the vector should point to arrays of length 514 getNumRows() and they should be allocated via new[]. <br> 515 516 <strong>NOTE for users of solver interfaces:</strong> <br> 517 It is the user's responsibility to free the double pointers in the 518 vector using delete[]. 519 */ 520 virtual std::vector<double*> getDualRays(int maxNumRays, 521 bool fullRay = false) const override; 522 /** Get as many primal rays as the solver can provide. (In case of proven 523 dual infeasibility there should be at least one.) 524 525 <strong>NOTE for implementers of solver interfaces:</strong> <br> 526 The double pointers in the vector should point to arrays of length 527 getNumCols() and they should be allocated via new[]. <br> 528 529 <strong>NOTE for users of solver interfaces:</strong> <br> 530 It is the user's responsibility to free the double pointers in the 531 vector using delete[]. 532 */ 533 virtual std::vector<double*> getPrimalRays(int maxNumRays) const override; 534 535 //@} 536 //@} 537 538 //--------------------------------------------------------------------------- 539 540 /**@name Problem modifying methods */ 541 //@{ 542 //------------------------------------------------------------------------- 543 /**@name Changing bounds on variables and constraints */ 544 //@{ 545 /** Set an objective function coefficient */ 546 virtual void setObjCoeff( int elementIndex, double elementValue ) override; 547 548 /** Set a single column lower bound<br> 549 Use -DBL_MAX for -infinity. */ 550 virtual void setColLower( int elementIndex, double elementValue ) override; 551 552 /** Set a single column upper bound<br> 553 Use DBL_MAX for infinity. */ 554 virtual void setColUpper( int elementIndex, double elementValue ) override; 555 556 /** Set a single column lower and upper bound */ 557 virtual void setColBounds( int elementIndex, 558 double lower, double upper ) override; 559 560 /** Set the bounds on a number of columns simultaneously<br> 561 The default implementation just invokes setColLower() and 562 setColUpper() over and over again. 563 @param indexFirst,indexLast pointers to the beginning and after the 564 end of the array of the indices of the variables whose 565 <em>either</em> bound changes 566 @param boundList the new lower/upper bound pairs for the variables 567 */ 568 virtual void setColSetBounds(const int* indexFirst, 569 const int* indexLast, 570 const double* boundList) override; 571 572 /** Set a single row lower bound<br> 573 Use -DBL_MAX for -infinity. */ 574 virtual void setRowLower( int elementIndex, double elementValue ) override; 575 576 /** Set a single row upper bound<br> 577 Use DBL_MAX for infinity. */ 578 virtual void setRowUpper( int elementIndex, double elementValue ) override ; 579 580 /** Set a single row lower and upper bound */ 581 virtual void setRowBounds( int elementIndex, 582 double lower, double upper ) override ; 583 584 /** Set the type of a single row<br> */ 585 virtual void setRowType(int index, char sense, double rightHandSide, 586 double range) override; 587 588 /** Set the bounds on a number of rows simultaneously<br> 589 The default implementation just invokes setRowLower() and 590 setRowUpper() over and over again. 591 @param indexFirst,indexLast pointers to the beginning and after the 592 end of the array of the indices of the constraints whose 593 <em>either</em> bound changes 594 @param boundList the new lower/upper bound pairs for the constraints 595 */ 596 virtual void setRowSetBounds(const int* indexFirst, 597 const int* indexLast, 598 const double* boundList) override; 599 600 /** Set the type of a number of rows simultaneously<br> 601 The default implementation just invokes setRowType() 602 over and over again. 603 @param indexFirst,indexLast pointers to the beginning and after the 604 end of the array of the indices of the constraints whose 605 <em>any</em> characteristics changes 606 @param senseList the new senses 607 @param rhsList the new right hand sides 608 @param rangeList the new ranges 609 */ 610 virtual void setRowSetTypes(const int* indexFirst, 611 const int* indexLast, 612 const char* senseList, 613 const double* rhsList, 614 const double* rangeList) override; 615 /** Set the objective coefficients for all columns 616 array [getNumCols()] is an array of values for the objective. 617 This defaults to a series of set operations and is here for speed. 618 */ 619 virtual void setObjective(const double * array) override; 620 621 /** Set the lower bounds for all columns 622 array [getNumCols()] is an array of values for the objective. 623 This defaults to a series of set operations and is here for speed. 624 */ 625 virtual void setColLower(const double * array) override; 626 627 /** Set the upper bounds for all columns 628 array [getNumCols()] is an array of values for the objective. 629 This defaults to a series of set operations and is here for speed. 630 */ 631 virtual void setColUpper(const double * array) override; 632 633 // using OsiSolverInterface::setRowName ; 634 /// Set name of row 635 // virtual void setRowName(int rowIndex, std::string & name) ; 636 virtual void setRowName(int rowIndex, std::string name) override ; 637 638 // using OsiSolverInterface::setColName ; 639 /// Set name of column 640 // virtual void setColName(int colIndex, std::string & name) ; 641 virtual void setColName(int colIndex, std::string name) override ; 642 643 //@} 644 645 //------------------------------------------------------------------------- 646 /**@name Integrality related changing methods */ 647 //@{ 648 /** Set the index-th variable to be a continuous variable */ 649 virtual void setContinuous(int index) override; 650 /** Set the index-th variable to be an integer variable */ 651 virtual void setInteger(int index) override; 652 /** Set the variables listed in indices (which is of length len) to be 653 continuous variables */ 654 virtual void setContinuous(const int* indices, int len) override; 655 /** Set the variables listed in indices (which is of length len) to be 656 integer variables */ 657 virtual void setInteger(const int* indices, int len) override; 658 /// Number of SOS sets numberSOS() const659 inline int numberSOS() const 660 { return numberSOS_;} 661 /// SOS set info setInfo() const662 inline const CoinSet * setInfo() const 663 { return setInfo_;} 664 /** \brief Identify integer variables and SOS and create corresponding objects. 665 666 Record integer variables and create an OsiSimpleInteger object for each 667 one. All existing OsiSimpleInteger objects will be destroyed. 668 If the solver supports SOS then do the same for SOS. 669 If justCount then no objects created and we just store numberIntegers_ 670 Returns number of SOS 671 */ 672 673 virtual int findIntegersAndSOS(bool justCount) override; 674 //@} 675 676 //------------------------------------------------------------------------- 677 /// Set objective function sense (1 for min (default), -1 for max,) setObjSense(double s)678 virtual void setObjSense(double s ) override 679 { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); } 680 681 /** Set the primal solution column values 682 683 colsol[numcols()] is an array of values of the problem column 684 variables. These values are copied to memory owned by the 685 solver object or the solver. They will be returned as the 686 result of colsol() until changed by another call to 687 setColsol() or by a call to any solver routine. Whether the 688 solver makes use of the solution in any way is 689 solver-dependent. 690 */ 691 virtual void setColSolution(const double * colsol) override; 692 693 /** Set dual solution vector 694 695 rowprice[numrows()] is an array of values of the problem row 696 dual variables. These values are copied to memory owned by the 697 solver object or the solver. They will be returned as the 698 result of rowprice() until changed by another call to 699 setRowprice() or by a call to any solver routine. Whether the 700 solver makes use of the solution in any way is 701 solver-dependent. 702 */ 703 virtual void setRowPrice(const double * rowprice) override; 704 705 //------------------------------------------------------------------------- 706 /**@name Methods to expand a problem.<br> 707 Note that if a column is added then by default it will correspond to a 708 continuous variable. */ 709 //@{ 710 711 //using OsiSolverInterface::addCol ; 712 /** */ 713 virtual void addCol(const CoinPackedVectorBase& vec, 714 const double collb, const double colub, 715 const double obj) override; 716 /*! \brief Add a named column (primal variable) to the problem. 717 */ 718 virtual void addCol(const CoinPackedVectorBase& vec, 719 const double collb, const double colub, 720 const double obj, std::string name) override ; 721 /** Add a column (primal variable) to the problem. */ 722 virtual void addCol(int numberElements, const int * rows, const double * elements, 723 const double collb, const double colub, 724 const double obj) override ; 725 /*! \brief Add a named column (primal variable) to the problem. 726 */ 727 virtual void addCol(int numberElements, 728 const int* rows, const double* elements, 729 const double collb, const double colub, 730 const double obj, std::string name) override ; 731 /** */ 732 virtual void addCols(const int numcols, 733 const CoinPackedVectorBase * const * cols, 734 const double* collb, const double* colub, 735 const double* obj) override; 736 /** */ 737 virtual void addCols(const int numcols, 738 const int * columnStarts, const int * rows, const double * elements, 739 const double* collb, const double* colub, 740 const double* obj) override; 741 /** */ 742 virtual void deleteCols(const int num, const int * colIndices) override; 743 744 /** */ 745 virtual void addRow(const CoinPackedVectorBase& vec, 746 const double rowlb, const double rowub) override; 747 /** */ 748 /*! \brief Add a named row (constraint) to the problem. 749 750 The default implementation adds the row, then changes the name. This 751 can surely be made more efficient within an OsiXXX class. 752 */ 753 virtual void addRow(const CoinPackedVectorBase& vec, 754 const double rowlb, const double rowub, 755 std::string name) override ; 756 virtual void addRow(const CoinPackedVectorBase& vec, 757 const char rowsen, const double rowrhs, 758 const double rowrng) override; 759 /** Add a row (constraint) to the problem. */ 760 virtual void addRow(int numberElements, const int * columns, const double * element, 761 const double rowlb, const double rowub) override ; 762 /*! \brief Add a named row (constraint) to the problem. 763 */ 764 virtual void addRow(const CoinPackedVectorBase& vec, 765 const char rowsen, const double rowrhs, 766 const double rowrng, std::string name) override ; 767 /** */ 768 virtual void addRows(const int numrows, 769 const CoinPackedVectorBase * const * rows, 770 const double* rowlb, const double* rowub) override; 771 /** */ 772 virtual void addRows(const int numrows, 773 const CoinPackedVectorBase * const * rows, 774 const char* rowsen, const double* rowrhs, 775 const double* rowrng) override; 776 777 /** */ 778 virtual void addRows(const int numrows, 779 const int * rowStarts, const int * columns, const double * element, 780 const double* rowlb, const double* rowub) override; 781 /// modifyCoefficient(int row,int column,double newElement,bool keepZero=false)782 void modifyCoefficient(int row, int column, double newElement, 783 bool keepZero=false) 784 {modelPtr_->modifyCoefficient(row,column,newElement, keepZero);} 785 786 /** */ 787 virtual void deleteRows(const int num, const int * rowIndices) override; 788 /** If solver wants it can save a copy of "base" (continuous) model here 789 */ 790 virtual void saveBaseModel() override ; 791 /** Strip off rows to get to this number of rows. 792 If solver wants it can restore a copy of "base" (continuous) model here 793 */ 794 virtual void restoreBaseModel(int numberRows) override; 795 796 //----------------------------------------------------------------------- 797 /** Apply a collection of row cuts which are all effective. 798 applyCuts seems to do one at a time which seems inefficient. 799 */ 800 virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts) override; 801 /** Apply a collection of row cuts which are all effective. 802 applyCuts seems to do one at a time which seems inefficient. 803 This uses array of pointers 804 */ 805 virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts) override; 806 /** Apply a collection of cuts. 807 808 Only cuts which have an <code>effectiveness >= effectivenessLb</code> 809 are applied. 810 <ul> 811 <li> ReturnCode.getNumineffective() -- number of cuts which were 812 not applied because they had an 813 <code>effectiveness < effectivenessLb</code> 814 <li> ReturnCode.getNuminconsistent() -- number of invalid cuts 815 <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of 816 cuts that are invalid with respect to this integer model 817 <li> ReturnCode.getNuminfeasible() -- number of cuts that would 818 make this integer model infeasible 819 <li> ReturnCode.getNumApplied() -- number of integer cuts which 820 were applied to the integer model 821 <li> cs.size() == getNumineffective() + 822 getNuminconsistent() + 823 getNuminconsistentWrtIntegerModel() + 824 getNuminfeasible() + 825 getNumApplied() 826 </ul> 827 */ 828 virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, 829 double effectivenessLb = 0.0) override; 830 831 //@} 832 //@} 833 834 //--------------------------------------------------------------------------- 835 836 public: 837 838 /**@name Methods to input a problem */ 839 //@{ 840 /** Load in an problem by copying the arguments (the constraints on the 841 rows are given by lower and upper bounds). If a pointer is NULL then the 842 following values are the default: 843 <ul> 844 <li> <code>colub</code>: all columns have upper bound infinity 845 <li> <code>collb</code>: all columns have lower bound 0 846 <li> <code>rowub</code>: all rows have upper bound infinity 847 <li> <code>rowlb</code>: all rows have lower bound -infinity 848 <li> <code>obj</code>: all variables have 0 objective coefficient 849 </ul> 850 */ 851 virtual void loadProblem(const CoinPackedMatrix& matrix, 852 const double* collb, const double* colub, 853 const double* obj, 854 const double* rowlb, const double* rowub) override; 855 856 /** Load in an problem by assuming ownership of the arguments (the 857 constraints on the rows are given by lower and upper bounds). For 858 default values see the previous method. <br> 859 <strong>WARNING</strong>: The arguments passed to this method will be 860 freed using the C++ <code>delete</code> and <code>delete[]</code> 861 functions. 862 */ 863 virtual void assignProblem(CoinPackedMatrix*& matrix, 864 double*& collb, double*& colub, double*& obj, 865 double*& rowlb, double*& rowub) override; 866 867 /** Load in an problem by copying the arguments (the constraints on the 868 rows are given by sense/rhs/range triplets). If a pointer is NULL then the 869 following values are the default: 870 <ul> 871 <li> <code>colub</code>: all columns have upper bound infinity 872 <li> <code>collb</code>: all columns have lower bound 0 873 <li> <code>obj</code>: all variables have 0 objective coefficient 874 <li> <code>rowsen</code>: all rows are >= 875 <li> <code>rowrhs</code>: all right hand sides are 0 876 <li> <code>rowrng</code>: 0 for the ranged rows 877 </ul> 878 */ 879 virtual void loadProblem(const CoinPackedMatrix& matrix, 880 const double* collb, const double* colub, 881 const double* obj, 882 const char* rowsen, const double* rowrhs, 883 const double* rowrng) override; 884 885 /** Load in an problem by assuming ownership of the arguments (the 886 constraints on the rows are given by sense/rhs/range triplets). For 887 default values see the previous method. <br> 888 <strong>WARNING</strong>: The arguments passed to this method will be 889 freed using the C++ <code>delete</code> and <code>delete[]</code> 890 functions. 891 */ 892 virtual void assignProblem(CoinPackedMatrix*& matrix, 893 double*& collb, double*& colub, double*& obj, 894 char*& rowsen, double*& rowrhs, 895 double*& rowrng) override; 896 897 /** Just like the other loadProblem() methods except that the matrix is 898 given as a ClpMatrixBase. */ 899 virtual void loadProblem(const ClpMatrixBase& matrix, 900 const double* collb, const double* colub, 901 const double* obj, 902 const double* rowlb, const double* rowub) ; 903 904 /** Just like the other loadProblem() methods except that the matrix is 905 given in a standard column major ordered format (without gaps). */ 906 virtual void loadProblem(const int numcols, const int numrows, 907 const CoinBigIndex * start, const int* index, 908 const double* value, 909 const double* collb, const double* colub, 910 const double* obj, 911 const double* rowlb, const double* rowub) override; 912 913 /** Just like the other loadProblem() methods except that the matrix is 914 given in a standard column major ordered format (without gaps). */ 915 virtual void loadProblem(const int numcols, const int numrows, 916 const CoinBigIndex * start, const int* index, 917 const double* value, 918 const double* collb, const double* colub, 919 const double* obj, 920 const char* rowsen, const double* rowrhs, 921 const double* rowrng) override; 922 /// This loads a model from a coinModel object - returns number of errors 923 virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false) override; 924 925 using OsiSolverInterface::readMps ; 926 /** Read an mps file from the given filename (defaults to Osi reader) - returns 927 number of errors (see OsiMpsReader class) */ 928 virtual int readMps(const char *filename, 929 const char *extension = "mps") override ; 930 /** Read an mps file from the given filename returns 931 number of errors (see OsiMpsReader class) */ 932 int readMps(const char *filename,bool keepNames,bool allowErrors); 933 /// Read an mps file 934 virtual int readMps (const char *filename, const char*extension, 935 int & numberSets, CoinSet ** & sets) override; 936 937 /** Write the problem into an mps file of the given filename. 938 If objSense is non zero then -1.0 forces the code to write a 939 maximization objective and +1.0 to write a minimization one. 940 If 0.0 then solver can do what it wants */ 941 virtual void writeMps(const char *filename, 942 const char *extension = "mps", 943 double objSense=0.0) const override; 944 /** Write the problem into an mps file of the given filename, 945 names may be null. formatType is 946 0 - normal 947 1 - extra accuracy 948 2 - IEEE hex (later) 949 950 Returns non-zero on I/O error 951 */ 952 virtual int writeMpsNative(const char *filename, 953 const char ** rowNames, const char ** columnNames, 954 int formatType=0,int numberAcross=2, 955 double objSense=0.0) const ; 956 /// Read file in LP format (with names) 957 virtual int readLp(const char *filename, const double epsilon = 1e-5) override; 958 /** Write the problem into an Lp file of the given filename. 959 If objSense is non zero then -1.0 forces the code to write a 960 maximization objective and +1.0 to write a minimization one. 961 If 0.0 then solver can do what it wants. 962 This version calls writeLpNative with names */ 963 virtual void writeLp(const char *filename, 964 const char *extension = "lp", 965 double epsilon = 1e-5, 966 int numberAcross = 10, 967 int decimals = 5, 968 double objSense = 0.0, 969 bool useRowNames = true) const override; 970 /** Write the problem into the file pointed to by the parameter fp. 971 Other parameters are similar to 972 those of writeLp() with first parameter filename. 973 */ 974 virtual void writeLp(FILE *fp, 975 double epsilon = 1e-5, 976 int numberAcross = 10, 977 int decimals = 5, 978 double objSense = 0.0, 979 bool useRowNames = true) const override; 980 /** 981 I (JJF) am getting annoyed because I can't just replace a matrix. 982 The default behavior of this is do nothing so only use where that would not matter 983 e.g. strengthening a matrix for MIP 984 */ 985 virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix) override; 986 /// And if it does matter (not used at present) 987 virtual void replaceMatrix(const CoinPackedMatrix & matrix) override ; 988 //@} 989 990 /**@name Message handling (extra for Clp messages). 991 Normally I presume you would want the same language. 992 If not then you could use underlying model pointer */ 993 //@{ 994 /** Pass in a message handler 995 996 It is the client's responsibility to destroy a message handler installed 997 by this routine; it will not be destroyed when the solver interface is 998 destroyed. 999 */ 1000 virtual void passInMessageHandler(CoinMessageHandler * handler) override; 1001 /// Set language 1002 void newLanguage(CoinMessages::Language language); setLanguage(CoinMessages::Language language)1003 void setLanguage(CoinMessages::Language language) 1004 {newLanguage(language);} 1005 /// Set log level (will also set underlying solver's log level) 1006 void setLogLevel(int value); 1007 /// Create C++ lines to get to current state 1008 void generateCpp( FILE * fp); 1009 //@} 1010 //--------------------------------------------------------------------------- 1011 1012 /**@name Clp specific public interfaces */ 1013 //@{ 1014 /// Get pointer to Clp model 1015 ClpSimplex * getModelPtr() const ; 1016 /// Set pointer to Clp model and return old swapModelPtr(ClpSimplex * newModel)1017 inline ClpSimplex * swapModelPtr(ClpSimplex * newModel) 1018 { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;} 1019 /// Get special options specialOptions() const1020 inline unsigned int specialOptions() const 1021 { return specialOptions_;} 1022 void setSpecialOptions(unsigned int value); 1023 /// Last algorithm used , 1 = primal, 2 = dual other unknown lastAlgorithm() const1024 inline int lastAlgorithm() const 1025 { return lastAlgorithm_;} 1026 /// Set last algorithm used , 1 = primal, 2 = dual other unknown setLastAlgorithm(int value)1027 inline void setLastAlgorithm(int value) 1028 { lastAlgorithm_ = value;} 1029 /// Get scaling action option cleanupScaling() const1030 inline int cleanupScaling() const 1031 { return cleanupScaling_;} 1032 /** Set Scaling option 1033 When scaling is on it is possible that the scaled problem 1034 is feasible but the unscaled is not. Clp returns a secondary 1035 status code to that effect. This option allows for a cleanup. 1036 If you use it I would suggest 1. 1037 This only affects actions when scaled optimal 1038 0 - no action 1039 1 - clean up using dual if primal infeasibility 1040 2 - clean up using dual if dual infeasibility 1041 3 - clean up using dual if primal or dual infeasibility 1042 11,12,13 - as 1,2,3 but use primal 1043 */ setCleanupScaling(int value)1044 inline void setCleanupScaling(int value) 1045 { cleanupScaling_=value;} 1046 /** Get smallest allowed element in cut. 1047 If smaller than this then ignored */ smallestElementInCut() const1048 inline double smallestElementInCut() const 1049 { return smallestElementInCut_;} 1050 /** Set smallest allowed element in cut. 1051 If smaller than this then ignored */ setSmallestElementInCut(double value)1052 inline void setSmallestElementInCut(double value) 1053 { smallestElementInCut_=value;} 1054 /** Get smallest change in cut. 1055 If (upper-lower)*element < this then element is 1056 taken out and cut relaxed. 1057 (upper-lower) is taken to be at least 1.0 and 1058 this is assumed >= smallestElementInCut_ 1059 */ smallestChangeInCut() const1060 inline double smallestChangeInCut() const 1061 { return smallestChangeInCut_;} 1062 /** Set smallest change in cut. 1063 If (upper-lower)*element < this then element is 1064 taken out and cut relaxed. 1065 (upper-lower) is taken to be at least 1.0 and 1066 this is assumed >= smallestElementInCut_ 1067 */ setSmallestChangeInCut(double value)1068 inline void setSmallestChangeInCut(double value) 1069 { smallestChangeInCut_=value;} 1070 /// Pass in initial solve options setSolveOptions(const ClpSolve & options)1071 inline void setSolveOptions(const ClpSolve & options) 1072 { solveOptions_ = options;} 1073 /** Tighten bounds - lightweight or very lightweight 1074 0 - normal, 1 lightweight but just integers, 2 lightweight and all 1075 */ 1076 virtual int tightenBounds(int lightweight=0); 1077 /// Return number of entries in L part of current factorization 1078 virtual CoinBigIndex getSizeL() const; 1079 /// Return number of entries in U part of current factorization 1080 virtual CoinBigIndex getSizeU() const; 1081 /// Get disaster handler disasterHandler() const1082 const OsiClpDisasterHandler * disasterHandler() const 1083 { return disasterHandler_;} 1084 /// Pass in disaster handler 1085 void passInDisasterHandler(OsiClpDisasterHandler * handler); 1086 /// Get fake objective fakeObjective() const1087 ClpLinearObjective * fakeObjective() const 1088 { return fakeObjective_;} 1089 /// Set fake objective (and take ownership) 1090 void setFakeObjective(ClpLinearObjective * fakeObjective); 1091 /// Set fake objective 1092 void setFakeObjective(double * fakeObjective); 1093 /*! \brief Set up solver for repeated use by Osi interface. 1094 1095 The normal usage does things like keeping factorization around so can be 1096 used. Will also do things like keep scaling and row copy of matrix if 1097 matrix does not change. 1098 1099 \p senseOfAdventure: 1100 - 0 - safe stuff as above 1101 - 1 - will take more risks - if it does not work then bug which will be 1102 fixed 1103 - 2 - don't bother doing most extreme termination checks e.g. don't bother 1104 re-factorizing if less than 20 iterations. 1105 - 3 - Actually safer than 1 (mainly just keeps factorization) 1106 1107 \p printOut 1108 - -1 always skip round common messages instead of doing some work 1109 - 0 skip if normal defaults 1110 - 1 leaves 1111 */ 1112 void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0); 1113 /// Synchronize model (really if no cuts in tree) 1114 virtual void synchronizeModel(); 1115 /*! \brief Set special options in underlying clp solver. 1116 1117 Safe as const because #modelPtr_ is mutable. 1118 */ 1119 void setSpecialOptionsMutable(unsigned int value) const; 1120 1121 //@} 1122 1123 //--------------------------------------------------------------------------- 1124 1125 /**@name Constructors and destructors */ 1126 //@{ 1127 /// Default Constructor 1128 OsiClpSolverInterface (); 1129 1130 /// Clone 1131 virtual OsiSolverInterface * clone(bool copyData = true) const override; 1132 1133 /// Copy constructor 1134 OsiClpSolverInterface (const OsiClpSolverInterface &); 1135 1136 /// Borrow constructor - only delete one copy 1137 OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false); 1138 1139 /// Releases so won't error 1140 void releaseClp(); 1141 1142 /// Assignment operator 1143 OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs); 1144 1145 /// Destructor 1146 virtual ~OsiClpSolverInterface (); 1147 1148 /// Resets as if default constructor 1149 virtual void reset() override; 1150 //@} 1151 1152 //--------------------------------------------------------------------------- 1153 1154 protected: 1155 ///@name Protected methods 1156 //@{ 1157 /** Apply a row cut (append to constraint matrix). */ 1158 virtual void applyRowCut(const OsiRowCut& rc) override; 1159 1160 /** Apply a column cut (adjust one or more bounds). */ 1161 virtual void applyColCut(const OsiColCut& cc) override; 1162 //@} 1163 1164 //--------------------------------------------------------------------------- 1165 1166 protected: 1167 /**@name Protected methods */ 1168 //@{ 1169 /// The real work of a copy constructor (used by copy and assignment) 1170 void gutsOfDestructor(); 1171 1172 /// Deletes all mutable stuff 1173 void freeCachedResults() const; 1174 1175 /// Deletes all mutable stuff for row ranges etc 1176 void freeCachedResults0() const; 1177 1178 /// Deletes all mutable stuff for matrix etc 1179 void freeCachedResults1() const; 1180 1181 /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays 1182 void extractSenseRhsRange() const; 1183 1184 /// 1185 void fillParamMaps(); 1186 /** Warm start 1187 1188 NOTE artificials are treated as +1 elements so for <= rhs 1189 artificial will be at lower bound if constraint is tight 1190 1191 This means that Clpsimplex flips artificials as it works 1192 in terms of row activities 1193 */ 1194 CoinWarmStartBasis getBasis(ClpSimplex * model) const; 1195 /** Sets up working basis as a copy of input 1196 1197 NOTE artificials are treated as +1 elements so for <= rhs 1198 artificial will be at lower bound if constraint is tight 1199 1200 This means that Clpsimplex flips artificials as it works 1201 in terms of row activities 1202 */ 1203 void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model); 1204 /// Crunch down problem a bit 1205 void crunch(); 1206 /// Extend scale factors 1207 void redoScaleFactors(int numberRows,const CoinBigIndex * starts, 1208 const int * indices, const double * elements); 1209 public: 1210 /** Sets up working basis as a copy of input and puts in as basis 1211 */ 1212 void setBasis( const CoinWarmStartBasis & basis); 1213 /// Just puts current basis_ into ClpSimplex model setBasis()1214 inline void setBasis( ) 1215 { setBasis(basis_,modelPtr_);} 1216 /// Warm start difference from basis_ to statusArray 1217 CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ; 1218 /// Warm start from statusArray 1219 CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ; 1220 /// Delete all scale factor stuff and reset option 1221 void deleteScaleFactors(); 1222 /// If doing fast hot start then ranges are computed upRange() const1223 inline const double * upRange() const 1224 { return rowActivity_;} downRange() const1225 inline const double * downRange() const 1226 { return columnActivity_;} 1227 /// Pass in range array passInRanges(int * array)1228 inline void passInRanges(int * array) 1229 { whichRange_=array;} 1230 /// Pass in sos stuff from AMPl 1231 void setSOSData(int numberSOS,const char * type, 1232 const int * start,const int * indices, const double * weights=nullptr); 1233 /// Compute largest amount any at continuous away from bound 1234 void computeLargestAway(); 1235 /// Get largest amount continuous away from bound largestAway() const1236 inline double largestAway() const 1237 { return largestAway_;} 1238 /// Set largest amount continuous away from bound setLargestAway(double value)1239 inline void setLargestAway(double value) 1240 { largestAway_ = value;} 1241 /// Sort of lexicographic resolve 1242 void lexSolve(); 1243 //@} 1244 1245 protected: 1246 /**@name Protected member data */ 1247 //@{ 1248 /// Clp model represented by this class instance 1249 mutable ClpSimplex * modelPtr_; 1250 //@} 1251 /**@name Cached information derived from the OSL model */ 1252 //@{ 1253 /// Pointer to dense vector of row sense indicators 1254 mutable char *rowsense_; 1255 1256 /// Pointer to dense vector of row right-hand side values 1257 mutable double *rhs_; 1258 1259 /** Pointer to dense vector of slack upper bounds for range 1260 constraints (undefined for non-range rows) 1261 */ 1262 mutable double *rowrange_; 1263 1264 /** A pointer to the warmstart information to be used in the hotstarts. 1265 This is NOT efficient and more thought should be given to it... */ 1266 mutable CoinWarmStartBasis* ws_; 1267 /** also save row and column information for hot starts 1268 only used in hotstarts so can be casual */ 1269 mutable double * rowActivity_; 1270 mutable double * columnActivity_; 1271 /// Stuff for fast dual 1272 ClpNodeStuff stuff_; 1273 /// Number of SOS sets 1274 int numberSOS_; 1275 /// SOS set info 1276 CoinSet * setInfo_; 1277 /// Alternate model (hot starts) - but also could be permanent and used for crunch 1278 ClpSimplex * smallModel_; 1279 /// factorization for hot starts 1280 ClpFactorization * factorization_; 1281 /** Smallest allowed element in cut. 1282 If smaller than this then ignored */ 1283 double smallestElementInCut_; 1284 /** Smallest change in cut. 1285 If (upper-lower)*element < this then element is 1286 taken out and cut relaxed. */ 1287 double smallestChangeInCut_; 1288 /// Largest amount continuous away from bound 1289 double largestAway_; 1290 /// Arrays for hot starts 1291 char * spareArrays_; 1292 /** Warmstart information to be used in resolves. */ 1293 CoinWarmStartBasis basis_; 1294 /** The original iteration limit before hotstarts started. */ 1295 int itlimOrig_; 1296 1297 /*! \brief Last algorithm used 1298 1299 Coded as 1300 - 0 invalid 1301 - 1 primal 1302 - 2 dual 1303 - -911 disaster in the algorithm that was attempted 1304 - 999 current solution no longer optimal due to change in problem or 1305 basis 1306 */ 1307 mutable int lastAlgorithm_; 1308 1309 /// To say if destructor should delete underlying model 1310 bool notOwned_; 1311 1312 /// Pointer to row-wise copy of problem matrix coefficients. 1313 mutable CoinPackedMatrix *matrixByRow_; 1314 1315 /// Pointer to row-wise copy of continuous problem matrix coefficients. 1316 CoinPackedMatrix *matrixByRowAtContinuous_; 1317 1318 /// Pointer to integer information 1319 char * integerInformation_; 1320 1321 /** Pointer to variables for which we want range information 1322 The number is in [0] 1323 memory is not owned by OsiClp 1324 */ 1325 int * whichRange_; 1326 1327 //std::map<OsiIntParam, ClpIntParam> intParamMap_; 1328 //std::map<OsiDblParam, ClpDblParam> dblParamMap_; 1329 //std::map<OsiStrParam, ClpStrParam> strParamMap_; 1330 1331 /*! \brief Faking min to get proper dual solution signs in simplex API */ 1332 mutable bool fakeMinInSimplex_ ; 1333 /*! \brief Linear objective 1334 1335 Normally a pointer to the linear coefficient array in the clp objective. 1336 An independent copy when #fakeMinInSimplex_ is true, because we need 1337 something permanent to point to when #getObjCoefficients is called. 1338 */ 1339 mutable double *linearObjective_; 1340 1341 /// To save data in OsiSimplex stuff 1342 mutable ClpDataSave saveData_; 1343 /// Options for initialSolve 1344 ClpSolve solveOptions_; 1345 /** Scaling option 1346 When scaling is on it is possible that the scaled problem 1347 is feasible but the unscaled is not. Clp returns a secondary 1348 status code to that effect. This option allows for a cleanup. 1349 If you use it I would suggest 1. 1350 This only affects actions when scaled optimal 1351 0 - no action 1352 1 - clean up using dual if primal infeasibility 1353 2 - clean up using dual if dual infeasibility 1354 3 - clean up using dual if primal or dual infeasibility 1355 11,12,13 - as 1,2,3 but use primal 1356 */ 1357 int cleanupScaling_; 1358 /** Special options 1359 0x80000000 off 1360 0 simple stuff for branch and bound 1361 1 try and keep work regions as much as possible 1362 2 do not use any perturbation 1363 4 allow exit before re-factorization 1364 8 try and re-use factorization if no cuts 1365 16 use standard strong branching rather than clp's 1366 32 Just go to first factorization in fast dual 1367 64 try and tighten bounds in crunch 1368 128 Model will only change in column bounds 1369 256 Clean up model before hot start 1370 512 Give user direct access to Clp regions in getBInvARow etc (i.e., 1371 do not unscale, and do not return result in getBInv parameters; 1372 you have to know where to look for the answer) 1373 1024 Don't "borrow" model in initialSolve 1374 2048 Don't crunch 1375 4096 quick check for optimality 1376 Bits above 8192 give where called from in Cbc 1377 At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check 1378 65536 Keep simple i.e. no crunch etc 1379 131072 Try and keep scaling factors around 1380 262144 Don't try and tighten bounds (funny global cuts) 1381 524288 Fake objective and 0-1 1382 1048576 Don't recompute ray after crunch 1383 2097152 1384 */ 1385 mutable unsigned int specialOptions_; 1386 /// Copy of model when option 131072 set 1387 ClpSimplex * baseModel_; 1388 /// Number of rows when last "scaled" 1389 int lastNumberRows_; 1390 /// Continuous model 1391 ClpSimplex * continuousModel_; 1392 /// Possible disaster handler 1393 OsiClpDisasterHandler * disasterHandler_ ; 1394 /// Fake objective 1395 ClpLinearObjective * fakeObjective_; 1396 /// Row scale factors (has inverse at end) 1397 CoinDoubleArrayWithLength rowScale_; 1398 /// Column scale factors (has inverse at end) 1399 CoinDoubleArrayWithLength columnScale_; 1400 //@} 1401 }; 1402 1403 class OsiClpDisasterHandler : public ClpDisasterHandler { 1404 public: 1405 /**@name Virtual methods that the derived classe should provide. 1406 */ 1407 //@{ 1408 /// Into simplex 1409 virtual void intoSimplex() override; 1410 /// Checks if disaster 1411 virtual bool check() const override ; 1412 /// saves information for next attempt 1413 virtual void saveInfo() override; 1414 /// Type of disaster 0 can fix, 1 abort 1415 virtual int typeOfDisaster() override; 1416 //@} 1417 1418 1419 /**@name Constructors, destructor */ 1420 1421 //@{ 1422 /** Default constructor. */ 1423 OsiClpDisasterHandler(OsiClpSolverInterface * model = nullptr); 1424 /** Destructor */ 1425 virtual ~OsiClpDisasterHandler(); 1426 // Copy 1427 OsiClpDisasterHandler(const OsiClpDisasterHandler&); 1428 // Assignment 1429 OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&); 1430 /// Clone 1431 virtual ClpDisasterHandler * clone() const override; 1432 1433 //@} 1434 1435 /**@name Sets/gets */ 1436 1437 //@{ 1438 /** set model. */ 1439 void setOsiModel(OsiClpSolverInterface * model); 1440 /// Get model osiModel() const1441 inline OsiClpSolverInterface * osiModel() const 1442 { return osiModel_;} 1443 /// Set where from setWhereFrom(int value)1444 inline void setWhereFrom(int value) 1445 { whereFrom_=value;} 1446 /// Get where from whereFrom() const1447 inline int whereFrom() const 1448 { return whereFrom_;} 1449 /// Set phase setPhase(int value)1450 inline void setPhase(int value) 1451 { phase_=value;} 1452 /// Get phase phase() const1453 inline int phase() const 1454 { return phase_;} 1455 /// are we in trouble inTrouble() const1456 inline bool inTrouble() const 1457 { return inTrouble_;} 1458 1459 //@} 1460 1461 1462 protected: 1463 /**@name Data members 1464 The data members are protected to allow access for derived classes. */ 1465 //@{ 1466 /// Pointer to model 1467 OsiClpSolverInterface * osiModel_; 1468 /** Where from 1469 0 dual (resolve) 1470 1 crunch 1471 2 primal (resolve) 1472 4 dual (initialSolve) 1473 6 primal (initialSolve) 1474 */ 1475 int whereFrom_; 1476 /** phase 1477 0 initial 1478 1 trying continuing with back in and maybe different perturb 1479 2 trying continuing with back in and different scaling 1480 3 trying dual from all slack 1481 4 trying primal from previous stored basis 1482 */ 1483 int phase_; 1484 /// Are we in trouble 1485 bool inTrouble_; 1486 //@} 1487 }; 1488 // So unit test can find out if NDEBUG set 1489 bool OsiClpHasNDEBUG(); 1490 //############################################################################# 1491 /** A function that tests the methods in the OsiClpSolverInterface class. */ 1492 void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); 1493 #endif 1494