source: trunk/Couenne/src/convex/CouenneCutGenerator.cpp @ 575

Last change on this file since 575 was 575, checked in by fmargot, 9 years ago

Fixes bugs related to use of CouenneRecordBestSol?

  • Property svn:keywords set to Author Date Id Revision
File size: 7.0 KB
Line 
1/* $Id: CouenneCutGenerator.cpp 575 2011-05-10 19:21:33Z fmargot $
2 *
3 * Name:    CouenneCutGenerator.cpp
4 * Author:  Pietro Belotti
5 * Purpose: define a class of convexification procedures
6 *
7 * (C) Carnegie-Mellon University, 2006-09.
8 * This file is licensed under the Eclipse Public License (EPL)
9 */
10
11#include "CglCutGenerator.hpp"
12
13#include "CouenneCutGenerator.hpp"
14
15#include "CouenneProblem.hpp"
16#include "CouenneChooseStrong.hpp"
17#include "CouenneChooseVariable.hpp"
18
19#include "BonCbc.hpp"
20#include "CouenneRecordBestSol.hpp"
21
22using namespace Couenne;
23
24/// constructor
25CouenneCutGenerator::CouenneCutGenerator (Bonmin::OsiTMINLPInterface *nlp,
26                                          Bonmin::BabSetupBase *base,
27                                          CouenneProblem *problem,
28                                          struct ASL *asl):
29
30  CglCutGenerator (),
31 
32  firstcall_      (true),
33  problem_        (problem),
34  nrootcuts_      (0),
35  ntotalcuts_     (0),
36  septime_        (0),
37  objValue_       (- DBL_MAX),
38  nlp_            (nlp),
39  BabPtr_         (NULL),
40  infeasNode_     (false),
41  jnlst_          (base ? base -> journalist () : NULL),
42  rootTime_       (-1.) {
43
44  if (base) {
45
46    base -> options () -> GetIntegerValue ("convexification_points", nSamples_, "couenne.");
47
48    std::string s;
49
50    base -> options () -> GetStringValue ("convexification_type", s, "couenne.");
51    if      (s == "current-point-only") convtype_ = CURRENT_ONLY;
52    else if (s == "uniform-grid")       convtype_ = UNIFORM_GRID;
53    else                                convtype_ = AROUND_CURPOINT;
54
55    base -> options () -> GetStringValue ("violated_cuts_only", s, "couenne."); 
56    addviolated_ = (s == "yes");
57
58    base -> options () -> GetStringValue ("check_lp", s, "couenne."); 
59    check_lp_ = (s == "yes");
60
61    base -> options () -> GetStringValue ("enable_lp_implied_bounds", s, "couenne.");
62    enable_lp_implied_bounds_ = (s == "yes");
63
64  } else {
65
66    nSamples_                 = 4;
67    convtype_                 = CURRENT_ONLY;
68    addviolated_              = true;
69    check_lp_                 = false;
70    enable_lp_implied_bounds_ = false;
71  }
72
73  lastPrintLine = -1;
74
75  //if (asl) // deal with problems not originating from AMPL
76  //problem_ = new CouenneProblem (asl, base, jnlst_);
77}
78
79
80/// destructor
81CouenneCutGenerator::~CouenneCutGenerator ()
82{}//if (problem_) delete problem_;}
83
84
85/// copy constructor
86CouenneCutGenerator::CouenneCutGenerator (const CouenneCutGenerator &src):
87
88  CglCutGenerator (src),
89
90  firstcall_   (src. firstcall_),
91  addviolated_ (src. addviolated_), 
92  convtype_    (src. convtype_), 
93  nSamples_    (src. nSamples_),
94  problem_     (src. problem_),// -> clone ()),
95  nrootcuts_   (src. nrootcuts_),
96  ntotalcuts_  (src. ntotalcuts_),
97  septime_     (src. septime_),
98  objValue_    (src. objValue_),
99  nlp_         (src. nlp_),
100  BabPtr_      (src. BabPtr_),
101  infeasNode_  (src. infeasNode_),
102  jnlst_       (src. jnlst_),
103  rootTime_    (src. rootTime_),
104  check_lp_    (src. check_lp_),
105  enable_lp_implied_bounds_ (src.enable_lp_implied_bounds_),
106  lastPrintLine(src.lastPrintLine)
107{}
108
109
110#define MAX_SLOPE 1e3
111
112/// add half-space through two points (x1,y1) and (x2,y2)
113int CouenneCutGenerator::addSegment (OsiCuts &cs, int wi, int xi, 
114                                     CouNumber x1, CouNumber y1, 
115                                     CouNumber x2, CouNumber y2, int sign) const { 
116
117  if (fabs (x2-x1) < COUENNE_EPS) {
118    if (fabs (y2-y1) > MAX_SLOPE * COUENNE_EPS)
119      jnlst_->Printf(J_WARNING, J_CONVEXIFYING,
120                     "warning, discontinuity of %e over an interval of %e\n", y2-y1, x2-x1);
121    else return createCut (cs, y2, (int) 0, wi, 1.);
122  }
123
124  CouNumber dx = x2-x1, dy = y2-y1;
125
126  //  return createCut (cs, y1 + oppslope * x1, sign, wi, 1., xi, oppslope);
127  return createCut (cs, y1*dx - dy*x1, (dx>0) ? sign : -sign, wi, dx, xi, -dy);
128}
129
130
131/// add tangent at (x,w) with given slope
132int CouenneCutGenerator::addTangent (OsiCuts &cs, int wi, int xi, 
133                                     CouNumber x, CouNumber w, 
134                                     CouNumber slope, int sign) const
135  {return createCut (cs, w - slope * x, sign, wi, 1., xi, - slope);}
136
137
138/// total number of variables (original + auxiliary) of the problem
139int CouenneCutGenerator::getnvars () const
140  {return problem_ -> nVars ();} 
141
142
143/// Add list of options to be read from file
144void CouenneCutGenerator::registerOptions (Ipopt::SmartPtr <Bonmin::RegisteredOptions> roptions) {
145
146  roptions -> SetRegisteringCategory ("Couenne options", Bonmin::RegisteredOptions::CouenneCategory);
147
148  roptions -> AddLowerBoundedIntegerOption
149    ("convexification_cuts",
150     "Specify the frequency (in terms of nodes) at which couenne ecp cuts are generated.",
151     -99,1,
152     "A frequency of 0 amounts to never solve the NLP relaxation.");
153
154  roptions -> AddStringOption2
155    ("check_lp",
156     "Check all LPs through an independent call to OsiClpSolverInterface::initialSolve()",
157     "no",
158     "no","",
159     "yes","");
160
161  roptions -> AddStringOption3
162    ("convexification_type",
163     "Determines in which point the linear over/under-estimator are generated",
164     "current-point-only",
165     "current-point-only","Only at current optimum of relaxation",
166     "uniform-grid","Points chosen in a uniform grid between the bounds of the problem",
167     "around-current-point","At points around current optimum of relaxation",
168     "For the lower envelopes of convex functions, this is the number of points where a supporting hyperplane is generated. "
169     "This only holds for the initial linearization, as all other linearizations only add at most one cut per expression."
170    );
171   
172  roptions -> AddLowerBoundedIntegerOption
173    ("convexification_points",
174     "Specify the number of points at which to convexify when convexification type "
175     "is uniform-grid or around-current-point.",
176     0,4,
177     "");
178
179  roptions -> AddStringOption2
180    ("violated_cuts_only",
181     "Yes if only violated convexification cuts should be added",
182     "yes",
183     "no","",
184     "yes","");
185
186  roptions -> AddStringOption2
187    ("enable_lp_implied_bounds",
188     "Enable OsiSolverInterface::tightenBounds () -- warning: it has caused "
189     "some trouble to Couenne",
190     "no",
191     "no","",
192     "yes","");
193
194  roptions -> AddStringOption3
195    ("multilinear_separation",
196     "Separation for multilinear terms",
197     "tight",
198     "none",   "No separation -- just use the four McCormick inequalities",
199     "simple", "Use one considering lower curve only",
200     "tight",  "Use one considering both curves pi(x) = l_{k+1} and pi(x) = u_{k+1}",
201     "Type of separation for multilinear terms where the dependent variable is also bounded"
202    );
203}
204
205/*********************************************************************/
206void CouenneCutGenerator::printLineInfo() const {
207
208  double cbcLb = BabPtr_->model().getBestPossibleObjValue();
209  double lpVal = BabPtr_->model().solver()->getObjValue();
210  int nbNodes = BabPtr_->model().getNodeCount();
211  int depth = BabPtr_->model().currentDepth();
212  CouenneRecordBestSol *rs = problem_->getRecordBestSol();
213
214  if(rs->getHasSol()) {
215    double bestSolVal = rs->getVal(); 
216    printf("%10d  %10d  %10.6f  %10.6f  %10.6f\n", 
217           nbNodes, depth, cbcLb, lpVal, bestSolVal);
218  }
219  else {
220    printf("%10d  %10d  %10.6f  %10.6f   ----------\n", 
221           nbNodes, depth, cbcLb, lpVal);
222  }
223} /* printLineInfo */
Note: See TracBrowser for help on using the repository browser.