BonCutStrengthener.cpp
Go to the documentation of this file.
1 // Copyright (C) 2007 International Business Machines and others.
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // $Id: BonCutStrengthener.cpp 2106 2015-01-20 10:33:55Z stefan $
6 //
7 // Author: Andreas Waechter IBM 2007-03-30
8 
9 #include "BonCutStrengthener.hpp"
10 #include "IpBlas.hpp"
11 
12 namespace Bonmin
13 {
14  using namespace Ipopt;
15 
17  SmartPtr<OptionsList> options)
18  :
19  tnlp_solver_(tnlp_solver)
20  {
21  options->GetIntegerValue("oa_log_level", oa_log_level_, tnlp_solver->prefix());
22  options->GetEnumValue("cut_strengthening_type", cut_strengthening_type_,
23  tnlp_solver->prefix());
24  options->GetEnumValue("disjunctive_cut_type", disjunctive_cut_type_,
25  tnlp_solver->prefix());
26 
27  tnlp_solver_->options()->clear();
28  if (!tnlp_solver_->Initialize("strength.opt")) {
29  throw CoinError("CutStrengthener","CutStrengthener","Error during initialization of tnlp_solver_");
30  }
31  tnlp_solver_->options()->SetStringValue("hessian_approximation","limited-memory");
32  tnlp_solver_->options()->SetStringValue("mu_strategy", "adaptive");
33  }
34 
36  {
37  }
38 
39  bool CutStrengthener::HandleOneCut(bool is_tight, TMINLP* tminlp,
40  TMINLP2TNLP* problem,
41  const double* minlp_lb,
42  const double* minlp_ub,
43  const int gindex, CoinPackedVector& cut,
44  double& cut_lb, double& cut_ub,
45  int n, const double* x,
46  double infty)
47  {
48  bool retval = true;
49  const int cut_nele = cut.getNumElements();
50  const int* cut_indices = cut.getIndices();
51  const TMINLP::VariableType* vartypes = problem->var_types();
52  const double* cut_elements = cut.getElements();
53  switch (disjunctive_cut_type_) {
54  case DC_None:
55  if (!is_tight) {
56  retval = StrengthenCut(tminlp, gindex, cut, n, x, minlp_lb, minlp_ub,
57  cut_lb, cut_ub);
58  }
59  break;
60  case DC_MostFractional: {
61  // First check if there is a discrete variable to do disjunction on
62  int imostfra = -1;
63  double viol = 1e-6;
64  for (int i=0; i<cut_nele; i++) {
65  const int& idx = cut_indices[i];
66  if (idx < n && (vartypes[idx] == TMINLP::BINARY ||
67  vartypes[idx] == TMINLP::INTEGER)) {
68  const double& xi = x[idx];
69  const double this_viol = CoinMin(xi-floor(xi),ceil(xi)-xi);
70  if (this_viol > viol) {
71  imostfra = i;
72  viol = this_viol;
73  }
74  }
75  }
76  if (imostfra == -1) {
77  // No disjunction to be done
78  if (!is_tight) {
79  retval = StrengthenCut(tminlp, gindex, cut, n, x, minlp_lb, minlp_ub,
80  cut_lb, cut_ub);
81  }
82  }
83  else {
84  //Do the disjunction for imostfra
85  const int& idx = cut_indices[imostfra];
86  const double& xi = x[idx];
87  if (oa_log_level_>=2) {
88  printf("Doing disjunction for constr %d on x[%d] = %e\n", gindex, idx, xi);
89  }
90  const double down_xi = floor(xi);
91  double* changed_bnds = new double[n];
92  // First the down disjunction:
93  CoinCopyN(minlp_ub, n, changed_bnds);
94  changed_bnds[idx] = down_xi;
95  double cut_lb_down = cut_lb;
96  double cut_ub_down = cut_ub;
97  retval = StrengthenCut(tminlp, gindex, cut, n, x, minlp_lb,
98  changed_bnds, cut_lb_down, cut_ub_down);
99  double cut_lb_up = cut_lb;
100  double cut_ub_up = cut_ub;
101  if (retval) {
102  CoinCopyN(minlp_lb, n, changed_bnds);
103  changed_bnds[idx] = down_xi + 1.;
104  retval = StrengthenCut(tminlp, gindex, cut, n, x, changed_bnds,
105  minlp_ub, cut_lb_up, cut_ub_up);
106  }
107  delete [] changed_bnds;
108  if (retval) {
109  // change the cut
110  double coeff_xi = cut_elements[imostfra];
111  const double old_coeff = coeff_xi;
112  if (cut_lb <= -infty) {
113  // cut has upper bound
114  coeff_xi += cut_ub_down - cut_ub_up;
115  cut_ub = cut_ub_up + (down_xi+1.)*(cut_ub_down - cut_ub_up);
116  }
117  else {
118  // cut has lower bound
119  coeff_xi += cut_lb_down - cut_lb_up;
120  cut_lb = cut_lb_up + (down_xi+1.)*(cut_lb_down - cut_lb_up);
121  }
122  cut.setElement(imostfra, coeff_xi);
123  printf("old coeff = %e new = %e\n", old_coeff, coeff_xi);
124  }
125  }
126  }
127  break;
128  default:
129  std::cerr << "Invalid case for disjunctive_cut_type_ in CutStrengthener HandleOneCut\n";
130  exit(-2);
131  break;
132  }
133 
134  return retval;
135  }
136 
138  TMINLP* tminlp,
139  TMINLP2TNLP* problem,
140  const int gindex, CoinPackedVector& cut,
141  double& cut_lb, double& cut_ub,
142  const double g_val, const double g_lb,
143  const double g_ub,
144  int n, const double* x,
145  double infty)
146  {
147  //printf("before: lb = %e ub = %e rl = %e ru = %e g = %e\n", lb[i], ub[i], rowLower[bindi], rowUpper[bindi], g[bindi]);
148  // First check if the cut is indeed away from the constraint
149  bool is_tight = false;
150  if (gindex==-1) {
151  is_tight = true;
152  }
153  else {
154  const Number tight_tol = 1e-8;
155  if (cut_lb <= -infty && g_ub - g_val <= tight_tol) {
156  is_tight = true;
157  }
158  else if (cut_ub >= infty && g_val - g_lb <= tight_tol) {
159  is_tight = true;
160  }
161  }
164  const double orig_lb = cut_lb;
165  const double orig_ub = cut_ub;
166  bool retval = HandleOneCut(is_tight, tminlp, problem,
167  problem->orig_x_l(),
168  problem->orig_x_u(), gindex, cut,
169  cut_lb, cut_ub, n, x, infty);
170  if (!retval) {
171  if (oa_log_level_ >= 1) {
172  printf(" Error during strengthening of global cut for constraint %d\n", gindex);
173  }
174  }
175  else {
176  if (oa_log_level_ >=2 && (fabs(orig_lb-cut_lb)>1e-4 ||
177  fabs(orig_ub-cut_ub)>1e-4)) {
178  if (orig_ub < infty) {
179  printf(" Strengthening ub of global cut for constraint %d from %e to %e\n", gindex, orig_ub, cut_ub);
180  }
181  else {
182  printf(" Strengthening lb of global cut for constraint %d from %e to %e\n", gindex, orig_lb, cut_lb);
183  }
184  }
185  }
186  }
189  Number lb2 = cut_lb;
190  Number ub2 = cut_ub;
191  CoinPackedVector cut2(cut);
192  bool retval = HandleOneCut(is_tight, tminlp, problem, problem->x_l(),
193  problem->x_u(), gindex, cut2,
194  lb2, ub2, n, x, infty);
195  if (!retval) {
196  if (oa_log_level_ >= 1) {
197  printf(" Error during strengthening of local cut for constraint %d\n", gindex);
198  }
199  }
200  else {
201  const Number localCutTol = 1e-4;
202  if (fabs(lb2-cut_lb) >= localCutTol || fabs(cut_ub-ub2) >= localCutTol) {
203  if (ub2 < infty) {
204  printf(" Strengthening ub of local cut for constraint %d from %e to %e\n", gindex, cut_ub, ub2);
205  }
206  else {
207  printf(" Strengthening ub of local cut for constraint %d from %e to %e\n", gindex, cut_lb, lb2);
208  }
209  // Now we generate a new cut
210  OsiRowCut newCut2;
211  newCut2.setEffectiveness(99.99e99);
212  newCut2.setLb(lb2);
213  newCut2.setUb(ub2);
214  newCut2.setRow(cut2);
215  cs.insert(newCut2);
216  }
217  }
218  }
219  return true;
220  }
221 
223  int constr_index,
224  const CoinPackedVector& row,
225  int n,
226  const double* x,
227  const double* x_l,
228  const double* x_u,
229  double& lb,
230  double& ub)
231  {
232  // Get data to set up the NLP to be solved
233  Index nele_grad_gi;
234  Index* jCol = new Index[n+1];
235  bool new_x = true;
236  if (constr_index == -1) {
237  // Objective function
238  // Compute random perturbation of point
239  double* x_rand = new double[n];
240  for (int i=0; i<n; i++) {
241  const double radius = CoinMin(1., x_u[i]-x_l[i]);
242  const double p = CoinMax(CoinMin(x[i]-0.5*radius, x_u[i]-radius),
243  x_l[i]);
244  x_rand[i] = p + radius*CoinDrand48();
245  }
246  Number* grad_f = new Number[n];
247  bool retval = tminlp->eval_grad_f(n, x_rand, new_x, grad_f);
248  delete [] x_rand;
249  if (!retval) {
250  delete [] grad_f;
251  delete [] jCol;
252  return false;
253  }
254  nele_grad_gi = 0;
255  for (int i=0; i<n; i++) {
256  if (grad_f[i] != 0.) {
257  jCol[nele_grad_gi++] = i;
258  }
259  }
260  delete [] grad_f;
261  jCol[nele_grad_gi++] = n; // for the z variable
262  }
263  else {
264  if (!tminlp->eval_grad_gi(n, x, new_x, constr_index, nele_grad_gi,
265  jCol, NULL)) {
266  delete [] jCol;
267  return false;
268  }
269  }
270 
271  bool lower_bound;
272  if (lb <= -COIN_DBL_MAX) {
273  assert(ub < COIN_DBL_MAX);
274  lower_bound = false;
275  }
276  else {
277  assert(ub >= COIN_DBL_MAX);
278  lower_bound = true;
279  }
281  new StrengtheningTNLP(tminlp, row, lower_bound, n, x, x_l, x_u,
282  constr_index, nele_grad_gi, jCol);
283 
284  delete [] jCol;
285 
286  TNLPSolver::ReturnStatus status =
287  tnlp_solver_->OptimizeTNLP(GetRawPtr(stnlp));
288 
289  if (status == TNLPSolver::solvedOptimal ||
290  status == TNLPSolver::solvedOptimalTol) {
291  const Number tiny_move = 0e-8;
292  const Number final_bound = stnlp->StrengthenedBound();
293  if (lower_bound) {
294  lb = final_bound - tiny_move;
295  }
296  else {
297  ub = final_bound + tiny_move;
298  }
299  }
300  else {
301  return false;
302  }
303 
304  return true;
305  }
306 
309  const CoinPackedVector& cut,
310  bool lower_bound,
311  Index n,
312  const Number* starting_point,
313  const double* x_l_orig,
314  const double* x_u_orig,
315  Index constr_index,
316  Index nvar_constr ,
317  const Index* jCol)
318  :
319  tminlp_(tminlp),
320  n_orig_(n),
321  constr_index_(constr_index),
322  nvar_constr_(nvar_constr),
323  lower_bound_(lower_bound),
324  have_final_bound_(false),
325  grad_f_(NULL)
326  {
327  starting_point_ = new Number[n_orig_];
328  x_full_ = new Number[n_orig_];
329  IpBlasDcopy(n_orig_, starting_point, 1, starting_point_, 1);
330  IpBlasDcopy(n_orig_, starting_point, 1, x_full_, 1);
331 
332  obj_grad_ = new Number[nvar_constr_];
333  x_l_ = new Number[nvar_constr_];
334  x_u_ = new Number[nvar_constr_];
335  const Number zero = 0.;
336  IpBlasDcopy(nvar_constr_, &zero, 0, obj_grad_, 1);
337 
338  const int cut_nele = cut.getNumElements();
339  const int* cut_indices = cut.getIndices();
340  const double* cut_elements = cut.getElements();
341 
342  for (int i = 0; i<cut_nele; i++) {
343  const int& idx = cut_indices[i];
344  // ToDo: This could be done more efficiently
345  Index jidx = -1;
346  for (int j=0; j<nvar_constr_; j++) {
347  if (idx == jCol[j]) {
348  jidx = j;
349  break;
350  }
351  }
352  if (jidx < 0) {
353  printf("There is an index (%d) in the cut that does not appear in the constraint.\n",idx);
354  exit(-99);
355  }
356 
357  if (lower_bound) {
358  obj_grad_[jidx] = cut_elements[i];
359  }
360  else {
361  obj_grad_[jidx] = -cut_elements[i];
362  }
363 
364  }
365 
366  var_indices_ = new Index[nvar_constr_];
367  for (int i=0; i<nvar_constr_; i++) {
368  const Index& j = jCol[i];
369  var_indices_[i] = j;
370  if (j < n) {
371  x_l_[i] = x_l_orig[j];
372  x_u_[i] = x_u_orig[j];
373  }
374  else {
375  x_l_[i] = -1e100;
376  x_u_[i] = 1e100;
377  }
378  }
379 
380  if (constr_index_ == -1) {
381  grad_f_ = new Number[n_orig_];
382  }
383  }
384 
386  {
387  delete [] obj_grad_;
388  delete [] x_l_;
389  delete [] x_u_;
390  delete [] var_indices_;
391  delete [] starting_point_;
392  delete [] x_full_;
393  delete [] grad_f_;
394  }
395 
397  get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
398  Index& nnz_h_lag, IndexStyleEnum& index_style)
399  {
400  n = nvar_constr_;
401  m = 1;
402  nnz_jac_g = nvar_constr_;
403  nnz_h_lag = 0;
404  index_style = C_STYLE;
405 
406  Index n_orig;
407  Index nnz_jac_g_orig;
408  Index nnz_h_lag_orig;
409  TNLP::IndexStyleEnum index_style_orig;
410  if(!tminlp_->get_nlp_info(n_orig, m_orig_, nnz_jac_g_orig, nnz_h_lag_orig,
411  index_style_orig)) {
412  return false;
413  }
414  if (n_orig_ != n_orig) {
415  std::cerr << "Number of variables inconsistent in StrengtheningTNLP::get_nlp_info\n";
416  return false;
417  }
418 
419  return true;
420  }
421 
423  get_bounds_info(Index n, Number* x_l, Number* x_u,
424  Index m, Number* g_l, Number* g_u)
425  {
426  if (constr_index_ == -1) {
427  g_l[0] = -1e100;
428  g_u[0] = 0.;
429  }
430  else {
431  Number* x_l_orig = new Number[n_orig_];
432  Number* x_u_orig = new Number[n_orig_];
433  Number* g_l_orig = new Number[m_orig_];
434  Number* g_u_orig = new Number[m_orig_];
435 
436  if (!tminlp_->get_bounds_info(n_orig_, x_l_orig, x_u_orig,
437  m_orig_, g_l_orig, g_u_orig)) {
438  delete [] x_l_orig;
439  delete [] x_u_orig;
440  delete [] g_l_orig;
441  delete [] g_u_orig;
442  return false;
443  }
444 
445  g_l[0] = g_l_orig[constr_index_];
446  g_u[0] = g_u_orig[constr_index_];
447 
448  delete [] x_l_orig;
449  delete [] x_u_orig;
450  delete [] g_l_orig;
451  delete [] g_u_orig;
452  }
453 
454  for (Index i=0; i<nvar_constr_; i++) {
455  x_l[i] = x_l_[i];
456  x_u[i] = x_u_[i];
457  }
458 
459  return true;
460  }
461 
463  get_starting_point(Index n, bool init_x, Number* x,
464  bool init_z, Number* z_L, Number* z_U,
465  Index m, bool init_lambda,
466  Number* lambda)
467  {
468  assert(!init_z && !init_lambda);
469  assert(n = nvar_constr_);
470  if (init_x) {
471  if (constr_index_ == -1) {
472  for (Index i=0; i<n-1; i++) {
473  x[i] = starting_point_[var_indices_[i]];
474  }
475  x[n-1] = 0.;
476  }
477  else {
478  for (Index i=0; i<n; i++) {
479  x[i] = starting_point_[var_indices_[i]];
480  }
481  }
482  }
483 
484  return true;
485  }
486 
488  eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
489  {
490  obj_value = 0.;
491  for (Index i=0; i<n; i++) {
492  obj_value += obj_grad_[i]*x[i];
493  }
494  return true;
495  }
496 
498  eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
499  {
500  IpBlasDcopy(n, obj_grad_, 1, grad_f, 1);
501  return true;
502  }
503 
505  eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
506  {
507  update_x_full(x);
508  bool retval;
509  if (constr_index_ == -1) {
510  retval = tminlp_->eval_f(n_orig_, x_full_, new_x, g[0]);
511  g[0] -= x[n-1];
512  }
513  else {
514  retval = tminlp_->eval_gi(n_orig_, x_full_, new_x, constr_index_, g[0]);
515  }
516  return retval;
517  }
518 
520  eval_jac_g(Index n, const Number* x, bool new_x,
521  Index m, Index nele_jac, Index* iRow, Index *jCol,
522  Number* values)
523  {
524  bool retval = true;
525  if (iRow) {
526  DBG_ASSERT(jCol && !values);
527  for (Index i=0; i<nele_jac; i++) {
528  iRow[i] = 0;
529  jCol[i] = i;
530  }
531  }
532  else {
533  DBG_ASSERT(!iRow && values);
534  update_x_full(x);
535  if (constr_index_ == -1) {
536  retval = tminlp_->eval_grad_f(n_orig_, x_full_, new_x, grad_f_);
537  if (retval) {
538  for (Index i=0; i<n-1; i++) {
539  values[i] = grad_f_[var_indices_[i]];
540  }
541  values[n-1] = -1.;
542  }
543  }
544  else {
545  retval = tminlp_->eval_grad_gi(n_orig_, x_full_, new_x, constr_index_,
546  nele_jac, NULL, values);
547  }
548  }
549  return retval;
550  }
551 
553  eval_h(Index n, const Number* x, bool new_x,
554  Number obj_factor, Index m, const Number* lambda,
555  bool new_lambda, Index nele_hess,
556  Index* iRow, Index* jCol, Number* values)
557  {
558  std::cerr << "At the moment, StrengtheningTNLP::eval_h is not yet implemented\n";
559  return false;
560  }
561 
563  update_x_full(const Number *x)
564  {
565  if (constr_index_ == -1) {
566  for (Index i=0; i<nvar_constr_-1; i++) {
567  x_full_[var_indices_[i]] = x[i];
568  }
569  }
570  else {
571  for (Index i=0; i<nvar_constr_; i++) {
572  x_full_[var_indices_[i]] = x[i];
573  }
574  }
575  }
576 
578  finalize_solution(SolverReturn status,
579  Index n, const Number* x, const Number* z_L, const Number* z_U,
580  Index m, const Number* g, const Number* lambda,
581  Number obj_value,
582  const IpoptData* ip_data,
583  IpoptCalculatedQuantities* ip_cq)
584  {
585  if (status == SUCCESS || status == STOP_AT_ACCEPTABLE_POINT) {
586  have_final_bound_ = true;
587  strengthened_bound_ = obj_value;
588  }
589  else {
590  have_final_bound_ = false;
591  }
592  }
593 
595  {
596  DBG_ASSERT(have_final_bound_);
597  if (lower_bound_) {
598  return strengthened_bound_;
599  }
600  else {
601  return -strengthened_bound_;
602  }
603  }
604 
605 
606 } // namespace Bonmin
double * values
Base class for all MINLPs that use a standard triplet matrix form and dense vectors.
Definition: BonTMINLP.hpp:59
CutStrengthener()
Default Constructor.
virtual bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
Method to return the objective value.
Ipopt::Number * grad_f_
space for original gradient if objective function is handled
virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number *x_l, Ipopt::Number *x_u, Ipopt::Index m, Ipopt::Number *g_l, Ipopt::Number *g_u)
Method to return the bounds for my problem.
static char * j
Definition: OSdtoa.cpp:3622
Ipopt::Number * x_full_
Full dimentional x which is used to call the TMINLP evaluation routines.
void fint fint fint real fint real real real real real real real real real * e
const Ipopt::Number * x_l()
Get the current values for the lower bounds.
virtual bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, Ipopt::TNLP::IndexStyleEnum &index_style)
Method to return some info about the nlp.
int cut_strengthening_type_
Type of OA cut strengthener.
const Ipopt::Number * x_u()
Get the current values for the upper bounds.
Ipopt::Number * starting_point_
Starting point.
Ipopt::Number * x_l_
Lower bounds for constraint variables.
virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number *x, bool init_z, Ipopt::Number *z_L, Ipopt::Number *z_U, Ipopt::Index m, bool init_lambda, Ipopt::Number *lambda)
Method to return the starting point for the algorithm.
const Ipopt::Number * orig_x_l() const
Get the original values for the lower bounds.
Ipopt::Number * x_u_
Upper bounds for constraint variables.
Ipopt::Index * var_indices_
List of variables appearing on the constraints.
U * GetRawPtr(const OSSmartPtr< U > &smart_ptr)
Definition: OSSmartPtr.hpp:452
const Ipopt::Number * orig_x_u() const
Get the original values for the upper bounds.
virtual void finalize_solution(Ipopt::SolverReturn status, Ipopt::Index n, const Ipopt::Number *x, const Ipopt::Number *z_L, const Ipopt::Number *z_U, Ipopt::Index m, const Ipopt::Number *g, const Ipopt::Number *lambda, Ipopt::Number obj_value, const Ipopt::IpoptData *ip_data, Ipopt::IpoptCalculatedQuantities *ip_cq)
This method is called when the algorithm is complete so the TNLP can store/write the solution...
ReturnStatus
Standard return statuses for a solver.
virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the jacobian (if &quot;values&quot; is NULL) 2) The values of the jacobia...
bool StrengthenCut(Ipopt::SmartPtr< TMINLP > tminlp, int constr_index, const CoinPackedVector &row, int n, const double *x, const double *x_l, const double *x_u, double &lb, double &ub)
Method for strengthening one cut.
Ipopt::Number * obj_grad_
Gradient of the (linear) objective function.
Ipopt::SmartPtr< TNLPSolver > tnlp_solver_
Object for solving the TNLPs.
Class implementing the TNLP for strengthening one cut.
virtual bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
Method to return the constraint residuals.
bool HandleOneCut(bool is_tight, TMINLP *tminlp, TMINLP2TNLP *problem, const double *minlp_lb, const double *minlp_ub, const int gindex, CoinPackedVector &cut, double &cut_lb, double &cut_ub, int n, const double *x, double infty)
Method for generating one type of cut (strengthened or disjunctive)
void fint fint fint real fint real real real real real real * g
virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
Method to return the gradient of the objective.
virtual bool eval_h(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number *lambda, bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index *iRow, Ipopt::Index *jCol, Ipopt::Number *values)
Method to return: 1) The structure of the hessian of the lagrangian (if &quot;values&quot; is NULL) 2) The valu...
void fint * m
This is an adapter class that converts a TMINLP to a TNLP to be solved by Ipopt.
int oa_log_level_
verbosity level for OA-related output
void update_x_full(const Ipopt::Number *x)
Auxilliary method for updating the full x variable.
void fint * n
VariableType
Type of the variables.
Definition: BonTMINLP.hpp:192
Ipopt::Number StrengthenedBound() const
Method for asking for the strengthened bound.
virtual ~CutStrengthener()
Destructor.
int disjunctive_cut_type_
What kind of disjuntion should be done.
bool ComputeCuts(OsiCuts &cs, TMINLP *tminlp, TMINLP2TNLP *problem, const int gindex, CoinPackedVector &cut, double &cut_lb, double &cut_ub, const double g_val, const double g_lb, const double g_ub, int n, const double *x, double infty)
Method for generating and strenghtening all desired cuts.
const TMINLP::VariableType * var_types()
Get the variable types.
real infty
void fint fint fint real fint real * x