00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00036 #include "CbcCutGenerator.hpp"
00037 #include "CouenneCutGenerator.hpp"
00038 #include "CouenneProblem.hpp"
00039
00040 using namespace Couenne;
00041
00042
00043 #define PRINTED_PRECISION 1e-5
00044
00045 using Ipopt::SmartPtr;
00046
00047 static const int infeasible = 1;
00048
00049 bool parseCommandLine(int argc, char* argv[], Ipopt::SmartPtr<Ipopt::OptionsList> options) {
00050 assert(IsValid(options));
00051
00052 if (argc==3 && strcmp(argv[1], "-AMPL")==0)
00053 options->SetStringValue("nlfile", argv[2]);
00054
00055 if (argc==3 && strcmp(argv[1], "-OSIL")==0)
00056 options->SetStringValue("osilfile", argv[2]);
00057
00058 return true;
00059 }
00060
00061 int main (int argc, char *argv[]) {
00062 WindowsErrorPopupBlocker();
00063
00064 double time_start = CoinCpuTime();
00065
00066
00067 SmartPtr<Bonmin::RegisteredOptions> roptions = new Bonmin::RegisteredOptions();
00068 Bonmin::CouenneSetup::registerAllOptions(roptions);
00069 #ifdef COIN_HAS_ASL
00070 CouenneAmplInterface::registerOptions(roptions);
00071 #endif
00072 #ifdef COIN_HAS_OS
00073 CouenneOSInterface::registerOptions(roptions);
00074 #endif
00075
00076 SmartPtr<Ipopt::Journalist> jnlst = new Ipopt::Journalist();
00077
00078
00079 SmartPtr<Ipopt::OptionsList> options = new Ipopt::OptionsList(GetRawPtr(roptions), jnlst);
00080 if (!parseCommandLine(argc, argv, options))
00081 return EXIT_FAILURE;
00082
00083
00084
00085 CouenneUserInterface* userinterface = NULL;
00086
00087 std::string dummy;
00088 #ifdef COIN_HAS_ASL
00089 if (!userinterface && options->GetStringValue("nlfile", dummy, "")) {
00090 userinterface = new CouenneAmplInterface(options, jnlst);
00091 ((CouenneAmplInterface*)userinterface) -> setRegisteredOptions(roptions);
00092 }
00093 #endif
00094 #ifdef COIN_HAS_OS
00095 if (!userinterface && options->GetStringValue("osilfile", dummy, "")) {
00096 userinterface = new CouenneOSInterface();
00097 }
00098 #endif
00099
00100 if (!userinterface) {
00101 fprintf(stderr, "Error: No input file given.\n");
00102 return EXIT_FAILURE;
00103 }
00104
00105 if (!userinterface->setupJournals())
00106 return EXIT_FAILURE;
00107
00108 CouenneProblem* problem = userinterface->getCouenneProblem();
00109 if (!problem)
00110 return EXIT_FAILURE;
00111 problem->initOptions(options);
00112
00113 SmartPtr<Bonmin::TMINLP> tminlp = userinterface->getTMINLP();
00114 if (Ipopt::IsNull(tminlp))
00115 return EXIT_FAILURE;
00116
00117 try {
00118 Bonmin::Bab bb;
00119 bb.setUsingCouenne (true);
00120
00121 Bonmin::CouenneSetup couenne;
00122 couenne.setOptionsAndJournalist(roptions, options, jnlst);
00123 if (!couenne.InitializeCouenne (NULL, problem, tminlp))
00124 throw infeasible;
00125
00126 double timeLimit = 0;
00127 options -> GetNumericValue ("time_limit", timeLimit, "couenne.");
00128 couenne.setDoubleParameter (Bonmin::BabSetupBase::MaxTime, timeLimit - (time_start = (CoinCpuTime () - time_start)));
00129
00130 if (!userinterface->addBabPlugins(bb))
00131 return EXIT_FAILURE;
00132
00133 bb (couenne);
00134
00135
00136 double global_opt;
00137 options -> GetNumericValue ("couenne_check", global_opt, "couenne.");
00138
00139 if (global_opt < COUENNE_INFINITY) {
00140 double opt = bb.model (). getBestPossibleObjValue ();
00141
00142 jnlst -> Printf(Ipopt::J_SUMMARY, J_PROBLEM, "Global Optimum Test on %-40s %s\n",
00143 problem -> problemName ().c_str (),
00144 (fabs (opt - global_opt) /
00145 (1. + CoinMax (fabs (opt), fabs (global_opt))) < PRINTED_PRECISION) ?
00146 "OK" : "FAILED");
00147
00148 } else if (couenne.displayStats ()) {
00149
00150 int nr=-1, nt=-1;
00151 double st=-1;
00152
00153 CouenneCutGenerator* cg = NULL;
00154 if (bb.model (). cutGenerators ())
00155 cg = dynamic_cast <CouenneCutGenerator *> (bb.model (). cutGenerators () [0] -> generator ());
00156 if (cg) cg -> getStats (nr, nt, st);
00157 else jnlst -> Printf(Ipopt::J_WARNING, J_PROBLEM, "Warning: Could not get pointer to CouenneCutGenerator\n");
00158
00159 jnlst -> Printf(Ipopt::J_SUMMARY, J_PROBLEM, "Stats: %-15s %4d [var] %4d [int] %4d [con] %4d [aux] "
00160 "%6d [root] %8d [tot] %6g [sep] %8g [time] %8g [bb] "
00161 "%20e [lower] %20e [upper] %7d [nodes]\n",
00162 problem -> problemName ().c_str (),
00163 problem -> nOrigVars (),
00164 problem -> nOrigIntVars(),
00165 problem -> nOrigCons (),
00166 problem -> nVars () - problem -> nOrigVars (),
00167 nr, nt, st,
00168 CoinCpuTime () - time_start,
00169 cg ? (CoinCpuTime () - cg -> rootTime ()) : CoinCpuTime (),
00170 bb.model (). getBestPossibleObjValue (),
00171 bb.model (). getObjValue (),
00172
00173
00174 bb.numNodes ()
00175
00176
00177 );
00178 }
00179
00180 if (!userinterface->writeSolution(bb))
00181 return EXIT_FAILURE;
00182
00183 } catch(Bonmin::TNLPSolver::UnsolvedError *E) {
00184 E->writeDiffFiles();
00185 E->printError(std::cerr);
00186
00187
00188
00189
00190
00191 } catch(Bonmin::OsiTMINLPInterface::SimpleError &E) {
00192 std::cerr<<E.className()<<"::"<<E.methodName()
00193 <<std::endl
00194 <<E.message()<<std::endl;
00195
00196 } catch(CoinError &E) {
00197 std::cerr<<E.className()<<"::"<<E.methodName()
00198 <<std::endl
00199 <<E.message()<<std::endl;
00200
00201 } catch (Ipopt::OPTION_INVALID &E) {
00202 std::cerr<<"Ipopt exception : "<<E.Message()<<std::endl;
00203
00204 } catch (int generic_error) {
00205 if (generic_error == infeasible)
00206 jnlst->Printf(Ipopt::J_SUMMARY, J_PROBLEM, "problem infeasible\n");
00207 }
00208
00209 delete userinterface;
00210
00211 return EXIT_SUCCESS;
00212 }