[868] | 1 | // Copyright (C) 2008, International Business Machines |
---|
| 2 | // Corporation and others. All Rights Reserved. |
---|
| 3 | #if defined(_MSC_VER) |
---|
| 4 | // Turn off compiler warning about long names |
---|
| 5 | # pragma warning(disable:4786) |
---|
| 6 | #endif |
---|
| 7 | |
---|
| 8 | #include "CbcHeuristicDiveGuided.hpp" |
---|
| 9 | #include "CbcStrategy.hpp" |
---|
| 10 | |
---|
| 11 | // Default Constructor |
---|
| 12 | CbcHeuristicDiveGuided::CbcHeuristicDiveGuided() |
---|
[912] | 13 | :CbcHeuristicDive() |
---|
[868] | 14 | { |
---|
| 15 | } |
---|
| 16 | |
---|
| 17 | // Constructor from model |
---|
| 18 | CbcHeuristicDiveGuided::CbcHeuristicDiveGuided(CbcModel & model) |
---|
[912] | 19 | :CbcHeuristicDive(model) |
---|
[868] | 20 | { |
---|
| 21 | } |
---|
| 22 | |
---|
| 23 | // Destructor |
---|
| 24 | CbcHeuristicDiveGuided::~CbcHeuristicDiveGuided () |
---|
| 25 | { |
---|
| 26 | } |
---|
| 27 | |
---|
| 28 | // Clone |
---|
| 29 | CbcHeuristicDiveGuided * |
---|
| 30 | CbcHeuristicDiveGuided::clone() const |
---|
| 31 | { |
---|
| 32 | return new CbcHeuristicDiveGuided(*this); |
---|
| 33 | } |
---|
| 34 | |
---|
| 35 | // Create C++ lines to get to current state |
---|
| 36 | void |
---|
| 37 | CbcHeuristicDiveGuided::generateCpp( FILE * fp) |
---|
| 38 | { |
---|
| 39 | CbcHeuristicDiveGuided other; |
---|
| 40 | fprintf(fp,"0#include \"CbcHeuristicDiveGuided.hpp\"\n"); |
---|
| 41 | fprintf(fp,"3 CbcHeuristicDiveGuided heuristicDiveGuided(*cbcModel);\n"); |
---|
| 42 | CbcHeuristic::generateCpp(fp,"heuristicDiveGuided"); |
---|
| 43 | fprintf(fp,"3 cbcModel->addHeuristic(&heuristicDiveGuided);\n"); |
---|
| 44 | } |
---|
| 45 | |
---|
| 46 | // Copy constructor |
---|
| 47 | CbcHeuristicDiveGuided::CbcHeuristicDiveGuided(const CbcHeuristicDiveGuided & rhs) |
---|
| 48 | : |
---|
[912] | 49 | CbcHeuristicDive(rhs) |
---|
[868] | 50 | { |
---|
| 51 | } |
---|
| 52 | |
---|
| 53 | // Assignment operator |
---|
| 54 | CbcHeuristicDiveGuided & |
---|
| 55 | CbcHeuristicDiveGuided::operator=( const CbcHeuristicDiveGuided& rhs) |
---|
| 56 | { |
---|
| 57 | if (this!=&rhs) { |
---|
[912] | 58 | CbcHeuristicDive::operator=(rhs); |
---|
[868] | 59 | } |
---|
| 60 | return *this; |
---|
| 61 | } |
---|
| 62 | |
---|
[912] | 63 | bool |
---|
| 64 | CbcHeuristicDiveGuided::canHeuristicRun() |
---|
[868] | 65 | { |
---|
[912] | 66 | double* bestIntegerSolution = model_->bestSolution(); |
---|
| 67 | if(bestIntegerSolution == NULL) |
---|
| 68 | return false; // no integer solution available. Switch off heuristic |
---|
| 69 | |
---|
| 70 | return CbcHeuristicDive::canHeuristicRun(); |
---|
[868] | 71 | } |
---|
| 72 | |
---|
[944] | 73 | bool |
---|
[912] | 74 | CbcHeuristicDiveGuided::selectVariableToBranch(OsiSolverInterface* solver, |
---|
[944] | 75 | const double* newSolution, |
---|
| 76 | int& bestColumn, |
---|
| 77 | int& bestRound) |
---|
[868] | 78 | { |
---|
| 79 | double* bestIntegerSolution = model_->bestSolution(); |
---|
| 80 | |
---|
| 81 | int numberIntegers = model_->numberIntegers(); |
---|
| 82 | const int * integerVariable = model_->integerVariable(); |
---|
[912] | 83 | double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance); |
---|
[868] | 84 | |
---|
[912] | 85 | bestColumn = -1; |
---|
| 86 | bestRound = -1; // -1 rounds down, +1 rounds up |
---|
| 87 | double bestFraction = DBL_MAX; |
---|
[944] | 88 | bool allTriviallyRoundableSoFar = true; |
---|
[868] | 89 | for (int i=0; i<numberIntegers; i++) { |
---|
| 90 | int iColumn = integerVariable[i]; |
---|
| 91 | double value=newSolution[iColumn]; |
---|
[912] | 92 | double fraction=value-floor(value); |
---|
| 93 | int round = 0; |
---|
[868] | 94 | if (fabs(floor(value+0.5)-value)>integerTolerance) { |
---|
[944] | 95 | if(allTriviallyRoundableSoFar||(downLocks_[i]>0&&upLocks_[i]>0)) { |
---|
| 96 | |
---|
| 97 | if(allTriviallyRoundableSoFar&&downLocks_[i]>0&&upLocks_[i]>0) { |
---|
| 98 | allTriviallyRoundableSoFar = false; |
---|
| 99 | bestFraction = DBL_MAX; |
---|
| 100 | } |
---|
| 101 | |
---|
[912] | 102 | if(value >= bestIntegerSolution[iColumn]) |
---|
| 103 | round = -1; |
---|
| 104 | else { |
---|
| 105 | round = 1; |
---|
| 106 | fraction = 1.0 - fraction; |
---|
[868] | 107 | } |
---|
[912] | 108 | |
---|
| 109 | // if variable is not binary, penalize it |
---|
| 110 | if(!solver->isBinary(iColumn)) |
---|
| 111 | fraction *= 1000.0; |
---|
[868] | 112 | |
---|
[912] | 113 | if(fraction < bestFraction) { |
---|
| 114 | bestColumn = iColumn; |
---|
| 115 | bestFraction = fraction; |
---|
| 116 | bestRound = round; |
---|
[868] | 117 | } |
---|
| 118 | } |
---|
| 119 | } |
---|
| 120 | } |
---|
[944] | 121 | return allTriviallyRoundableSoFar; |
---|
[868] | 122 | } |
---|