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
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
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
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
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);
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);
00151
00152
00153 double global_opt;
00154 options -> GetNumericValue ("couenne_check", global_opt, "couenne.");
00155
00156 if (global_opt < COUENNE_INFINITY) {
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 ()) {
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",
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
00190
00191 bb.numNodes ()
00192
00193
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
00204
00205
00206
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
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251