source: trunk/Cbc/src/CbcHeuristicDiveGuided.cpp @ 2280

Last change on this file since 2280 was 2280, checked in by forrest, 3 years ago

allow heuristics to see if integers are 'optional'

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.0 KB
Line 
1/* $Id: CbcHeuristicDiveGuided.cpp 2280 2016-06-14 14:39:54Z forrest $ */
2// Copyright (C) 2008, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#if defined(_MSC_VER)
7// Turn off compiler warning about long names
8#  pragma warning(disable:4786)
9#endif
10
11#include "CbcHeuristicDiveGuided.hpp"
12#include "CbcStrategy.hpp"
13
14// Default Constructor
15CbcHeuristicDiveGuided::CbcHeuristicDiveGuided()
16        : CbcHeuristicDive()
17{
18}
19
20// Constructor from model
21CbcHeuristicDiveGuided::CbcHeuristicDiveGuided(CbcModel & model)
22        : CbcHeuristicDive(model)
23{
24}
25
26// Destructor
27CbcHeuristicDiveGuided::~CbcHeuristicDiveGuided ()
28{
29}
30
31// Clone
32CbcHeuristicDiveGuided *
33CbcHeuristicDiveGuided::clone() const
34{
35    return new CbcHeuristicDiveGuided(*this);
36}
37
38// Create C++ lines to get to current state
39void
40CbcHeuristicDiveGuided::generateCpp( FILE * fp)
41{
42    CbcHeuristicDiveGuided other;
43    fprintf(fp, "0#include \"CbcHeuristicDiveGuided.hpp\"\n");
44    fprintf(fp, "3  CbcHeuristicDiveGuided heuristicDiveGuided(*cbcModel);\n");
45    CbcHeuristic::generateCpp(fp, "heuristicDiveGuided");
46    fprintf(fp, "3  cbcModel->addHeuristic(&heuristicDiveGuided);\n");
47}
48
49// Copy constructor
50CbcHeuristicDiveGuided::CbcHeuristicDiveGuided(const CbcHeuristicDiveGuided & rhs)
51        :
52        CbcHeuristicDive(rhs)
53{
54}
55
56// Assignment operator
57CbcHeuristicDiveGuided &
58CbcHeuristicDiveGuided::operator=( const CbcHeuristicDiveGuided & rhs)
59{
60    if (this != &rhs) {
61        CbcHeuristicDive::operator=(rhs);
62    }
63    return *this;
64}
65
66bool
67CbcHeuristicDiveGuided::canHeuristicRun()
68{
69    double* bestIntegerSolution = model_->bestSolution();
70    if (bestIntegerSolution == NULL)
71        return false; // no integer solution available. Switch off heuristic
72
73    return CbcHeuristicDive::canHeuristicRun();
74}
75
76bool
77CbcHeuristicDiveGuided::selectVariableToBranch(OsiSolverInterface* solver,
78        const double* newSolution,
79        int& bestColumn,
80        int& bestRound)
81{
82    double* bestIntegerSolution = model_->bestSolution();
83
84    int numberIntegers = model_->numberIntegers();
85    const int * integerVariable = model_->integerVariable();
86    double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
87
88    bestColumn = -1;
89    bestRound = -1; // -1 rounds down, +1 rounds up
90    double bestFraction = COIN_DBL_MAX;
91    bool allTriviallyRoundableSoFar = true;
92    int bestPriority = COIN_INT_MAX;
93    for (int i = 0; i < numberIntegers; i++) {
94        int iColumn = integerVariable[i];
95        if (!isHeuristicInteger(solver,iColumn))
96          continue;
97        double value = newSolution[iColumn];
98        double fraction = value - floor(value);
99        int round = 0;
100        if (fabs(floor(value + 0.5) - value) > integerTolerance) {
101            if (allTriviallyRoundableSoFar || (downLocks_[i] > 0 && upLocks_[i] > 0)) {
102
103                if (allTriviallyRoundableSoFar && downLocks_[i] > 0 && upLocks_[i] > 0) {
104                    allTriviallyRoundableSoFar = false;
105                    bestFraction = COIN_DBL_MAX;
106                }
107
108                if (value >= bestIntegerSolution[iColumn])
109                    round = -1;
110                else {
111                    round = 1;
112                    fraction = 1.0 - fraction;
113                }
114
115                // if variable is not binary, penalize it
116                if (!solver->isBinary(iColumn))
117                    fraction *= 1000.0;
118
119                // if priorities then use
120                if (priority_) {
121                  int thisRound=static_cast<int>(priority_[i].direction);
122                  if ((thisRound&1)!=0) 
123                    round = ((thisRound&2)==0) ? -1 : +1;
124                  if (priority_[i].priority>bestPriority) {
125                    fraction=COIN_DBL_MAX;
126                  } else if (priority_[i].priority<bestPriority) {
127                    bestPriority=static_cast<int>(priority_[i].priority);
128                    bestFraction=COIN_DBL_MAX;
129                  }
130                }
131                if (fraction < bestFraction) {
132                    bestColumn = iColumn;
133                    bestFraction = fraction;
134                    bestRound = round;
135                }
136            }
137        }
138    }
139    return allTriviallyRoundableSoFar;
140}
141
Note: See TracBrowser for help on using the repository browser.