1 // Copyright (C) 2000, International Business Machines 2 // Corporation and others. All Rights Reserved. 3 // This code is licensed under the terms of the Eclipse Public License (EPL). 4 5 #ifndef OsiXprSolverInterface_H 6 #define OsiXprSolverInterface_H 7 8 #include <string> 9 #include <cstdio> 10 11 #include "OsiSolverInterface.hpp" 12 13 typedef struct xo_prob_struct *XPRSprob; 14 15 //############################################################################# 16 17 /** XPRESS-MP Solver Interface 18 19 Instantiation of OsiSolverInterface for XPRESS-MP 20 */ 21 class OsiXprSolverInterface : virtual public OsiSolverInterface { 22 friend void OsiXprSolverInterfaceUnitTest(const std::string &mpsDir, const std::string &netlibDir); 23 24 public: 25 /**@name Solve methods */ 26 //@{ 27 /// Solve initial LP relaxation 28 virtual void initialSolve(); 29 30 /// Resolve an LP relaxation after problem modification 31 virtual void resolve(); 32 33 /// Invoke solver's built-in enumeration algorithm 34 virtual void branchAndBound(); 35 //@} 36 37 /**@name Parameter set/get methods 38 39 The set methods return true if the parameter was set to the given value, 40 false otherwise. There can be various reasons for failure: the given 41 parameter is not applicable for the solver (e.g., refactorization 42 frequency for the volume algorithm), the parameter is not yet implemented 43 for the solver or simply the value of the parameter is out of the range 44 the solver accepts. If a parameter setting call returns false check the 45 details of your solver. 46 47 The get methods return true if the given parameter is applicable for the 48 solver and is implemented. In this case the value of the parameter is 49 returned in the second argument. Otherwise they return false. 50 */ 51 //@{ 52 // Set an integer parameter 53 bool setIntParam(OsiIntParam key, int value); 54 // Set an double parameter 55 bool setDblParam(OsiDblParam key, double value); 56 // Set a string parameter 57 bool setStrParam(OsiStrParam key, const std::string &value); 58 // Get an integer parameter 59 bool getIntParam(OsiIntParam key, int &value) const; 60 // Get an double parameter 61 bool getDblParam(OsiDblParam key, double &value) const; 62 // Get a string parameter 63 bool getStrParam(OsiStrParam key, std::string &value) const; 64 // Set mipstart option (pass column solution to XPRESS before MIP start) setMipStart(bool value)65 void setMipStart(bool value) { domipstart = value; } 66 // Get mipstart option value getMipStart() const67 bool getMipStart() const { return domipstart; } 68 //@} 69 70 //--------------------------------------------------------------------------- 71 ///@name Methods returning info on how the solution process terminated 72 //@{ 73 /// Are there a numerical difficulties? 74 virtual bool isAbandoned() const; 75 /// Is optimality proven? 76 virtual bool isProvenOptimal() const; 77 /// Is primal infeasiblity proven? 78 virtual bool isProvenPrimalInfeasible() const; 79 /// Is dual infeasiblity proven? 80 virtual bool isProvenDualInfeasible() const; 81 /// Is the given primal objective limit reached? 82 virtual bool isPrimalObjectiveLimitReached() const; 83 /// Is the given dual objective limit reached? 84 virtual bool isDualObjectiveLimitReached() const; 85 /// Iteration limit reached? 86 virtual bool isIterationLimitReached() const; 87 //@} 88 89 //--------------------------------------------------------------------------- 90 /**@name WarmStart related methods */ 91 //@{ 92 /// Get empty warm start object 93 CoinWarmStart *getEmptyWarmStart() const; 94 /// Get warmstarting information 95 virtual CoinWarmStart *getWarmStart() const; 96 /** Set warmstarting information. Return true/false depending on whether 97 the warmstart information was accepted or not. */ 98 virtual bool setWarmStart(const CoinWarmStart *warmstart); 99 //@} 100 101 //--------------------------------------------------------------------------- 102 /**@name Hotstart related methods (primarily used in strong branching). <br> 103 The user can create a hotstart (a snapshot) of the optimization process 104 then reoptimize over and over again always starting from there.<br> 105 <strong>NOTE</strong>: between hotstarted optimizations only 106 bound changes are allowed. */ 107 //@{ 108 /// Create a hotstart point of the optimization process 109 virtual void markHotStart(); 110 /// Optimize starting from the hotstart 111 virtual void solveFromHotStart(); 112 /// Delete the snapshot 113 virtual void unmarkHotStart(); 114 //@} 115 116 //--------------------------------------------------------------------------- 117 /**@name Problem information methods 118 119 These methods call the solver's query routines to return 120 information about the problem referred to by the current object. 121 Querying a problem that has no data associated with it result in 122 zeros for the number of rows and columns, and NULL pointers from 123 the methods that return vectors. 124 125 Const pointers returned from any data-query method are valid as 126 long as the data is unchanged and the solver is not called. 127 */ 128 //@{ 129 /**@name Methods related to querying the input data */ 130 //@{ 131 /// Get number of columns 132 virtual int getNumCols() const; 133 134 /// Get number of rows 135 virtual int getNumRows() const; 136 137 /// Get number of nonzero elements 138 virtual int getNumElements() const; 139 140 /// Get pointer to array[getNumCols()] of column lower bounds 141 virtual const double *getColLower() const; 142 143 /// Get pointer to array[getNumCols()] of column upper bounds 144 virtual const double *getColUpper() const; 145 146 /** Get pointer to array[getNumRows()] of row constraint senses. 147 <ul> 148 <li>'L': <= constraint 149 <li>'E': = constraint 150 <li>'G': >= constraint 151 <li>'R': ranged constraint 152 <li>'N': free constraint 153 </ul> 154 */ 155 virtual const char *getRowSense() const; 156 157 /** Get pointer to array[getNumRows()] of rows right-hand sides 158 <ul> 159 <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] 160 <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] 161 <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] 162 <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 163 </ul> 164 */ 165 virtual const double *getRightHandSide() const; 166 167 /** Get pointer to array[getNumRows()] of row ranges. 168 <ul> 169 <li> if rowsense()[i] == 'R' then 170 rowrange()[i] == rowupper()[i] - rowlower()[i] 171 <li> if rowsense()[i] != 'R' then 172 rowrange()[i] is 0.0 173 </ul> 174 */ 175 virtual const double *getRowRange() const; 176 177 /// Get pointer to array[getNumRows()] of row lower bounds 178 virtual const double *getRowLower() const; 179 180 /// Get pointer to array[getNumRows()] of row upper bounds 181 virtual const double *getRowUpper() const; 182 183 /// Get pointer to array[getNumCols()] of objective function coefficients 184 virtual const double *getObjCoefficients() const; 185 186 /// Get objective function sense (1 for min (default), -1 for max) 187 virtual double getObjSense() const; 188 189 /// Return true if variable is continuous 190 virtual bool isContinuous(int colIndex) const; 191 192 #if 0 193 /// Return true if variable is binary 194 virtual bool isBinary(int colIndex) const; 195 196 /** Return true if column is integer. 197 Note: This function returns true if the the column 198 is binary or a general integer. 199 */ 200 virtual bool isInteger(int colIndex) const; 201 202 /// Return true if variable is general integer 203 virtual bool isIntegerNonBinary(int colIndex) const; 204 205 /// Return true if variable is binary and not fixed at either bound 206 virtual bool isFreeBinary(int colIndex) const; 207 #endif 208 /// Get pointer to row-wise copy of matrix 209 virtual const CoinPackedMatrix *getMatrixByRow() const; 210 211 /// Get pointer to column-wise copy of matrix 212 virtual const CoinPackedMatrix *getMatrixByCol() const; 213 214 /// Get solver's value for infinity 215 virtual double getInfinity() const; 216 //@} 217 218 /**@name Methods related to querying the solution */ 219 //@{ 220 /// Get pointer to array[getNumCols()] of primal solution vector 221 virtual const double *getColSolution() const; 222 223 /// Get pointer to array[getNumRows()] of dual prices 224 virtual const double *getRowPrice() const; 225 226 /// Get a pointer to array[getNumCols()] of reduced costs 227 virtual const double *getReducedCost() const; 228 229 /** Get pointer to array[getNumRows()] of row activity levels (constraint 230 matrix times the solution vector */ 231 virtual const double *getRowActivity() const; 232 233 /// Get objective function value 234 virtual double getObjValue() const; 235 236 /** Get how many iterations it took to solve the problem (whatever 237 "iteration" mean to the solver. */ 238 virtual int getIterationCount() const; 239 240 /** Get as many dual rays as the solver can provide. (In case of proven 241 primal infeasibility there should be at least one.) 242 243 The first getNumRows() ray components will always be associated with 244 the row duals (as returned by getRowPrice()). If \c fullRay is true, 245 the final getNumCols() entries will correspond to the ray components 246 associated with the nonbasic variables. If the full ray is requested 247 and the method cannot provide it, it will throw an exception. 248 249 <strong>NOTE for implementers of solver interfaces:</strong> <br> 250 The double pointers in the vector should point to arrays of length 251 getNumRows() and they should be allocated via new[]. <br> 252 253 <strong>NOTE for users of solver interfaces:</strong> <br> 254 It is the user's responsibility to free the double pointers in the 255 vector using delete[]. 256 */ 257 virtual std::vector< double * > getDualRays(int maxNumRays, 258 bool fullRay = false) const; 259 /** Get as many primal rays as the solver can provide. (In case of proven 260 dual infeasibility there should be at least one.) 261 262 <strong>NOTE for implementers of solver interfaces:</strong> <br> 263 The double pointers in the vector should point to arrays of length 264 getNumCols() and they should be allocated via new[]. <br> 265 266 <strong>NOTE for users of solver interfaces:</strong> <br> 267 It is the user's responsibility to free the double pointers in the 268 vector using delete[]. 269 */ 270 virtual std::vector< double * > getPrimalRays(int maxNumRays) const; 271 272 #if 0 273 /** Get vector of indices of solution which are integer variables 274 presently at fractional values */ 275 virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05) 276 const; 277 #endif 278 //@} 279 //@} 280 281 //--------------------------------------------------------------------------- 282 283 /**@name Problem modifying methods */ 284 //@{ 285 //------------------------------------------------------------------------- 286 /**@name Changing bounds on variables and constraints */ 287 //@{ 288 /** Set an objective function coefficient */ 289 virtual void setObjCoeff(int elementIndex, double elementValue); 290 291 /** Set a single column lower bound<br> 292 Use -COIN_DBL_MAX for -infinity. */ 293 virtual void setColLower(int elementIndex, double elementValue); 294 295 /** Set a single column upper bound<br> 296 Use COIN_DBL_MAX for infinity. */ 297 virtual void setColUpper(int elementIndex, double elementValue); 298 299 /** Set a single column lower and upper bound<br> 300 The default implementation just invokes setColLower() and 301 setColUpper() */ 302 virtual void setColBounds(int elementIndex, 303 double lower, double upper); 304 305 /** Set the bounds on a number of columns simultaneously<br> 306 The default implementation just invokes setColLower() and 307 setColUpper() over and over again. 308 @param indexFirst,indexLast pointers to the beginning and after the 309 end of the array of the indices of the variables whose 310 <em>either</em> bound changes 311 @param boundList the new lower/upper bound pairs for the variables 312 */ 313 virtual void setColSetBounds(const int *indexFirst, 314 const int *indexLast, 315 const double *boundList); 316 317 /** Set a single row lower bound<br> 318 Use -COIN_DBL_MAX for -infinity. */ 319 virtual void setRowLower(int elementIndex, double elementValue); 320 321 /** Set a single row upper bound<br> 322 Use COIN_DBL_MAX for infinity. */ 323 virtual void setRowUpper(int elementIndex, double elementValue); 324 325 /** Set a single row lower and upper bound<br> 326 The default implementation just invokes setRowLower() and 327 setRowUpper() */ 328 virtual void setRowBounds(int elementIndex, 329 double lower, double upper); 330 331 /** Set the type of a single row<br> */ 332 virtual void setRowType(int index, char sense, double rightHandSide, 333 double range); 334 335 /** Set the bounds on a number of rows simultaneously<br> 336 The default implementation just invokes setRowLower() and 337 setRowUpper() over and over again. 338 @param indexFirst,indexLast pointers to the beginning and after the 339 end of the array of the indices of the constraints whose 340 <em>either</em> bound changes 341 @param boundList the new lower/upper bound pairs for the constraints 342 */ 343 virtual void setRowSetBounds(const int *indexFirst, 344 const int *indexLast, 345 const double *boundList); 346 347 /** Set the type of a number of rows simultaneously<br> 348 The default implementation just invokes setRowType() 349 over and over again. 350 @param indexFirst,indexLast pointers to the beginning and after the 351 end of the array of the indices of the constraints whose 352 <em>any</em> characteristics changes 353 @param senseList the new senses 354 @param rhsList the new right hand sides 355 @param rangeList the new ranges 356 */ 357 virtual void setRowSetTypes(const int *indexFirst, 358 const int *indexLast, 359 const char *senseList, 360 const double *rhsList, 361 const double *rangeList); 362 //@} 363 364 //------------------------------------------------------------------------- 365 /**@name Integrality related changing methods */ 366 //@{ 367 /** Set the index-th variable to be a continuous variable */ 368 virtual void setContinuous(int index); 369 /** Set the index-th variable to be an integer variable */ 370 virtual void setInteger(int index); 371 /** Set the variables listed in indices (which is of length len) to be 372 continuous variables */ 373 virtual void setContinuous(const int *indices, int len); 374 /** Set the variables listed in indices (which is of length len) to be 375 integer variables */ 376 virtual void setInteger(const int *indices, int len); 377 //@} 378 379 //------------------------------------------------------------------------- 380 /// Set objective function sense (1 for min (default), -1 for max,) 381 virtual void setObjSense(double s); 382 383 /** Set the primal solution column values 384 385 colsol[numcols()] is an array of values of the problem column 386 variables. These values are copied to memory owned by the 387 solver object or the solver. They will be returned as the 388 result of colsol() until changed by another call to 389 setColsol() or by a call to any solver routine. Whether the 390 solver makes use of the solution in any way is 391 solver-dependent. 392 */ 393 virtual void setColSolution(const double *colsol); 394 395 /** Set dual solution vector 396 397 rowprice[numrows()] is an array of values of the problem row 398 dual variables. These values are copied to memory owned by the 399 solver object or the solver. They will be returned as the 400 result of rowprice() until changed by another call to 401 setRowprice() or by a call to any solver routine. Whether the 402 solver makes use of the solution in any way is 403 solver-dependent. 404 */ 405 virtual void setRowPrice(const double *rowprice); 406 407 //------------------------------------------------------------------------- 408 /**@name Methods to expand a problem.<br> 409 Note that if a column is added then by default it will correspond to a 410 continuous variable. */ 411 //@{ 412 /** */ 413 virtual void addCol(const CoinPackedVectorBase &vec, 414 const double collb, const double colub, 415 const double obj); 416 /** */ 417 virtual void addCols(const int numcols, 418 const CoinPackedVectorBase *const *cols, 419 const double *collb, const double *colub, 420 const double *obj); 421 /** */ 422 virtual void deleteCols(const int num, const int *colIndices); 423 424 /** */ 425 virtual void addRow(const CoinPackedVectorBase &vec, 426 const double rowlb, const double rowub); 427 /** */ 428 virtual void addRow(const CoinPackedVectorBase &vec, 429 const char rowsen, const double rowrhs, 430 const double rowrng); 431 /** */ 432 virtual void addRows(const int numrows, 433 const CoinPackedVectorBase *const *rows, 434 const double *rowlb, const double *rowub); 435 /** */ 436 virtual void addRows(const int numrows, 437 const CoinPackedVectorBase *const *rows, 438 const char *rowsen, const double *rowrhs, 439 const double *rowrng); 440 /** */ 441 virtual void deleteRows(const int num, const int *rowIndices); 442 #if 0 443 //----------------------------------------------------------------------- 444 /** Apply a collection of cuts.<br> 445 Only cuts which have an <code>effectiveness >= effectivenessLb</code> 446 are applied. 447 <ul> 448 <li> ReturnCode.numberIneffective() -- number of cuts which were 449 not applied because they had an 450 <code>effectiveness < effectivenessLb</code> 451 <li> ReturnCode.numberInconsistent() -- number of invalid cuts 452 <li> ReturnCode.numberInconsistentWrtIntegerModel() -- number of 453 cuts that are invalid with respect to this integer model 454 <li> ReturnCode.numberInfeasible() -- number of cuts that would 455 make this integer model infeasible 456 <li> ReturnCode.numberApplied() -- number of integer cuts which 457 were applied to the integer model 458 <li> cs.size() == numberIneffective() + 459 numberInconsistent() + 460 numberInconsistentWrtIntegerModel() + 461 numberInfeasible() + 462 nubmerApplied() 463 </ul> 464 */ 465 virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, 466 double effectivenessLb = 0.0); 467 //@} 468 //@} 469 #endif 470 //--------------------------------------------------------------------------- 471 472 /**@name Methods to input a problem */ 473 //@{ 474 /** Load in an problem by copying the arguments (the constraints on the 475 rows are given by lower and upper bounds). If a pointer is 0 then the 476 following values are the default: 477 <ul> 478 <li> <code>colub</code>: all columns have upper bound infinity 479 <li> <code>collb</code>: all columns have lower bound 0 480 <li> <code>rowub</code>: all rows have upper bound infinity 481 <li> <code>rowlb</code>: all rows have lower bound -infinity 482 <li> <code>obj</code>: all variables have 0 objective coefficient 483 </ul> 484 */ 485 virtual void loadProblem(const CoinPackedMatrix &matrix, 486 const double *collb, const double *colub, 487 const double *obj, 488 const double *rowlb, const double *rowub); 489 490 /** Load in an problem by assuming ownership of the arguments (the 491 constraints on the rows are given by lower and upper bounds). For 492 default values see the previous method. <br> 493 <strong>WARNING</strong>: The arguments passed to this method will be 494 freed using the C++ <code>delete</code> and <code>delete[]</code> 495 functions. 496 */ 497 virtual void assignProblem(CoinPackedMatrix *&matrix, 498 double *&collb, double *&colub, double *&obj, 499 double *&rowlb, double *&rowub); 500 501 /** Load in an problem by copying the arguments (the constraints on the 502 rows are given by sense/rhs/range triplets). If a pointer is 0 then the 503 following values are the default: 504 <ul> 505 <li> <code>colub</code>: all columns have upper bound infinity 506 <li> <code>collb</code>: all columns have lower bound 0 507 <li> <code>obj</code>: all variables have 0 objective coefficient 508 <li> <code>rowsen</code>: all rows are >= 509 <li> <code>rowrhs</code>: all right hand sides are 0 510 <li> <code>rowrng</code>: 0 for the ranged rows 511 </ul> 512 */ 513 virtual void loadProblem(const CoinPackedMatrix &matrix, 514 const double *collb, const double *colub, 515 const double *obj, 516 const char *rowsen, const double *rowrhs, 517 const double *rowrng); 518 519 /** Load in an problem by assuming ownership of the arguments (the 520 constraints on the rows are given by sense/rhs/range triplets). For 521 default values see the previous method. <br> 522 <strong>WARNING</strong>: The arguments passed to this method will be 523 freed using the C++ <code>delete</code> and <code>delete[]</code> 524 functions. 525 */ 526 virtual void assignProblem(CoinPackedMatrix *&matrix, 527 double *&collb, double *&colub, double *&obj, 528 char *&rowsen, double *&rowrhs, 529 double *&rowrng); 530 531 /** Just like the other loadProblem() methods except that the matrix is 532 given in a standard column major ordered format (without gaps). */ 533 virtual void loadProblem(const int numcols, const int numrows, 534 const int *start, const int *index, 535 const double *value, 536 const double *collb, const double *colub, 537 const double *obj, 538 const double *rowlb, const double *rowub); 539 540 /** Just like the other loadProblem() methods except that the matrix is 541 given in a standard column major ordered format (without gaps). */ 542 virtual void loadProblem(const int numcols, const int numrows, 543 const int *start, const int *index, 544 const double *value, 545 const double *collb, const double *colub, 546 const double *obj, 547 const char *rowsen, const double *rowrhs, 548 const double *rowrng); 549 550 /** Read an mps file from the given filename */ 551 virtual int readMps(const char *filename, 552 const char *extension = "mps"); 553 554 /** Write the problem into an mps file of the given filename. 555 If objSense is non zero then -1.0 forces the code to write a 556 maximization objective and +1.0 to write a minimization one. 557 If 0.0 then solver can do what it wants */ 558 virtual void writeMps(const char *filename, 559 const char *extension = "mps", 560 double objSense = 0.0) const; 561 //@} 562 563 /**@name Message handling */ 564 //@{ 565 /** Pass in a message handler 566 It is the client's responsibility to destroy a message handler installed 567 by this routine; it will not be destroyed when the solver interface is 568 destroyed. 569 */ 570 void passInMessageHandler(CoinMessageHandler *handler); 571 //@} 572 573 //--------------------------------------------------------------------------- 574 575 /**@name XPRESS specific public interfaces */ 576 //@{ 577 /**@name Static instance counter methods */ 578 //@{ 579 /** XPRESS has a context that must be created prior to all other XPRESS 580 calls. 581 This method: 582 <ul> 583 <li>Increments by 1 the number of uses of the XPRESS environment. 584 <li>Creates the XPRESS context when the number of uses is changed to 1 585 from 0. 586 </ul> 587 */ 588 static void incrementInstanceCounter(); 589 590 /** XPRESS has a context that should be deleted after XPRESS calls. 591 This method: 592 <ul> 593 <li>Decrements by 1 the number of uses of the XPRESS environment. 594 <li>Deletes the XPRESS context when the number of uses is change to 595 0 from 1. 596 </ul> 597 */ 598 static void decrementInstanceCounter(); 599 600 /** Return the number of instances of instantiated objects using XPRESS 601 services. */ 602 static unsigned int getNumInstances(); 603 604 /** Return a pointer to the XPRESS problem */ getLpPtr()605 XPRSprob getLpPtr() { return prob_; } 606 //@} 607 608 /// Return XPRESS-MP Version number 609 static int version(); 610 611 /**@name Log File */ 612 //@{ 613 static int iXprCallCount_; 614 615 /// Get logfile FILE * 616 static FILE *getLogFilePtr(); 617 /**Set logfile name. The logfile is an attempt to 618 capture the calls to Xpress functions for debugging. */ 619 static void setLogFileName(const char *filename); 620 //@} 621 //@} 622 623 /**@name Constructors and destructors */ 624 //@{ 625 /// Default Constructor 626 OsiXprSolverInterface(int newrows = 50, int newnz = 100); 627 628 /// Clone 629 virtual OsiSolverInterface *clone(bool copyData = true) const; 630 631 /// Copy constructor 632 OsiXprSolverInterface(const OsiXprSolverInterface &); 633 634 /// Assignment operator 635 OsiXprSolverInterface &operator=(const OsiXprSolverInterface &rhs); 636 637 /// Destructor 638 virtual ~OsiXprSolverInterface(); 639 //@} 640 641 protected: 642 /**@name Protected methods */ 643 //@{ 644 /// Apply a row cut. Return true if cut was applied. 645 virtual void applyRowCut(const OsiRowCut &rc); 646 647 /** Apply a column cut (bound adjustment). 648 Return true if cut was applied. 649 */ 650 virtual void applyColCut(const OsiColCut &cc); 651 //@} 652 653 private: 654 /**@name Private static class data */ 655 //@{ 656 /// Name of the logfile 657 static const char *logFileName_; 658 659 /// The FILE* to the logfile 660 static FILE *logFilePtr_; 661 662 /// Number of live problem instances 663 static unsigned int numInstances_; 664 665 /// Counts calls to incrementInstanceCounter() 666 static unsigned int osiSerial_; 667 668 //@} 669 670 /**@name Private methods */ 671 //@{ 672 /// The real work of a copy constructor (used by copy and assignment) 673 void gutsOfCopy(const OsiXprSolverInterface &source); 674 675 /// The real work of a constructor (used by construct and assignment) 676 void gutsOfConstructor(); 677 678 /// The real work of a destructor (used by copy and assignment) 679 void gutsOfDestructor(); 680 681 /// Destroy cached copy of solution data (whenever it changes) 682 void freeSolution(); 683 684 /** Destroy cached copies of problem and solution data (whenever they 685 change) */ 686 void freeCachedResults(); 687 688 /// Number of integer variables in the problem 689 int getNumIntVars() const; 690 691 /**@name Methods to support for XPRESS-MP multiple matrix facility */ 692 //@{ 693 /// Build cached copy of variable types 694 void getVarTypes() const; 695 696 /** Save the current problem in XPRESS (if necessary) and 697 make this problem current (restore if necessary). 698 */ 699 void activateMe() const; 700 701 /** Save and restore are necessary if there is data associated with 702 this problem. Also, queries to a problem with no data should 703 respond sensibly; XPRESS query results are undefined. 704 */ 705 bool isDataLoaded() const; 706 //@} 707 //@} 708 709 /**@name Private member data */ 710 //@{ 711 712 /**@name Data to support for XPRESS-MP multiple matrix facility */ 713 //@{ 714 715 mutable XPRSprob prob_; 716 717 /// XPRESS problem name (should be unique for each saved problem) 718 mutable std::string xprProbname_; 719 //@} 720 721 /**@name Cached copies of XPRESS-MP problem data */ 722 //@{ 723 /** Pointer to row-wise copy of problem matrix coefficients.<br> 724 Note that XPRESS keeps the objective row in the 725 problem matrix, so row indices and counts are adjusted 726 accordingly. 727 */ 728 mutable CoinPackedMatrix *matrixByRow_; 729 mutable CoinPackedMatrix *matrixByCol_; 730 731 /// Pointer to dense vector of structural variable upper bounds 732 mutable double *colupper_; 733 734 /// Pointer to dense vector of structural variable lower bounds 735 mutable double *collower_; 736 737 /// Pointer to dense vector of slack variable upper bounds 738 mutable double *rowupper_; 739 740 /// Pointer to dense vector of slack variable lower bounds 741 mutable double *rowlower_; 742 743 /// Pointer to dense vector of row sense indicators 744 mutable char *rowsense_; 745 746 /// Pointer to dense vector of row right-hand side values 747 mutable double *rhs_; 748 749 /** Pointer to dense vector of slack upper bounds for range 750 constraints (undefined for non-range rows) 751 */ 752 mutable double *rowrange_; 753 754 /// Pointer to dense vector of objective coefficients 755 mutable double *objcoeffs_; 756 757 /// Sense of objective (1 for min; -1 for max) 758 mutable double objsense_; 759 760 /// Pointer to dense vector of primal structural variable values 761 mutable double *colsol_; 762 763 /// Pointer to dense vector of primal slack variable values 764 mutable double *rowsol_; 765 766 /// Pointer to dense vector of primal slack variable values 767 mutable double *rowact_; 768 769 /// Pointer to dense vector of dual row variable values 770 mutable double *rowprice_; 771 772 /// Pointer to dense vector of dual column variable values 773 mutable double *colprice_; 774 775 /// Pointer to list of indices of XPRESS "global" variables 776 mutable int *ivarind_; 777 778 /** Pointer to list of global variable types: 779 <ul> 780 <li>'B': binary variable 781 <li>'I': general integer variable (but might have 0-1 bounds) 782 <li>'P': partial integer variable (not currently supported) 783 <li>'S': sem-continuous variable (not currently supported) 784 </ul> 785 */ 786 mutable char *ivartype_; 787 788 /** Pointer to dense vector of variable types 789 (as above, or 'C' for continuous) 790 */ 791 mutable char *vartype_; 792 793 /** Indicates whether the last solve was for a MIP or an LP. */ 794 mutable bool lastsolvewasmip; 795 //@} 796 //@} 797 798 /// Whether to pass a column solution to XPRESS before starting MIP solve (loadmipsol) 799 bool domipstart; 800 }; 801 802 //############################################################################# 803 /** A function that tests the methods in the OsiXprSolverInterface class. */ 804 void OsiXprSolverInterfaceUnitTest(const std::string &mpsDir, const std::string &netlibDir); 805 806 #endif 807 808 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 809 */ 810