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