source: stable/1.17/Clp/src/OsiClp/OsiClpSolverInterface.hpp

Last change on this file was 2531, checked in by stefan, 19 months ago

merge r2503,r2504,r2506,r2509..r2512,r2527 from trunk

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