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

Last change on this file since 2439 was 2386, checked in by unxusr, 2 years ago

formatting

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