source: trunk/Cbc/src/CbcSimpleIntegerPseudoCost.cpp @ 2464

Last change on this file since 2464 was 2464, checked in by unxusr, 6 months ago

.clang-format with proposal for formatting code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.0 KB
Line 
1// $Id: CbcSimpleIntegerPseudoCost.cpp 2464 2019-01-03 19:03:23Z unxusr $
2// Copyright (C) 2002, 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// Edwin 11/10/2009-- carved out of CbcBranchActual
7
8#if defined(_MSC_VER)
9// Turn off compiler warning about long names
10#pragma warning(disable : 4786)
11#endif
12#include <cassert>
13#include <cstdlib>
14#include <cmath>
15#include <cfloat>
16//#define CBC_DEBUG
17
18#include "CoinTypes.hpp"
19#include "OsiSolverInterface.hpp"
20#include "OsiSolverBranch.hpp"
21#include "CbcModel.hpp"
22#include "CbcMessage.hpp"
23#include "CbcSimpleIntegerPseudoCost.hpp"
24#include "CbcSimpleIntegerDynamicPseudoCost.hpp"
25#include "CbcBranchActual.hpp"
26#include "CoinSort.hpp"
27#include "CoinError.hpp"
28
29//##############################################################################
30
31/** Default Constructor
32
33  Equivalent to an unspecified binary variable.
34*/
35CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost()
36  : CbcSimpleInteger()
37  , downPseudoCost_(1.0e-5)
38  , upPseudoCost_(1.0e-5)
39  , upDownSeparator_(-1.0)
40  , method_(0)
41{
42}
43
44/** Useful constructor
45
46  Loads actual upper & lower bounds for the specified variable.
47*/
48CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost(CbcModel *model,
49  int iColumn, double breakEven)
50  : CbcSimpleInteger(model, iColumn, breakEven)
51{
52  const double *cost = model->getObjCoefficients();
53  double costValue = CoinMax(1.0e-5, fabs(cost[iColumn]));
54  // treat as if will cost what it says up
55  upPseudoCost_ = costValue;
56  // and balance at breakeven
57  downPseudoCost_ = ((1.0 - breakEven_) * upPseudoCost_) / breakEven_;
58  upDownSeparator_ = -1.0;
59  method_ = 0;
60}
61
62/** Useful constructor
63
64  Loads actual upper & lower bounds for the specified variable.
65*/
66CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost(CbcModel *model,
67  int iColumn, double downPseudoCost,
68  double upPseudoCost)
69  : CbcSimpleInteger(model, iColumn)
70{
71  downPseudoCost_ = CoinMax(1.0e-10, downPseudoCost);
72  upPseudoCost_ = CoinMax(1.0e-10, upPseudoCost);
73  breakEven_ = upPseudoCost_ / (upPseudoCost_ + downPseudoCost_);
74  upDownSeparator_ = -1.0;
75  method_ = 0;
76}
77// Useful constructor - passed and model index and pseudo costs
78CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost(CbcModel *model,
79  int /*dummy*/,
80  int iColumn,
81  double downPseudoCost, double upPseudoCost)
82{
83  *this = CbcSimpleIntegerPseudoCost(model, iColumn, downPseudoCost, upPseudoCost);
84  columnNumber_ = iColumn;
85}
86
87// Copy constructor
88CbcSimpleIntegerPseudoCost::CbcSimpleIntegerPseudoCost(const CbcSimpleIntegerPseudoCost &rhs)
89  : CbcSimpleInteger(rhs)
90  , downPseudoCost_(rhs.downPseudoCost_)
91  , upPseudoCost_(rhs.upPseudoCost_)
92  , upDownSeparator_(rhs.upDownSeparator_)
93  , method_(rhs.method_)
94
95{
96}
97
98// Clone
99CbcObject *
100CbcSimpleIntegerPseudoCost::clone() const
101{
102  return new CbcSimpleIntegerPseudoCost(*this);
103}
104
105// Assignment operator
106CbcSimpleIntegerPseudoCost &
107CbcSimpleIntegerPseudoCost::operator=(const CbcSimpleIntegerPseudoCost &rhs)
108{
109  if (this != &rhs) {
110    CbcSimpleInteger::operator=(rhs);
111    downPseudoCost_ = rhs.downPseudoCost_;
112    upPseudoCost_ = rhs.upPseudoCost_;
113    upDownSeparator_ = rhs.upDownSeparator_;
114    method_ = rhs.method_;
115  }
116  return *this;
117}
118
119// Destructor
120CbcSimpleIntegerPseudoCost::~CbcSimpleIntegerPseudoCost()
121{
122}
123CbcBranchingObject *
124CbcSimpleIntegerPseudoCost::createCbcBranch(OsiSolverInterface *solver, const OsiBranchingInformation * /*info*/, int way)
125{
126  //OsiSolverInterface * solver = model_->solver();
127  const double *solution = model_->testSolution();
128  const double *lower = solver->getColLower();
129  const double *upper = solver->getColUpper();
130  double value = solution[columnNumber_];
131  value = CoinMax(value, lower[columnNumber_]);
132  value = CoinMin(value, upper[columnNumber_]);
133#ifndef NDEBUG
134  double nearest = floor(value + 0.5);
135  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
136  assert(upper[columnNumber_] > lower[columnNumber_]);
137#endif
138  if (!model_->hotstartSolution()) {
139    assert(fabs(value - nearest) > integerTolerance);
140  } else {
141    const double *hotstartSolution = model_->hotstartSolution();
142    double targetValue = hotstartSolution[columnNumber_];
143    if (way > 0)
144      value = targetValue - 0.1;
145    else
146      value = targetValue + 0.1;
147  }
148  CbcIntegerPseudoCostBranchingObject *newObject = new CbcIntegerPseudoCostBranchingObject(model_, columnNumber_, way,
149    value);
150  double up = upPseudoCost_ * (ceil(value) - value);
151  double down = downPseudoCost_ * (value - floor(value));
152  double changeInGuessed = up - down;
153  if (way > 0)
154    changeInGuessed = -changeInGuessed;
155  changeInGuessed = CoinMax(0.0, changeInGuessed);
156  //if (way>0)
157  //changeInGuessed += 1.0e8; // bias to stay up
158  newObject->setChangeInGuessed(changeInGuessed);
159  newObject->setOriginalObject(this);
160  return newObject;
161}
162double
163CbcSimpleIntegerPseudoCost::infeasibility(const OsiBranchingInformation * /*info*/,
164  int &preferredWay) const
165{
166  OsiSolverInterface *solver = model_->solver();
167  const double *solution = model_->testSolution();
168  const double *lower = solver->getColLower();
169  const double *upper = solver->getColUpper();
170  if (upper[columnNumber_] == lower[columnNumber_]) {
171    // fixed
172    preferredWay = 1;
173    return 0.0;
174  }
175  double value = solution[columnNumber_];
176  value = CoinMax(value, lower[columnNumber_]);
177  value = CoinMin(value, upper[columnNumber_]);
178  /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
179      solution[columnNumber_],upper[columnNumber_]);*/
180  double nearest = floor(value + 0.5);
181  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
182  double below = floor(value + integerTolerance);
183  double above = below + 1.0;
184  if (above > upper[columnNumber_]) {
185    above = below;
186    below = above - 1;
187  }
188  double downCost = CoinMax((value - below) * downPseudoCost_, 0.0);
189  double upCost = CoinMax((above - value) * upPseudoCost_, 0.0);
190  if (downCost >= upCost)
191    preferredWay = 1;
192  else
193    preferredWay = -1;
194  // See if up down choice set
195  if (upDownSeparator_ > 0.0) {
196    preferredWay = (value - below >= upDownSeparator_) ? 1 : -1;
197  }
198  if (preferredWay_)
199    preferredWay = preferredWay_;
200  if (fabs(value - nearest) <= integerTolerance) {
201    return 0.0;
202  } else {
203    // can't get at model so 1,2 don't make sense
204    assert(method_ < 1 || method_ > 2);
205    if (!method_)
206      return CoinMin(downCost, upCost);
207    else
208      return CoinMax(downCost, upCost);
209  }
210}
211
212// Return "up" estimate
213double
214CbcSimpleIntegerPseudoCost::upEstimate() const
215{
216  OsiSolverInterface *solver = model_->solver();
217  const double *solution = model_->testSolution();
218  const double *lower = solver->getColLower();
219  const double *upper = solver->getColUpper();
220  double value = solution[columnNumber_];
221  value = CoinMax(value, lower[columnNumber_]);
222  value = CoinMin(value, upper[columnNumber_]);
223  if (upper[columnNumber_] == lower[columnNumber_]) {
224    // fixed
225    return 0.0;
226  }
227  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
228  double below = floor(value + integerTolerance);
229  double above = below + 1.0;
230  if (above > upper[columnNumber_]) {
231    above = below;
232    below = above - 1;
233  }
234  double upCost = CoinMax((above - value) * upPseudoCost_, 0.0);
235  return upCost;
236}
237// Return "down" estimate
238double
239CbcSimpleIntegerPseudoCost::downEstimate() const
240{
241  OsiSolverInterface *solver = model_->solver();
242  const double *solution = model_->testSolution();
243  const double *lower = solver->getColLower();
244  const double *upper = solver->getColUpper();
245  double value = solution[columnNumber_];
246  value = CoinMax(value, lower[columnNumber_]);
247  value = CoinMin(value, upper[columnNumber_]);
248  if (upper[columnNumber_] == lower[columnNumber_]) {
249    // fixed
250    return 0.0;
251  }
252  double integerTolerance = model_->getDblParam(CbcModel::CbcIntegerTolerance);
253  double below = floor(value + integerTolerance);
254  double above = below + 1.0;
255  if (above > upper[columnNumber_]) {
256    above = below;
257    below = above - 1;
258  }
259  double downCost = CoinMax((value - below) * downPseudoCost_, 0.0);
260  return downCost;
261}
Note: See TracBrowser for help on using the repository browser.