/home/coin/SVN-release/OS-2.4.0/Couenne/src/main/Couenne.cpp

Go to the documentation of this file.
00001 // $Id: Couenne.cpp 530 2011-03-12 16:52:06Z pbelotti $
00002 //
00003 // (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006, 2007
00004 // All Rights Reserved.
00005 // This code is published under the Eclipse Public License (EPL).
00006 //
00007 // Authors :
00008 // Pietro Belotti, Lehigh University
00009 // Stefan Vigerske, Humboldt University
00010 //
00011 // Date : 07/06/2009
00012 
00013 //#include "CouenneConfig.h"
00014 
00015 #include <cstdlib>
00016 
00017 #include "CoinPragma.hpp"
00018 #include "CoinError.hpp"
00019 #include "CoinTime.hpp"
00020 
00021 #include "CouenneUserInterface.hpp"
00022 #ifdef COIN_HAS_ASL
00023 #include "CouenneAmplInterface.hpp"
00024 #endif
00025 #ifdef COIN_HAS_OS
00026 #include "CouenneOSInterface.hpp"
00027 #endif
00028 
00029 #include "BonRegisteredOptions.hpp"
00030 #include "BonCbc.hpp"
00031 
00032 #include "BonCouenneSetup.hpp"
00033 #include "BonCouenneInterface.hpp"
00034 
00035 // for printing of statistics
00036 #include "CbcCutGenerator.hpp"      
00037 #include "CouenneCutGenerator.hpp" 
00038 #include "CouenneProblem.hpp"
00039 
00040 
00041 namespace Ipopt {
00042   class OptionsList;
00043   class Journalist;
00044 }
00045 
00046 using Ipopt::SmartPtr;
00047 
00048 namespace Bonmin {
00049   class RegisteredOptions;
00050   class TMINLP;
00051   class Bab;
00052   class BabSetupBase;
00053   class TNLPSolver;
00054   class OsiTMINLPInterface;
00055 }
00056 
00057 using namespace Couenne;
00058 
00059 // the maximum difference between a printed optimum and a CouNumber
00060 #define PRINTED_PRECISION 1e-5
00061 
00062 using Ipopt::SmartPtr;
00063 
00064 static const int infeasible = 1;
00065 
00066 bool parseCommandLine(int argc, char* argv[], Ipopt::SmartPtr<Ipopt::OptionsList> options) {
00067   assert(IsValid(options));
00068         
00069   if (argc==3 && strcmp(argv[1], "-AMPL")==0)
00070     options->SetStringValue("nlfile", argv[2]);
00071 
00072   if (argc==3 && strcmp(argv[1], "-OSIL")==0)
00073     options->SetStringValue("osilfile", argv[2]);
00074 
00075   return true;
00076 }
00077 
00078 int main (int argc, char *argv[]) {
00079   WindowsErrorPopupBlocker();
00080 
00081   double time_start = CoinCpuTime();
00082   
00083   // register options to prepare for parsing the command line
00084   SmartPtr<Bonmin::RegisteredOptions> roptions = new Bonmin::RegisteredOptions();
00085   Couenne::CouenneSetup::registerAllOptions(roptions);
00086 #ifdef COIN_HAS_ASL
00087   CouenneAmplInterface::registerOptions(roptions);
00088 #endif
00089 #ifdef COIN_HAS_OS
00090   CouenneOSInterface::registerOptions(roptions);
00091 #endif
00092         
00093   SmartPtr<Ipopt::Journalist> jnlst = new Ipopt::Journalist();
00094   // do not add journals yet, maybe the user wants to do so; but what if parsing the command line gives errors?
00095         
00096   SmartPtr<Ipopt::OptionsList> options = new Ipopt::OptionsList(GetRawPtr(roptions), jnlst);
00097   if (!parseCommandLine(argc, argv, options))
00098     return EXIT_FAILURE;
00099         
00100         
00101 
00102   CouenneUserInterface* userinterface = NULL;
00103         
00104   std::string dummy;
00105 #ifdef COIN_HAS_ASL
00106   if (!userinterface && options->GetStringValue("nlfile", dummy, "")) {
00107     userinterface = new CouenneAmplInterface(options, jnlst);
00108     ((CouenneAmplInterface*)userinterface) -> setRegisteredOptions(roptions); // for some reason the TMINLP constructor needs the registered options
00109   }
00110 #endif
00111 #ifdef COIN_HAS_OS
00112   if (!userinterface && options->GetStringValue("osilfile", dummy, "")) {
00113     userinterface = new CouenneOSInterface();
00114   }
00115 #endif
00116         
00117   if (!userinterface) {
00118     fprintf(stderr, "Error: No input file given.\n");
00119     return EXIT_FAILURE;
00120   }
00121         
00122   if (!userinterface->setupJournals())
00123     return EXIT_FAILURE;
00124         
00125   CouenneProblem* problem = userinterface->getCouenneProblem();
00126   if (!problem)
00127     return EXIT_FAILURE;
00128   problem->initOptions(options);
00129         
00130   SmartPtr<Bonmin::TMINLP> tminlp = userinterface->getTMINLP();
00131   if (Ipopt::IsNull(tminlp))
00132     return EXIT_FAILURE;
00133 
00134   try {
00135     Bonmin::Bab bb;
00136     bb.setUsingCouenne (true);
00137 
00138     CouenneSetup couenne;
00139     couenne.setOptionsAndJournalist(roptions, options, jnlst);
00140     if (!couenne.InitializeCouenne (NULL, problem, tminlp))
00141       throw infeasible;
00142 
00143     double timeLimit = 0;
00144     options -> GetNumericValue ("time_limit", timeLimit, "couenne.");
00145     couenne.setDoubleParameter (Bonmin::BabSetupBase::MaxTime, timeLimit - (time_start = (CoinCpuTime () - time_start)));
00146   
00147     if (!userinterface->addBabPlugins(bb))
00148       return EXIT_FAILURE;
00149 
00150     bb (couenne); // do branch and bound
00151     
00152     // retrieve test value to check
00153     double global_opt;
00154     options -> GetNumericValue ("couenne_check", global_opt, "couenne.");
00155 
00156     if (global_opt < COUENNE_INFINITY) { // some value found in couenne.opt
00157       double opt = bb.model (). getBestPossibleObjValue ();
00158 
00159       jnlst -> Printf(Ipopt::J_SUMMARY, J_PROBLEM, "Global Optimum Test on %-40s %s\n", 
00160                       problem -> problemName ().c_str (), 
00161                       (fabs (opt - global_opt) / 
00162                        (1. + CoinMax (fabs (opt), fabs (global_opt))) < PRINTED_PRECISION) ? 
00163                       "OK" : "FAILED");
00164 
00165     } else if (couenne.displayStats ()) { // print statistics
00166 
00167       int nr=-1, nt=-1;
00168       double st=-1;
00169 
00170       CouenneCutGenerator* cg = NULL;
00171       if (bb.model (). cutGenerators ())
00172         cg = dynamic_cast <CouenneCutGenerator *>       (bb.model (). cutGenerators () [0] -> generator ());
00173       if (cg) cg -> getStats (nr, nt, st);
00174       else jnlst -> Printf(Ipopt::J_WARNING, J_PROBLEM, "Warning: Could not get pointer to CouenneCutGenerator\n");
00175 
00176       jnlst -> Printf(Ipopt::J_SUMMARY, J_PROBLEM, "Stats: %-15s %4d [var] %4d [int] %4d [con] %4d [aux] "
00177                       "%6d [root] %8d [tot] %6g [sep] %8g [time] %8g [bb] "
00178                       "%20e [lower] %20e [upper] %7d [nodes]\n",// %s %s\n",
00179                       problem -> problemName ().c_str (),
00180                       problem -> nOrigVars   (), 
00181                       problem -> nOrigIntVars(), 
00182                       problem -> nOrigCons   (),
00183                       problem -> nVars       () - problem -> nOrigVars (),
00184                       nr, nt, st, 
00185                       CoinCpuTime () - time_start,
00186                       cg ? (CoinCpuTime () - cg -> rootTime ()) : CoinCpuTime (),
00187                       bb.model (). getBestPossibleObjValue (),
00188                       bb.model (). getObjValue (),
00189                       //bb.bestBound (),
00190                       //bb.bestObj (),
00191                       bb.numNodes ()
00192                       //bb.iterationCount (),
00193                       //status.c_str (), message.c_str ()
00194                       );
00195     }    
00196 
00197     if (!userinterface->writeSolution(bb))
00198       return EXIT_FAILURE;
00199         
00200   } catch(Bonmin::TNLPSolver::UnsolvedError *E) {
00201     E->writeDiffFiles();
00202     E->printError(std::cerr);
00203     //There has been a failure to solve a problem with Ipopt.
00204     //And we will output file with information on what has been changed in the problem to make it fail.
00205     //Now depending on what algorithm has been called (B-BB or other) the failed problem may be at different place.
00206     //    const OsiSolverInterface &si1 = (algo > 0) ? nlpSolver : *model.solver();
00207      
00208   } catch(Bonmin::OsiTMINLPInterface::SimpleError &E) {
00209     std::cerr<<E.className()<<"::"<<E.methodName()
00210              <<std::endl
00211              <<E.message()<<std::endl;
00212     
00213   } catch(CoinError &E) {
00214     std::cerr<<E.className()<<"::"<<E.methodName()
00215              <<std::endl
00216              <<E.message()<<std::endl;
00217     
00218   } catch (Ipopt::OPTION_INVALID &E) {
00219     std::cerr<<"Ipopt exception : "<<E.Message()<<std::endl;
00220    
00221   } catch (int generic_error) {
00222     if (generic_error == infeasible)
00223       jnlst->Printf(Ipopt::J_SUMMARY, J_PROBLEM, "problem infeasible\n");
00224   }
00225   
00226   delete userinterface;
00227   
00228   return EXIT_SUCCESS;
00229 }
00230 
00231 
00232 
00233 //int main (int argc, char **argv) {
00234 
00235 // read options
00236 
00237 // create problem
00238 
00239 // create bb solver
00240 
00241 // add cut generators
00242 // add heuristics
00243 // add branching rules
00244 // add bound reduction
00245 
00246 // solve
00247 
00248 // print result
00249 
00250 //  return retval;
00251 //}

Generated on Thu Sep 22 03:05:59 2011 by  doxygen 1.4.7