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