BonHeuristicDiveMIPVectorLength.cpp
Go to the documentation of this file.
1 // Copyright (C) 2007, International Business Machines Corporation and others.
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // Joao P. Goncalves, International Business Machines Corporation
7 //
8 // Date : November 12, 2007
9 
10 #include "CoinPragma.hpp"
12 #include "CbcModel.hpp"
13 
14 namespace Bonmin
15 {
16 #if 0
18  :
19  HeuristicDiveMIP(),
20  columnLength_(NULL)
21  {}
22 #endif
23 
25  :
26  HeuristicDiveMIP(setup),
27  columnLength_(NULL)
28  {
29  Initialize(setup->options());
30  }
31 
33  :
34  HeuristicDiveMIP(copy),
35  columnLength_(NULL)
36  {
37  }
38 
41  {
42  if (this!=&rhs) {
44  delete [] columnLength_;
45  columnLength_ = NULL;
46  }
47  return *this;
48  }
49 
50  CbcHeuristic *
52  {
53  return new HeuristicDiveMIPVectorLength(*this);
54  }
55 
56  void
58  {
59  delete [] columnLength_;
60 
61  int numberColumns;
62  int numberRows;
63  int nnz_jac_g;
64  int nnz_h_lag;
65  Ipopt::TNLP::IndexStyleEnum index_style;
66  minlp->get_nlp_info(numberColumns, numberRows, nnz_jac_g,
67  nnz_h_lag, index_style);
68 
69  const double* x_sol = minlp->x_sol();
70 
71  // Get the indicies of the jacobian
72  // This is also a way of knowing which variables are
73  // used in each row
74  int* indexRow = new int[nnz_jac_g];
75  int* indexCol = new int[nnz_jac_g];
76  minlp->eval_jac_g(numberColumns, x_sol, false,
77  numberRows, nnz_jac_g,
78  indexRow, indexCol, 0);
79  columnLength_ = new int[numberColumns];
80  int indexCorrection = (index_style == Ipopt::TNLP::C_STYLE) ? 0 : 1;
81  int iniCol = -1;
82  for(int i=0; i<nnz_jac_g; i++) {
83  int thisIndexCol = indexCol[i]-indexCorrection;
84  if(indexCol[i] != iniCol) {
85  iniCol = indexCol[i];
86  columnLength_[thisIndexCol] = 1;
87  }
88  else {
89  columnLength_[thisIndexCol]++;
90  }
91  }
92 
93  }
94 
95  void
97  const vector<int> & integerColumns,
98  const double* newSolution,
99  int& bestColumn,
100  int& bestRound)
101  {
102  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
103 
104  const double* x_l = minlp->x_l();
105  const double* x_u = minlp->x_u();
106 
107  int numberColumns;
108  int numberRows;
109  int nnz_jac_g;
110  int nnz_h_lag;
111  Ipopt::TNLP::IndexStyleEnum index_style;
112  minlp->get_nlp_info(numberColumns, numberRows, nnz_jac_g,
113  nnz_h_lag, index_style);
114 
115  double* gradient_f = new double[numberColumns];
116 
117  double bestScore = COIN_DBL_MAX;
118  bestColumn = -1;
119  bestRound = -1; // -1 rounds down, +1 rounds up
120  minlp->eval_grad_f(numberColumns,newSolution,true,gradient_f);
121  for(int iIntCol=0; iIntCol<(int)integerColumns.size(); iIntCol++) {
122  int iColumn = integerColumns[iIntCol];
123  double value=newSolution[iColumn];
124  if (fabs(floor(value+0.5)-value)>integerTolerance) {
125  double below = floor(value);
126  double downFraction = COIN_DBL_MAX;
127  //double downCost = COIN_DBL_MAX;
128  double gradient = gradient_f[iColumn];
129  if(below >= x_l[iColumn])
130  downFraction = value-below;
131  double above = ceil(value);
132  double upFraction = COIN_DBL_MAX;
133  if(above <= x_u[iColumn])
134  upFraction = ceil(value)-value;
135  double objdelta = 0;
136  int round = 0;
137  if(gradient>=0.0 && upFraction < COIN_DBL_MAX) {
138  objdelta = gradient*upFraction;
139  round = 1;
140  } else if(gradient<0.0 && downFraction < COIN_DBL_MAX) {
141  objdelta = gradient*downFraction;
142  round = -1;
143  } else if(upFraction < COIN_DBL_MAX) {
144  objdelta = gradient*upFraction;
145  round = 1;
146  } else {
147  objdelta = gradient*downFraction;
148  round = -1;
149  }
150  double score = (objdelta + 1e-6)/((double)columnLength_[iColumn]+1.0);
151  if(score<bestScore) {
152  bestScore = score;
153  bestColumn = iColumn;
154  bestRound = round;
155  }
156  }
157  }
158 
159  delete [] gradient_f;
160 
161  }
162 
163  void
165  roptions->SetRegisteringCategory("Primal Heuristics", RegisteredOptions::BonminCategory);
166  roptions->AddStringOption2(
167  "heuristic_dive_MIP_vectorLength",
168  "if yes runs the Dive MIP VectorLength heuristic",
169  "no",
170  "no", "",
171  "yes", "",
172  "");
173  roptions->setOptionExtraInfo("heuristic_dive_MIP_vectorLength", 63);
174  }
175 
176  void
178  }
179 
180 }
HeuristicDiveMIP & operator=(const HeuristicDiveMIP &rhs)
Assignment operator.
virtual CbcHeuristic * clone() const
Clone.
int * columnLength_
the number of nonzero elements in each column
void Initialize(Ipopt::SmartPtr< Ipopt::OptionsList > options)
Initiaize using passed options.
HeuristicDiveMIPVectorLength()
Default Constructor.
HeuristicDiveMIPVectorLength & operator=(const HeuristicDiveMIPVectorLength &rhs)
Assignment operator.
virtual void setInternalVariables(TMINLP2TNLP *minlp)
sets internal variables
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.
const Ipopt::Number * x_u()
Get the current values for the upper bounds.
virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)
Returns the vector of the gradient of the objective w.r.t.
static int
Definition: OSdtoa.cpp:2173
const Ipopt::Number * x_sol() const
get the solution values
virtual void selectVariableToBranch(TMINLP2TNLP *minlp, const vector< int > &integerColumns, const double *newSolution, int &bestColumn, int &bestRound)
Selects the next variable to branch on.
Ipopt::SmartPtr< Ipopt::OptionsList > options()
Acces list of Options.
This is an adapter class that converts a TMINLP to a TNLP to be solved by Ipopt.
virtual bool get_nlp_info(Ipopt::Index &n, Ipopt::Index &m, Ipopt::Index &nnz_jac_g, Ipopt::Index &nnz_h_lag, TNLP::IndexStyleEnum &index_style)
This call is just passed onto the TMINLP object.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
Register the options common to all local search based heuristics.
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)
Returns the jacobian of the constraints.