| 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 OsiSolverInterface_H |
| 6 | #define OsiSolverInterface_H |
| 7 | |
| 8 | #include <cstdlib> |
| 9 | #include <string> |
| 10 | #include <vector> |
| 11 | |
| 12 | #include "CoinMessageHandler.hpp" |
| 13 | #include "CoinPackedVectorBase.hpp" |
| 14 | #include "CoinTypes.hpp" |
| 15 | |
| 16 | #include "OsiCollections.hpp" |
| 17 | #include "OsiSolverParameters.hpp" |
| 18 | |
| 19 | class CoinPackedMatrix; |
| 20 | class CoinWarmStart; |
| 21 | class CoinSnapshot; |
| 22 | class CoinLpIO; |
| 23 | class CoinMpsIO; |
| 24 | |
| 25 | class OsiCuts; |
| 26 | class OsiAuxInfo; |
| 27 | class OsiRowCut; |
| 28 | class OsiRowCutDebugger; |
| 29 | class CoinSet; |
| 30 | class CoinBuild; |
| 31 | class CoinModel; |
| 32 | class OsiSolverBranch; |
| 33 | class OsiSolverResult; |
| 34 | class OsiObject; |
| 35 | |
| 36 | |
| 37 | //############################################################################# |
| 38 | |
| 39 | /*! \brief Abstract Base Class for describing an interface to a solver. |
| 40 | |
| 41 | Many OsiSolverInterface query methods return a const pointer to the |
| 42 | requested read-only data. If the model data is changed or the solver |
| 43 | is called, these pointers may no longer be valid and should be |
| 44 | refreshed by invoking the member function to obtain an updated copy |
| 45 | of the pointer. |
| 46 | For example: |
| 47 | \code |
| 48 | OsiSolverInterface solverInterfacePtr ; |
| 49 | const double * ruBnds = solverInterfacePtr->getRowUpper(); |
| 50 | solverInterfacePtr->applyCuts(someSetOfCuts); |
| 51 | // ruBnds is no longer a valid pointer and must be refreshed |
| 52 | ruBnds = solverInterfacePtr->getRowUpper(); |
| 53 | \endcode |
| 54 | |
| 55 | Querying a problem that has no data associated with it will result in |
| 56 | zeros for the number of rows and columns, and NULL pointers from |
| 57 | the methods that return vectors. |
| 58 | */ |
| 59 | |
| 60 | class OsiSolverInterface { |
| 61 | friend void OsiSolverInterfaceCommonUnitTest( |
| 62 | const OsiSolverInterface* emptySi, |
| 63 | const std::string & mpsDir, |
| 64 | const std::string & netlibDir); |
| 65 | friend void OsiSolverInterfaceMpsUnitTest( |
| 66 | const std::vector<OsiSolverInterface*> & vecSiP, |
| 67 | const std::string & mpsDir); |
| 68 | |
| 69 | public: |
| 70 | |
| 71 | /// Internal class for obtaining status from the applyCuts method |
| 72 | class ApplyCutsReturnCode { |
| 73 | friend class OsiSolverInterface; |
| 74 | friend class OsiOslSolverInterface; |
| 75 | friend class OsiClpSolverInterface; |
| 76 | |
| 77 | public: |
| 78 | ///@name Constructors and desctructors |
| 79 | //@{ |
| 80 | /// Default constructor |
| 81 | ApplyCutsReturnCode(): |
| 82 | intInconsistent_(0), |
| 83 | extInconsistent_(0), |
| 84 | infeasible_(0), |
| 85 | ineffective_(0), |
| 86 | applied_(0) {} |
| 87 | /// Copy constructor |
| 88 | ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs): |
| 89 | intInconsistent_(rhs.intInconsistent_), |
| 90 | extInconsistent_(rhs.extInconsistent_), |
| 91 | infeasible_(rhs.infeasible_), |
| 92 | ineffective_(rhs.ineffective_), |
| 93 | applied_(rhs.applied_) {} |
| 94 | /// Assignment operator |
| 95 | ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs) |
| 96 | { |
| 97 | if (this != &rhs) { |
| 98 | intInconsistent_ = rhs.intInconsistent_; |
| 99 | extInconsistent_ = rhs.extInconsistent_; |
| 100 | infeasible_ = rhs.infeasible_; |
| 101 | ineffective_ = rhs.ineffective_; |
| 102 | applied_ = rhs.applied_; |
| 103 | } |
| 104 | return *this; |
| 105 | } |
| 106 | /// Destructor |
| 107 | ~ApplyCutsReturnCode(){} |
| 108 | //@} |
| 109 | |
| 110 | /**@name Accessing return code attributes */ |
| 111 | //@{ |
| 112 | /// Number of logically inconsistent cuts |
| 113 | inline int getNumInconsistent(){return intInconsistent_;} |
| 114 | /// Number of cuts inconsistent with the current model |
| 115 | inline int getNumInconsistentWrtIntegerModel(){return extInconsistent_;} |
| 116 | /// Number of cuts that cause obvious infeasibility |
| 117 | inline int getNumInfeasible(){return infeasible_;} |
| 118 | /// Number of redundant or ineffective cuts |
| 119 | inline int getNumIneffective(){return ineffective_;} |
| 120 | /// Number of cuts applied |
| 121 | inline int getNumApplied(){return applied_;} |
| 122 | //@} |
| 123 | |
| 124 | private: |
| 125 | /**@name Private methods */ |
| 126 | //@{ |
| 127 | /// Increment logically inconsistent cut counter |
| 128 | inline void incrementInternallyInconsistent(){intInconsistent_++;} |
| 129 | /// Increment model-inconsistent counter |
| 130 | inline void incrementExternallyInconsistent(){extInconsistent_++;} |
| 131 | /// Increment infeasible cut counter |
| 132 | inline void incrementInfeasible(){infeasible_++;} |
| 133 | /// Increment ineffective cut counter |
| 134 | inline void incrementIneffective(){ineffective_++;} |
| 135 | /// Increment applied cut counter |
| 136 | inline void incrementApplied(){applied_++;} |
| 137 | //@} |
| 138 | |
| 139 | ///@name Private member data |
| 140 | //@{ |
| 141 | /// Counter for logically inconsistent cuts |
| 142 | int intInconsistent_; |
| 143 | /// Counter for model-inconsistent cuts |
| 144 | int extInconsistent_; |
| 145 | /// Counter for infeasible cuts |
| 146 | int infeasible_; |
| 147 | /// Counter for ineffective cuts |
| 148 | int ineffective_; |
| 149 | /// Counter for applied cuts |
| 150 | int applied_; |
| 151 | //@} |
| 152 | }; |
| 153 | |
| 154 | //--------------------------------------------------------------------------- |
| 155 | |
| 156 | ///@name Solve methods |
| 157 | //@{ |
| 158 | /// Solve initial LP relaxation |
| 159 | virtual void initialSolve() = 0; |
| 160 | |
| 161 | /*! \brief Resolve an LP relaxation after problem modification |
| 162 | |
| 163 | Note the `re-' in `resolve'. initialSolve() should be used to solve the |
| 164 | problem for the first time. |
| 165 | */ |
| 166 | virtual void resolve() = 0; |
| 167 | |
| 168 | /// Invoke solver's built-in enumeration algorithm |
| 169 | virtual void branchAndBound() = 0; |
| 170 | |
| 171 | #ifdef CBC_NEXT_VERSION |
| 172 | /* |
| 173 | Would it make sense to collect all of these routines in a `MIP Helper' |
| 174 | section? It'd make it easier for users and implementors to find them. |
| 175 | */ |
| 176 | /** |
| 177 | Solve 2**N (N==depth) problems and return solutions and bases. |
| 178 | There are N branches each of which changes bounds on both sides |
| 179 | as given by branch. The user should provide an array of (empty) |
| 180 | results which will be filled in. See OsiSolveResult for more details |
| 181 | (in OsiSolveBranch.?pp) but it will include a basis and primal solution. |
| 182 | |
| 183 | The order of results is left to right at feasible leaf nodes so first one |
| 184 | is down, down, ..... |
| 185 | |
| 186 | Returns number of feasible leaves. Also sets number of solves done and number |
| 187 | of iterations. |
| 188 | |
| 189 | This is provided so a solver can do faster. |
| 190 | |
| 191 | If forceBranch true then branch done even if satisfied |
| 192 | */ |
| 193 | virtual int solveBranches(int depth,const OsiSolverBranch * branch, |
| 194 | OsiSolverResult * result, |
| 195 | int & numberSolves, int & numberIterations, |
| 196 | bool forceBranch=false); |
| 197 | #endif |
| 198 | //@} |
| 199 | |
| 200 | //--------------------------------------------------------------------------- |
| 201 | /**@name Parameter set/get methods |
| 202 | |
| 203 | The set methods return true if the parameter was set to the given value, |
| 204 | false otherwise. When a set method returns false, the original value (if |
| 205 | any) should be unchanged. There can be various reasons for failure: the |
| 206 | given parameter is not applicable for the solver (e.g., refactorization |
| 207 | frequency for the volume algorithm), the parameter is not yet |
| 208 | implemented for the solver or simply the value of the parameter is out |
| 209 | of the range the solver accepts. If a parameter setting call returns |
| 210 | false check the details of your solver. |
| 211 | |
| 212 | The get methods return true if the given parameter is applicable for the |
| 213 | solver and is implemented. In this case the value of the parameter is |
| 214 | returned in the second argument. Otherwise they return false. |
| 215 | |
| 216 | \note |
| 217 | There is a default implementation of the set/get |
| 218 | methods, namely to store/retrieve the given value using an array in the |
| 219 | base class. A specific solver implementation can use this feature, for |
| 220 | example, to store parameters that should be used later on. Implementors |
| 221 | of a solver interface should overload these functions to provide the |
| 222 | proper interface to and accurately reflect the capabilities of a |
| 223 | specific solver. |
| 224 | |
| 225 | The format for hints is slightly different in that a boolean specifies |
| 226 | the sense of the hint and an enum specifies the strength of the hint. |
| 227 | Hints should be initialised when a solver is instantiated. |
| 228 | (See OsiSolverParameters.hpp for defined hint parameters and strength.) |
| 229 | When specifying the sense of the hint, a value of true means to work with |
| 230 | the hint, false to work against it. For example, |
| 231 | <ul> |
| 232 | <li> \code setHintParam(OsiDoScale,true,OsiHintTry) \endcode |
| 233 | is a mild suggestion to the solver to scale the constraint |
| 234 | system. |
| 235 | <li> \code setHintParam(OsiDoScale,false,OsiForceDo) \endcode |
| 236 | tells the solver to disable scaling, or throw an exception if |
| 237 | it cannot comply. |
| 238 | </ul> |
| 239 | As another example, a solver interface could use the value and strength |
| 240 | of the \c OsiDoReducePrint hint to adjust the amount of information |
| 241 | printed by the interface and/or solver. The extent to which a solver |
| 242 | obeys hints is left to the solver. The value and strength returned by |
| 243 | \c getHintParam will match the most recent call to \c setHintParam, |
| 244 | and will not necessarily reflect the solver's ability to comply with the |
| 245 | hint. If the hint strength is \c OsiForceDo, the solver is required to |
| 246 | throw an exception if it cannot perform the specified action. |
| 247 | |
| 248 | \note |
| 249 | As with the other set/get methods, there is a default implementation |
| 250 | which maintains arrays in the base class for hint sense and strength. |
| 251 | The default implementation does not store the \c otherInformation |
| 252 | pointer, and always throws an exception for strength \c OsiForceDo. |
| 253 | Implementors of a solver interface should override these functions to |
| 254 | provide the proper interface to and accurately reflect the capabilities |
| 255 | of a specific solver. |
| 256 | */ |
| 257 | //@{ |
| 258 | //! Set an integer parameter |
| 259 | virtual bool setIntParam(OsiIntParam key, int value) { |
| 260 | if (key == OsiLastIntParam) return (false) ; |
| 261 | intParam_[key] = value; |
| 262 | return true; |
| 263 | } |
| 264 | //! Set a double parameter |
| 265 | virtual bool setDblParam(OsiDblParam key, double value) { |
| 266 | if (key == OsiLastDblParam) return (false) ; |
| 267 | dblParam_[key] = value; |
| 268 | return true; |
| 269 | } |
| 270 | //! Set a string parameter |
| 271 | virtual bool setStrParam(OsiStrParam key, const std::string & value) { |
| 272 | if (key == OsiLastStrParam) return (false) ; |
| 273 | strParam_[key] = value; |
| 274 | return true; |
| 275 | } |
| 276 | /*! \brief Set a hint parameter |
| 277 | |
| 278 | The \c otherInformation parameter can be used to pass in an arbitrary |
| 279 | block of information which is interpreted by the OSI and the underlying |
| 280 | solver. Users are cautioned that this hook is solver-specific. |
| 281 | |
| 282 | Implementors: |
| 283 | The default implementation completely ignores \c otherInformation and |
| 284 | always throws an exception for OsiForceDo. This is almost certainly not |
| 285 | the behaviour you want; you really should override this method. |
| 286 | */ |
| 287 | virtual bool setHintParam(OsiHintParam key, bool yesNo=true, |
| 288 | OsiHintStrength strength=OsiHintTry, |
| 289 | void * /*otherInformation*/ = nullptr) { |
| 290 | if (key==OsiLastHintParam) |
| 291 | return false; |
| 292 | hintParam_[key] = yesNo; |
| 293 | hintStrength_[key] = strength; |
| 294 | if (strength == OsiForceDo) |
| 295 | throw CoinError("OsiForceDo illegal" , |
| 296 | "setHintParam" , "OsiSolverInterface" ); |
| 297 | return true; |
| 298 | } |
| 299 | //! Get an integer parameter |
| 300 | virtual bool getIntParam(OsiIntParam key, int& value) const { |
| 301 | if (key == OsiLastIntParam) return (false) ; |
| 302 | value = intParam_[key]; |
| 303 | return true; |
| 304 | } |
| 305 | //! Get a double parameter |
| 306 | virtual bool getDblParam(OsiDblParam key, double& value) const { |
| 307 | if (key == OsiLastDblParam) return (false) ; |
| 308 | value = dblParam_[key]; |
| 309 | return true; |
| 310 | } |
| 311 | //! Get a string parameter |
| 312 | virtual bool (OsiStrParam key, std::string& value) const { |
| 313 | if (key == OsiLastStrParam) return (false) ; |
| 314 | value = strParam_[key]; |
| 315 | return true; |
| 316 | } |
| 317 | /*! \brief Get a hint parameter (all information) |
| 318 | |
| 319 | Return all available information for the hint: sense, strength, |
| 320 | and any extra information associated with the hint. |
| 321 | |
| 322 | Implementors: The default implementation will always set |
| 323 | \c otherInformation to NULL. This is almost certainly not the |
| 324 | behaviour you want; you really should override this method. |
| 325 | */ |
| 326 | virtual bool getHintParam(OsiHintParam key, bool& yesNo, |
| 327 | OsiHintStrength& strength, |
| 328 | void *& otherInformation) const { |
| 329 | if (key==OsiLastHintParam) |
| 330 | return false; |
| 331 | yesNo = hintParam_[key]; |
| 332 | strength = hintStrength_[key]; |
| 333 | otherInformation=nullptr; |
| 334 | return true; |
| 335 | } |
| 336 | /*! \brief Get a hint parameter (sense and strength only) |
| 337 | |
| 338 | Return only the sense and strength of the hint. |
| 339 | */ |
| 340 | virtual bool getHintParam(OsiHintParam key, bool& yesNo, |
| 341 | OsiHintStrength& strength) const { |
| 342 | if (key==OsiLastHintParam) |
| 343 | return false; |
| 344 | yesNo = hintParam_[key]; |
| 345 | strength = hintStrength_[key]; |
| 346 | return true; |
| 347 | } |
| 348 | /*! \brief Get a hint parameter (sense only) |
| 349 | |
| 350 | Return only the sense (true/false) of the hint. |
| 351 | */ |
| 352 | virtual bool getHintParam(OsiHintParam key, bool& yesNo) const { |
| 353 | if (key==OsiLastHintParam) |
| 354 | return false; |
| 355 | yesNo = hintParam_[key]; |
| 356 | return true; |
| 357 | } |
| 358 | /*! \brief Copy all parameters in this section from one solver to another |
| 359 | |
| 360 | Note that the current implementation also copies the appData block, |
| 361 | message handler, and rowCutDebugger. Arguably these should have |
| 362 | independent copy methods. |
| 363 | */ |
| 364 | void copyParameters(OsiSolverInterface & rhs); |
| 365 | |
| 366 | /** \brief Return the integrality tolerance of the underlying solver. |
| 367 | |
| 368 | We should be able to get an integrality tolerance, but |
| 369 | until that time just use the primal tolerance |
| 370 | |
| 371 | \todo |
| 372 | This method should be replaced; it's architecturally wrong. This |
| 373 | should be an honest dblParam with a keyword. Underlying solvers |
| 374 | that do not support integer variables should return false for set and |
| 375 | get on this parameter. Underlying solvers that support integrality |
| 376 | should add this to the parameters they support, using whatever |
| 377 | tolerance is appropriate. -lh, 091021- |
| 378 | */ |
| 379 | inline double getIntegerTolerance() const |
| 380 | { return dblParam_[OsiPrimalTolerance];} |
| 381 | //@} |
| 382 | |
| 383 | //--------------------------------------------------------------------------- |
| 384 | ///@name Methods returning info on how the solution process terminated |
| 385 | //@{ |
| 386 | /// Are there numerical difficulties? |
| 387 | virtual bool isAbandoned() const = 0; |
| 388 | /// Is optimality proven? |
| 389 | virtual bool isProvenOptimal() const = 0; |
| 390 | /// Is primal infeasibility proven? |
| 391 | virtual bool isProvenPrimalInfeasible() const = 0; |
| 392 | /// Is dual infeasibility proven? |
| 393 | virtual bool isProvenDualInfeasible() const = 0; |
| 394 | /// Is the given primal objective limit reached? |
| 395 | virtual bool isPrimalObjectiveLimitReached() const; |
| 396 | /// Is the given dual objective limit reached? |
| 397 | virtual bool isDualObjectiveLimitReached() const; |
| 398 | /// Iteration limit reached? |
| 399 | virtual bool isIterationLimitReached() const = 0; |
| 400 | //@} |
| 401 | |
| 402 | //--------------------------------------------------------------------------- |
| 403 | /** \name Warm start methods |
| 404 | |
| 405 | Note that the warm start methods return a generic CoinWarmStart object. |
| 406 | The precise characteristics of this object are solver-dependent. Clients |
| 407 | who wish to maintain a maximum degree of solver independence should take |
| 408 | care to avoid unnecessary assumptions about the properties of a warm start |
| 409 | object. |
| 410 | */ |
| 411 | //@{ |
| 412 | /*! \brief Get an empty warm start object |
| 413 | |
| 414 | This routine returns an empty warm start object. Its purpose is |
| 415 | to provide a way for a client to acquire a warm start object of the |
| 416 | appropriate type for the solver, which can then be resized and modified |
| 417 | as desired. |
| 418 | */ |
| 419 | |
| 420 | virtual CoinWarmStart *getEmptyWarmStart () const = 0 ; |
| 421 | |
| 422 | /** \brief Get warm start information. |
| 423 | |
| 424 | Return warm start information for the current state of the solver |
| 425 | interface. If there is no valid warm start information, an empty warm |
| 426 | start object wil be returned. |
| 427 | */ |
| 428 | virtual CoinWarmStart* getWarmStart() const = 0; |
| 429 | /** \brief Get warm start information. |
| 430 | |
| 431 | Return warm start information for the current state of the solver |
| 432 | interface. If there is no valid warm start information, an empty warm |
| 433 | start object wil be returned. This does not necessarily create an |
| 434 | object - may just point to one. must Delete set true if user |
| 435 | should delete returned object. |
| 436 | */ |
| 437 | virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; |
| 438 | |
| 439 | /** \brief Set warm start information. |
| 440 | |
| 441 | Return true or false depending on whether the warm start information was |
| 442 | accepted or not. |
| 443 | By definition, a call to setWarmStart with a null parameter should |
| 444 | cause the solver interface to refresh its warm start information |
| 445 | from the underlying solver. |
| 446 | */ |
| 447 | virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0; |
| 448 | //@} |
| 449 | |
| 450 | //--------------------------------------------------------------------------- |
| 451 | /**@name Hot start methods |
| 452 | |
| 453 | Primarily used in strong branching. The user can create a hot start |
| 454 | object --- a snapshot of the optimization process --- then reoptimize |
| 455 | over and over again, starting from the same point. |
| 456 | |
| 457 | \note |
| 458 | <ul> |
| 459 | <li> Between hot started optimizations only bound changes are allowed. |
| 460 | <li> The copy constructor and assignment operator should NOT copy any |
| 461 | hot start information. |
| 462 | <li> The default implementation simply extracts a warm start object in |
| 463 | \c markHotStart, resets to the warm start object in |
| 464 | \c solveFromHotStart, and deletes the warm start object in |
| 465 | \c unmarkHotStart. |
| 466 | <em>Actual solver implementations are encouraged to do better.</em> |
| 467 | </ul> |
| 468 | |
| 469 | */ |
| 470 | //@{ |
| 471 | /// Create a hot start snapshot of the optimization process. |
| 472 | virtual void markHotStart(); |
| 473 | /// Optimize starting from the hot start snapshot. |
| 474 | virtual void solveFromHotStart(); |
| 475 | /// Delete the hot start snapshot. |
| 476 | virtual void unmarkHotStart(); |
| 477 | //@} |
| 478 | |
| 479 | //--------------------------------------------------------------------------- |
| 480 | /**@name Problem query methods |
| 481 | |
| 482 | Querying a problem that has no data associated with it will result in |
| 483 | zeros for the number of rows and columns, and NULL pointers from the |
| 484 | methods that return vectors. |
| 485 | |
| 486 | Const pointers returned from any data-query method are valid as long as |
| 487 | the data is unchanged and the solver is not called. |
| 488 | */ |
| 489 | //@{ |
| 490 | /// Get the number of columns |
| 491 | virtual int getNumCols() const = 0; |
| 492 | |
| 493 | /// Get the number of rows |
| 494 | virtual int getNumRows() const = 0; |
| 495 | |
| 496 | /// Get the number of nonzero elements |
| 497 | virtual int getNumElements() const = 0; |
| 498 | |
| 499 | /// Get the number of integer variables |
| 500 | virtual int getNumIntegers() const ; |
| 501 | |
| 502 | /// Get a pointer to an array[getNumCols()] of column lower bounds |
| 503 | virtual const double * getColLower() const = 0; |
| 504 | |
| 505 | /// Get a pointer to an array[getNumCols()] of column upper bounds |
| 506 | virtual const double * getColUpper() const = 0; |
| 507 | |
| 508 | /*! \brief Get a pointer to an array[getNumRows()] of row constraint senses. |
| 509 | |
| 510 | <ul> |
| 511 | <li>'L': <= constraint |
| 512 | <li>'E': = constraint |
| 513 | <li>'G': >= constraint |
| 514 | <li>'R': ranged constraint |
| 515 | <li>'N': free constraint |
| 516 | </ul> |
| 517 | */ |
| 518 | virtual const char * getRowSense() const = 0; |
| 519 | |
| 520 | /*! \brief Get a pointer to an array[getNumRows()] of row right-hand sides |
| 521 | |
| 522 | <ul> |
| 523 | <li> if getRowSense()[i] == 'L' then |
| 524 | getRightHandSide()[i] == getRowUpper()[i] |
| 525 | <li> if getRowSense()[i] == 'G' then |
| 526 | getRightHandSide()[i] == getRowLower()[i] |
| 527 | <li> if getRowSense()[i] == 'R' then |
| 528 | getRightHandSide()[i] == getRowUpper()[i] |
| 529 | <li> if getRowSense()[i] == 'N' then |
| 530 | getRightHandSide()[i] == 0.0 |
| 531 | </ul> |
| 532 | */ |
| 533 | virtual const double * getRightHandSide() const = 0; |
| 534 | |
| 535 | /*! \brief Get a pointer to an array[getNumRows()] of row ranges. |
| 536 | |
| 537 | <ul> |
| 538 | <li> if getRowSense()[i] == 'R' then |
| 539 | getRowRange()[i] == getRowUpper()[i] - getRowLower()[i] |
| 540 | <li> if getRowSense()[i] != 'R' then |
| 541 | getRowRange()[i] is 0.0 |
| 542 | </ul> |
| 543 | */ |
| 544 | virtual const double * getRowRange() const = 0; |
| 545 | |
| 546 | /// Get a pointer to an array[getNumRows()] of row lower bounds |
| 547 | virtual const double * getRowLower() const = 0; |
| 548 | |
| 549 | /// Get a pointer to an array[getNumRows()] of row upper bounds |
| 550 | virtual const double * getRowUpper() const = 0; |
| 551 | |
| 552 | /*! \brief Get a pointer to an array[getNumCols()] of objective |
| 553 | function coefficients. |
| 554 | */ |
| 555 | virtual const double * getObjCoefficients() const = 0; |
| 556 | |
| 557 | /*! \brief Get the objective function sense |
| 558 | |
| 559 | - 1 for minimisation (default) |
| 560 | - -1 for maximisation |
| 561 | */ |
| 562 | virtual double getObjSense() const = 0; |
| 563 | |
| 564 | /// Return true if the variable is continuous |
| 565 | virtual bool isContinuous(int colIndex) const = 0; |
| 566 | |
| 567 | /// Return true if the variable is binary |
| 568 | virtual bool isBinary(int colIndex) const; |
| 569 | |
| 570 | /*! \brief Return true if the variable is integer. |
| 571 | |
| 572 | This method returns true if the variable is binary or general integer. |
| 573 | */ |
| 574 | virtual bool isInteger(int colIndex) const; |
| 575 | |
| 576 | /// Return true if the variable is general integer |
| 577 | virtual bool isIntegerNonBinary(int colIndex) const; |
| 578 | |
| 579 | /// Return true if the variable is binary and not fixed |
| 580 | virtual bool isFreeBinary(int colIndex) const; |
| 581 | |
| 582 | /*! \brief Return an array[getNumCols()] of column types |
| 583 | |
| 584 | \deprecated See #getColType |
| 585 | */ |
| 586 | inline const char *columnType(bool refresh=false) const |
| 587 | { return getColType(refresh); } |
| 588 | |
| 589 | /*! \brief Return an array[getNumCols()] of column types |
| 590 | |
| 591 | - 0 - continuous |
| 592 | - 1 - binary |
| 593 | - 2 - general integer |
| 594 | |
| 595 | If \p refresh is true, the classification of integer variables as |
| 596 | binary or general integer will be reevaluated. If the current bounds |
| 597 | are [0,1], or if the variable is fixed at 0 or 1, it will be classified |
| 598 | as binary, otherwise it will be classified as general integer. |
| 599 | */ |
| 600 | virtual const char * getColType(bool refresh=false) const; |
| 601 | |
| 602 | /// Get a pointer to a row-wise copy of the matrix |
| 603 | virtual const CoinPackedMatrix * getMatrixByRow() const = 0; |
| 604 | |
| 605 | /// Get a pointer to a column-wise copy of the matrix |
| 606 | virtual const CoinPackedMatrix * getMatrixByCol() const = 0; |
| 607 | |
| 608 | /*! \brief Get a pointer to a mutable row-wise copy of the matrix. |
| 609 | |
| 610 | Returns NULL if the request is not meaningful (i.e., the OSI will not |
| 611 | recognise any modifications to the matrix). |
| 612 | */ |
| 613 | virtual CoinPackedMatrix * getMutableMatrixByRow() const {return nullptr;} |
| 614 | |
| 615 | /*! \brief Get a pointer to a mutable column-wise copy of the matrix |
| 616 | |
| 617 | Returns NULL if the request is not meaningful (i.e., the OSI will not |
| 618 | recognise any modifications to the matrix). |
| 619 | */ |
| 620 | virtual CoinPackedMatrix * getMutableMatrixByCol() const {return nullptr;} |
| 621 | |
| 622 | /// Get the solver's value for infinity |
| 623 | virtual double getInfinity() const = 0; |
| 624 | //@} |
| 625 | |
| 626 | /**@name Solution query methods */ |
| 627 | //@{ |
| 628 | /// Get a pointer to an array[getNumCols()] of primal variable values |
| 629 | virtual const double * getColSolution() const = 0; |
| 630 | |
| 631 | /** Get a pointer to an array[getNumCols()] of primal variable values |
| 632 | guaranteed to be between the column lower and upper bounds. |
| 633 | */ |
| 634 | virtual const double * getStrictColSolution(); |
| 635 | |
| 636 | /// Get pointer to array[getNumRows()] of dual variable values |
| 637 | virtual const double * getRowPrice() const = 0; |
| 638 | |
| 639 | /// Get a pointer to an array[getNumCols()] of reduced costs |
| 640 | virtual const double * getReducedCost() const = 0; |
| 641 | |
| 642 | /** Get a pointer to array[getNumRows()] of row activity levels. |
| 643 | |
| 644 | The row activity for a row is the left-hand side evaluated at the |
| 645 | current solution. |
| 646 | */ |
| 647 | virtual const double * getRowActivity() const = 0; |
| 648 | |
| 649 | /// Get the objective function value. |
| 650 | virtual double getObjValue() const = 0; |
| 651 | |
| 652 | /** Get the number of iterations it took to solve the problem (whatever |
| 653 | `iteration' means to the solver). |
| 654 | */ |
| 655 | virtual int getIterationCount() const = 0; |
| 656 | |
| 657 | /** Get as many dual rays as the solver can provide. In case of proven |
| 658 | primal infeasibility there should (with high probability) be at least |
| 659 | one. |
| 660 | |
| 661 | The first getNumRows() ray components will always be associated with |
| 662 | the row duals (as returned by getRowPrice()). If \c fullRay is true, |
| 663 | the final getNumCols() entries will correspond to the ray components |
| 664 | associated with the nonbasic variables. If the full ray is requested |
| 665 | and the method cannot provide it, it will throw an exception. |
| 666 | |
| 667 | \note |
| 668 | Implementors of solver interfaces note that the double pointers in |
| 669 | the vector should point to arrays of length getNumRows() (fullRay = |
| 670 | false) or (getNumRows()+getNumCols()) (fullRay = true) and they should |
| 671 | be allocated with new[]. |
| 672 | |
| 673 | \note |
| 674 | Clients of solver interfaces note that it is the client's |
| 675 | responsibility to free the double pointers in the vector using |
| 676 | delete[]. Clients are reminded that a problem can be dual and primal |
| 677 | infeasible. |
| 678 | */ |
| 679 | virtual std::vector<double*> getDualRays(int maxNumRays, |
| 680 | bool fullRay = false) const = 0; |
| 681 | |
| 682 | /** Get as many primal rays as the solver can provide. In case of proven |
| 683 | dual infeasibility there should (with high probability) be at least |
| 684 | one. |
| 685 | |
| 686 | \note |
| 687 | Implementors of solver interfaces note that the double pointers in |
| 688 | the vector should point to arrays of length getNumCols() and they |
| 689 | should be allocated with new[]. |
| 690 | |
| 691 | \note |
| 692 | Clients of solver interfaces note that it is the client's |
| 693 | responsibility to free the double pointers in the vector using |
| 694 | delete[]. Clients are reminded that a problem can be dual and primal |
| 695 | infeasible. |
| 696 | */ |
| 697 | virtual std::vector<double*> getPrimalRays(int maxNumRays) const = 0; |
| 698 | |
| 699 | /** Get vector of indices of primal variables which are integer variables |
| 700 | but have fractional values in the current solution. */ |
| 701 | virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05) |
| 702 | const; |
| 703 | //@} |
| 704 | |
| 705 | //------------------------------------------------------------------------- |
| 706 | /**@name Methods to modify the objective, bounds, and solution |
| 707 | |
| 708 | For functions which take a set of indices as parameters |
| 709 | (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(), |
| 710 | \c setRowSetTypes()), the parameters follow the C++ STL iterator |
| 711 | convention: \c indexFirst points to the first index in the |
| 712 | set, and \c indexLast points to a position one past the last index |
| 713 | in the set. |
| 714 | |
| 715 | */ |
| 716 | //@{ |
| 717 | /** Set an objective function coefficient */ |
| 718 | virtual void setObjCoeff( int elementIndex, double elementValue ) = 0; |
| 719 | |
| 720 | /** Set a set of objective function coefficients */ |
| 721 | virtual void setObjCoeffSet(const int* indexFirst, |
| 722 | const int* indexLast, |
| 723 | const double* coeffList); |
| 724 | |
| 725 | /** Set the objective coefficients for all columns. |
| 726 | |
| 727 | array [getNumCols()] is an array of values for the objective. |
| 728 | This defaults to a series of set operations and is here for speed. |
| 729 | */ |
| 730 | virtual void setObjective(const double * array); |
| 731 | |
| 732 | /** Set the objective function sense. |
| 733 | |
| 734 | Use 1 for minimisation (default), -1 for maximisation. |
| 735 | |
| 736 | \note |
| 737 | Implementors note that objective function sense is a parameter of |
| 738 | the OSI, not a property of the problem. Objective sense can be |
| 739 | set prior to problem load and should not be affected by loading a |
| 740 | new problem. |
| 741 | */ |
| 742 | virtual void setObjSense(double s) = 0; |
| 743 | |
| 744 | |
| 745 | /** Set a single column lower bound. |
| 746 | Use -getInfinity() for -infinity. */ |
| 747 | virtual void setColLower( int elementIndex, double elementValue ) = 0; |
| 748 | |
| 749 | /** Set the lower bounds for all columns. |
| 750 | |
| 751 | array [getNumCols()] is an array of values for the lower bounds. |
| 752 | This defaults to a series of set operations and is here for speed. |
| 753 | */ |
| 754 | virtual void setColLower(const double * array); |
| 755 | |
| 756 | /** Set a single column upper bound. |
| 757 | Use getInfinity() for infinity. */ |
| 758 | virtual void setColUpper( int elementIndex, double elementValue ) = 0; |
| 759 | |
| 760 | /** Set the upper bounds for all columns. |
| 761 | |
| 762 | array [getNumCols()] is an array of values for the upper bounds. |
| 763 | This defaults to a series of set operations and is here for speed. |
| 764 | */ |
| 765 | virtual void setColUpper(const double * array); |
| 766 | |
| 767 | |
| 768 | /** Set a single column lower and upper bound. |
| 769 | The default implementation just invokes setColLower() and |
| 770 | setColUpper() */ |
| 771 | virtual void setColBounds( int elementIndex, |
| 772 | double lower, double upper ) { |
| 773 | setColLower(elementIndex, lower); |
| 774 | setColUpper(elementIndex, upper); |
| 775 | } |
| 776 | |
| 777 | /** Set the upper and lower bounds of a set of columns. |
| 778 | |
| 779 | The default implementation just invokes setColBounds() over and over |
| 780 | again. For each column, boundList must contain both a lower and |
| 781 | upper bound, in that order. |
| 782 | */ |
| 783 | virtual void setColSetBounds(const int* indexFirst, |
| 784 | const int* indexLast, |
| 785 | const double* boundList); |
| 786 | |
| 787 | /** Set a single row lower bound. |
| 788 | Use -getInfinity() for -infinity. */ |
| 789 | virtual void setRowLower( int elementIndex, double elementValue ) = 0; |
| 790 | |
| 791 | /** Set a single row upper bound. |
| 792 | Use getInfinity() for infinity. */ |
| 793 | virtual void setRowUpper( int elementIndex, double elementValue ) = 0; |
| 794 | |
| 795 | /** Set a single row lower and upper bound. |
| 796 | The default implementation just invokes setRowLower() and |
| 797 | setRowUpper() */ |
| 798 | virtual void setRowBounds( int elementIndex, |
| 799 | double lower, double upper ) { |
| 800 | setRowLower(elementIndex, lower); |
| 801 | setRowUpper(elementIndex, upper); |
| 802 | } |
| 803 | |
| 804 | /** Set the bounds on a set of rows. |
| 805 | |
| 806 | The default implementation just invokes setRowBounds() over and over |
| 807 | again. For each row, boundList must contain both a lower and |
| 808 | upper bound, in that order. |
| 809 | */ |
| 810 | virtual void setRowSetBounds(const int* indexFirst, |
| 811 | const int* indexLast, |
| 812 | const double* boundList); |
| 813 | |
| 814 | |
| 815 | /** Set the type of a single row */ |
| 816 | virtual void setRowType(int index, char sense, double rightHandSide, |
| 817 | double range) = 0; |
| 818 | |
| 819 | /** Set the type of a set of rows. |
| 820 | The default implementation just invokes setRowType() |
| 821 | over and over again. |
| 822 | */ |
| 823 | virtual void setRowSetTypes(const int* indexFirst, |
| 824 | const int* indexLast, |
| 825 | const char* senseList, |
| 826 | const double* rhsList, |
| 827 | const double* rangeList); |
| 828 | |
| 829 | /** Set the primal solution variable values |
| 830 | |
| 831 | colsol[getNumCols()] is an array of values for the primal variables. |
| 832 | These values are copied to memory owned by the solver interface |
| 833 | object or the solver. They will be returned as the result of |
| 834 | getColSolution() until changed by another call to setColSolution() or |
| 835 | by a call to any solver routine. Whether the solver makes use of the |
| 836 | solution in any way is solver-dependent. |
| 837 | */ |
| 838 | virtual void setColSolution(const double *colsol) = 0; |
| 839 | |
| 840 | /** Set dual solution variable values |
| 841 | |
| 842 | rowprice[getNumRows()] is an array of values for the dual variables. |
| 843 | These values are copied to memory owned by the solver interface |
| 844 | object or the solver. They will be returned as the result of |
| 845 | getRowPrice() until changed by another call to setRowPrice() or by a |
| 846 | call to any solver routine. Whether the solver makes use of the |
| 847 | solution in any way is solver-dependent. |
| 848 | */ |
| 849 | virtual void setRowPrice(const double * rowprice) = 0; |
| 850 | |
| 851 | /** Fix variables at bound based on reduced cost |
| 852 | |
| 853 | For variables currently at bound, fix the variable at bound if the |
| 854 | reduced cost exceeds the gap. Return the number of variables fixed. |
| 855 | |
| 856 | If justInteger is set to false, the routine will also fix continuous |
| 857 | variables, but the test still assumes a delta of 1.0. |
| 858 | */ |
| 859 | virtual int reducedCostFix(double gap, bool justInteger=true); |
| 860 | //@} |
| 861 | |
| 862 | //------------------------------------------------------------------------- |
| 863 | /**@name Methods to set variable type */ |
| 864 | //@{ |
| 865 | /** Set the index-th variable to be a continuous variable */ |
| 866 | virtual void setContinuous(int index) = 0; |
| 867 | /** Set the index-th variable to be an integer variable */ |
| 868 | virtual void setInteger(int index) = 0; |
| 869 | /** Set the variables listed in indices (which is of length len) to be |
| 870 | continuous variables */ |
| 871 | virtual void setContinuous(const int* indices, int len); |
| 872 | /** Set the variables listed in indices (which is of length len) to be |
| 873 | integer variables */ |
| 874 | virtual void setInteger(const int* indices, int len); |
| 875 | //@} |
| 876 | //------------------------------------------------------------------------- |
| 877 | |
| 878 | //------------------------------------------------------------------------- |
| 879 | |
| 880 | /*! \brief Data type for name vectors. */ |
| 881 | typedef std::vector<std::string> OsiNameVec ; |
| 882 | |
| 883 | /*! \name Methods for row and column names |
| 884 | |
| 885 | Osi defines three name management disciplines: `auto names' (0), `lazy |
| 886 | names' (1), and `full names' (2). See the description of |
| 887 | #OsiNameDiscipline for details. Changing the name discipline (via |
| 888 | setIntParam()) will not automatically add or remove name information, |
| 889 | but setting the discipline to auto will make existing information |
| 890 | inaccessible until the discipline is reset to lazy or full. |
| 891 | |
| 892 | By definition, a row index of getNumRows() (<i>i.e.</i>, one larger than |
| 893 | the largest valid row index) refers to the objective function. |
| 894 | |
| 895 | OSI users and implementors: While the OSI base class can define an |
| 896 | interface and provide rudimentary support, use of names really depends |
| 897 | on support by the OsiXXX class to ensure that names are managed |
| 898 | correctly. If an OsiXXX class does not support names, it should return |
| 899 | false for calls to getIntParam() or setIntParam() that reference |
| 900 | OsiNameDiscipline. |
| 901 | */ |
| 902 | //@{ |
| 903 | |
| 904 | /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn |
| 905 | |
| 906 | Set \p rc to 'r' for a row name, 'c' for a column name. |
| 907 | The `nnnnnnn' part is generated from ndx and will contain 7 digits |
| 908 | by default, padded with zeros if necessary. As a special case, |
| 909 | ndx = getNumRows() is interpreted as a request for the name of the |
| 910 | objective function. OBJECTIVE is returned, truncated to digits+1 |
| 911 | characters to match the row and column names. |
| 912 | */ |
| 913 | virtual std::string dfltRowColName(char rc, |
| 914 | int ndx, unsigned digits = 7) const ; |
| 915 | |
| 916 | /*! \brief Return the name of the objective function */ |
| 917 | #pragma warning(suppress: 4309) |
| 918 | virtual std::string getObjName (unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; |
| 919 | |
| 920 | /*! \brief Set the name of the objective function */ |
| 921 | |
| 922 | virtual inline void setObjName (std::string name) |
| 923 | { objName_ = name ; } |
| 924 | |
| 925 | /*! \brief Return the name of the row. |
| 926 | |
| 927 | The routine will <i>always</i> return some name, regardless of the name |
| 928 | discipline or the level of support by an OsiXXX derived class. Use |
| 929 | maxLen to limit the length. |
| 930 | */ |
| 931 | virtual std::string getRowName(int rowIndex, |
| 932 | #pragma warning(suppress: 4309) |
| 933 | unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; |
| 934 | |
| 935 | /*! \brief Return a pointer to a vector of row names |
| 936 | |
| 937 | If the name discipline (#OsiNameDiscipline) is auto, the return value |
| 938 | will be a vector of length zero. If the name discipline is lazy, the |
| 939 | vector will contain only names supplied by the client and will be no |
| 940 | larger than needed to hold those names; entries not supplied will be |
| 941 | null strings. In particular, the objective name is <i>not</i> |
| 942 | included in the vector for lazy names. If the name discipline is |
| 943 | full, the vector will have getNumRows() names, either supplied or |
| 944 | generated, plus one additional entry for the objective name. |
| 945 | */ |
| 946 | virtual const OsiNameVec &getRowNames() ; |
| 947 | |
| 948 | /*! \brief Set a row name |
| 949 | |
| 950 | Quietly does nothing if the name discipline (#OsiNameDiscipline) is |
| 951 | auto. Quietly fails if the row index is invalid. |
| 952 | */ |
| 953 | virtual void setRowName(int ndx, std::string name) ; |
| 954 | |
| 955 | /*! \brief Set multiple row names |
| 956 | |
| 957 | The run of len entries starting at srcNames[srcStart] are installed as |
| 958 | row names starting at row index tgtStart. The base class implementation |
| 959 | makes repeated calls to setRowName. |
| 960 | */ |
| 961 | virtual void setRowNames(OsiNameVec &srcNames, |
| 962 | int srcStart, int len, int tgtStart) ; |
| 963 | |
| 964 | /*! \brief Delete len row names starting at index tgtStart |
| 965 | |
| 966 | The specified row names are removed and the remaining row names are |
| 967 | copied down to close the gap. |
| 968 | */ |
| 969 | virtual void deleteRowNames(int tgtStart, int len) ; |
| 970 | |
| 971 | /*! \brief Return the name of the column |
| 972 | |
| 973 | The routine will <i>always</i> return some name, regardless of the name |
| 974 | discipline or the level of support by an OsiXXX derived class. Use |
| 975 | maxLen to limit the length. |
| 976 | */ |
| 977 | virtual std::string getColName(int colIndex, |
| 978 | #pragma warning(suppress: 4309) |
| 979 | unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; |
| 980 | |
| 981 | /*! \brief Return a pointer to a vector of column names |
| 982 | |
| 983 | If the name discipline (#OsiNameDiscipline) is auto, the return value |
| 984 | will be a vector of length zero. If the name discipline is lazy, the |
| 985 | vector will contain only names supplied by the client and will be no |
| 986 | larger than needed to hold those names; entries not supplied will be |
| 987 | null strings. If the name discipline is full, the vector will have |
| 988 | getNumCols() names, either supplied or generated. |
| 989 | */ |
| 990 | virtual const OsiNameVec &getColNames() ; |
| 991 | |
| 992 | /*! \brief Set a column name |
| 993 | |
| 994 | Quietly does nothing if the name discipline (#OsiNameDiscipline) is |
| 995 | auto. Quietly fails if the column index is invalid. |
| 996 | */ |
| 997 | virtual void setColName(int ndx, std::string name) ; |
| 998 | |
| 999 | /*! \brief Set multiple column names |
| 1000 | |
| 1001 | The run of len entries starting at srcNames[srcStart] are installed as |
| 1002 | column names starting at column index tgtStart. The base class |
| 1003 | implementation makes repeated calls to setColName. |
| 1004 | */ |
| 1005 | virtual void setColNames(OsiNameVec &srcNames, |
| 1006 | int srcStart, int len, int tgtStart) ; |
| 1007 | |
| 1008 | /*! \brief Delete len column names starting at index tgtStart |
| 1009 | |
| 1010 | The specified column names are removed and the remaining column names |
| 1011 | are copied down to close the gap. |
| 1012 | */ |
| 1013 | virtual void deleteColNames(int tgtStart, int len) ; |
| 1014 | |
| 1015 | |
| 1016 | /*! \brief Set row and column names from a CoinMpsIO object. |
| 1017 | |
| 1018 | Also sets the name of the objective function. If the name discipline |
| 1019 | is auto, you get what you asked for. This routine does not use |
| 1020 | setRowName or setColName. |
| 1021 | */ |
| 1022 | void setRowColNames(const CoinMpsIO &mps) ; |
| 1023 | |
| 1024 | /*! \brief Set row and column names from a CoinModel object. |
| 1025 | |
| 1026 | If the name discipline is auto, you get what you asked for. |
| 1027 | This routine does not use setRowName or setColName. |
| 1028 | */ |
| 1029 | void setRowColNames(CoinModel &mod) ; |
| 1030 | |
| 1031 | /*! \brief Set row and column names from a CoinLpIO object. |
| 1032 | |
| 1033 | Also sets the name of the objective function. If the name discipline is |
| 1034 | auto, you get what you asked for. This routine does not use setRowName |
| 1035 | or setColName. |
| 1036 | */ |
| 1037 | void setRowColNames(CoinLpIO &mod) ; |
| 1038 | |
| 1039 | //@} |
| 1040 | //------------------------------------------------------------------------- |
| 1041 | |
| 1042 | //------------------------------------------------------------------------- |
| 1043 | /**@name Methods to modify the constraint system. |
| 1044 | |
| 1045 | Note that new columns are added as continuous variables. |
| 1046 | */ |
| 1047 | //@{ |
| 1048 | |
| 1049 | /** Add a column (primal variable) to the problem. */ |
| 1050 | virtual void addCol(const CoinPackedVectorBase& vec, |
| 1051 | const double collb, const double colub, |
| 1052 | const double obj) = 0; |
| 1053 | |
| 1054 | /*! \brief Add a named column (primal variable) to the problem. |
| 1055 | |
| 1056 | The default implementation adds the column, then changes the name. This |
| 1057 | can surely be made more efficient within an OsiXXX class. |
| 1058 | */ |
| 1059 | virtual void addCol(const CoinPackedVectorBase& vec, |
| 1060 | const double collb, const double colub, |
| 1061 | const double obj, std::string name) ; |
| 1062 | |
| 1063 | /** Add a column (primal variable) to the problem. */ |
| 1064 | virtual void addCol(int numberElements, |
| 1065 | const int* rows, const double* elements, |
| 1066 | const double collb, const double colub, |
| 1067 | const double obj) ; |
| 1068 | |
| 1069 | /*! \brief Add a named column (primal variable) to the problem. |
| 1070 | |
| 1071 | The default implementation adds the column, then changes the name. This |
| 1072 | can surely be made more efficient within an OsiXXX class. |
| 1073 | */ |
| 1074 | virtual void addCol(int numberElements, |
| 1075 | const int* rows, const double* elements, |
| 1076 | const double collb, const double colub, |
| 1077 | const double obj, std::string name) ; |
| 1078 | |
| 1079 | /** Add a set of columns (primal variables) to the problem. |
| 1080 | |
| 1081 | The default implementation simply makes repeated calls to |
| 1082 | addCol(). |
| 1083 | */ |
| 1084 | virtual void addCols(const int numcols, |
| 1085 | const CoinPackedVectorBase * const * cols, |
| 1086 | const double* collb, const double* colub, |
| 1087 | const double* obj); |
| 1088 | |
| 1089 | /** Add a set of columns (primal variables) to the problem. |
| 1090 | |
| 1091 | The default implementation simply makes repeated calls to |
| 1092 | addCol(). |
| 1093 | */ |
| 1094 | virtual void addCols(const int numcols, const int* columnStarts, |
| 1095 | const int* rows, const double* elements, |
| 1096 | const double* collb, const double* colub, |
| 1097 | const double* obj); |
| 1098 | |
| 1099 | /// Add columns using a CoinBuild object |
| 1100 | void addCols(const CoinBuild & buildObject); |
| 1101 | |
| 1102 | /** Add columns from a model object. returns |
| 1103 | -1 if object in bad state (i.e. has row information) |
| 1104 | otherwise number of errors |
| 1105 | modelObject non const as can be regularized as part of build |
| 1106 | */ |
| 1107 | int addCols(CoinModel & modelObject); |
| 1108 | |
| 1109 | #if 0 |
| 1110 | /** */ |
| 1111 | virtual void addCols(const CoinPackedMatrix& matrix, |
| 1112 | const double* collb, const double* colub, |
| 1113 | const double* obj); |
| 1114 | #endif |
| 1115 | |
| 1116 | /** \brief Remove a set of columns (primal variables) from the |
| 1117 | problem. |
| 1118 | |
| 1119 | The solver interface for a basis-oriented solver will maintain valid |
| 1120 | warm start information if all deleted variables are nonbasic. |
| 1121 | */ |
| 1122 | virtual void deleteCols(const int num, const int * colIndices) = 0; |
| 1123 | |
| 1124 | /*! \brief Add a row (constraint) to the problem. */ |
| 1125 | virtual void addRow(const CoinPackedVectorBase& vec, |
| 1126 | const double rowlb, const double rowub) = 0; |
| 1127 | |
| 1128 | /*! \brief Add a named row (constraint) to the problem. |
| 1129 | |
| 1130 | The default implementation adds the row, then changes the name. This |
| 1131 | can surely be made more efficient within an OsiXXX class. |
| 1132 | */ |
| 1133 | virtual void addRow(const CoinPackedVectorBase& vec, |
| 1134 | const double rowlb, const double rowub, |
| 1135 | std::string name) ; |
| 1136 | |
| 1137 | /*! \brief Add a row (constraint) to the problem. */ |
| 1138 | virtual void addRow(const CoinPackedVectorBase& vec, |
| 1139 | const char rowsen, const double rowrhs, |
| 1140 | const double rowrng) = 0; |
| 1141 | |
| 1142 | /*! \brief Add a named row (constraint) to the problem. |
| 1143 | |
| 1144 | The default implementation adds the row, then changes the name. This |
| 1145 | can surely be made more efficient within an OsiXXX class. |
| 1146 | */ |
| 1147 | virtual void addRow(const CoinPackedVectorBase& vec, |
| 1148 | const char rowsen, const double rowrhs, |
| 1149 | const double rowrng, std::string name) ; |
| 1150 | |
| 1151 | /*! Add a row (constraint) to the problem. |
| 1152 | |
| 1153 | Converts to addRow(CoinPackedVectorBase&,const double,const double). |
| 1154 | */ |
| 1155 | virtual void addRow(int numberElements, |
| 1156 | const int *columns, const double *element, |
| 1157 | const double rowlb, const double rowub) ; |
| 1158 | |
| 1159 | /*! Add a set of rows (constraints) to the problem. |
| 1160 | |
| 1161 | The default implementation simply makes repeated calls to |
| 1162 | addRow(). |
| 1163 | */ |
| 1164 | virtual void addRows(const int numrows, |
| 1165 | const CoinPackedVectorBase * const * rows, |
| 1166 | const double* rowlb, const double* rowub); |
| 1167 | |
| 1168 | /** Add a set of rows (constraints) to the problem. |
| 1169 | |
| 1170 | The default implementation simply makes repeated calls to |
| 1171 | addRow(). |
| 1172 | */ |
| 1173 | virtual void addRows(const int numrows, |
| 1174 | const CoinPackedVectorBase * const * rows, |
| 1175 | const char* rowsen, const double* rowrhs, |
| 1176 | const double* rowrng); |
| 1177 | |
| 1178 | /** Add a set of rows (constraints) to the problem. |
| 1179 | |
| 1180 | The default implementation simply makes repeated calls to |
| 1181 | addRow(). |
| 1182 | */ |
| 1183 | virtual void addRows(const int numrows, const int *rowStarts, |
| 1184 | const int *columns, const double *element, |
| 1185 | const double *rowlb, const double *rowub); |
| 1186 | |
| 1187 | /// Add rows using a CoinBuild object |
| 1188 | void addRows(const CoinBuild &buildObject); |
| 1189 | |
| 1190 | /*! Add rows from a CoinModel object. |
| 1191 | |
| 1192 | Returns -1 if the object is in the wrong state (<i>i.e.</i>, has |
| 1193 | column-major information), otherwise the number of errors. |
| 1194 | |
| 1195 | The modelObject is not const as it can be regularized as part of |
| 1196 | the build. |
| 1197 | */ |
| 1198 | int addRows(CoinModel &modelObject); |
| 1199 | |
| 1200 | #if 0 |
| 1201 | /** */ |
| 1202 | virtual void addRows(const CoinPackedMatrix& matrix, |
| 1203 | const double* rowlb, const double* rowub); |
| 1204 | /** */ |
| 1205 | virtual void addRows(const CoinPackedMatrix& matrix, |
| 1206 | const char* rowsen, const double* rowrhs, |
| 1207 | const double* rowrng); |
| 1208 | #endif |
| 1209 | |
| 1210 | /** \brief Delete a set of rows (constraints) from the problem. |
| 1211 | |
| 1212 | The solver interface for a basis-oriented solver will maintain valid |
| 1213 | warm start information if all deleted rows are loose. |
| 1214 | */ |
| 1215 | virtual void deleteRows(const int num, const int * rowIndices) = 0; |
| 1216 | |
| 1217 | /** \brief Replace the constraint matrix |
| 1218 | |
| 1219 | I (JJF) am getting annoyed because I can't just replace a matrix. |
| 1220 | The default behavior of this is do nothing so only use where that would |
| 1221 | not matter, e.g. strengthening a matrix for MIP. |
| 1222 | */ |
| 1223 | virtual void replaceMatrixOptional(const CoinPackedMatrix & ) {} |
| 1224 | |
| 1225 | /** \brief Replace the constraint matrix |
| 1226 | |
| 1227 | And if it does matter (not used at present) |
| 1228 | */ |
| 1229 | virtual void replaceMatrix(const CoinPackedMatrix & ) {abort();} |
| 1230 | |
| 1231 | /** \brief Save a copy of the base model |
| 1232 | |
| 1233 | If solver wants it can save a copy of "base" (continuous) model here. |
| 1234 | */ |
| 1235 | virtual void saveBaseModel() {} |
| 1236 | |
| 1237 | /** \brief Reduce the constraint system to the specified number of |
| 1238 | constraints. |
| 1239 | |
| 1240 | If solver wants it can restore a copy of "base" (continuous) model |
| 1241 | here. |
| 1242 | |
| 1243 | \note |
| 1244 | The name is somewhat misleading. Implementors should consider |
| 1245 | the opportunity to optimise behaviour in the common case where |
| 1246 | \p numberRows is exactly the number of original constraints. Do not, |
| 1247 | however, neglect the possibility that \p numberRows does not equal |
| 1248 | the number of original constraints. |
| 1249 | */ |
| 1250 | virtual void restoreBaseModel(int numberRows); |
| 1251 | //----------------------------------------------------------------------- |
| 1252 | /** Apply a collection of cuts. |
| 1253 | |
| 1254 | Only cuts which have an <code>effectiveness >= effectivenessLb</code> |
| 1255 | are applied. |
| 1256 | <ul> |
| 1257 | <li> ReturnCode.getNumineffective() -- number of cuts which were |
| 1258 | not applied because they had an |
| 1259 | <code>effectiveness < effectivenessLb</code> |
| 1260 | <li> ReturnCode.getNuminconsistent() -- number of invalid cuts |
| 1261 | <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of |
| 1262 | cuts that are invalid with respect to this integer model |
| 1263 | <li> ReturnCode.getNuminfeasible() -- number of cuts that would |
| 1264 | make this integer model infeasible |
| 1265 | <li> ReturnCode.getNumApplied() -- number of integer cuts which |
| 1266 | were applied to the integer model |
| 1267 | <li> cs.size() == getNumineffective() + |
| 1268 | getNuminconsistent() + |
| 1269 | getNuminconsistentWrtIntegerModel() + |
| 1270 | getNuminfeasible() + |
| 1271 | getNumApplied() |
| 1272 | </ul> |
| 1273 | */ |
| 1274 | virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, |
| 1275 | double effectivenessLb = 0.0); |
| 1276 | |
| 1277 | /** Apply a collection of row cuts which are all effective. |
| 1278 | applyCuts seems to do one at a time which seems inefficient. |
| 1279 | Would be even more efficient to pass an array of pointers. |
| 1280 | */ |
| 1281 | virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); |
| 1282 | |
| 1283 | /** Apply a collection of row cuts which are all effective. |
| 1284 | This is passed in as an array of pointers. |
| 1285 | */ |
| 1286 | virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); |
| 1287 | |
| 1288 | /// Deletes branching information before columns deleted |
| 1289 | void deleteBranchingInfo(int numberDeleted, const int * which); |
| 1290 | |
| 1291 | //@} |
| 1292 | |
| 1293 | //--------------------------------------------------------------------------- |
| 1294 | |
| 1295 | /**@name Methods for problem input and output */ |
| 1296 | //@{ |
| 1297 | /*! \brief Load in a problem by copying the arguments. The constraints on |
| 1298 | the rows are given by lower and upper bounds. |
| 1299 | |
| 1300 | If a pointer is 0 then the following values are the default: |
| 1301 | <ul> |
| 1302 | <li> <code>colub</code>: all columns have upper bound infinity |
| 1303 | <li> <code>collb</code>: all columns have lower bound 0 |
| 1304 | <li> <code>rowub</code>: all rows have upper bound infinity |
| 1305 | <li> <code>rowlb</code>: all rows have lower bound -infinity |
| 1306 | <li> <code>obj</code>: all variables have 0 objective coefficient |
| 1307 | </ul> |
| 1308 | |
| 1309 | Note that the default values for rowub and rowlb produce the |
| 1310 | constraint -infty <= ax <= infty. This is probably not what you want. |
| 1311 | */ |
| 1312 | virtual void loadProblem (const CoinPackedMatrix& matrix, |
| 1313 | const double* collb, const double* colub, |
| 1314 | const double* obj, |
| 1315 | const double* rowlb, const double* rowub) = 0; |
| 1316 | |
| 1317 | /*! \brief Load in a problem by assuming ownership of the arguments. |
| 1318 | The constraints on the rows are given by lower and upper bounds. |
| 1319 | |
| 1320 | For default argument values see the matching loadProblem method. |
| 1321 | |
| 1322 | \warning |
| 1323 | The arguments passed to this method will be freed using the |
| 1324 | C++ <code>delete</code> and <code>delete[]</code> functions. |
| 1325 | */ |
| 1326 | virtual void assignProblem (CoinPackedMatrix*& matrix, |
| 1327 | double*& collb, double*& colub, double*& obj, |
| 1328 | double*& rowlb, double*& rowub) = 0; |
| 1329 | |
| 1330 | /*! \brief Load in a problem by copying the arguments. |
| 1331 | The constraints on the rows are given by sense/rhs/range triplets. |
| 1332 | |
| 1333 | If a pointer is 0 then the following values are the default: |
| 1334 | <ul> |
| 1335 | <li> <code>colub</code>: all columns have upper bound infinity |
| 1336 | <li> <code>collb</code>: all columns have lower bound 0 |
| 1337 | <li> <code>obj</code>: all variables have 0 objective coefficient |
| 1338 | <li> <code>rowsen</code>: all rows are >= |
| 1339 | <li> <code>rowrhs</code>: all right hand sides are 0 |
| 1340 | <li> <code>rowrng</code>: 0 for the ranged rows |
| 1341 | </ul> |
| 1342 | |
| 1343 | Note that the default values for rowsen, rowrhs, and rowrng produce the |
| 1344 | constraint ax >= 0. |
| 1345 | */ |
| 1346 | virtual void loadProblem (const CoinPackedMatrix& matrix, |
| 1347 | const double* collb, const double* colub, |
| 1348 | const double* obj, |
| 1349 | const char* rowsen, const double* rowrhs, |
| 1350 | const double* rowrng) = 0; |
| 1351 | |
| 1352 | /*! \brief Load in a problem by assuming ownership of the arguments. |
| 1353 | The constraints on the rows are given by sense/rhs/range triplets. |
| 1354 | |
| 1355 | For default argument values see the matching loadProblem method. |
| 1356 | |
| 1357 | \warning |
| 1358 | The arguments passed to this method will be freed using the |
| 1359 | C++ <code>delete</code> and <code>delete[]</code> functions. |
| 1360 | */ |
| 1361 | virtual void assignProblem (CoinPackedMatrix*& matrix, |
| 1362 | double*& collb, double*& colub, double*& obj, |
| 1363 | char*& rowsen, double*& rowrhs, |
| 1364 | double*& rowrng) = 0; |
| 1365 | |
| 1366 | /*! \brief Load in a problem by copying the arguments. The constraint |
| 1367 | matrix is is specified with standard column-major |
| 1368 | column starts / row indices / coefficients vectors. |
| 1369 | The constraints on the rows are given by lower and upper bounds. |
| 1370 | |
| 1371 | The matrix vectors must be gap-free. Note that <code>start</code> must |
| 1372 | have <code>numcols+1</code> entries so that the length of the last column |
| 1373 | can be calculated as <code>start[numcols]-start[numcols-1]</code>. |
| 1374 | |
| 1375 | See the previous loadProblem method using rowlb and rowub for default |
| 1376 | argument values. |
| 1377 | */ |
| 1378 | virtual void loadProblem (const int numcols, const int numrows, |
| 1379 | const CoinBigIndex * start, const int* index, |
| 1380 | const double* value, |
| 1381 | const double* collb, const double* colub, |
| 1382 | const double* obj, |
| 1383 | const double* rowlb, const double* rowub) = 0; |
| 1384 | |
| 1385 | /*! \brief Load in a problem by copying the arguments. The constraint |
| 1386 | matrix is is specified with standard column-major |
| 1387 | column starts / row indices / coefficients vectors. |
| 1388 | The constraints on the rows are given by sense/rhs/range triplets. |
| 1389 | |
| 1390 | The matrix vectors must be gap-free. Note that <code>start</code> must |
| 1391 | have <code>numcols+1</code> entries so that the length of the last column |
| 1392 | can be calculated as <code>start[numcols]-start[numcols-1]</code>. |
| 1393 | |
| 1394 | See the previous loadProblem method using sense/rhs/range for default |
| 1395 | argument values. |
| 1396 | */ |
| 1397 | virtual void loadProblem (const int numcols, const int numrows, |
| 1398 | const CoinBigIndex * start, const int* index, |
| 1399 | const double* value, |
| 1400 | const double* collb, const double* colub, |
| 1401 | const double* obj, |
| 1402 | const char* rowsen, const double* rowrhs, |
| 1403 | const double* rowrng) = 0; |
| 1404 | |
| 1405 | /*! \brief Load a model from a CoinModel object. Return the number of |
| 1406 | errors encountered. |
| 1407 | |
| 1408 | The modelObject parameter cannot be const as it may be changed as part |
| 1409 | of process. If keepSolution is true will try and keep warmStart. |
| 1410 | */ |
| 1411 | virtual int loadFromCoinModel (CoinModel & modelObject, |
| 1412 | bool keepSolution=false); |
| 1413 | |
| 1414 | /*! \brief Read a problem in MPS format from the given filename. |
| 1415 | |
| 1416 | The default implementation uses CoinMpsIO::readMps() to read |
| 1417 | the MPS file and returns the number of errors encountered. |
| 1418 | */ |
| 1419 | virtual int readMps (const char *filename, |
| 1420 | const char *extension = "mps" ) ; |
| 1421 | |
| 1422 | /*! \brief Read a problem in MPS format from the given full filename. |
| 1423 | |
| 1424 | This uses CoinMpsIO::readMps() to read the MPS file and returns the |
| 1425 | number of errors encountered. It also may return an array of set |
| 1426 | information |
| 1427 | */ |
| 1428 | virtual int readMps (const char *filename, const char*extension, |
| 1429 | int & numberSets, CoinSet ** & sets); |
| 1430 | |
| 1431 | /*! \brief Read a problem in GMPL format from the given filenames. |
| 1432 | |
| 1433 | The default implementation uses CoinMpsIO::readGMPL(). This capability |
| 1434 | is available only if the third-party package Glpk is installed. |
| 1435 | */ |
| 1436 | virtual int readGMPL (const char *filename, const char *dataname=nullptr); |
| 1437 | |
| 1438 | /*! \brief Write the problem in MPS format to the specified file. |
| 1439 | |
| 1440 | If objSense is non-zero, a value of -1.0 causes the problem to be |
| 1441 | written with a maximization objective; +1.0 forces a minimization |
| 1442 | objective. If objSense is zero, the choice is left to the implementation. |
| 1443 | */ |
| 1444 | virtual void writeMps (const char *filename, |
| 1445 | const char *extension = "mps" , |
| 1446 | double objSense=0.0) const = 0; |
| 1447 | |
| 1448 | /*! \brief Write the problem in MPS format to the specified file with |
| 1449 | more control over the output. |
| 1450 | |
| 1451 | Row and column names may be null. |
| 1452 | formatType is |
| 1453 | <ul> |
| 1454 | <li> 0 - normal |
| 1455 | <li> 1 - extra accuracy |
| 1456 | <li> 2 - IEEE hex |
| 1457 | </ul> |
| 1458 | |
| 1459 | Returns non-zero on I/O error |
| 1460 | */ |
| 1461 | int writeMpsNative (const char *filename, |
| 1462 | const char ** rowNames, const char ** columnNames, |
| 1463 | int formatType=0,int numberAcross=2, |
| 1464 | double objSense=0.0, int numberSOS=0, |
| 1465 | const CoinSet * setInfo=nullptr) const ; |
| 1466 | |
| 1467 | /***********************************************************************/ |
| 1468 | // Lp files |
| 1469 | |
| 1470 | /** Write the problem into an Lp file of the given filename with the |
| 1471 | specified extension. |
| 1472 | Coefficients with value less than epsilon away from an integer value |
| 1473 | are written as integers. |
| 1474 | Write at most numberAcross monomials on a line. |
| 1475 | Write non integer numbers with decimals digits after the decimal point. |
| 1476 | |
| 1477 | The written problem is always a minimization problem. |
| 1478 | If the current problem is a maximization problem, the |
| 1479 | intended objective function for the written problem is the current |
| 1480 | objective function multiplied by -1. If the current problem is a |
| 1481 | minimization problem, the intended objective function for the |
| 1482 | written problem is the current objective function. |
| 1483 | If objSense < 0, the intended objective function is multiplied by -1 |
| 1484 | before writing the problem. It is left unchanged otherwise. |
| 1485 | |
| 1486 | Write objective function name and constraint names if useRowNames is |
| 1487 | true. This version calls writeLpNative(). |
| 1488 | */ |
| 1489 | virtual void writeLp(const char *filename, |
| 1490 | const char *extension = "lp" , |
| 1491 | double epsilon = 1e-5, |
| 1492 | int numberAcross = 10, |
| 1493 | int decimals = 5, |
| 1494 | double objSense = 0.0, |
| 1495 | bool useRowNames = true) const; |
| 1496 | |
| 1497 | /** Write the problem into the file pointed to by the parameter fp. |
| 1498 | Other parameters are similar to |
| 1499 | those of writeLp() with first parameter filename. |
| 1500 | */ |
| 1501 | virtual void writeLp(FILE *fp, |
| 1502 | double epsilon = 1e-5, |
| 1503 | int numberAcross = 10, |
| 1504 | int decimals = 5, |
| 1505 | double objSense = 0.0, |
| 1506 | bool useRowNames = true) const; |
| 1507 | |
| 1508 | /** Write the problem into an Lp file. Parameters are similar to |
| 1509 | those of writeLp(), but in addition row names and column names |
| 1510 | may be given. |
| 1511 | |
| 1512 | Parameter rowNames may be NULL, in which case default row names |
| 1513 | are used. If rowNames is not NULL, it must have exactly one entry |
| 1514 | per row in the problem and one additional |
| 1515 | entry (rowNames[getNumRows()] with the objective function name. |
| 1516 | These getNumRows()+1 entries must be distinct. If this is not the |
| 1517 | case, default row names |
| 1518 | are used. In addition, format restrictions are imposed on names |
| 1519 | (see CoinLpIO::is_invalid_name() for details). |
| 1520 | |
| 1521 | Similar remarks can be made for the parameter columnNames which |
| 1522 | must either be NULL or have exactly getNumCols() distinct entries. |
| 1523 | |
| 1524 | Write objective function name and constraint names if |
| 1525 | useRowNames is true. */ |
| 1526 | int writeLpNative(const char *filename, |
| 1527 | char const * const * const rowNames, |
| 1528 | char const * const * const columnNames, |
| 1529 | const double epsilon = 1.0e-5, |
| 1530 | const int numberAcross = 10, |
| 1531 | const int decimals = 5, |
| 1532 | const double objSense = 0.0, |
| 1533 | const bool useRowNames = true) const; |
| 1534 | |
| 1535 | /** Write the problem into the file pointed to by the parameter fp. |
| 1536 | Other parameters are similar to |
| 1537 | those of writeLpNative() with first parameter filename. |
| 1538 | */ |
| 1539 | int writeLpNative(FILE *fp, |
| 1540 | char const * const * const rowNames, |
| 1541 | char const * const * const columnNames, |
| 1542 | const double epsilon = 1.0e-5, |
| 1543 | const int numberAcross = 10, |
| 1544 | const int decimals = 5, |
| 1545 | const double objSense = 0.0, |
| 1546 | const bool useRowNames = true) const; |
| 1547 | |
| 1548 | /// Read file in LP format from file with name filename. |
| 1549 | /// See class CoinLpIO for description of this format. |
| 1550 | virtual int readLp(const char *filename, const double epsilon = 1e-5); |
| 1551 | |
| 1552 | /// Read file in LP format from the file pointed to by fp. |
| 1553 | /// See class CoinLpIO for description of this format. |
| 1554 | int readLp(FILE *fp, const double epsilon = 1e-5); |
| 1555 | |
| 1556 | //@} |
| 1557 | |
| 1558 | //--------------------------------------------------------------------------- |
| 1559 | |
| 1560 | /**@name Miscellaneous */ |
| 1561 | //@{ |
| 1562 | #ifdef COIN_SNAPSHOT |
| 1563 | /// Return a CoinSnapshot |
| 1564 | virtual CoinSnapshot * snapshot(bool createArrays=true) const; |
| 1565 | #endif |
| 1566 | #ifdef COIN_FACTORIZATION_INFO |
| 1567 | /// Return number of entries in L part of current factorization |
| 1568 | virtual CoinBigIndex getSizeL() const; |
| 1569 | /// Return number of entries in U part of current factorization |
| 1570 | virtual CoinBigIndex getSizeU() const; |
| 1571 | #endif |
| 1572 | //@} |
| 1573 | |
| 1574 | //--------------------------------------------------------------------------- |
| 1575 | |
| 1576 | /**@name Setting/Accessing application data */ |
| 1577 | //@{ |
| 1578 | /** Set application data. |
| 1579 | |
| 1580 | This is a pointer that the application can store into and |
| 1581 | retrieve from the solver interface. |
| 1582 | This field is available for the application to optionally |
| 1583 | define and use. |
| 1584 | */ |
| 1585 | void setApplicationData (void * appData); |
| 1586 | /** Create a clone of an Auxiliary Information object. |
| 1587 | The base class just stores an application data pointer |
| 1588 | but can be more general. Application data pointer is |
| 1589 | designed for one user while this can be extended to cope |
| 1590 | with more general extensions. |
| 1591 | */ |
| 1592 | void setAuxiliaryInfo(OsiAuxInfo * auxiliaryInfo); |
| 1593 | |
| 1594 | /// Get application data |
| 1595 | void * getApplicationData() const; |
| 1596 | /// Get pointer to auxiliary info object |
| 1597 | OsiAuxInfo * getAuxiliaryInfo() const; |
| 1598 | //@} |
| 1599 | //--------------------------------------------------------------------------- |
| 1600 | |
| 1601 | /**@name Message handling |
| 1602 | |
| 1603 | See the COIN library documentation for additional information about |
| 1604 | COIN message facilities. |
| 1605 | |
| 1606 | */ |
| 1607 | //@{ |
| 1608 | /** Pass in a message handler |
| 1609 | |
| 1610 | It is the client's responsibility to destroy a message handler installed |
| 1611 | by this routine; it will not be destroyed when the solver interface is |
| 1612 | destroyed. |
| 1613 | */ |
| 1614 | virtual void passInMessageHandler(CoinMessageHandler * handler); |
| 1615 | /// Set language |
| 1616 | void newLanguage(CoinMessages::Language language); |
| 1617 | inline void setLanguage(CoinMessages::Language language) |
| 1618 | {newLanguage(language);} |
| 1619 | /// Return a pointer to the current message handler |
| 1620 | inline CoinMessageHandler * messageHandler() const |
| 1621 | {return handler_;} |
| 1622 | /// Return the current set of messages |
| 1623 | inline CoinMessages messages() |
| 1624 | {return messages_;} |
| 1625 | /// Return a pointer to the current set of messages |
| 1626 | inline CoinMessages * messagesPointer() |
| 1627 | {return &messages_;} |
| 1628 | /// Return true if default handler |
| 1629 | inline bool defaultHandler() const |
| 1630 | { return defaultHandler_;} |
| 1631 | //@} |
| 1632 | //--------------------------------------------------------------------------- |
| 1633 | /**@name Methods for dealing with discontinuities other than integers. |
| 1634 | |
| 1635 | Osi should be able to know about SOS and other types. This is an optional |
| 1636 | section where such information can be stored. |
| 1637 | |
| 1638 | */ |
| 1639 | //@{ |
| 1640 | /** \brief Identify integer variables and create corresponding objects. |
| 1641 | |
| 1642 | Record integer variables and create an OsiSimpleInteger object for each |
| 1643 | one. All existing OsiSimpleInteger objects will be destroyed. |
| 1644 | If justCount then no objects created and we just store numberIntegers_ |
| 1645 | */ |
| 1646 | |
| 1647 | void findIntegers(bool justCount); |
| 1648 | /** \brief Identify integer variables and SOS and create corresponding objects. |
| 1649 | |
| 1650 | Record integer variables and create an OsiSimpleInteger object for each |
| 1651 | one. All existing OsiSimpleInteger objects will be destroyed. |
| 1652 | If the solver supports SOS then do the same for SOS. |
| 1653 | |
| 1654 | If justCount then no objects created and we just store numberIntegers_ |
| 1655 | Returns number of SOS |
| 1656 | */ |
| 1657 | |
| 1658 | virtual int findIntegersAndSOS(bool justCount); |
| 1659 | /// Get the number of objects |
| 1660 | inline int numberObjects() const { return numberObjects_;} |
| 1661 | /// Set the number of objects |
| 1662 | inline void setNumberObjects(int number) |
| 1663 | { numberObjects_=number;} |
| 1664 | |
| 1665 | /// Get the array of objects |
| 1666 | inline OsiObject ** objects() const { return object_;} |
| 1667 | |
| 1668 | /// Get the specified object |
| 1669 | const inline OsiObject * object(int which) const { return object_[which];} |
| 1670 | /// Get the specified object |
| 1671 | inline OsiObject * modifiableObject(int which) const { return object_[which];} |
| 1672 | |
| 1673 | /// Delete all object information |
| 1674 | void deleteObjects(); |
| 1675 | |
| 1676 | /** Add in object information. |
| 1677 | |
| 1678 | Objects are cloned; the owner can delete the originals. |
| 1679 | */ |
| 1680 | void addObjects(int numberObjects, OsiObject ** objects); |
| 1681 | /** Use current solution to set bounds so current integer feasible solution will stay feasible. |
| 1682 | Only feasible bounds will be used, even if current solution outside bounds. The amount of |
| 1683 | such violation will be returned (and if small can be ignored) |
| 1684 | */ |
| 1685 | double forceFeasible(); |
| 1686 | //@} |
| 1687 | //--------------------------------------------------------------------------- |
| 1688 | |
| 1689 | /*! @name Methods related to testing generated cuts |
| 1690 | |
| 1691 | See the documentation for OsiRowCutDebugger for additional details. |
| 1692 | */ |
| 1693 | //@{ |
| 1694 | /*! \brief Activate the row cut debugger. |
| 1695 | |
| 1696 | If \p modelName is in the set of known models then all cuts are |
| 1697 | checked to see that they do NOT cut off the optimal solution known |
| 1698 | to the debugger. |
| 1699 | */ |
| 1700 | virtual void activateRowCutDebugger (const char *modelName); |
| 1701 | |
| 1702 | /*! \brief Activate the row cut debugger using a full solution array. |
| 1703 | |
| 1704 | |
| 1705 | Activate the debugger for a model not included in the debugger's |
| 1706 | internal database. Cuts will be checked to see that they do NOT |
| 1707 | cut off the given solution. |
| 1708 | |
| 1709 | \p solution must be a full solution vector, but only the integer |
| 1710 | variables need to be correct. The debugger will fill in the continuous |
| 1711 | variables by solving an lp relaxation with the integer variables |
| 1712 | fixed as specified. If the given values for the continuous variables |
| 1713 | should be preserved, set \p keepContinuous to true. |
| 1714 | */ |
| 1715 | virtual void activateRowCutDebugger(const double *solution, |
| 1716 | bool enforceOptimality = true); |
| 1717 | |
| 1718 | /*! \brief Get the row cut debugger provided the solution known to the |
| 1719 | debugger is within the feasible region held in the solver. |
| 1720 | |
| 1721 | If there is a row cut debugger object associated with model AND if |
| 1722 | the solution known to the debugger is within the solver's current |
| 1723 | feasible region (i.e., the column bounds held in the solver are |
| 1724 | compatible with the known solution) then a pointer to the debugger |
| 1725 | is returned which may be used to test validity of cuts. |
| 1726 | |
| 1727 | Otherwise NULL is returned |
| 1728 | */ |
| 1729 | const OsiRowCutDebugger *getRowCutDebugger() const; |
| 1730 | |
| 1731 | /*! \brief Get the row cut debugger object |
| 1732 | |
| 1733 | Return the row cut debugger object if it exists. One common usage of |
| 1734 | this method is to obtain a debugger object in order to execute |
| 1735 | OsiRowCutDebugger::redoSolution (so that the stored solution is again |
| 1736 | compatible with the problem held in the solver). |
| 1737 | */ |
| 1738 | OsiRowCutDebugger * getRowCutDebuggerAlways() const; |
| 1739 | //@} |
| 1740 | |
| 1741 | /*! \name OsiSimplexInterface |
| 1742 | \brief Simplex Interface |
| 1743 | |
| 1744 | Methods for an advanced interface to a simplex solver. The interface |
| 1745 | comprises two groups of methods. Group 1 contains methods for tableau |
| 1746 | access. Group 2 contains methods for dictating individual simplex pivots. |
| 1747 | */ |
| 1748 | //@{ |
| 1749 | |
| 1750 | /*! \brief Return the simplex implementation level. |
| 1751 | |
| 1752 | The return codes are: |
| 1753 | - 0: the simplex interface is not implemented. |
| 1754 | - 1: the Group 1 (tableau access) methods are implemented. |
| 1755 | - 2: the Group 2 (pivoting) methods are implemented |
| 1756 | |
| 1757 | The codes are cumulative - a solver which implements Group 2 also |
| 1758 | implements Group 1. |
| 1759 | */ |
| 1760 | virtual int canDoSimplexInterface() const ; |
| 1761 | //@} |
| 1762 | |
| 1763 | /*! \name OsiSimplex Group 1 |
| 1764 | \brief Tableau access methods. |
| 1765 | |
| 1766 | This group of methods provides access to rows and columns of the basis |
| 1767 | inverse and to rows and columns of the tableau. |
| 1768 | */ |
| 1769 | //@{ |
| 1770 | |
| 1771 | /*! \brief Prepare the solver for the use of tableau access methods. |
| 1772 | |
| 1773 | Prepares the solver for the use of the tableau access methods, if |
| 1774 | any such preparation is required. |
| 1775 | |
| 1776 | The \c const attribute is required due to the places this method |
| 1777 | may be called (e.g., within CglCutGenerator::generateCuts()). |
| 1778 | */ |
| 1779 | virtual void enableFactorization() const ; |
| 1780 | |
| 1781 | /*! \brief Undo the effects of #enableFactorization. */ |
| 1782 | virtual void disableFactorization() const ; |
| 1783 | |
| 1784 | /*! \brief Check if an optimal basis is available. |
| 1785 | |
| 1786 | Returns true if the problem has been solved to optimality and a |
| 1787 | basis is available. This should be used to see if the tableau access |
| 1788 | operations are possible and meaningful. |
| 1789 | |
| 1790 | \note |
| 1791 | Implementors please note that this method may be called |
| 1792 | before #enableFactorization. |
| 1793 | */ |
| 1794 | virtual bool basisIsAvailable() const ; |
| 1795 | |
| 1796 | /// Synonym for #basisIsAvailable |
| 1797 | inline bool optimalBasisIsAvailable() const { return basisIsAvailable() ; } |
| 1798 | |
| 1799 | /*! \brief Retrieve status information for column and row variables. |
| 1800 | |
| 1801 | This method returns status as integer codes: |
| 1802 | <ul> |
| 1803 | <li> 0: free |
| 1804 | <li> 1: basic |
| 1805 | <li> 2: nonbasic at upper bound |
| 1806 | <li> 3: nonbasic at lower bound |
| 1807 | </ul> |
| 1808 | |
| 1809 | The #getWarmStart method provides essentially the same functionality |
| 1810 | for a simplex-oriented solver, but the implementation details are very |
| 1811 | different. |
| 1812 | |
| 1813 | \note |
| 1814 | Logical variables associated with rows are all assumed to have +1 |
| 1815 | coefficients, so for a <= constraint the logical will be at lower |
| 1816 | bound if the constraint is tight. |
| 1817 | |
| 1818 | \note |
| 1819 | Implementors may choose to implement this method as a wrapper which |
| 1820 | converts a CoinWarmStartBasis to the requested representation. |
| 1821 | */ |
| 1822 | virtual void getBasisStatus(int* cstat, int* rstat) const ; |
| 1823 | |
| 1824 | /*! \brief Set the status of column and row variables and update |
| 1825 | the basis factorization and solution. |
| 1826 | |
| 1827 | Status information should be coded as documented for #getBasisStatus. |
| 1828 | Returns 0 if all goes well, 1 if something goes wrong. |
| 1829 | |
| 1830 | This method differs from #setWarmStart in the format of the input |
| 1831 | and in its immediate effect. Think of it as #setWarmStart immediately |
| 1832 | followed by #resolve, but no pivots are allowed. |
| 1833 | |
| 1834 | \note |
| 1835 | Implementors may choose to implement this method as a wrapper that calls |
| 1836 | #setWarmStart and #resolve if the no pivot requirement can be satisfied. |
| 1837 | */ |
| 1838 | virtual int setBasisStatus(const int* cstat, const int* rstat) ; |
| 1839 | |
| 1840 | /*! \brief Calculate duals and reduced costs for the given objective |
| 1841 | coefficients. |
| 1842 | |
| 1843 | The solver's objective coefficient vector is not changed. |
| 1844 | */ |
| 1845 | virtual void getReducedGradient(double* columnReducedCosts, |
| 1846 | double* duals, const double* c) const ; |
| 1847 | |
| 1848 | /*! \brief Get a row of the tableau |
| 1849 | |
| 1850 | If \p slack is not null, it will be loaded with the coefficients for |
| 1851 | the artificial (logical) variables (i.e., the row of the basis inverse). |
| 1852 | */ |
| 1853 | virtual void getBInvARow(int row, double* z, double* slack = nullptr) const ; |
| 1854 | |
| 1855 | /*! \brief Get a row of the basis inverse */ |
| 1856 | virtual void getBInvRow(int row, double* z) const ; |
| 1857 | |
| 1858 | /*! \brief Get a column of the tableau */ |
| 1859 | virtual void getBInvACol(int col, double* vec) const ; |
| 1860 | |
| 1861 | /*! \brief Get a column of the basis inverse */ |
| 1862 | virtual void getBInvCol(int col, double* vec) const ; |
| 1863 | |
| 1864 | /*! \brief Get indices of basic variables |
| 1865 | |
| 1866 | If the logical (artificial) for row i is basic, the index should be coded |
| 1867 | as (#getNumCols + i). |
| 1868 | The order of indices must match the order of elements in the vectors |
| 1869 | returned by #getBInvACol and #getBInvCol. |
| 1870 | */ |
| 1871 | virtual void getBasics(int* index) const ; |
| 1872 | |
| 1873 | //@} |
| 1874 | |
| 1875 | /*! \name OsiSimplex Group 2 |
| 1876 | \brief Pivoting methods |
| 1877 | |
| 1878 | This group of methods provides for control of individual pivots by a |
| 1879 | simplex solver. |
| 1880 | */ |
| 1881 | //@{ |
| 1882 | |
| 1883 | /**Enables normal operation of subsequent functions. |
| 1884 | This method is supposed to ensure that all typical things (like |
| 1885 | reduced costs, etc.) are updated when individual pivots are executed |
| 1886 | and can be queried by other methods. says whether will be |
| 1887 | doing primal or dual |
| 1888 | */ |
| 1889 | virtual void enableSimplexInterface(bool doingPrimal) ; |
| 1890 | |
| 1891 | ///Undo whatever setting changes the above method had to make |
| 1892 | virtual void disableSimplexInterface() ; |
| 1893 | /** Perform a pivot by substituting a colIn for colOut in the basis. |
| 1894 | The status of the leaving variable is given in outStatus. Where |
| 1895 | 1 is to upper bound, -1 to lower bound |
| 1896 | Return code was undefined - now for OsiClp is 0 for okay, |
| 1897 | 1 if inaccuracy forced re-factorization (should be okay) and |
| 1898 | -1 for singular factorization |
| 1899 | */ |
| 1900 | virtual int pivot(int colIn, int colOut, int outStatus) ; |
| 1901 | |
| 1902 | /** Obtain a result of the primal pivot |
| 1903 | Outputs: colOut -- leaving column, outStatus -- its status, |
| 1904 | t -- step size, and, if dx!=NULL, *dx -- primal ray direction. |
| 1905 | Inputs: colIn -- entering column, sign -- direction of its change (+/-1). |
| 1906 | Both for colIn and colOut, artificial variables are index by |
| 1907 | the negative of the row index minus 1. |
| 1908 | Return code (for now): 0 -- leaving variable found, |
| 1909 | -1 -- everything else? |
| 1910 | Clearly, more informative set of return values is required |
| 1911 | Primal and dual solutions are updated |
| 1912 | */ |
| 1913 | virtual int primalPivotResult(int colIn, int sign, |
| 1914 | int& colOut, int& outStatus, |
| 1915 | double& t, CoinPackedVector* dx); |
| 1916 | |
| 1917 | /** Obtain a result of the dual pivot (similar to the previous method) |
| 1918 | Differences: entering variable and a sign of its change are now |
| 1919 | the outputs, the leaving variable and its statuts -- the inputs |
| 1920 | If dx!=NULL, then *dx contains dual ray |
| 1921 | Return code: same |
| 1922 | */ |
| 1923 | virtual int dualPivotResult(int& colIn, int& sign, |
| 1924 | int colOut, int outStatus, |
| 1925 | double& t, CoinPackedVector* dx) ; |
| 1926 | //@} |
| 1927 | |
| 1928 | //--------------------------------------------------------------------------- |
| 1929 | |
| 1930 | ///@name Constructors and destructors |
| 1931 | //@{ |
| 1932 | /// Default Constructor |
| 1933 | OsiSolverInterface(); |
| 1934 | |
| 1935 | /** Clone |
| 1936 | |
| 1937 | The result of calling clone(false) is defined to be equivalent to |
| 1938 | calling the default constructor OsiSolverInterface(). |
| 1939 | */ |
| 1940 | virtual OsiSolverInterface * clone(bool copyData = true) const = 0; |
| 1941 | |
| 1942 | /// Copy constructor |
| 1943 | OsiSolverInterface(const OsiSolverInterface &); |
| 1944 | |
| 1945 | /// Assignment operator |
| 1946 | OsiSolverInterface & operator=(const OsiSolverInterface& rhs); |
| 1947 | |
| 1948 | /// Destructor |
| 1949 | virtual ~OsiSolverInterface (); |
| 1950 | |
| 1951 | /** Reset the solver interface. |
| 1952 | |
| 1953 | A call to reset() returns the solver interface to the same state as |
| 1954 | it would have if it had just been constructed by calling the default |
| 1955 | constructor OsiSolverInterface(). |
| 1956 | */ |
| 1957 | virtual void reset(); |
| 1958 | //@} |
| 1959 | |
| 1960 | //--------------------------------------------------------------------------- |
| 1961 | |
| 1962 | protected: |
| 1963 | ///@name Protected methods |
| 1964 | //@{ |
| 1965 | /** Apply a row cut (append to the constraint matrix). */ |
| 1966 | virtual void applyRowCut( const OsiRowCut & rc ) = 0; |
| 1967 | |
| 1968 | /** Apply a column cut (adjust the bounds of one or more variables). */ |
| 1969 | virtual void applyColCut( const OsiColCut & cc ) = 0; |
| 1970 | |
| 1971 | /** A quick inlined function to convert from the lb/ub style of |
| 1972 | constraint definition to the sense/rhs/range style */ |
| 1973 | inline void |
| 1974 | convertBoundToSense(const double lower, const double upper, |
| 1975 | char& sense, double& right, double& range) const; |
| 1976 | /** A quick inlined function to convert from the sense/rhs/range style |
| 1977 | of constraint definition to the lb/ub style */ |
| 1978 | inline void |
| 1979 | convertSenseToBound(const char sense, const double right, |
| 1980 | const double range, |
| 1981 | double& lower, double& upper) const; |
| 1982 | /** A quick inlined function to force a value to be between a minimum and |
| 1983 | a maximum value */ |
| 1984 | template <class T> inline T |
| 1985 | forceIntoRange(const T value, const T lower, const T upper) const { |
| 1986 | return value < lower ? lower : (value > upper ? upper : value); |
| 1987 | } |
| 1988 | /** Set OsiSolverInterface object state for default constructor |
| 1989 | |
| 1990 | This routine establishes the initial values of data fields in the |
| 1991 | OsiSolverInterface object when the object is created using the |
| 1992 | default constructor. |
| 1993 | */ |
| 1994 | void setInitialData(); |
| 1995 | //@} |
| 1996 | |
| 1997 | ///@name Protected member data |
| 1998 | //@{ |
| 1999 | /*! \brief Pointer to row cut debugger object |
| 2000 | |
| 2001 | Mutable so that we can update the solution held in the debugger while |
| 2002 | maintaining const'ness for the Osi object. |
| 2003 | */ |
| 2004 | mutable OsiRowCutDebugger * rowCutDebugger_; |
| 2005 | // Why not just make useful stuff protected? |
| 2006 | /// Message handler |
| 2007 | CoinMessageHandler * handler_; |
| 2008 | /** Flag to say if the currrent handler is the default handler. |
| 2009 | Indicates if the solver interface object is responsible |
| 2010 | for destruction of the handler (true) or if the client is |
| 2011 | responsible (false). |
| 2012 | */ |
| 2013 | bool defaultHandler_; |
| 2014 | /// Messages |
| 2015 | CoinMessages messages_; |
| 2016 | /// Number of integers |
| 2017 | int numberIntegers_; |
| 2018 | /// Total number of objects |
| 2019 | int numberObjects_; |
| 2020 | |
| 2021 | /// Integer and ... information (integer info normally at beginning) |
| 2022 | OsiObject ** object_; |
| 2023 | /** Column type |
| 2024 | 0 - continuous |
| 2025 | 1 - binary (may get fixed later) |
| 2026 | 2 - general integer (may get fixed later) |
| 2027 | */ |
| 2028 | mutable char * columnType_; |
| 2029 | |
| 2030 | //@} |
| 2031 | |
| 2032 | //--------------------------------------------------------------------------- |
| 2033 | |
| 2034 | private: |
| 2035 | ///@name Private member data |
| 2036 | //@{ |
| 2037 | /// Pointer to user-defined data structure - and more if user wants |
| 2038 | OsiAuxInfo * appDataEtc_; |
| 2039 | /// Array of integer parameters |
| 2040 | int intParam_[OsiLastIntParam]; |
| 2041 | /// Array of double parameters |
| 2042 | double dblParam_[OsiLastDblParam]; |
| 2043 | /// Array of string parameters |
| 2044 | std::string strParam_[OsiLastStrParam]; |
| 2045 | /// Array of hint parameters |
| 2046 | bool hintParam_[OsiLastHintParam]; |
| 2047 | /// Array of hint strengths |
| 2048 | OsiHintStrength hintStrength_[OsiLastHintParam]; |
| 2049 | /** Warm start information used for hot starts when the default |
| 2050 | hot start implementation is used. */ |
| 2051 | CoinWarmStart* ws_; |
| 2052 | /// Column solution satisfying lower and upper column bounds |
| 2053 | std::vector<double> strictColSolution_; |
| 2054 | |
| 2055 | /// Row names |
| 2056 | OsiNameVec rowNames_ ; |
| 2057 | /// Column names |
| 2058 | OsiNameVec colNames_ ; |
| 2059 | /// Objective name |
| 2060 | std::string objName_ ; |
| 2061 | |
| 2062 | //@} |
| 2063 | }; |
| 2064 | |
| 2065 | //############################################################################# |
| 2066 | /** A quick inlined function to convert from the lb/ub style of constraint |
| 2067 | definition to the sense/rhs/range style */ |
| 2068 | inline void |
| 2069 | OsiSolverInterface::convertBoundToSense(const double lower, const double upper, |
| 2070 | char& sense, double& right, |
| 2071 | double& range) const |
| 2072 | { |
| 2073 | double inf = getInfinity(); |
| 2074 | range = 0.0; |
| 2075 | if (lower > -inf) { |
| 2076 | if (upper < inf) { |
| 2077 | right = upper; |
| 2078 | if (upper==lower) { |
| 2079 | sense = 'E'; |
| 2080 | } else { |
| 2081 | sense = 'R'; |
| 2082 | range = upper - lower; |
| 2083 | } |
| 2084 | } else { |
| 2085 | sense = 'G'; |
| 2086 | right = lower; |
| 2087 | } |
| 2088 | } else { |
| 2089 | if (upper < inf) { |
| 2090 | sense = 'L'; |
| 2091 | right = upper; |
| 2092 | } else { |
| 2093 | sense = 'N'; |
| 2094 | right = 0.0; |
| 2095 | } |
| 2096 | } |
| 2097 | } |
| 2098 | |
| 2099 | //----------------------------------------------------------------------------- |
| 2100 | /** A quick inlined function to convert from the sense/rhs/range style of |
| 2101 | constraint definition to the lb/ub style */ |
| 2102 | inline void |
| 2103 | OsiSolverInterface::convertSenseToBound(const char sense, const double right, |
| 2104 | const double range, |
| 2105 | double& lower, double& upper) const |
| 2106 | { |
| 2107 | double inf=getInfinity(); |
| 2108 | switch (sense) { |
| 2109 | case 'E': |
| 2110 | lower = upper = right; |
| 2111 | break; |
| 2112 | case 'L': |
| 2113 | lower = -inf; |
| 2114 | upper = right; |
| 2115 | break; |
| 2116 | case 'G': |
| 2117 | lower = right; |
| 2118 | upper = inf; |
| 2119 | break; |
| 2120 | case 'R': |
| 2121 | lower = right - range; |
| 2122 | upper = right; |
| 2123 | break; |
| 2124 | case 'N': |
| 2125 | lower = -inf; |
| 2126 | upper = inf; |
| 2127 | break; |
| 2128 | } |
| 2129 | } |
| 2130 | |
| 2131 | #endif |
| 2132 | |