00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "BonTNLPSolver.hpp"
00012 #include "BonColReader.hpp"
00013
00014
00015 #include "IpBlas.hpp"
00016
00017
00018 #include <fstream>
00019
00020 namespace Bonmin{
00021 using namespace Ipopt;
00022
00023
00024 #if 0
00025 string TNLPSolver::returnCodes[TNLPSolver::numReturnCodes] = {
00026 "Hit iteration limit" ,
00027 "Some error was made in computations." ,
00028 "Problem has more equations than free variables." ,
00029 "Problem is not well defined.",
00030 "Illegal option set.",
00031 "Exception in some the third-party code used by solver." ,
00032 "Unrecognized exception.",
00033 "Problem solved to optimality",
00034 "Problem solvedd to acceptable level of tolerance",
00035 "Problem is infeasible" ,
00036 "Problem is unbounded", };
00037 #endif
00038
00039
00040 TNLPSolver::TNLPSolver():
00041 start_time_(0),
00042 time_limit_(DBL_MAX)
00043 {
00044 initializeOptionsAndJournalist();
00045 }
00046
00047 TNLPSolver::TNLPSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions,
00048 Ipopt::SmartPtr<Ipopt::OptionsList> options,
00049 Ipopt::SmartPtr<Ipopt::Journalist> journalist,
00050 const std::string & prefix):
00051 journalist_(journalist),
00052 options_(options),
00053 roptions_(roptions),
00054 prefix_(prefix),
00055 start_time_(0),
00056 time_limit_(DBL_MAX)
00057 {
00058 }
00059
00060 TNLPSolver::TNLPSolver(const TNLPSolver &other):
00061 journalist_(other.journalist_),
00062 options_(NULL),
00063 roptions_(other.roptions_),
00064 prefix_(other.prefix_),
00065 start_time_(other.start_time_),
00066 time_limit_(other.time_limit_){
00067 options_ = new Ipopt::OptionsList();
00068 *options_ = *other.options_;
00069 }
00070
00071 TNLPSolver::~TNLPSolver()
00072 {}
00073
00074
00075 bool
00076 TNLPSolver::zeroDimension(const Ipopt::SmartPtr<Ipopt::TNLP>& tnlp, ReturnStatus &optimizationStatus)
00077 {
00078
00079 int n,m,dum1, dum2;
00080 Ipopt::TNLP::IndexStyleEnum dum3;
00081 tnlp->get_nlp_info(n,m,dum1, dum2, dum3);
00082 double * x_l = new double[n];
00083 double * x_u = new double[n];
00084
00085 double * g_l = (m>0) ? new double[m] : NULL;
00086 double * g_u = (m >0) ? new double[m] : NULL;
00087
00088 tnlp->get_bounds_info(n, x_l, x_u, m, g_l , g_u);
00089
00090
00091 for(int i = 0 ; i < n ; i++) {
00092 if(x_u[i] - x_l[i] > 1e-5)
00093 {
00094 delete [] x_l;
00095 delete [] x_u;
00096 if(m > 0){
00097 delete [] g_l;
00098 delete [] g_u;
00099 }
00100 return 0;
00101 }
00102 }
00103
00104
00105
00106 double obj_value;
00107
00108 tnlp->eval_f(n, x_l, true, obj_value);
00109
00110 double * x_sol = new double[n];
00111
00112
00113 IpBlasDcopy(n, x_l, 1, x_sol, 1);
00114
00115 delete [] x_l;
00116 delete [] x_u;
00117
00118 double * g_sol = (m > 0) ? new double [m] : NULL;
00119
00120 tnlp->eval_g(n, x_sol, true, m, g_sol);
00121
00122 optimizationStatus = solvedOptimal;
00123 for(int i = 0 ; i < m ; i++) {
00124 if(g_sol[i] - g_l[i] < - 1e-07 || g_sol[i] - g_u[i] > 1e-07) {
00125 optimizationStatus = provenInfeasible;
00126
00127 delete [] g_l;
00128 delete [] g_u;
00129 double * lam = (m > 0) ? new double[m]: NULL;
00130 CoinFillN(lam,m,0.);
00131 double * z = new double[n];
00132 CoinFillN(z,n,0.);
00133 tnlp->finalize_solution(Ipopt::LOCAL_INFEASIBILITY,
00134 n, x_sol, NULL, NULL,
00135 m, g_sol, NULL, obj_value, NULL, NULL);
00136 if (m > 0) delete [] lam;
00137 delete [] z;
00138 if (m > 0) delete [] g_sol;
00139 delete [] x_sol;
00140
00141 return 1;
00142 }
00143 }
00144 if (m > 0) delete [] g_l;
00145 if (m > 0) delete [] g_u;
00146
00147 double * lam = (m > 0) ? new double[m] : NULL;
00148 CoinFillN(lam,m,0.);
00149 double * z = new double[n];
00150 CoinFillN(z,n,0.);
00151 tnlp->finalize_solution(Ipopt::SUCCESS,
00152 n, x_sol, z, z,
00153 m, g_sol, lam, obj_value, NULL, NULL);
00154 if (m > 0) delete [] lam;
00155 delete [] z;
00156 if (m > 0) delete [] g_sol;
00157 delete [] x_sol;
00158 return 1;
00159 }
00160
00161 void
00162 TNLPSolver::UnsolvedError::printError(std::ostream &os)
00163 {
00164 os<<solverName()<<" exited with error code "<<errorNum_<<" "<<errorName()<<std::endl;
00165 }
00166
00167 void
00168 TNLPSolver::UnsolvedError::writeDiffFiles(const std::string prefix) const{
00169 const int numcols = model_->num_variables();
00170 const int numrows = model_->num_constraints();
00171
00172 const double * currentLower = model_->x_l();
00173 const double * currentUpper = model_->x_u();
00174
00175 const double * originalLower = model_->orig_x_l();
00176 const double * originalUpper = model_->orig_x_u();
00177 CoinRelFltEq eq;
00178 std::string fBoundsName = prefix + name_;
00179 fBoundsName+="_bounds";
00180
00181 std::string fModName = fBoundsName + ".mod";
00182 std::ofstream fBounds;
00183 std::ofstream fMod;
00184
00186 bool hasVarNames = 0;
00187 NamesReader reader(name_,".col");
00188
00189 if(reader.readFile())
00190 hasVarNames=1;
00191 if(hasVarNames)
00192 fMod.open(fModName.c_str());
00193 fBounds.open(fBoundsName.c_str());
00194
00195 for(int i = 0 ; i < numcols ; i++)
00196 {
00197 if(!eq(currentLower[i],originalLower[i]))
00198 {
00199 if(hasVarNames)
00200 fMod<<"bounds"<<i<<": "
00201 <<reader.name(i)<<" >= "
00202 <<currentLower[i]<<";\n";
00203
00204
00205 fBounds<<"LO"<<"\t"<<i<<"\t"<<currentLower[i]<<std::endl;
00206 }
00207 if(!eq(currentUpper[i],originalUpper[i]))
00208 {
00209 if(hasVarNames)
00210 fMod<<"bounds"<<i<<": "
00211 <<reader.name(i)<<" <= "
00212 <<currentUpper[i]<<";\n";
00213
00214 fBounds<<"UP"<<"\t"<<i<<"\t"<<currentUpper[i]<<std::endl;
00215 }
00216 }
00217
00218
00219 std::string fStartPointName = name_;
00220 fStartPointName+="_start";
00221
00222
00223
00224 const double * primals = model_->x_init();
00225 const double * duals = model_->duals_init();
00226
00227 if(!primals)
00228 {
00229 std::cerr<<"A failure has occured but no starting point exists"<<std::endl;
00230 return;
00231 }
00232
00233 std::ofstream fStartPoint(fStartPointName.c_str());
00234 fStartPoint.precision(17);
00235 fStartPoint<<numcols<<"\t"<<2*numcols+numrows<<std::endl;
00236 for(int i = 0 ; i < numcols ; i++)
00237 fStartPoint<<primals[i]<<std::endl;
00238 int end = 2*numcols + numrows;
00239 if(duals)
00240 {
00241 for(int i = 0 ; i < end; i++)
00242 fStartPoint<<duals[i]<<std::endl;
00243 }
00244
00245
00246 }
00247
00250 bool
00251 TNLPSolver::isRecoverable(ReturnStatus &r){
00252 return (r >=0 || (r != illDefinedProblem && r != illegalOption && r != computationError && r != timeLimit) );
00253 }
00254
00256 void
00257 TNLPSolver::initializeOptionsAndJournalist(){
00258 prefix_ = "bonmin.";
00259 options_ = new Ipopt::OptionsList();
00260
00261 journalist_= new Ipopt::Journalist();
00262 roptions_ = new Bonmin::RegisteredOptions();
00263
00264 try{
00265 Ipopt::SmartPtr<Ipopt::Journal> stdout_journal =
00266 journalist_->AddFileJournal("console", "stdout", Ipopt::J_ITERSUMMARY);
00267
00268 options_->SetJournalist(journalist_);
00269 options_->SetRegisteredOptions(GetRawPtr(roptions_));
00270 }
00271 catch (Ipopt::IpoptException &E){
00272 E.ReportException(*journalist_);
00273 throw E;
00274 }
00275 catch(std::bad_alloc){
00276 journalist_->Printf(Ipopt::J_ERROR, Ipopt::J_MAIN, "\n Not enough memory .... EXIT\n");
00277 throw -1;
00278 }
00279 catch(...){
00280 Ipopt::IpoptException E("Uncaught exception in FilterSolver::FilterSolver()",
00281 "BonFilterSolver.cpp",-1);
00282 throw E;
00283 }
00284
00285 }
00286
00287
00288 }
00289