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 | |