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

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

added counter for symmetry branching. moved symmetry group comps to a less frequent part of the code

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