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