CouenneFPSolveNLP.cpp
Go to the documentation of this file.
1 /* $Id: CouenneFPSolveNLP.cpp 1058 2014-02-01 13:50:36Z pbelotti $
2  *
3  * Name: CouenneFPSolveNLP.cpp
4  * Authors: Pietro Belotti
5  * Timo Berthold, ZIB Berlin
6  * Purpose: Implement the NLP solution method for the Feasibility Pump
7  *
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #include "CbcModel.hpp"
12 #include "CoinTime.hpp"
13 #include "CoinHelperFunctions.hpp"
14 
15 #include "CouenneFeasPump.hpp"
17 #include "CouenneProblem.hpp"
18 #include "CouenneProblemElem.hpp"
19 #include "CouenneCutGenerator.hpp"
20 
21 #include "CouenneTNLP.hpp"
22 
23 using namespace Ipopt;
24 using namespace Couenne;
25 
27 CouNumber CouenneFeasPump::solveNLP (const CouNumber *iSol, CouNumber *&nSol) {
28 
29  // Solve the continuous nonlinear programming problem
30  //
31  // min f(x)
32  // s.t. g(x) <= 0
33  //
34  // where g(x) are the original constraints and f(x) is one of the
35  // following:
36  //
37  // 1) sum {i in Vars} (x_i - x_i^0)^2
38  // 2) sum {i in I} (x_i - x_i^0)^2
39  // 3) sum {i in Vars} (P^i (x - x^0))^2
40  // 4) sum {i in I} (P^i (x - x^0))^2
41  //
42  // where is x^0 is the optimal solution of a MILP problem. P should
43  // be a PSD matrix, but the Hessian is, in general, indefinite at
44  // the IP point we are starting from. A cheap convexification
45  // consists of computing the minimum eigenvalue lambda_min of H and,
46  // if lambda_min < 0, replace H with
47  //
48  // H - lambda_min I
49  //
50  // Similarly to the MILP case, we have
51  //
52  // P = beta I + (1-beta) (H + lambda_min I)
53  // = (beta + lambda_min (1 - beta)) I + (1-beta) H
54 
55  bool firstNLP = (nlp_ == NULL);
56 
57  if (firstNLP) // first call (in this call to FP). Create NLP
58  nlp_ = new CouenneTNLP (problem_);
59 
60  problem_ -> domain () -> push (problem_ -> nVars (),
61  iSol,
62  problem_ -> domain () -> lb (),
63  problem_ -> domain () -> ub ());
64  //false); // to avoid overlapping with nsol within NLP
65 
66  // set new objective
68  *oldObj = problem_ -> Obj (0) -> Body (),
69  *newObj = updateNLPObj (iSol);
70 
71  newObj -> realign (problem_);
72  problem_ -> setObjective (0, newObj);
73  nlp_ -> setObjective (newObj);
74 
75  if (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC)) {
76  printf ("----------------------- now solving NLP:\n");
77  problem_ -> print ();
78  printf ("-----------------------\n");
79  }
80 
81  // FIXME: probably the previous NLP optimum is a better starting point
82 
83  // compute H_2-closest NLP feasible solution
84  nlp_ -> setInitSol (iSol);
85 
87 
88  ApplicationReturnStatus status = firstNLP ?
89  app_ -> OptimizeTNLP (nlp_) :
90  app_ -> ReOptimizeTNLP (nlp_);
91 
93 
94  if (nlp_ -> getSolution ()) // check if non-NULL
95 
96  if (nSol) CoinCopyN (nlp_ -> getSolution (), problem_ -> nVars (), nSol);
97  else nSol = CoinCopyOfArray (nlp_ -> getSolution (), problem_ -> nVars ());
98 
99  else problem_ -> Jnlst () -> Printf (J_WARNING, J_NLPHEURISTIC, "FP: warning, NLP returns a NULL solution\n");
100 
101  if (nlp_ -> getSolution () && (problem_ -> Jnlst () -> ProduceOutput (J_ALL, J_NLPHEURISTIC))) { // check if non-NULL
102  printf ("######################## NLP solution (nlp):\n");
103  for (int i=0; i< problem_ -> nVars ();) {
104  printf ("%+e ", nSol [i]);
105  if (!(++i % 15)) printf ("\n");
106  }
107  }
108 
109  delete newObj;
110 
111  CouNumber retval;
112 
113  problem_ -> setObjective (0, oldObj);
114 
115  if ((status != Solve_Succeeded) &&
116  (status != Solved_To_Acceptable_Level))
117 
118  problem_ -> Jnlst () -> Printf
119  (J_WARNING, J_NLPHEURISTIC, "Feasibility Pump: Error solving NLP problem\n");
120 
121  retval = nlp_ -> getSolValue ();
122 
123  problem_ -> domain () -> pop ();
124 
125  return retval;
126 }
double CouNumber
main number type in Couenne
const Ipopt::EJournalCategory J_NLPHEURISTIC(Ipopt::J_USER5)
Expression base class.
Class for handling NLPs using CouenneProblem.
Definition: CouenneTNLP.hpp:27