11 #include "CoinHelperFunctions.hpp"
12 #include "CbcModel.hpp"
14 #include "OsiAuxInfo.hpp"
16 #include "CoinTime.hpp"
28 HeuristicDive::HeuristicDive()
32 percentageToFix_(0.2),
40 percentageToFix_(0.2),
50 percentageToFix_(copy.percentageToFix_),
51 howOften_(copy.howOften_)
58 CbcHeuristic::operator=(rhs);
70 if ((model_->getNodeCount()%
howOften_)!=0||model_->getCurrentPassNumber()>1)
77 nlp = dynamic_cast<OsiTMINLPInterface *>(model_->solver()->clone());
84 double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
85 double primalTolerance = 1.0e-6;
91 Ipopt::TNLP::IndexStyleEnum index_style;
92 minlp->
get_nlp_info(numberColumns, numberRows, nnz_jac_g,
93 nnz_h_lag, index_style);
96 const double* x_sol = minlp->
x_sol();
97 const double* x_l = minlp->
x_l();
98 const double* x_u = minlp->
x_u();
100 const double* g_l = minlp->
g_l();
101 const double* g_u = minlp->
g_u();
108 double* newSolution =
new double [numberColumns];
109 memcpy(newSolution,x_sol,numberColumns*
sizeof(
double));
110 double* new_g_sol =
new double [numberRows];
115 int numberFractionalVariables = 0;
116 for (
int iColumn=0;iColumn<numberColumns;iColumn++) {
118 integerColumns.push_back(iColumn);
119 double value=newSolution[iColumn];
120 if (fabs(floor(value+0.5)-value)>integerTolerance) {
121 numberFractionalVariables++;
129 int numberIntegers = (
int) integerColumns.size();
130 int* columnFixed =
new int [numberIntegers];
131 double* originalBound =
new double [numberIntegers];
132 bool * fixedAtLowerBound =
new bool [numberIntegers];
137 while(numberFractionalVariables) {
144 bestColumn, bestRound);
147 int numberAtBoundFixed = 0;
148 for (
int i=0; i<numberIntegers; i++) {
149 int iColumn = integerColumns[i];
150 double value=newSolution[iColumn];
151 if(fabs(floor(value+0.5)-value)<=integerTolerance &&
152 numberAtBoundFixed < maxNumberAtBoundToFix) {
154 if (fabs(x_l[iColumn]-value)<=integerTolerance &&
155 x_l[iColumn] != x_u[iColumn]) {
156 columnFixed[numberAtBoundFixed] = iColumn;
157 originalBound[numberAtBoundFixed] = x_u[iColumn];
158 fixedAtLowerBound[numberAtBoundFixed] =
true;
160 numberAtBoundFixed++;
162 else if(fabs(x_u[iColumn]-value)<=integerTolerance &&
163 x_l[iColumn] != x_u[iColumn]) {
164 columnFixed[numberAtBoundFixed] = iColumn;
165 originalBound[numberAtBoundFixed] = x_l[iColumn];
166 fixedAtLowerBound[numberAtBoundFixed] =
false;
168 numberAtBoundFixed++;
170 if(numberAtBoundFixed == maxNumberAtBoundToFix)
175 double originalBoundBestColumn;
176 if(bestColumn >= 0) {
178 originalBoundBestColumn = x_u[bestColumn];
182 originalBoundBestColumn = x_l[bestColumn];
188 int originalBestRound = bestRound;
194 if(numberAtBoundFixed > 0) {
196 for(
int i=0; i<numberAtBoundFixed; i++) {
197 int iColFixed = columnFixed[i];
198 if(fixedAtLowerBound[i])
203 numberAtBoundFixed = 0;
205 else if(bestRound == originalBestRound) {
227 memcpy(newSolution,x_sol,numberColumns*
sizeof(
double));
229 double newSolutionValue;
230 minlp->
eval_f(numberColumns, newSolution,
true, newSolutionValue);
231 if(newSolutionValue >= solutionValue)
234 numberFractionalVariables = 0;
235 for(
int iIntCol=0; iIntCol<(
int)integerColumns.size(); iIntCol++) {
236 int iColumn = integerColumns[iIntCol];
237 double value=newSolution[iColumn];
238 if (fabs(floor(value+0.5)-value)>integerTolerance)
239 numberFractionalVariables++;
244 bool feasible =
true;
245 for (
int iColumn=0;iColumn<numberColumns;iColumn++) {
246 double value=newSolution[iColumn];
247 if(value < x_l[iColumn] || value > x_u[iColumn]) {
252 if (fabs(floor(value+0.5)-value)>integerTolerance) {
258 minlp->
eval_g(numberColumns, newSolution,
true,
259 numberRows, new_g_sol);
260 for(
int iRow=0; iRow<numberRows; iRow++) {
261 if(new_g_sol[iRow]<g_l[iRow]-primalTolerance ||
262 new_g_sol[iRow]>g_u[iRow]+primalTolerance) {
267 #ifdef DEBUG_BON_HEURISTIC_DIVE
268 cout<<
"It should be infeasible because: "<<endl;
269 cout<<
"g_l["<<iRow<<
"]= "<<g_l[iRow]<<
" "
270 <<
"g_sol["<<iRow<<
"]= "<<new_g_sol[iRow]<<
" "
271 <<
"g_u["<<iRow<<
"]= "<<g_u[iRow]<<endl;
272 cout<<
"primalTolerance= "<<primalTolerance<<endl;
281 double newSolutionValue;
282 minlp->
eval_f(numberColumns, newSolution,
true, newSolutionValue);
283 if(newSolutionValue < solutionValue) {
284 memcpy(betterSolution,newSolution,numberColumns*
sizeof(
double));
285 solutionValue = newSolutionValue;
290 delete [] newSolution;
293 delete [] columnFixed;
294 delete [] originalBound;
295 delete [] fixedAtLowerBound;
297 #ifdef DEBUG_BON_HEURISTIC_DIVE
298 std::cout<<
"Dive returnCode = "<<returnCode<<std::endl;
312 Ipopt::TNLP::IndexStyleEnum index_style;
313 minlp->
get_nlp_info(numberColumns, numberRows, nnz_jac_g,
314 nnz_h_lag, index_style);
316 const double* x_sol = minlp->
x_sol();
317 const double* x_l = minlp->
x_l();
318 const double* x_u = minlp->
x_u();
319 const double* g_sol = minlp->
g_sol();
320 const double* g_l = minlp->
g_l();
321 const double* g_u = minlp->
g_u();
324 for (
int iColumn=0;iColumn<numberColumns;iColumn++) {
325 double value=x_sol[iColumn];
326 if(value < x_l[iColumn] || value > x_u[iColumn]) {
330 for(
int iRow=0; iRow<numberRows; iRow++) {
331 if(g_sol[iRow]<g_l[iRow]-primalTolerance ||
332 g_sol[iRow]>g_u[iRow]+primalTolerance) {
347 Ipopt::TNLP::IndexStyleEnum index_style;
348 minlp->
get_nlp_info(numberColumns, numberRows, nnz_jac_g,
349 nnz_h_lag, index_style);
351 const double* g_sol = minlp->
g_sol();
352 const double* g_l = minlp->
g_l();
353 const double* g_u = minlp->
g_u();
355 for(
int iRow=0; iRow<numberRows; iRow++) {
356 if(g_sol[iRow]<g_l[iRow]-primalTolerance) {
357 primalTolerance = g_l[iRow]-g_sol[iRow];
358 }
else if(g_sol[iRow]>g_u[iRow]+primalTolerance) {
359 primalTolerance = g_sol[iRow]-g_u[iRow];
virtual void selectVariableToBranch(TMINLP2TNLP *minlp, const vector< int > &integerColumns, const double *newSolution, int &bestColumn, int &bestRound)=0
Selects the next variable to branch on.
HeuristicDive()
Default constructor.
int howOften_
How often to do (code can change)
bool isNlpFeasible(TMINLP2TNLP *minlp, const double primalTolerance)
checks if the NLP relaxation of the problem is feasible
const TMINLP2TNLP * problem() const
get pointer to the TMINLP2TNLP adapter
This is class provides an Osi interface for a Mixed Integer Linear Program expressed as a TMINLP (so ...
void adjustPrimalTolerance(TMINLP2TNLP *minlp, double &primalTolerance)
Adjusts the primalTolerance in case some of the constraints are violated.
OsiSolverInterface * clone(bool copyData=true) const
Virtual copy constructor.
void SetVariableLowerBound(Ipopt::Index var_no, Ipopt::Number x_l)
Change the lower bound on the variable.
BonminSetup * setup_
Setup to use for local searches (will make copies).
HeuristicDive & operator=(const HeuristicDive &rhs)
Assignment operator.
Ipopt::SolverReturn optimization_status() const
Get Optimization status.
void SetVariableUpperBound(Ipopt::Index var_no, Ipopt::Number x_u)
Change the upper bound on the variable.
virtual void initialSolve()
Solve initial continuous relaxation.
Bonmin::Algorithm getAlgorithm()
Get the algorithm used.
const Ipopt::Number * x_l()
Get the current values for the lower bounds.
const Ipopt::Number * g_sol() const
get the g solution (activities)
virtual bool eval_g(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index m, Ipopt::Number *g)
Returns the vector of constraint values in x.
const Ipopt::Number * x_u()
Get the current values for the upper bounds.
const Ipopt::Number * g_l()
Get the current values for constraints lower bounds.
const Ipopt::Number * x_sol() const
get the solution values
virtual void setInternalVariables(TMINLP2TNLP *minlp)=0
sets internal variables
OsiTMINLPInterface * nonlinearSolver()
Pointer to the non-linear solver used.
virtual bool eval_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number &obj_value)
Returns the value of the objective function in x.
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.
virtual int solution(double &solutionValue, double *betterSolution)
Performs heuristic.
double percentageToFix_
Percentage of integer variables to fix at bounds.
const Ipopt::Number * g_u()
Get the current values for constraints upper bounds.
VariableType
Type of the variables.
const TMINLP::VariableType * var_types()
Get the variable types.