source: branches/devel/Bonmin/src/IpoptInterface/IpoptInterface.hpp @ 26

Last change on this file since 26 was 26, checked in by andreasw, 13 years ago

Fix ticket #2, improve behavior of OA in non-convex problems

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Revision"
File size: 30.0 KB
Line 
1// (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2004
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Pierre Bonami, Carnegie Mellon University,
7// Carl D. Laird, Carnegie Mellon University,
8// Andreas Waechter, International Business Machines Corporation
9//
10// Date : 12/01/2004
11
12
13#ifndef IpoptInterface_H
14#define IpoptInterface_H
15
16#include <string>
17#include <iostream>
18
19#include "OsiSolverInterface.hpp"
20#include "CoinWarmStartBasis.hpp"
21
22#include "TMINLP.hpp"
23#include "TMINLP2TNLP.hpp"
24#include "TNLP2FPNLP.hpp"
25
26#include "IpIpoptApplication.hpp"
27
28
29/**
30   This is class provides an Osi interface for Ipopt
31   (so that we can use it for example as the continuous solver in Cbc).
32*/
33
34class IpoptInterface : public OsiSolverInterface
35{
36  friend class BonminParam;
37
38public:
39
40  //#############################################################################
41
42  /**Error class to throw exceptions from IpoptInterface.
43   * Inherited from CoinError, we just want to have a different class to be able to catch
44   * errors thrown by IpoptInterface.
45  */
46class SimpleError : public CoinError
47  {
48  public:
49    /// Default constructor
50    SimpleError() : CoinError()
51    {}
52
53    ///Alternate constructor using strings
54    SimpleError(std::string message,
55        std::string methodName)
56        :
57        CoinError(message,methodName,std::string("IpoptInterface"))
58    {}
59    ///Alternate constructor using const char *
60    SimpleError (const char * message,
61        const char * methodName)
62        :
63        CoinError(message,methodName,"IpoptInterface")
64    {}
65
66  }
67  ;
68
69  //#############################################################################
70
71  /** We will throw this error when a problem is not solved.
72      Eventually store the error code from Ipopt*/
73  class UnsolvedError
74  {
75  public:
76    /** Constructor */
77    UnsolvedError(int errorNum_ = 10000);
78    /** Print error message.*/
79    void printError(std::ostream & os);
80    /** Get the string corresponding to error.*/
81    const std::string& errorName() const;
82  private:
83    int errorNum_;
84    static std::string errorNames [17];
85  }
86  ;
87
88
89  //#############################################################################
90
91
92  /** Type of the messages specifically outputed by IpoptInterface.*/
93  enum MessagesTypes{
94    SOLUTION_FOUND/**found a feasible solution*/,
95    INFEASIBLE_SOLUTION_FOUND/**found an infeasible problem*/,
96    UNSOLVED_PROBLEM_FOUND/**found an unsolved problem*/,
97    WARNING_RESOLVING /** Warn that a problem is resolved*/,
98    WARN_SUCCESS_WS/** Problem not solved with warm start but solved without*/,
99    WARN_SUCCESS_RANDOM/** Subproblem not solve with warm start but solved with random point*/,
100    WARN_CONTINUING_ON_FAILURE/** a failure occured but is continuing*/,
101    SUSPECT_PROBLEM/** Output the number of the problem.*/,
102    SUSPECT_PROBLEM2/** Output the number of the problem.*/,
103    IPOPT_SUMMARY /** Output summary statistics on Ipopt solution.*/,
104    BETTER_SOL /** Found a better solution with random values.*/,
105    LOG_HEAD/** Head of "civilized" log.*/,
106    LOG_FIRST_LINE/** First line (first solve) of log.*/,
107    LOG_LINE/**standard line (retry solving) of log.*/,
108    WARN_RESOLVE_BEFORE_INITIAL_SOLVE /** resolve() has been called but there
109                                              was no previous call to initialSolve().
110                                         */,
111    IPOTPINTERFACE_DUMMY_END
112  };
113
114  //#############################################################################
115
116
117  /** Messages outputed by an IpoptInterface. */
118class Messages : public CoinMessages
119  {
120  public:
121    /// Constructor
122    Messages();
123  };
124
125
126  //#############################################################################
127
128
129  /**@name Constructors and destructors */
130  //@{
131  /// Default Constructor
132  IpoptInterface();
133  /** Constructor with given (user) TMINLP.
134    \warning In this constructor option file is not read, use readOptionFile to read one.
135  */
136  IpoptInterface (Ipopt::SmartPtr<Ipopt::TMINLP> tminlp);
137
138  /// Clone
139  virtual OsiSolverInterface * clone(bool CopyData=true) const;
140
141  /** Copy constructor
142  */
143  IpoptInterface (const IpoptInterface &);
144
145  /// Assignment operator
146  IpoptInterface & operator=(const IpoptInterface& rhs);
147
148  /// Destructor
149  virtual ~IpoptInterface ();
150
151
152  /// Retrieve IpoptApplication option list
153  Ipopt::SmartPtr<Ipopt::OptionsList> retrieve_options();
154
155  /** Register all possible options to Ipopt */
156  void register_ALL_options (Ipopt::SmartPtr<Ipopt::RegisteredOptions> roptions);
157
158  /** Set specific Ipopt default for MINLP's */
159  void set_ipopt_minlp_default(SmartPtr<OptionsList> Options);
160
161  /// Read parameter file
162  void readOptionFile(const char * fileName);
163  //@}
164
165  void extractInterfaceParams();
166
167  //---------------------------------------------------------------------------
168  /**@name Solve methods */
169  //@{
170  /// Solve initial continuous relaxation
171  virtual void initialSolve();
172
173  /** Resolve the continuous relaxation after problem modification.
174      Have to call initialSolve before calling this
175   */
176  virtual void resolve();
177
178  /** Resolve the problem with different random starting points
179      to try to find a better solution (only makes sense for a non-convex problem.*/
180  void resolveForCost(int numretry);
181
182  /** Method to be called when a problem has failed to be solved. Will try
183      to resolve it with different settings.
184  */
185  void resolveForRobustness(int numretry);
186
187  /// Nescessary for compatibility with OsiSolverInterface but does nothing.
188  virtual void branchAndBound()
189  {
190    throw SimpleError("Function not implemented for IpoptInterface","branchAndBound()");
191  }
192  //@}
193
194
195
196  //---------------------------------------------------------------------------
197  ///@name Methods returning info on how the solution process terminated
198  //@{
199  /// Are there a numerical difficulties?
200  virtual bool isAbandoned() const;
201  /// Is optimality proven?
202  virtual bool isProvenOptimal() const;
203  /// Is primal infeasiblity proven?
204  virtual bool isProvenPrimalInfeasible() const;
205  /// Is dual infeasiblity proven?
206  virtual bool isProvenDualInfeasible() const;
207  /// Is the given primal objective limit reached?
208  virtual bool isPrimalObjectiveLimitReached() const;
209  /// Is the given dual objective limit reached?
210  virtual bool isDualObjectiveLimitReached() const;
211  /// Iteration limit reached?
212  virtual bool isIterationLimitReached() const;
213  /// Return status of last optimization
214  Ipopt::ApplicationReturnStatus getOptStatus() const
215  {
216    return optimization_status_;
217  }
218
219  ///Warn solver that branch-and-bound is continuing after a failure
220  void continuingOnAFailure()
221  {
222    hasContinuedAfterNlpFailure_ = true;
223  }
224  /// Did we continue on a failure
225  bool hasContinuedOnAFailure()
226  {
227    return hasContinuedAfterNlpFailure_;
228  }
229  /// tell to ignore the failures (don't throw, don't fathom, don't report)
230  void ignoreFailures()
231  {
232    pretendFailIsInfeasible_ = 2;
233  }
234  /// Force current solution to be infeasible
235  void forceInfeasible()
236  {
237    problem_->set_obj_value(1e200);
238  }
239  /// Force current solution to be branched on (make it fractionnal with small objective)
240  void forceBranchable()
241  {
242    problem_->set_obj_value(-1e200);
243    problem_->force_fractionnal_sol();
244  }
245  //@}
246
247
248  //---------------------------------------------------------------------------
249  /**@name Parameter set/get methods
250
251     The set methods return true if the parameter was set to the given value,
252     false otherwise. There can be various reasons for failure: the given
253     parameter is not applicable for the solver (e.g., refactorization
254     frequency for the clp algorithm), the parameter is not yet implemented
255     for the solver or simply the value of the parameter is out of the range
256     the solver accepts. If a parameter setting call returns false check the
257     details of your solver.
258
259     The get methods return true if the given parameter is applicable for the
260     solver and is implemented. In this case the value of the parameter is
261     returned in the second argument. Otherwise they return false.
262  */
263  //@{
264  // Set an integer parameter
265  bool setIntParam(OsiIntParam key, int value);
266  // Set an double parameter
267  bool setDblParam(OsiDblParam key, double value);
268  // Set a string parameter
269  bool setStrParam(OsiStrParam key, const std::string & value);
270  // Get an integer parameter
271  bool getIntParam(OsiIntParam key, int& value) const;
272  // Get an double parameter
273  bool getDblParam(OsiDblParam key, double& value) const;
274  // Get a string parameter
275  bool getStrParam(OsiStrParam key, std::string& value) const;
276
277  // Get the push values for starting point
278  inline double getPushFact() const
279  {
280    return pushValue_;
281  }
282
283  //@}
284
285  //---------------------------------------------------------------------------
286  /**@name Problem information methods
287
288     These methods call the solver's query routines to return
289     information about the problem referred to by the current object.
290     Querying a problem that has no data associated with it result in
291     zeros for the number of rows and columns, and NULL pointers from
292     the methods that return vectors.
293
294     Const pointers returned from any data-query method are valid as
295     long as the data is unchanged and the solver is not called.
296  */
297  //@{
298  /**@name Methods related to querying the input data */
299  //@{
300  /// Get number of columns
301  virtual int getNumCols() const;
302
303  /// Get number of rows
304  virtual int getNumRows() const;
305
306  ///get name of variables
307  const std::string * getVarNames() const;
308  /// Get pointer to array[getNumCols()] of column lower bounds
309  virtual const double * getColLower() const;
310
311  /// Get pointer to array[getNumCols()] of column upper bounds
312  virtual const double * getColUpper() const;
313
314  /** Get pointer to array[getNumRows()] of row constraint senses.
315      <ul>
316      <li>'L': <= constraint
317      <li>'E': =  constraint
318      <li>'G': >= constraint
319      <li>'R': ranged constraint
320      <li>'N': free constraint
321      </ul>
322  */
323  virtual const char * getRowSense() const;
324
325  /** Get pointer to array[getNumRows()] of rows right-hand sides
326      <ul>
327      <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i]
328      <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i]
329      <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i]
330      <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0
331      </ul>
332  */
333  virtual const double * getRightHandSide() const;
334
335  /** Get pointer to array[getNumRows()] of row ranges.
336      <ul>
337      <li> if rowsense()[i] == 'R' then
338      rowrange()[i] == rowupper()[i] - rowlower()[i]
339      <li> if rowsense()[i] != 'R' then
340      rowrange()[i] is 0.0
341      </ul>
342  */
343  virtual const double * getRowRange() const;
344
345  /// Get pointer to array[getNumRows()] of row lower bounds
346  virtual const double * getRowLower() const;
347
348  /// Get pointer to array[getNumRows()] of row upper bounds
349  virtual const double * getRowUpper() const;
350
351  /** Get objective function sense (1 for min (default), -1 for max)
352   * Ipopt always minimizes */
353  virtual double getObjSense() const
354  {
355    return 1;
356  }
357
358  /// Return true if column is continuous
359  virtual bool isContinuous(int colNumber) const;
360
361  /// Return true if column is binary
362  virtual bool isBinary(int columnNumber) const;
363
364  /** Return true if column is integer.
365      Note: This function returns true if the the column
366      is binary or a general integer.
367  */
368  virtual bool isInteger(int columnNumber) const;
369
370  /// Return true if column is general integer
371  virtual bool isIntegerNonBinary(int columnNumber) const;
372
373  /// Return true if column is binary and not fixed at either bound
374  virtual bool isFreeBinary(int columnNumber) const;
375
376  /// Get solver's value for infinity
377  virtual double getInfinity() const;
378
379  ///Get priorities on integer variables.
380  const int * getPriorities() const
381  {
382    const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
383    if(branch)
384      return branch->priorities;
385    else return NULL;
386  }
387  ///get prefered branching directions
388  const int * getBranchingDirections() const
389  {
390    const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
391    if(branch)
392      return branch->branchingDirections;
393    else return NULL;
394  }
395  const double * getUpPsCosts() const
396  {
397    const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
398    if(branch)
399    return branch->upPsCosts;
400    else return NULL;
401  }
402  const double * getDownPsCosts() const
403  {
404    const Ipopt::TMINLP::BranchingInfo * branch = tminlp_->branchingInfo();
405    if(branch)
406    return branch->downPsCosts;
407    else return NULL;
408  }
409
410
411  //@}
412
413  /**@name Methods related to querying the solution */
414  //@{
415  /// Get pointer to array[getNumCols()] of primal solution vector
416  virtual const double * getColSolution() const;
417
418  /// Get pointer to array[getNumRows()] of dual prices
419  virtual const double * getRowPrice() const;
420
421  /// Get a pointer to array[getNumCols()] of reduced costs
422  virtual const double * getReducedCost() const;
423
424  /** Get pointer to array[getNumRows()] of row activity levels (constraint
425      matrix times the solution vector */
426  virtual const double * getRowActivity() const;
427
428
429  /** Get how many iterations it took to solve the problem (whatever
430      "iteration" mean to the solver.
431      * \todo Figure out what it could mean for Ipopt.
432      */
433  virtual int getIterationCount() const;
434
435  /** get total number of calls to solve.*/
436  int nCallOptimizeTNLP()
437  {
438    return nCallOptimizeTNLP_;
439  }
440  /** get total time taken to solve NLP's. */
441  double totalNlpSolveTime()
442  {
443    return totalNlpSolveTime_;
444  }
445  /** get total number of iterations */
446  int totalIterations()
447  {
448    return totalIterations_;
449  }
450
451
452  //@}
453  //-------------------------------------------------------------------------
454  /**@name Methods to modify the objective, bounds, and solution
455  */
456  //@{
457
458  /** Set a single column lower bound.
459      Use -getInfinity() for -infinity. */
460  virtual void setColLower( int elementIndex, double elementValue );
461
462  /** Set a single column upper bound.
463      Use getInfinity() for infinity. */
464  virtual void setColUpper( int elementIndex, double elementValue );
465
466
467
468  /** Set a single row lower bound.
469      Use -getInfinity() for -infinity. */
470  virtual void setRowLower( int elementIndex, double elementValue );
471
472  /** Set a single row upper bound.
473      Use getInfinity() for infinity. */
474  virtual void setRowUpper( int elementIndex, double elementValue );
475
476  /** Set the type of a single row */
477  virtual void setRowType(int index, char sense, double rightHandSide,
478      double range);
479
480
481  /** \brief Set the objective function sense (disabled).
482   * (1 for min (default), -1 for max)
483   \todo Make it work.
484   \bug Can not treat maximisation problems. */
485  virtual void setObjSense(double s);
486
487  /** Set the primal solution variable values
488      Set the values for the starting point.
489      \warning getColSolution will never return this vector (unless it is optimal).
490  */
491  virtual void setColSolution(const double *colsol);
492
493  /** Set dual solution variable values.
494      set the values for the starting point.
495      \warning getRowPrice will never return this vector (unless it is optimal).
496  */
497  virtual void setRowPrice(const double * rowprice);
498
499  //@}
500
501
502  //---------------------------------------------------------------------------
503  /**@name WarmStart related methods (those should really do nothing for the moment)*/
504  //@{
505
506  /*! \brief Get an empty warm start object
507
508  This routine returns an empty CoinWarmStartBasis object. Its purpose is
509  to provide a way to give a client a warm start basis object of the
510  appropriate type, which can resized and modified as desired.
511  */
512  CoinWarmStart *getEmptyWarmStart () const;
513
514  /** Get warmstarting information */
515  virtual CoinWarmStart* getWarmStart() const;
516
517  /** Set warmstarting information. Return true/false depending on whether
518      the warmstart information was accepted or not. */
519  virtual bool setWarmStart(const CoinWarmStart* warmstart);
520
521
522  void setWarmStartOptions()
523  {
524    //    app_->Options()->SetIntegerValue("warm_start_init_point", 1);
525    app_->Options()->SetStringValue("warm_start_init_point", "yes");
526  }
527  void unsetWarmStartOptions()
528  {
529    //app_->Options()->SetIntegerValue("warm_start_init_point", 1);
530    app_->Options()->SetStringValue("warm_start_init_point", "no");
531    problem_->resetStartingPoint();
532  }
533
534  void randomStartingPoint();
535
536  //Returns true if a basis is available
537  virtual bool basisIsAvailable() const
538  {
539    // Throw an exception
540    throw SimpleError("Needs coding for this interface", "basisIsAvailable");
541  }
542
543
544  //@}
545
546  //-------------------------------------------------------------------------
547  /**@name Methods to set variable type */
548  //@{
549  /** Set the index-th variable to be a continuous variable */
550  virtual void setContinuous(int index);
551  /** Set the index-th variable to be an integer variable */
552  virtual void setInteger(int index);
553  //@}
554
555  //Set numIterationSuspect_
556  void setNumIterationSuspect(int value)
557  {
558    numIterationSuspect_ = value;
559  }
560
561  /**@name Dummy functions
562   * Functions which have to be implemented in an OsiSolverInterface,
563   * but which do not do anything (but throwing exceptions) here in the case of a
564   * minlp solved using Ipopt for continuous relaxations */
565  //@{
566
567  /** Cbc will understand that no matrix exsits if return -1
568  */
569  virtual int getNumElements() const
570  {
571    return -1;
572  }
573
574
575  /** We have to keep this but it will throw an error.
576  */
577  virtual const double * getObjCoefficients() const
578  {
579    if(!obj_)
580      throw SimpleError("Ipopt model does not implement this function (function irelevant in an minlp).",
581          "getObjCoefficients");
582    return obj_;
583  }
584
585  /** We have to keep this but it will throw an error.
586   */
587  virtual const CoinPackedMatrix * getMatrixByRow() const
588  {
589    throw CoinError("Ipopt model does not implement this function.",
590        "getMatrixByRow()","IpoptInterface");
591  }
592
593
594  /** We have to keep this but it will throw an error.
595   */
596  virtual const CoinPackedMatrix * getMatrixByCol() const
597  {
598    throw CoinError("Ipopt model does not implement this function.",
599        "getMatrixByCol()","IpoptInterface");
600  }
601
602  /** We have to keep this but it will throw an error.
603  */
604  virtual void setObjCoeff( int elementIndex, double elementValue )
605  {
606    throw CoinError("Ipopt model does not implement this function.",
607        "setObjCoeff","IpoptInterface");
608  }
609
610  /** We have to keep this but it will throw an error.
611  */
612  virtual void addCol(const CoinPackedVectorBase& vec,
613      const double collb, const double colub,
614      const double obj)
615  {
616    throw CoinError("Ipopt model does not implement this function.",
617        "addCol","IpoptInterface");
618  }
619  /** We have to keep this but it will throw an error.
620  */
621  virtual void deleteCols(const int num, const int * colIndices)
622  {
623    throw CoinError("Ipopt model does not implement this function.",
624        "deleteCols","IpoptInterface");
625  }
626
627  /** We have to keep this but it will throw an error.
628  */
629  virtual void addRow(const CoinPackedVectorBase& vec,
630      const double rowlb, const double rowub)
631  {
632    throw CoinError("Ipopt model does not implement this function.",
633        "addRow","IpoptInterface");
634  }
635  /** We have to keep this but it will throw an error.
636  */
637  virtual void addRow(const CoinPackedVectorBase& vec,
638      const char rowsen, const double rowrhs,
639      const double rowrng)
640  {
641    throw CoinError("Ipopt model does not implement this function.",
642        "addRow","IpoptInterface");
643  }
644  /** We have to keep this but it will throw an error.
645  */
646  virtual void deleteRows(const int num, const int * rowIndices)
647  {
648    if(num>0)
649      throw CoinError("Ipopt model does not implement this function.",
650          "deleteRows","IpoptInterface");
651  }
652
653  /** We have to keep this but it will throw an error
654  */
655  virtual void loadProblem(const CoinPackedMatrix& matrix,
656      const double* collb, const double* colub,
657      const double* obj,
658      const double* rowlb, const double* rowub)
659  {
660    throw CoinError("Ipopt model does not implement this function.",
661        "loadProblem","IpoptInterface");
662  }
663
664
665  /** We have to keep this but it will throw an error.
666  */
667  virtual void assignProblem(CoinPackedMatrix*& matrix,
668      double*& collb, double*& colub, double*& obj,
669      double*& rowlb, double*& rowub)
670  {
671    throw CoinError("Ipopt model does not implement this function.",
672        "assignProblem","IpoptInterface");
673  }
674
675  /** We have to keep this but it will throw an error.
676  */
677  virtual void loadProblem(const CoinPackedMatrix& matrix,
678      const double* collb, const double* colub,
679      const double* obj,
680      const char* rowsen, const double* rowrhs,
681      const double* rowrng)
682  {
683    throw CoinError("Ipopt model does not implement this function.",
684        "loadProblem","IpoptInterface");
685  }
686
687  /** We have to keep this but it will throw an error.
688  */
689  virtual void assignProblem(CoinPackedMatrix*& matrix,
690      double*& collb, double*& colub, double*& obj,
691      char*& rowsen, double*& rowrhs,
692      double*& rowrng)
693  {
694    throw CoinError("Ipopt model does not implement this function.",
695        "assignProblem","IpoptInterface");
696  }
697
698
699  /** We have to keep this but it will throw an error.
700  */
701  virtual void loadProblem(const int numcols, const int numrows,
702      const int* start, const int* index,
703      const double* value,
704      const double* collb, const double* colub,
705      const double* obj,
706      const double* rowlb, const double* rowub)
707  {
708    throw CoinError("Ipopt model does not implement this function.",
709        "loadProblem","IpoptInterface");
710  }
711
712  /** We have to keep this but it will throw an error.
713  */
714  virtual void loadProblem(const int numcols, const int numrows,
715      const int* start, const int* index,
716      const double* value,
717      const double* collb, const double* colub,
718      const double* obj,
719      const char* rowsen, const double* rowrhs,
720      const double* rowrng)
721  {
722    throw CoinError("Ipopt model does not implement this function.",
723        "loadProblem","IpoptInterface");
724  }
725
726  /** We have to keep this but it will throw an error.
727  */
728  virtual int readMps(const char *filename,
729      const char *extension = "mps")
730  {
731    throw CoinError("Ipopt model does not implement this function.",
732        "readMps","IpoptInterface");
733  }
734
735
736  /** We have to keep this but it will throw an error.
737  */
738  virtual void writeMps(const char *filename,
739      const char *extension = "mps",
740      double objSense=0.0) const
741  {
742    throw CoinError("Ipopt model does not implement this function.",
743        "writeMps","IpoptInterface");
744  }
745
746  /** Throws an error */
747  virtual std::vector<double*> getDualRays(int maxNumRays) const
748  {
749    throw SimpleError("Ipopt model does not implement this function.",
750        "getDualRays");
751  }
752
753  /** Throws an error */
754  virtual std::vector<double*> getPrimalRays(int maxNumRays) const
755  {
756    throw CoinError("Ipopt model does not implement this function.",
757        "getPrimalRays","IpoptInterface");
758  }
759
760  //@}
761
762  //---------------------------------------------------------------------------
763
764
765
766  /**@name Control of Ipopt output
767   */
768  //@{
769  void turnOffIpoptOutput();
770  void turnOnIpoptOutput();
771  //@}
772
773  /**@name Sets and Getss */
774  //@{
775  /// Get objective function value (can't use default)
776  virtual double getObjValue() const;
777
778  //@}
779
780  /** get pointer to the TMINLP2TNLP adapter */
781  const Ipopt::TMINLP2TNLP * problem() const
782  {
783    return GetRawPtr(problem_);
784  }
785
786  const Ipopt::TMINLP * model() const
787  {
788    return GetRawPtr(tminlp_);
789  }
790 
791  /** Methods to build outer approximations */
792  //@{
793  /** \brief Extract a linear relaxation of the MINLP.
794   * Solve the continuous relaxation and takes first-order outer-approximation constraints at the optimum.
795   * The put everything in an OsiSolverInterface.
796   */
797  void extractLinearRelaxation(OsiSolverInterface &si, bool getObj = 1);
798
799  /** Get the outer approximation constraints at the currently stored optimal point.
800   (Only get outer-approximations of nonlinear constraints of the problem.)*/
801  void getOuterApproximation(OsiCuts &cs, bool getObj = 1);
802
803  /** solve the problem of finding the closest point to x_bar in the subspace of coordinates given by ind
804   * (i.e., \f$ min \sum\limits_{i=1}^n (x_{ind[i]} -\overline{x}_i)^2 \f$ ,
805   * and get the corresponding outer-approximation constraints.
806      (Only get outer-approximations of nonlinear constraints of the problem.)
807   * \return Distance between feasibility set and x
808   * \param n number of element in arrays x and ind
809   * \param ind indices of the coordinate*/
810  double getFeasibilityOuterApproximation(int n, const double * x_bar,const int *ind, OsiCuts &cs);
811  //@}
812  /** get NLP constraint violation of current point */
813  double getConstraintViolation();
814
815//---------------------------------------------------------------------------
816protected:
817
818  /// Initialize data structures for storing the jacobian
819  int initializeJacobianArrays();
820
821  ///@name Virtual callbacks for application specific stuff
822  //@{
823  virtual std::string  appName()
824  {
825    return "bonmin";
826  }
827  //@}
828  ///@name Protected methods
829  //@{
830
831  /** Call Ipopt to solve or resolve the problem and check for errors.*/
832  void solveAndCheckErrors(bool doResolve, bool throwOnFailure,
833      const char * whereFrom);
834
835
836  /** We have to keep this but it will throw an error.
837  */
838  virtual void applyRowCut( const OsiRowCut & rc )
839  {
840    throw SimpleError("Ipopt model does not implement this function.",
841        "applyRowCut");
842  }
843  /** We have to keep this but it will throw an error.
844  */
845  virtual void applyColCut( const OsiColCut & cc )
846  {
847    throw SimpleError("Ipopt model does not implement this function.",
848        "applyColCut");
849  }
850
851  /** Read the name of the variables in an ampl .col file. */
852  void readVarNames() const;
853
854  //@}
855
856  /**@name Ipopt structures */
857  //@{
858  /** TMINLP model.*/
859  Ipopt::SmartPtr<Ipopt::TMINLP> tminlp_;
860  /** Adapter for a MINLP to a NLP */
861  Ipopt::SmartPtr<Ipopt::TMINLP2TNLP> problem_;
862  /** IpoptApplication */
863  Ipopt::SmartPtr<Ipopt::IpoptApplication> app_;
864  //@}
865
866  /**@name Cached information on the problem */
867  //@{
868  /** Free cached data relative to variables */
869  void freeCachedColRim();
870  /** Free cached data relative to constraints */
871  void freeCachedRowRim();
872  /** Free all cached data*/
873  void freeCachedData();
874  /** Extract rowsense_ vector rhs_ vector and rowrange_ vector from the lower and upper bounds
875   *  on the constraints */
876  void extractSenseRhsAndRange() const;
877  /// Pointer to dense vector of row sense indicators
878  mutable char    *rowsense_;
879
880  /// Pointer to dense vector of row right-hand side values
881  mutable double  *rhs_;
882
883  /// Pointer to dense vector of slack upper bounds for range constraints (undefined for non-range rows)
884  mutable double  *rowrange_;
885  /** Pointer to dense vector of reduced costs
886      \warning Always 0. with Ipopt*/
887  mutable double  *reducedCosts_;
888  /** DualObjectiveLimit is used to store the cutoff in Cbc*/
889  double OsiDualObjectiveLimit_;
890  /** Return status of the Ipopt optimization */
891  Ipopt::ApplicationReturnStatus optimization_status_;
892  /** Variable names */
893  mutable std::string * varNames_;
894  /** does the file variable names exists (will check automatically).*/
895  mutable bool hasVarNamesFile_;
896  //@}
897  /// number of time NLP has been solved
898  int nCallOptimizeTNLP_;
899  /// Total solution time of NLP
900  double totalNlpSolveTime_;
901  /// toatal number of iterations
902  int totalIterations_;
903  /// max radius for random point
904  double maxRandomRadius_;
905  /// Ipopt value for pushing initial point inside the bounds
906  double pushValue_;
907  /// Number of times problem will be resolved in initialSolve (root node)
908  int numRetryInitial_;
909  /// Number of times problem will be resolved in resolve
910  int numRetryResolve_;
911  /// Number of times problem will be resolved in case of a failure
912  int numRetryUnsolved_;
913  /** Messages specific to an IpoptInterface. */
914  Messages ipoptIMessages_;
915  /** If not 0 when a problem is not solved (failed to be solved)
916      will pretend that it is infeasible. If == 1 will care
917      (i.e. record the fact issue messages to user), if ==2 don't care (somebody else will) */
918  int pretendFailIsInfeasible_;
919  /** did we ever continue optimization ignoring a failure. */
920  bool hasContinuedAfterNlpFailure_;
921  /** number iterations above which a problem is considered suspect (-1 is considered \f$+ \infty \f$).
922        If in a call to solve a problem takes more than that number of iterations it will be outputed to files.*/
923  int numIterationSuspect_ ;
924  /** Has problem been optimized since last change (include setColSolution).
925     If yes getColSolution will return Ipopt point, otherwise will return
926     initial point.*/
927  bool hasBeenOptimized_;
928  /** Warm start strategy :
929  <ol>
930  <li> no warm start,</li>
931  <li> simple warm start (optimal point),</li>
932  <li> more elaborate strategies (interior point...).</li>
933  </ol>
934  */
935  int warmStartStrategy_;
936  /** A fake objective function (all variables to 1) to please Cbc pseudo costs initialization.*/
937  double * obj_;
938  /** flag to say wether options have been printed or not.*/
939  static bool hasPrintedOptions;
940
941  /** Adapter for TNLP to a feasibility problem */
942  Ipopt::SmartPtr<Ipopt::TNLP2FPNLP> feasibilityProblem_;
943
944
945  /** \name Arrays to store Jacobian matrix */
946  //@{
947  /** Row indices.*/
948  int * jRow_;
949  /** Column indices.*/
950  int * jCol_;
951  /** Values */
952  double * jValues_;
953  /** Number of elements.*/
954  int nnz_jac;
955  //@}
956
957  ///Store the types of the constraints (linear and nonlinear).
958  Ipopt::TMINLP::ConstraintType * constTypes_;
959  /* Numerotation of linear/nonlinear constraints
960   * Perform independent numerotation of linear (resp. nonlinear constraints)
961   * so that constraints of each type are numeroted consecutively */
962 // int * constTypesNum_;
963  /** Number of linear constraints */
964  int nLinear_;
965  /** Number of nonlinear constraint
966   */
967  int nNonLinear_;
968  /** Value for small non-zero element which we will try to remove cleanly in OA cuts.*/
969  double tiny_;
970  /** Value for small non-zero element which we will take the risk to ignore in OA cuts.*/
971  double veryTiny_;
972  /** Value for infinity. */
973  double infty_;
974
975};
976
977#endif
Note: See TracBrowser for help on using the repository browser.