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

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

Fix bug in CouenneProblem::checkAux(), cosmetic changes otherwise

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