/home/coin/SVN-release/OS-2.1.1/Bonmin/src/CbcBonmin/Heuristics/BonHeuristicDiveVectorLength.cpp

Go to the documentation of this file.
00001 // Copyright (C) 2007, International Business Machines Corporation and others. 
00002 // All Rights Reserved.
00003 // This code is published under the Common Public License.
00004 //
00005 // Authors :
00006 // Joao P. Goncalves, International Business Machines Corporation
00007 //
00008 // Date : November 12, 2007
00009 
00010 #if defined(_MSC_VER)
00011 // Turn off compiler warning about long names
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 &copy)
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     // Get the indicies of the jacobian
00074     // This is also a way of knowing which variables are
00075     // used in each row
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; // -1 rounds down, +1 rounds up
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         //double downCost = COIN_DBL_MAX;
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 }

Generated on Mon May 3 03:05:16 2010 by  doxygen 1.4.7