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

Last change on this file since 2464 was 2464, checked in by unxusr, 10 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.1 KB
Line 
1// $Id: CbcPartialNodeInfo.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/24/09 carved from CbcNode
7
8#include "CbcConfig.h"
9
10#include <string>
11//#define CBC_DEBUG 1
12//#define CHECK_CUT_COUNTS
13//#define CHECK_NODE
14//#define CBC_CHECK_BASIS
15#include <cassert>
16#include <cfloat>
17#define CUTS
18#include "CoinPragma.hpp"
19#include "OsiSolverInterface.hpp"
20#include "OsiChooseVariable.hpp"
21#include "OsiAuxInfo.hpp"
22#include "OsiSolverBranch.hpp"
23#include "CoinWarmStartBasis.hpp"
24#include "CoinTime.hpp"
25#include "CbcModel.hpp"
26#include "CbcNode.hpp"
27#include "CbcStatistics.hpp"
28#include "CbcStrategy.hpp"
29#include "CbcBranchActual.hpp"
30#include "CbcBranchDynamic.hpp"
31#include "OsiRowCut.hpp"
32#include "OsiRowCutDebugger.hpp"
33#include "OsiCuts.hpp"
34#include "CbcCountRowCut.hpp"
35#include "CbcFeasibilityBase.hpp"
36#include "CbcMessage.hpp"
37#ifdef COIN_HAS_CLP
38#include "OsiClpSolverInterface.hpp"
39#include "ClpSimplexOther.hpp"
40#endif
41using namespace std;
42#include "CglCutGenerator.hpp"
43
44// Default constructor
45CbcPartialNodeInfo::CbcPartialNodeInfo()
46
47  : CbcNodeInfo()
48  , basisDiff_(NULL)
49  , variables_(NULL)
50  , newBounds_(NULL)
51  , numberChangedBounds_(0)
52
53{ /* this space intentionally left blank */
54}
55
56// Constructor from current state
57CbcPartialNodeInfo::CbcPartialNodeInfo(CbcNodeInfo *parent, CbcNode *owner,
58  int numberChangedBounds,
59  const int *variables,
60  const double *boundChanges,
61  const CoinWarmStartDiff *basisDiff)
62  : CbcNodeInfo(parent, owner)
63{
64  basisDiff_ = basisDiff->clone();
65#ifdef CBC_CHECK_BASIS
66  std::cout << "Constructor (" << this << ") " << std::endl;
67#endif
68
69  numberChangedBounds_ = numberChangedBounds;
70  size_t size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
71  char *temp = new char[size];
72  newBounds_ = reinterpret_cast<double *>(temp);
73  variables_ = reinterpret_cast<int *>(newBounds_ + numberChangedBounds_);
74
75  int i;
76  for (i = 0; i < numberChangedBounds_; i++) {
77    variables_[i] = variables[i];
78    newBounds_[i] = boundChanges[i];
79  }
80}
81
82CbcPartialNodeInfo::CbcPartialNodeInfo(const CbcPartialNodeInfo &rhs)
83
84  : CbcNodeInfo(rhs)
85
86{
87  basisDiff_ = rhs.basisDiff_->clone();
88
89#ifdef CBC_CHECK_BASIS
90  std::cout << "Copy constructor (" << this << ") from " << this << std::endl;
91#endif
92  numberChangedBounds_ = rhs.numberChangedBounds_;
93  size_t size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
94  char *temp = new char[size];
95  newBounds_ = reinterpret_cast<double *>(temp);
96  variables_ = reinterpret_cast<int *>(newBounds_ + numberChangedBounds_);
97
98  int i;
99  for (i = 0; i < numberChangedBounds_; i++) {
100    variables_[i] = rhs.variables_[i];
101    newBounds_[i] = rhs.newBounds_[i];
102  }
103}
104
105CbcNodeInfo *
106CbcPartialNodeInfo::clone() const
107{
108  return (new CbcPartialNodeInfo(*this));
109}
110
111CbcPartialNodeInfo::~CbcPartialNodeInfo()
112{
113  delete basisDiff_;
114  delete[] newBounds_;
115}
116
117/**
118   The basis supplied as a parameter is incrementally modified, and lower and
119   upper bounds on variables in the model are incrementally modified. Any
120   cuts associated with this node are added to the list in addCuts.
121*/
122
123void CbcPartialNodeInfo::applyToModel(CbcModel *model,
124  CoinWarmStartBasis *&basis,
125  CbcCountRowCut **addCuts,
126  int &currentNumberCuts) const
127
128{
129  OsiSolverInterface *solver = model->solver();
130  if ((active_ & 4) != 0 && basis) {
131    basis->applyDiff(basisDiff_);
132#ifdef CBC_CHECK_BASIS
133    std::cout << "Basis (after applying " << this << ") " << std::endl;
134    basis->print();
135#endif
136  }
137
138  // branch - do bounds
139  int i;
140  if ((active_ & 1) != 0) {
141    for (i = 0; i < numberChangedBounds_; i++) {
142      int variable = variables_[i];
143      int k = variable & 0x3fffffff;
144      if ((variable & 0x80000000) == 0) {
145        // lower bound changing
146        //#define CBC_PRINT2
147#ifdef CBC_PRINT2
148        if (solver->getColLower()[k] != newBounds_[i])
149          printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
150#endif
151#ifndef NDEBUG
152        if ((variable & 0x40000000) == 0 && false) {
153          double oldValue = solver->getColLower()[k];
154          assert(newBounds_[i] > oldValue - 1.0e-8);
155          if (newBounds_[i] < oldValue + 1.0e-8)
156            printf("bad null lower change for column %d - bound %g\n", k, oldValue);
157        }
158#endif
159        solver->setColLower(k, newBounds_[i]);
160      } else {
161        // upper bound changing
162#ifdef CBC_PRINT2
163        if (solver->getColUpper()[k] != newBounds_[i])
164          printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
165#endif
166#ifndef NDEBUG
167        if ((variable & 0x40000000) == 0 && false) {
168          double oldValue = solver->getColUpper()[k];
169          assert(newBounds_[i] < oldValue + 1.0e-8);
170          if (newBounds_[i] > oldValue - 1.0e-8)
171            printf("bad null upper change for column %d - bound %g\n", k, oldValue);
172        }
173#endif
174        solver->setColUpper(k, newBounds_[i]);
175      }
176    }
177  }
178  if ((active_ & 2) != 0) {
179    for (i = 0; i < numberCuts_; i++) {
180      addCuts[currentNumberCuts + i] = cuts_[i];
181      if (cuts_[i] && model->messageHandler()->logLevel() > 4) {
182        cuts_[i]->print();
183      }
184    }
185
186    currentNumberCuts += numberCuts_;
187  }
188  return;
189}
190// Just apply bounds to one variable (1=>infeasible)
191int CbcPartialNodeInfo::applyBounds(int iColumn, double &lower, double &upper, int force)
192{
193  // branch - do bounds
194  int i;
195  int found = 0;
196  double newLower = -COIN_DBL_MAX;
197  double newUpper = COIN_DBL_MAX;
198  for (i = 0; i < numberChangedBounds_; i++) {
199    int variable = variables_[i];
200    int k = variable & 0x3fffffff;
201    if (k == iColumn) {
202      if ((variable & 0x80000000) == 0) {
203        // lower bound changing
204        found |= 1;
205        newLower = CoinMax(newLower, newBounds_[i]);
206        if ((force & 1) == 0) {
207          if (lower > newBounds_[i])
208            COIN_DETAIL_PRINT(printf("%d odd lower going from %g to %g\n", iColumn, lower, newBounds_[i]));
209          lower = newBounds_[i];
210        } else {
211          newBounds_[i] = lower;
212          variables_[i] |= 0x40000000; // say can go odd way
213        }
214      } else {
215        // upper bound changing
216        found |= 2;
217        newUpper = CoinMin(newUpper, newBounds_[i]);
218        if ((force & 2) == 0) {
219          if (upper < newBounds_[i])
220            COIN_DETAIL_PRINT(printf("%d odd upper going from %g to %g\n", iColumn, upper, newBounds_[i]));
221          upper = newBounds_[i];
222        } else {
223          newBounds_[i] = upper;
224          variables_[i] |= 0x40000000; // say can go odd way
225        }
226      }
227    }
228  }
229  newLower = CoinMax(newLower, lower);
230  newUpper = CoinMin(newUpper, upper);
231  int nAdd = 0;
232  if ((force & 2) != 0 && (found & 2) == 0) {
233    // need to add new upper
234    nAdd++;
235  }
236  if ((force & 1) != 0 && (found & 1) == 0) {
237    // need to add new lower
238    nAdd++;
239  }
240  if (nAdd) {
241    size_t size = (numberChangedBounds_ + nAdd) * (sizeof(double) + sizeof(int));
242    char *temp = new char[size];
243    double *newBounds = reinterpret_cast<double *>(temp);
244    int *variables = reinterpret_cast<int *>(newBounds + numberChangedBounds_ + nAdd);
245
246    int i;
247    for (i = 0; i < numberChangedBounds_; i++) {
248      variables[i] = variables_[i];
249      newBounds[i] = newBounds_[i];
250    }
251    delete[] newBounds_;
252    newBounds_ = newBounds;
253    variables_ = variables;
254    if ((force & 2) != 0 && (found & 2) == 0) {
255      // need to add new upper
256      int variable = iColumn | 0x80000000;
257      variables_[numberChangedBounds_] = variable;
258      newBounds_[numberChangedBounds_++] = newUpper;
259    }
260    if ((force & 1) != 0 && (found & 1) == 0) {
261      // need to add new lower
262      int variable = iColumn;
263      variables_[numberChangedBounds_] = variable;
264      newBounds_[numberChangedBounds_++] = newLower;
265    }
266  }
267
268  return (newUpper >= newLower) ? 0 : 1;
269}
270
271/* Builds up row basis backwards (until original model).
272   Returns NULL or previous one to apply .
273   Depends on Free being 0 and impossible for cuts
274*/
275
276CbcNodeInfo *
277CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis &basis) const
278
279{
280  basis.applyDiff(basisDiff_);
281
282  return parent_;
283}
Note: See TracBrowser for help on using the repository browser.