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
19class CoinPackedMatrix;
20class CoinWarmStart;
21class CoinSnapshot;
22class CoinLpIO;
23class CoinMpsIO;
24
25class OsiCuts;
26class OsiAuxInfo;
27class OsiRowCut;
28class OsiRowCutDebugger;
29class CoinSet;
30class CoinBuild;
31class CoinModel;
32class OsiSolverBranch;
33class OsiSolverResult;
34class 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
60class 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
69public:
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 getStrParam(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
1962protected:
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
2034private:
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 */
2068inline void
2069OsiSolverInterface::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 */
2102inline void
2103OsiSolverInterface::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