BonTNLPSolver.cpp
Go to the documentation of this file.
1 // (C) Copyright International Business Machines Corporation, 2006
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // Pierre Bonami, International Business Machines Corporation
7 //
8 // Date : 10/02/2006
9 
10 //Bonmin includes
11 #include "BonTNLPSolver.hpp"
12 
13 //Ipopt includes
14 #include "IpBlas.hpp"
15 
16 //Standard includes
17 #include <fstream>
18 
19 #include "BonColReader.hpp"
20 
21 
22 namespace Bonmin{
23  using namespace Ipopt;
24 
25 
26 #if 0
27  string TNLPSolver::returnCodes[TNLPSolver::numReturnCodes] = {
28  "Hit iteration limit" ,
29  "Some error was made in computations." ,
30  "Problem has more equations than free variables." ,
31  "Problem is not well defined.",
32  "Illegal option set.",
33  "Exception in some the third-party code used by solver." ,
34  "Unrecognized exception.",
35  "Problem solved to optimality",
36  "Problem solvedd to acceptable level of tolerance",
37  "Problem is infeasible" ,
38  "Problem is unbounded", };
39 #endif
40 
41 
43  start_time_(0),
44  time_limit_(DBL_MAX)
45  {
47  }
48 
52  const std::string & prefix):
53  journalist_(journalist),
54  options_(options),
55  roptions_(roptions),
56  prefix_(prefix),
57  start_time_(0),
58  time_limit_(DBL_MAX)
59  {
60  }
61 
63  journalist_(other.journalist_),
64  options_(NULL),
65  roptions_(other.roptions_),
66  prefix_(other.prefix_),
67  start_time_(other.start_time_),
68  time_limit_(other.time_limit_){
69  options_ = new Ipopt::OptionsList();
70  *options_ = *other.options_;
71  }
72 
74  {}
75 
76 
77  bool
79  {
80 
81  int n,m,dum1, dum2;
82  Ipopt::TNLP::IndexStyleEnum dum3;
83  tnlp->get_nlp_info(n,m,dum1, dum2, dum3);
84  double * x_l = new double[n];
85  double * x_u = new double[n];
86 
87  double * g_l = (m>0) ? new double[m] : NULL;
88  double * g_u = (m >0) ? new double[m] : NULL;
89 
90  tnlp->get_bounds_info(n, x_l, x_u, m, g_l , g_u);
91 
92 
93  for(int i = 0 ; i < n ; i++) {
94  if(x_u[i] - x_l[i] > 1e-5)
95  {
96  delete [] x_l;
97  delete [] x_u;
98  if(m > 0){
99  delete [] g_l;
100  delete [] g_u;
101  }
102  return 0;
103  }
104  }
105 
106  //Problem has no variables just check if the unique solution given by the bounds is
107  // feasible or not.
108  double obj_value;
109 
110  tnlp->eval_f(n, x_l, true, obj_value);
111 
112  double * x_sol = new double[n];
113 
114 
115  IpBlasDcopy(n, x_l, 1, x_sol, 1);
116 
117  delete [] x_l;
118  delete [] x_u;
119 
120  double * g_sol = (m > 0) ? new double [m] : NULL;
121 
122  tnlp->eval_g(n, x_sol, true, m, g_sol);
123 
124  optimizationStatus = solvedOptimal;
125  for(int i = 0 ; i < m ; i++) {
126  if(g_sol[i] - g_l[i] < - 1e-07 || g_sol[i] - g_u[i] > 1e-07) {
127  optimizationStatus = provenInfeasible;
128 
129  delete [] g_l;
130  delete [] g_u;
131  double * lam = (m > 0) ? new double[m]: NULL;
132  CoinFillN(lam,m,0.);
133  double * z = new double[n];
134  CoinFillN(z,n,0.);
135  tnlp->finalize_solution(Ipopt::LOCAL_INFEASIBILITY,
136  n, x_sol, NULL, NULL,
137  m, g_sol, NULL, obj_value, NULL, NULL);
138  if (m > 0) delete [] lam;
139  delete [] z;
140  if (m > 0) delete [] g_sol;
141  delete [] x_sol;
142 
143  return 1;
144  }
145  }
146  if (m > 0) delete [] g_l;
147  if (m > 0) delete [] g_u;
148 
149  double * lam = (m > 0) ? new double[m] : NULL;
150  CoinFillN(lam,m,0.);
151  double * z = new double[n];
152  CoinFillN(z,n,0.);
153  tnlp->finalize_solution(Ipopt::SUCCESS,
154  n, x_sol, z, z,
155  m, g_sol, lam, obj_value, NULL, NULL);
156  if (m > 0) delete [] lam;
157  delete [] z;
158  if (m > 0) delete [] g_sol;
159  delete [] x_sol;
160  return 1;
161  }
162 
163 void
165 {
166  os<<solverName()<<" exited with error code "<<errorNum_<<" "<<errorName()<<std::endl;
167 }
168 
169 void
171  const int numcols = model_->num_variables();
172  const int numrows = model_->num_constraints();
173 
174  const double * currentLower = model_->x_l();
175  const double * currentUpper = model_->x_u();
176 
177  const double * originalLower = model_->orig_x_l();
178  const double * originalUpper = model_->orig_x_u();
179  CoinRelFltEq eq;
180  std::string fBoundsName = prefix + name_;
181  fBoundsName+="_bounds";
182 
183  std::string fModName = fBoundsName + ".mod";
184  std::ofstream fBounds;
185  std::ofstream fMod;
186 
188  bool hasVarNames = 0;
189  NamesReader reader(name_,".col");
190 
191  if(reader.readFile())
192  hasVarNames=1;
193  if(hasVarNames)
194  fMod.open(fModName.c_str());
195  fBounds.open(fBoundsName.c_str());
196 
197  for(int i = 0 ; i < numcols ; i++)
198  {
199  if(!eq(currentLower[i],originalLower[i]))
200  {
201  if(hasVarNames)
202  fMod<<"bounds"<<i<<": "
203  <<reader.name(i)<<" >= "
204  <<currentLower[i]<<";\n";
205 
206 
207  fBounds<<"LO"<<"\t"<<i<<"\t"<<currentLower[i]<<std::endl;
208  }
209  if(!eq(currentUpper[i],originalUpper[i]))
210  {
211  if(hasVarNames)
212  fMod<<"bounds"<<i<<": "
213  <<reader.name(i)<<" <= "
214  <<currentUpper[i]<<";\n";
215 
216  fBounds<<"UP"<<"\t"<<i<<"\t"<<currentUpper[i]<<std::endl;
217  }
218  }
219 
220  //write a file with starting point
221  std::string fStartPointName = name_;
222  fStartPointName+="_start";
223 
224 
225 
226  const double * primals = model_->x_init();
227  const double * duals = model_->duals_init();
228 
229  if(!primals)//No starting point no output
230  {
231  std::cerr<<"A failure has occured but no starting point exists"<<std::endl;
232  return;
233  }
234 
235  std::ofstream fStartPoint(fStartPointName.c_str());
236  fStartPoint.precision(17);
237  fStartPoint<<numcols<<"\t"<<2*numcols+numrows<<std::endl;
238  for(int i = 0 ; i < numcols ; i++)
239  fStartPoint<<primals[i]<<std::endl;
240  int end = 2*numcols + numrows;
241  if(duals)
242  {
243  for(int i = 0 ; i < end; i++)
244  fStartPoint<<duals[i]<<std::endl;
245  }
246 
247 
248 }
249 
252  bool
254  return (r >=0 || (r != illDefinedProblem && r != notEnoughFreedom && r != illegalOption && r != computationError && r != timeLimit) );
255  }
256 
258 void
260  prefix_ = "bonmin.";
261  options_ = new Ipopt::OptionsList();
262 
263  journalist_= new Ipopt::Journalist();
265 
266  try{
267  Ipopt::SmartPtr<Ipopt::Journal> stdout_journal =
268  journalist_->AddFileJournal("console", "stdout", Ipopt::J_ITERSUMMARY);
269 
270  options_->SetJournalist(journalist_);
271  options_->SetRegisteredOptions(GetRawPtr(roptions_));
272  }
273  catch (Ipopt::IpoptException &E){
274  E.ReportException(*journalist_);
275  throw E;
276  }
277  catch(std::bad_alloc){
278  journalist_->Printf(Ipopt::J_ERROR, Ipopt::J_MAIN, "\n Not enough memory .... EXIT\n");
279  throw CoinError("TNLPSolver", "initializeOptionsAndJournalist", "Not enough memory");
280  }
281 #ifndef NO_CATCH_ALL
282  catch(...){
283  Ipopt::IpoptException E("Uncaught exception in FilterSolver::FilterSolver()",
284  "BonFilterSolver.cpp",-1);
285  throw E;
286  }
287 #endif
288 
289 }
290 
291 
292 }//end namespace Bonmin
293 
void initializeOptionsAndJournalist()
Initializes options and journalist.
Ipopt::SmartPtr< Ipopt::Journalist > journalist_
Storage of Journalist for output.
std::string prefix_
Prefix to use for reading bonmin&#39;s options.
void writeDiffFiles(const std::string prefix=std::string()) const
write files with differences between input model and this one
This is a generic class for calling an NLP solver to solve a TNLP.
bool readFile()
Reads the .col file.
virtual const std::string & errorName() const =0
Get the string corresponding to error.
void fint fint fint real fint real real real real real real real real real * e
int errorNum_
Error code (solver dependent).
virtual const std::string & solverName() const =0
Return the name of the solver.
fint end
void printError(std::ostream &os)
Print error message.
void fint fint fint real fint real real real real real real real * r
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions_
Registered Options.
ReturnStatus
Standard return statuses for a solver.
bool isRecoverable(ReturnStatus &r)
Say if an optimization status for a problem which failed is recoverable (problem may be solvable)...
A class for reading a .col or .row file containing name for variables and constraints (usually ampl g...
void fint fint fint fint fint fint fint fint fint fint real real real real real real real real real fint real fint real * lam
TNLPSolver()
default Constructor
static char prefix[100]
Definition: BM_lp.cpp:26
void fint * m
bool zeroDimension(const Ipopt::SmartPtr< Ipopt::TNLP > &tnlp, ReturnStatus &optimization_status)
Determine if problem is of dimension zero and if it is check if solution is feasible.
Ipopt::SmartPtr< Ipopt::OptionsList > options_
List of Options.
void fint * n
const char * prefix()
Get the prefix.
const std::string & name(int i)
Access Names of indexed by i.
Fake member to know size.
virtual ~TNLPSolver()
Virtual destructor.
Class to add a few more information to Ipopt::RegisteredOptions.