source: trunk/Cbc/src/CbcHeuristicDiveCoefficient.cpp @ 2093

Last change on this file since 2093 was 2093, checked in by forrest, 5 years ago

changes for diving heuristic

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.4 KB
Line 
1/* $Id: CbcHeuristicDiveCoefficient.cpp 2093 2014-11-06 16:17:38Z 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//#define PRINT_DEBUG
12
13#include "CbcHeuristicDiveCoefficient.hpp"
14#include "CbcStrategy.hpp"
15
16// Default Constructor
17CbcHeuristicDiveCoefficient::CbcHeuristicDiveCoefficient()
18        : CbcHeuristicDive()
19{
20}
21
22// Constructor from model
23CbcHeuristicDiveCoefficient::CbcHeuristicDiveCoefficient(CbcModel & model)
24        : CbcHeuristicDive(model)
25{
26}
27
28// Destructor
29CbcHeuristicDiveCoefficient::~CbcHeuristicDiveCoefficient ()
30{
31}
32
33// Clone
34CbcHeuristicDiveCoefficient *
35CbcHeuristicDiveCoefficient::clone() const
36{
37    return new CbcHeuristicDiveCoefficient(*this);
38}
39
40// Create C++ lines to get to current state
41void
42CbcHeuristicDiveCoefficient::generateCpp( FILE * fp)
43{
44    CbcHeuristicDiveCoefficient other;
45    fprintf(fp, "0#include \"CbcHeuristicDiveCoefficient.hpp\"\n");
46    fprintf(fp, "3  CbcHeuristicDiveCoefficient heuristicDiveCoefficient(*cbcModel);\n");
47    CbcHeuristic::generateCpp(fp, "heuristicDiveCoefficient");
48    fprintf(fp, "3  cbcModel->addHeuristic(&heuristicDiveCoefficient);\n");
49}
50
51// Copy constructor
52CbcHeuristicDiveCoefficient::CbcHeuristicDiveCoefficient(const CbcHeuristicDiveCoefficient & rhs)
53        :
54        CbcHeuristicDive(rhs)
55{
56}
57
58// Assignment operator
59CbcHeuristicDiveCoefficient &
60CbcHeuristicDiveCoefficient::operator=( const CbcHeuristicDiveCoefficient & rhs)
61{
62    if (this != &rhs) {
63        CbcHeuristicDive::operator=(rhs);
64    }
65    return *this;
66}
67
68bool
69CbcHeuristicDiveCoefficient::selectVariableToBranch(OsiSolverInterface* solver,
70        const double* newSolution,
71        int& bestColumn,
72        int& bestRound)
73{
74    int numberIntegers = model_->numberIntegers();
75    const int * integerVariable = model_->integerVariable();
76    double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
77
78    bestColumn = -1;
79    bestRound = -1; // -1 rounds down, +1 rounds up
80    double bestFraction = COIN_DBL_MAX;
81    int bestLocks = COIN_INT_MAX;
82    bool allTriviallyRoundableSoFar = true;
83    int bestPriority = COIN_INT_MAX;
84    for (int i = 0; i < numberIntegers; i++) {
85        int iColumn = integerVariable[i];
86        double value = newSolution[iColumn];
87        double fraction = value - floor(value);
88        int round = 0;
89        if (fabs(floor(value + 0.5) - value) > integerTolerance) {
90            int nDownLocks = downLocks_[i];
91            int nUpLocks = upLocks_[i];
92            if (allTriviallyRoundableSoFar || (nDownLocks > 0 && nUpLocks > 0)) {
93
94                if (allTriviallyRoundableSoFar && nDownLocks > 0 && nUpLocks > 0) {
95                    allTriviallyRoundableSoFar = false;
96                    bestFraction = COIN_DBL_MAX;
97                    bestLocks = COIN_INT_MAX;
98                }
99
100                // the variable cannot be rounded
101                int nLocks = nDownLocks;
102                if (nDownLocks < nUpLocks)
103                    round = -1;
104                else if (nDownLocks > nUpLocks) {
105                    round = 1;
106                    fraction = 1.0 - fraction;
107                    nLocks = nUpLocks;
108                } else if (fraction < 0.5)
109                    round = -1;
110                else {
111                    round = 1;
112                    fraction = 1.0 - fraction;
113                    nLocks = nUpLocks;
114                }
115
116                // if variable is not binary, penalize it
117                if (!solver->isBinary(iColumn))
118                    fraction *= 1000.0;
119
120                // if priorities then use
121                if (priority_) {
122                  int thisRound=static_cast<int>(priority_[i].direction);
123                  if ((thisRound&1)!=0) 
124                    round = ((thisRound&2)==0) ? -1 : +1;
125                  if (priority_[i].priority>bestPriority) {
126                    nLocks=COIN_INT_MAX;
127                  } else if (priority_[i].priority<bestPriority) {
128                    bestPriority=static_cast<int>(priority_[i].priority);
129                    bestLocks=COIN_INT_MAX;
130                  }
131                }
132                if (nLocks < bestLocks || (nLocks == bestLocks &&
133                                           fraction < bestFraction)) {
134                    bestColumn = iColumn;
135                    bestLocks = nLocks;
136                    bestFraction = fraction;
137                    bestRound = round;
138                }
139            }
140        }
141    }
142    return allTriviallyRoundableSoFar;
143}
144
Note: See TracBrowser for help on using the repository browser.