source: trunk/Couenne/src/main/BonCouenne.cpp @ 571

Last change on this file since 571 was 571, checked in by pbelotti, 9 years ago

added code to compile recordBestSol. minor fixes

  • Property svn:keywords set to Author Date Id Revision
File size: 8.5 KB
Line 
1// $Id: BonCouenne.cpp 571 2011-05-09 13:26:44Z 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 Eclipse Public License (EPL).
6//
7// Authors :
8// Pietro Belotti, Carnegie Mellon University,
9// Pierre Bonami, International Business Machines Corporation
10//
11// Date : 12/19/2006
12
13
14#if defined(_MSC_VER)
15// Turn off compiler warning about long names
16#  pragma warning(disable:4786)
17#endif
18#include <iomanip>
19#include <fstream>
20
21#include <stdlib.h>
22
23#include "CoinTime.hpp"
24#include "CoinError.hpp"
25#include "BonCouenneInterface.hpp"
26
27#include "BonCouenneSetup.hpp"
28
29#include "BonCbc.hpp"
30
31#include "CbcCutGenerator.hpp"
32#include "CouenneProblem.hpp"
33#include "CouenneCutGenerator.hpp"
34
35using namespace Couenne;
36
37// the maximum difference between a printed optimum and a CouNumber
38#define PRINTED_PRECISION 1e-5
39
40#include "CouenneExprVar.hpp"
41#include "CouenneExprConst.hpp"
42#include "CouenneExprSum.hpp"
43#include "CouenneExprClone.hpp"
44#include "CouenneProblemElem.hpp"
45#include "CouenneProblem.hpp"
46#include "CouenneJournalist.hpp"
47
48#ifdef COIN_HAS_NTY
49int nOrbBr = 0;
50#endif
51
52#include "CoinSignal.hpp"
53
54extern "C" {
55
56  static int nInterrupts = 0;
57  static void signal_handler (int sig) {
58
59    if (!nInterrupts) {
60      std::cerr << "[BREAK]" << std::endl;
61      abort ();
62    }
63    return;
64  }
65}
66
67int main (int argc, char *argv[]) {
68
69  //CoinSighandler_t saveSignal = SIG_DFL;
70  //saveSignal = signal (SIGINT, signal_handler);
71
72    printf ("Couenne %s --  an Open-Source exact solver for Mixed Integer Nonlinear Optimization\n\
73Mailing list: couenne@list.coin-or.org\n\
74Instructions: http://www.coin-or.org/Couenne\n", 
75            strcmp (COUENNE_VERSION, "trunk") ? COUENNE_VERSION : "");
76
77  WindowsErrorPopupBlocker();
78  using namespace Ipopt;
79
80  char * pbName = NULL;
81
82  const int infeasible = 1;
83
84  try {
85
86    Bonmin::Bab bb;
87    bb.setUsingCouenne (true);
88
89    CouenneProblem *p = NULL;
90    CouenneInterface *ci = NULL;
91
92#if 0
93    //ci = new CouenneInterface;
94    p = new CouenneProblem;
95
96    p -> addVariable (false, p -> domain ());
97    p -> addVariable (false, p -> domain ());
98    p -> addVariable (false, p -> domain ());
99    p -> addVariable (false, p -> domain ());
100
101    p -> addObjective    (new exprSum (new exprClone (p->Var (1)), new exprClone (p->Var (2))), "min");
102    p -> addLEConstraint (new exprSum (new exprClone (p->Var (0)), new exprClone (p->Var (2))),
103                          new exprConst (1));
104    p -> addEQConstraint (new exprSum (new exprClone (p->Var (1)), new exprClone (p->Var (2))),
105                          new exprConst (1));
106    p -> addEQConstraint (new exprSum (new exprClone (p->Var (1)), new exprClone (p->Var (3))),
107                          new exprConst (1));
108    p -> addEQConstraint (new exprSum (new exprClone (p->Var (2)), new exprClone (p->Var (3))),
109                          new exprConst (1));
110#endif
111
112    CouenneSetup couenne;
113    if (!couenne.InitializeCouenne (argv, p, NULL, ci, &bb))
114      throw infeasible;
115
116    // initial printout
117
118    ConstJnlstPtr jnlst = couenne. couennePtr () -> Jnlst ();
119
120    CouenneProblem *prob = couenne. couennePtr () -> Problem ();
121
122    jnlst -> Printf (J_ERROR, J_COUENNE, "\
123Loaded instance \"%s\"\n\
124Constraints:     %8d\n\
125Variables:       %8d (%d integer)\n\
126Auxiliaries:     %8d (%d integer)\n\n",
127                     prob -> problemName ().c_str (),
128                     prob -> nOrigCons (),
129                     prob -> nOrigVars (),
130                     prob -> nOrigIntVars (),
131                     prob -> nVars    () - prob -> nOrigVars (),
132                     prob -> nIntVars () - prob -> nOrigIntVars ());
133
134    double time_start = CoinCpuTime();
135
136#if 0
137    CouenneFeasibility feasibility;
138    bb.model().setProblemFeasibility (feasibility);
139#endif
140
141    /// update time limit (read/preprocessing might have taken some)
142    double timeLimit = 0;
143    couenne.options () -> GetNumericValue ("time_limit", timeLimit, "couenne.");
144    couenne.setDoubleParameter (Bonmin::BabSetupBase::MaxTime, 
145                                CoinMax (1., timeLimit - time_start));
146
147    jnlst -> Printf (J_ERROR, J_COUENNE, "Starting branch-and-bound\n");
148
149    //////////////////////////////////
150
151    bb (couenne); // do branch and bound
152
153#ifdef COIN_HAS_NTY
154    if (nOrbBr)
155      printf ("%d orbital nontrivial branchings\n", nOrbBr);
156#endif
157
158    //////////////////////////////////
159
160    std::cout.precision (10);
161
162    //////////////////////////////
163    CouenneCutGenerator *cg = NULL;
164
165    // there is only one cut generator, so scan array until
166    // dynamic_cast returns non-NULL
167
168    if (bb.model (). cutGenerators ()) {
169
170      int nGen = bb.model (). numberCutGenerators ();
171     
172      for (int i=0; !cg && i < nGen; i++)
173        cg = dynamic_cast <CouenneCutGenerator *> 
174          (bb.model (). cutGenerators () [i] -> generator ());
175    }
176
177    ////////////////////////////////
178    int nr=-1, nt=-1;
179    double st=-1;
180
181    if (cg) cg -> getStats (nr, nt, st);
182    else printf ("Warning, could not get pointer to CouenneCutGenerator\n");
183
184    CouenneProblem *cp = cg ? cg -> Problem () : NULL;
185
186    // retrieve test value to check
187    double global_opt;
188    couenne.options () -> GetNumericValue ("couenne_check", global_opt, "couenne.");
189
190    double 
191      ub = bb.model (). getObjValue (),
192      lb = bb.model (). getBestPossibleObjValue ();
193
194    char *gapstr = new char [80];
195
196    sprintf (gapstr, "%.2f%%", 100. * (ub - lb) / (1. + fabs (lb)));
197
198    jnlst -> Printf (J_ERROR, J_COUENNE, "\n\
199Linearization cuts added at root node:   %8d\n\
200Linearization cuts added in total:       %8d  (separation time: %gs)\n\
201Total solving time:                      %8gs (%gs in branch-and-bound)\n\
202Lower bound:                           %10g\n\
203Upper bound:                           %10g  (gap: %s)\n\
204Branch-and-bound nodes:                  %8d\n\n",
205                     nr, nt, st, 
206                     CoinCpuTime () - time_start,
207                     cg ? (CoinCpuTime () - cg -> rootTime ()) : CoinCpuTime (),
208                     lb, 
209                     ub,
210                     (ub > COUENNE_INFINITY/1e4) ? "inf" : gapstr,
211                     bb.numNodes ());
212
213    delete [] gapstr;
214
215    if (global_opt < COUENNE_INFINITY) { // some value found in couenne.opt
216
217      double opt = bb.model (). getBestPossibleObjValue ();
218
219      printf ("Global Optimum Test on %-40s %s\n", 
220              cp ? cp -> problemName ().c_str () : "unknown", 
221              (fabs (opt - global_opt) / 
222               (1. + CoinMax (fabs (opt), fabs (global_opt))) < PRINTED_PRECISION) ? 
223              (const char *) "OK" : (const char *) "FAILED");
224              //opt, global_opt,
225              //fabs (opt - global_opt));
226
227    } else // good old statistics
228
229    if (couenne.displayStats ()) { // print statistics
230
231      // CAUTION: assuming first cut generator is our CouenneCutGenerator
232
233      if (cg && !cp) printf ("Warning, could not get pointer to problem\n");
234      else
235        printf ("Stats: %-15s %4d [var] %4d [int] %4d [con] %4d [aux] "
236                "%6d [root] %8d [tot] %6g [sep] %8g [time] %8g [bb] "
237                "%20e [lower] %20e [upper] %7d [nodes]\n",// %s %s\n",
238                cp ? cp -> problemName (). c_str () : "unknown",
239                (cp) ? cp -> nOrigVars     () : -1, 
240                (cp) ? cp -> nOrigIntVars  () : -1, 
241                (cp) ? cp -> nOrigCons     () : -1,
242                (cp) ? (cp -> nVars     () - 
243                        cp -> nOrigVars ()): -1,
244                nr, nt, st, 
245                CoinCpuTime () - time_start,
246                cg ? (CoinCpuTime () - cg -> rootTime ()) : CoinCpuTime (),
247                bb.model (). getBestPossibleObjValue (),
248                bb.model (). getObjValue (),
249                //bb.bestBound (),
250                //bb.bestObj (),
251                bb.numNodes ());
252                //bb.iterationCount ());
253                //status.c_str (), message.c_str ());
254    }
255
256//    nlp_and_solver -> writeAmplSolFile (message, bb.bestSolution (), NULL);
257  }
258  catch(Bonmin::TNLPSolver::UnsolvedError *E) {
259     E->writeDiffFiles();
260     E->printError(std::cerr);
261    //There has been a failure to solve a problem with Ipopt.
262    //And we will output file with information on what has been changed in the problem to make it fail.
263    //Now depending on what algorithm has been called (B-BB or other) the failed problem may be at different place.
264    //    const OsiSolverInterface &si1 = (algo > 0) ? nlpSolver : *model.solver();
265  }
266  catch (Bonmin::OsiTMINLPInterface::SimpleError &E) {
267    std::cerr<<E.className()<<"::"<<E.methodName()
268             <<std::endl
269             <<E.message()<<std::endl;
270  }
271  catch (CoinError &E) {
272    std::cerr<<E.className()<<"::"<<E.methodName()
273             <<std::endl
274             <<E.message()<<std::endl;
275  }
276  catch (Ipopt::OPTION_INVALID &E)
277  {
278   std::cerr<<"Ipopt exception : "<<E.Message()<<std::endl;
279  }
280  catch (int generic_error) {
281    if (generic_error == infeasible)
282      printf ("problem infeasible\n");
283  }
284
285//  catch(...) {
286//    std::cerr<<pbName<<" unrecognized excpetion"<<std::endl;
287//    std::cerr<<pbName<<"\t Finished \t exception"<<std::endl;
288//    throw;
289//  }
290
291  delete [] pbName;
292  return 0;
293}
Note: See TracBrowser for help on using the repository browser.