source: trunk/Couenne/src/main/CouenneSolver.cpp @ 349

Last change on this file since 349 was 349, checked in by pbelotti, 10 years ago

Added Couenne namespace. Committed old code for Feas Pump. Added code for ellipsoid cuts. Added (empty) CouenneMINLPInterface that might replace AMPL interface to Ipopt. Fixed a few warnings. Solved a few namespace problems due to ambiguity in Bonmin and AMPL. Added (empty) code for sdp cuts.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1// $Id: CouenneSolver.cpp 349 2010-05-31 20:36:37Z pbelotti $
2//
3// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006, 2007
4// All Rights Reserved.
5// This code is published under the Common Public License.
6//
7// Authors :
8// Pietro Belotti, Lehigh University
9// Stefan Vigerske, Humboldt University
10//
11// Date : 07/06/2009
12
13#include "CouenneConfig.h"
14
15#include <cstdlib>
16
17#include "CoinPragma.hpp"
18#include "CoinError.hpp"
19#include "CoinTime.hpp"
20
21#include "CouenneUserInterface.hpp"
22#ifdef COIN_HAS_ASL
23#include "CouenneAmplInterface.hpp"
24#endif
25#ifdef COIN_HAS_OS
26#include "CouenneOSInterface.hpp"
27#endif
28
29#include "BonRegisteredOptions.hpp"
30#include "BonCbc.hpp"
31
32#include "BonCouenneSetup.hpp"
33#include "BonCouenneInterface.hpp"
34
35// for printing of statistics
36#include "CbcCutGenerator.hpp"     
37#include "CouenneCutGenerator.hpp"
38#include "CouenneProblem.hpp"
39
40using namespace Couenne;
41
42// the maximum difference between a printed optimum and a CouNumber
43#define PRINTED_PRECISION 1e-5
44
45using Ipopt::SmartPtr;
46
47static const int infeasible = 1;
48
49bool parseCommandLine(int argc, char* argv[], Ipopt::SmartPtr<Ipopt::OptionsList> options) {
50        assert(IsValid(options));
51       
52        if (argc==3 && strcmp(argv[1], "-AMPL")==0)
53                options->SetStringValue("nlfile", argv[2]);
54
55        if (argc==3 && strcmp(argv[1], "-OSIL")==0)
56                options->SetStringValue("osilfile", argv[2]);
57
58        return true;
59}
60
61int main (int argc, char *argv[]) {
62  WindowsErrorPopupBlocker();
63
64  double time_start = CoinCpuTime();
65 
66        // register options to prepare for parsing the command line
67        SmartPtr<Bonmin::RegisteredOptions> roptions = new Bonmin::RegisteredOptions();
68        Bonmin::CouenneSetup::registerAllOptions(roptions);
69#ifdef COIN_HAS_ASL
70        CouenneAmplInterface::registerOptions(roptions);
71#endif
72#ifdef COIN_HAS_OS
73        CouenneOSInterface::registerOptions(roptions);
74#endif
75       
76        SmartPtr<Ipopt::Journalist> jnlst = new Ipopt::Journalist();
77        // do not add journals yet, maybe the user wants to do so; but what if parsing the command line gives errors?
78       
79        SmartPtr<Ipopt::OptionsList> options = new Ipopt::OptionsList(GetRawPtr(roptions), jnlst);
80        if (!parseCommandLine(argc, argv, options))
81                return EXIT_FAILURE;
82       
83       
84
85        CouenneUserInterface* userinterface = NULL;
86       
87        std::string dummy;
88#ifdef COIN_HAS_ASL
89        if (!userinterface && options->GetStringValue("nlfile", dummy, "")) {
90                userinterface = new CouenneAmplInterface(options, jnlst);
91                ((CouenneAmplInterface*)userinterface) -> setRegisteredOptions(roptions); // for some reason the TMINLP constructor needs the registered options
92        }
93#endif
94#ifdef COIN_HAS_OS
95        if (!userinterface && options->GetStringValue("osilfile", dummy, "")) {
96                userinterface = new CouenneOSInterface();
97        }
98#endif
99       
100        if (!userinterface) {
101                fprintf(stderr, "Error: No input file given.\n");
102                return EXIT_FAILURE;
103        }
104       
105        if (!userinterface->setupJournals())
106                return EXIT_FAILURE;
107       
108        CouenneProblem* problem = userinterface->getCouenneProblem();
109        if (!problem)
110                return EXIT_FAILURE;
111        problem->initOptions(options);
112       
113        SmartPtr<Bonmin::TMINLP> tminlp = userinterface->getTMINLP();
114        if (Ipopt::IsNull(tminlp))
115                return EXIT_FAILURE;
116
117        try {
118    Bonmin::Bab bb;
119    bb.setUsingCouenne (true);
120
121    Bonmin::CouenneSetup couenne;
122    couenne.setOptionsAndJournalist(roptions, options, jnlst);
123    if (!couenne.InitializeCouenne (NULL, problem, tminlp))
124      throw infeasible;
125
126    double timeLimit = 0;
127    options -> GetNumericValue ("time_limit", timeLimit, "couenne.");
128    couenne.setDoubleParameter (Bonmin::BabSetupBase::MaxTime, timeLimit - (time_start = (CoinCpuTime () - time_start)));
129 
130    if (!userinterface->addBabPlugins(bb))
131        return EXIT_FAILURE;
132
133    bb (couenne); // do branch and bound
134   
135    // retrieve test value to check
136    double global_opt;
137    options -> GetNumericValue ("couenne_check", global_opt, "couenne.");
138
139    if (global_opt < COUENNE_INFINITY) { // some value found in couenne.opt
140      double opt = bb.model (). getBestPossibleObjValue ();
141
142      jnlst -> Printf(Ipopt::J_SUMMARY, J_PROBLEM, "Global Optimum Test on %-40s %s\n", 
143              problem -> problemName ().c_str (), 
144              (fabs (opt - global_opt) / 
145               (1. + CoinMax (fabs (opt), fabs (global_opt))) < PRINTED_PRECISION) ? 
146              "OK" : "FAILED");
147
148    } else if (couenne.displayStats ()) { // print statistics
149
150      int nr=-1, nt=-1;
151      double st=-1;
152
153      CouenneCutGenerator* cg = NULL;
154      if (bb.model (). cutGenerators ())
155        cg = dynamic_cast <CouenneCutGenerator *>       (bb.model (). cutGenerators () [0] -> generator ());
156      if (cg) cg -> getStats (nr, nt, st);
157      else jnlst -> Printf(Ipopt::J_WARNING, J_PROBLEM, "Warning: Could not get pointer to CouenneCutGenerator\n");
158
159        jnlst -> Printf(Ipopt::J_SUMMARY, J_PROBLEM, "Stats: %-15s %4d [var] %4d [int] %4d [con] %4d [aux] "
160                        "%6d [root] %8d [tot] %6g [sep] %8g [time] %8g [bb] "
161                        "%20e [lower] %20e [upper] %7d [nodes]\n",// %s %s\n",
162                        problem -> problemName ().c_str (),
163                        problem -> nOrigVars   (), 
164                        problem -> nOrigIntVars(), 
165                        problem -> nOrigCons   (),
166                        problem -> nVars       () - problem -> nOrigVars (),
167                        nr, nt, st, 
168                        CoinCpuTime () - time_start,
169                        cg ? (CoinCpuTime () - cg -> rootTime ()) : CoinCpuTime (),
170                        bb.model (). getBestPossibleObjValue (),
171                        bb.model (). getObjValue (),
172                        //bb.bestBound (),
173                        //bb.bestObj (),
174                        bb.numNodes ()
175                        //bb.iterationCount (),
176                        //status.c_str (), message.c_str ()
177        );
178    }   
179
180    if (!userinterface->writeSolution(bb))
181        return EXIT_FAILURE;
182       
183        } catch(Bonmin::TNLPSolver::UnsolvedError *E) {
184     E->writeDiffFiles();
185     E->printError(std::cerr);
186    //There has been a failure to solve a problem with Ipopt.
187    //And we will output file with information on what has been changed in the problem to make it fail.
188    //Now depending on what algorithm has been called (B-BB or other) the failed problem may be at different place.
189    //    const OsiSolverInterface &si1 = (algo > 0) ? nlpSolver : *model.solver();
190     
191  } catch(Bonmin::OsiTMINLPInterface::SimpleError &E) {
192    std::cerr<<E.className()<<"::"<<E.methodName()
193             <<std::endl
194             <<E.message()<<std::endl;
195   
196  } catch(CoinError &E) {
197    std::cerr<<E.className()<<"::"<<E.methodName()
198             <<std::endl
199             <<E.message()<<std::endl;
200   
201  } catch (Ipopt::OPTION_INVALID &E) {
202        std::cerr<<"Ipopt exception : "<<E.Message()<<std::endl;
203   
204  } catch (int generic_error) {
205    if (generic_error == infeasible)
206      jnlst->Printf(Ipopt::J_SUMMARY, J_PROBLEM, "problem infeasible\n");
207  }
208 
209  delete userinterface;
210 
211  return EXIT_SUCCESS;
212}
Note: See TracBrowser for help on using the repository browser.