00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "CoinPragma.hpp"
00011 #include "BonHeuristicDiveMIPVectorLength.hpp"
00012 #include "CbcModel.hpp"
00013
00014 namespace Bonmin
00015 {
00016 #if 0
00017 HeuristicDiveMIPVectorLength::HeuristicDiveMIPVectorLength()
00018 :
00019 HeuristicDiveMIP(),
00020 columnLength_(NULL)
00021 {}
00022 #endif
00023
00024 HeuristicDiveMIPVectorLength::HeuristicDiveMIPVectorLength(BonminSetup * setup)
00025 :
00026 HeuristicDiveMIP(setup),
00027 columnLength_(NULL)
00028 {
00029 Initialize(setup->options());
00030 }
00031
00032 HeuristicDiveMIPVectorLength::HeuristicDiveMIPVectorLength(const HeuristicDiveMIPVectorLength ©)
00033 :
00034 HeuristicDiveMIP(copy),
00035 columnLength_(NULL)
00036 {
00037 }
00038
00039 HeuristicDiveMIPVectorLength &
00040 HeuristicDiveMIPVectorLength::operator=( const HeuristicDiveMIPVectorLength& rhs)
00041 {
00042 if (this!=&rhs) {
00043 HeuristicDiveMIP::operator=(rhs);
00044 delete [] columnLength_;
00045 columnLength_ = NULL;
00046 }
00047 return *this;
00048 }
00049
00050 CbcHeuristic *
00051 HeuristicDiveMIPVectorLength::clone() const
00052 {
00053 return new HeuristicDiveMIPVectorLength(*this);
00054 }
00055
00056 void
00057 HeuristicDiveMIPVectorLength::setInternalVariables(TMINLP2TNLP* minlp)
00058 {
00059 delete [] columnLength_;
00060
00061 int numberColumns;
00062 int numberRows;
00063 int nnz_jac_g;
00064 int nnz_h_lag;
00065 Ipopt::TNLP::IndexStyleEnum index_style;
00066 minlp->get_nlp_info(numberColumns, numberRows, nnz_jac_g,
00067 nnz_h_lag, index_style);
00068
00069 const double* x_sol = minlp->x_sol();
00070
00071
00072
00073
00074 int* indexRow = new int[nnz_jac_g];
00075 int* indexCol = new int[nnz_jac_g];
00076 minlp->eval_jac_g(numberColumns, x_sol, false,
00077 numberRows, nnz_jac_g,
00078 indexRow, indexCol, 0);
00079 columnLength_ = new int[numberColumns];
00080 int indexCorrection = (index_style == Ipopt::TNLP::C_STYLE) ? 0 : 1;
00081 int iniCol = -1;
00082 for(int i=0; i<nnz_jac_g; i++) {
00083 int thisIndexCol = indexCol[i]-indexCorrection;
00084 if(indexCol[i] != iniCol) {
00085 iniCol = indexCol[i];
00086 columnLength_[thisIndexCol] = 1;
00087 }
00088 else {
00089 columnLength_[thisIndexCol]++;
00090 }
00091 }
00092
00093 }
00094
00095 void
00096 HeuristicDiveMIPVectorLength::selectVariableToBranch(TMINLP2TNLP* minlp,
00097 const vector<int> & integerColumns,
00098 const double* newSolution,
00099 int& bestColumn,
00100 int& bestRound)
00101 {
00102 double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
00103
00104 const double* x_l = minlp->x_l();
00105 const double* x_u = minlp->x_u();
00106
00107 int numberColumns;
00108 int numberRows;
00109 int nnz_jac_g;
00110 int nnz_h_lag;
00111 Ipopt::TNLP::IndexStyleEnum index_style;
00112 minlp->get_nlp_info(numberColumns, numberRows, nnz_jac_g,
00113 nnz_h_lag, index_style);
00114
00115 double* gradient_f = new double[numberColumns];
00116
00117 double bestScore = COIN_DBL_MAX;
00118 bestColumn = -1;
00119 bestRound = -1;
00120 minlp->eval_grad_f(numberColumns,newSolution,true,gradient_f);
00121 for(int iIntCol=0; iIntCol<(int)integerColumns.size(); iIntCol++) {
00122 int iColumn = integerColumns[iIntCol];
00123 double value=newSolution[iColumn];
00124 if (fabs(floor(value+0.5)-value)>integerTolerance) {
00125 double below = floor(value);
00126 double downFraction = COIN_DBL_MAX;
00127
00128 double gradient = gradient_f[iColumn];
00129 if(below >= x_l[iColumn])
00130 downFraction = value-below;
00131 double above = ceil(value);
00132 double upFraction = COIN_DBL_MAX;
00133 if(above <= x_u[iColumn])
00134 upFraction = ceil(value)-value;
00135 double objdelta = 0;
00136 int round = 0;
00137 if(gradient>=0.0 && upFraction < COIN_DBL_MAX) {
00138 objdelta = gradient*upFraction;
00139 round = 1;
00140 } else if(gradient<0.0 && downFraction < COIN_DBL_MAX) {
00141 objdelta = gradient*downFraction;
00142 round = -1;
00143 } else if(upFraction < COIN_DBL_MAX) {
00144 objdelta = gradient*upFraction;
00145 round = 1;
00146 } else {
00147 objdelta = gradient*downFraction;
00148 round = -1;
00149 }
00150 double score = (objdelta + 1e-6)/((double)columnLength_[iColumn]+1.0);
00151 if(score<bestScore) {
00152 bestScore = score;
00153 bestColumn = iColumn;
00154 bestRound = round;
00155 }
00156 }
00157 }
00158
00159 delete [] gradient_f;
00160
00161 }
00162
00163 void
00164 HeuristicDiveMIPVectorLength::registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){
00165 roptions->SetRegisteringCategory("Primal Heuristics", RegisteredOptions::BonminCategory);
00166 roptions->AddStringOption2(
00167 "heuristic_dive_MIP_vectorLength",
00168 "if yes runs the Dive MIP VectorLength heuristic",
00169 "no",
00170 "no", "",
00171 "yes", "",
00172 "");
00173 roptions->setOptionExtraInfo("heuristic_dive_MIP_vectorLength", 63);
00174 }
00175
00176 void
00177 HeuristicDiveMIPVectorLength::Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options){
00178 }
00179
00180 }