11 #include "CoinHelperFunctions.hpp"
12 #include "CbcModel.hpp"
15 #include "CoinTime.hpp"
21 #include "CoinHelperFunctions.hpp"
22 #include "OsiClpSolverInterface.hpp"
51 howOften_(copy.howOften_),
60 CbcHeuristic::operator=(rhs);
87 if(model_->getCurrentPassNumber() > 1)
return 0;
88 if (model_->currentDepth() > 2 && (model_->getNodeCount()%
howOften_)!=0)
95 nlp = dynamic_cast<OsiTMINLPInterface *>(model_->solver()->clone());
102 double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
109 Ipopt::TNLP::IndexStyleEnum index_style;
111 nnz_h_lag, index_style);
114 const double* x_sol = minlp->
x_sol();
115 const double* g_l = minlp->
g_l();
116 const double* g_u = minlp->
g_u();
118 const double * colsol = model_->solver()->getColSolution();
127 for (
int i=0;i<
m;i++) {
140 indexRow(), indexCol(), 0);
146 NULL, NULL, jac_g());
150 CoinIotaN(sortedIndex(), nnz_jac_g, 0);
154 std::sort(sortedIndex.begin(), sortedIndex.end(),
c);
160 int indexCorrection = (index_style == Ipopt::TNLP::C_STYLE) ? 0 : 1;
163 for(
int i=0; i<nnz_jac_g; i++) {
164 int thisIndexCol = indexCol[sortedIndex[i]]-indexCorrection;
165 int thisIndexRow = c_idx[indexRow[sortedIndex[i]] - indexCorrection];
166 if(thisIndexCol != iniCol) {
167 iniCol = thisIndexCol;
168 columnStart[thisIndexCol] =
nnz;
169 columnLength[thisIndexCol] = 0;
171 if(thisIndexRow == -1)
continue;
172 columnLength[thisIndexCol]++;
173 row[
nnz] = thisIndexRow;
174 value[
nnz] = jac_g[i];
181 for(
int i = 0 ; i <
m ; i++){
182 if(c_idx[i] == -1)
continue;
183 newRowLower[c_idx[i]] = g_l[i];
184 newRowUpper[c_idx[i]] = g_u[i];
189 std::copy(x_sol, x_sol + n, newSolution.begin());
192 CoinPackedMatrix matrix(
true,n_lin,n, nnz, value(), row(), columnStart(), columnLength());
200 idxIntegers.reserve(n);
201 for(
int i = 0 ; i <
n ; i++){
203 idxIntegers.push_back(i);
204 objective[i] = beta*(1 - 2*colsol[i]);
214 for(
int i = 0 ; i <
m ; i++){
217 tminlp->
eval_grad_gi(n, x_sol,
false, i, nnz, indices(), NULL);
218 tminlp->
eval_grad_gi(n, x_sol,
false, i, nnz, NULL, grad());
219 for(
int k = 0 ;
k <
nnz ;
k++){
220 objective[indices[
k]] +=
alpha *duals[i] * grad[
k];
223 for(
int i = 0 ; i <
n ; i++){
225 objective[i] +=
alpha * grad[i];
227 else objective[i] = 0;
229 std::copy(objective.begin(), objective.end(), std::ostream_iterator<double>(std::cout,
" "));
230 std::cout<<std::endl;
236 CoinMessageHandler * handler = model_->messageHandler()->clone();
237 si->passInMessageHandler(handler);
238 si->messageHandler()->setLogLevel(1);
240 si->loadProblem(matrix, model_->solver()->getColLower(), model_->solver()->getColUpper(), objective(),
241 newRowLower(), newRowUpper());
242 si->setInteger(idxIntegers(), static_cast<int>(idxIntegers.size()));
245 bool hasFractionnal =
true;
246 while(hasFractionnal){
248 hasFractionnal =
false;
250 bool feasible =
false;
253 std::copy(solution, solution + n, newSolution.begin());
263 for (
int iColumn=0;iColumn<
n;iColumn++) {
265 double value=newSolution[iColumn];
266 if (fabs(floor(value+0.5)-value)>integerTolerance) {
267 #ifdef DEBUG_BON_HEURISTIC_DIVE_MIP
268 cout<<
"It should be infeasible because: "<<endl;
269 cout<<
"variable "<<iColumn<<
" is not integer"<<endl;
275 value=floor(newSolution[iColumn]+0.5);
277 v.insert(iColumn, -1);
288 bool feasible =
false;
291 std::copy(solution, solution + n, newSolution.begin());
303 for (
int iColumn=0;iColumn<
n;iColumn++) {
305 double value=newSolution[iColumn];
306 if (fabs(floor(value+0.5)-value)>integerTolerance) {
311 value=floor(newSolution[iColumn]+0.5);
313 v.insert(iColumn, -1);
331 std::copy(x_sol,x_sol+n, newSolution.begin());
335 double newSolutionValue;
336 minlp->
eval_f(n, newSolution(),
true, newSolutionValue);
337 if(newSolutionValue < solutionValue) {
338 std::copy(newSolution.begin(), newSolution.end(), betterSolution);
339 solutionValue = newSolutionValue;
346 #ifdef DEBUG_BON_HEURISTIC_DIVE_MIP
347 std::cout<<
"DiveMIP returnCode = "<<returnCode<<std::endl;
355 roptions->AddStringOption2(
356 "MILP_rounding_heuristic",
357 "if yes runs the heuristic",
359 "no",
"don't run it",
360 "yes",
"runs the heuristic",
Base class for all MINLPs that use a standard triplet matrix form and dense vectors.
For undocumented options.
static void registerOptions(Ipopt::SmartPtr< Bonmin::RegisteredOptions > roptions)
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 ...
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.
Ipopt::SolverReturn optimization_status() const
Get Optimization status.
int howOften_
How often to do (code can change)
void SetVariableUpperBound(Ipopt::Index var_no, Ipopt::Number x_u)
Change the upper bound on the variable.
virtual void initialSolve()
Solve initial continuous relaxation.
const double * getLastSolution()
get the solution found in last local search (return NULL if no solution).
virtual bool get_constraints_linearity(Ipopt::Index m, Ipopt::TNLP::LinearityType *const_types)=0
overload this method to provide the constraint linearity.
A very simple class to provide a common interface for solving MIPs with Cplex and Cbc...
Bonmin::Algorithm getAlgorithm()
Get the algorithm used.
~MilpRounding()
Destructor.
OsiSolverInterface * solver()
const Ipopt::Number * g_l()
Get the current values for constraints lower bounds.
virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Index i, Ipopt::Index &nele_grad_gi, Ipopt::Index *jCol, Ipopt::Number *values)
Compute the structure or values of the gradient for one constraint.
virtual int solution(double &solutionValue, double *betterSolution)
Performs heuristic.
const TMINLP * model() const
virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number *x, bool new_x, Ipopt::Number *grad_f)=0
overload this method to return the vector of the gradient of the objective w.r.t. ...
bool operator()(int i, int j)
Destructor.
virtual const double * getRowPrice() const
Get pointer to array[getNumRows()] of dual prices.
const Ipopt::Number * x_sol() const
get the solution values
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.
MilpRounding(BonminSetup *setup)
Constructor with setup.
int nnz
ATTENTION: Filter expect the jacobian to be ordered by row.
This is an adapter class that converts a TMINLP to a TNLP to be solved by Ipopt.
SubMipSolver * mip_
A subsolver for MIP.
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.
BonminSetup * setup_
Setup to use for local searches (will make copies).
void optimize(double cutoff, int loglevel, double maxTime)
update cutoff and optimize MIP.
void Initialize(BonminSetup *setup)
Initialize method.
const Ipopt::Number * g_u()
Get the current values for constraints upper bounds.
const char * prefix() const
Get prefix to use for options.
VariableType
Type of the variables.
MilpRounding & operator=(const MilpRounding &rhs)
Assignment operator.
const TMINLP::VariableType * var_types()
Get the variable types.
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.