source: trunk/Cbc/src/CbcFullNodeInfo.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: 5.8 KB
Line 
1// $Id: CbcFullNodeInfo.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#if defined(_MSC_VER)
9// Turn off compiler warning about long names
10#pragma warning(disable : 4786)
11#endif
12
13#include "CbcConfig.h"
14
15#include <string>
16//#define CBC_DEBUG 1
17//#define CHECK_CUT_COUNTS
18//#define CHECK_NODE
19//#define CBC_CHECK_BASIS
20#include <cassert>
21#include <cfloat>
22#define CUTS
23#include "OsiSolverInterface.hpp"
24#include "OsiChooseVariable.hpp"
25#include "OsiAuxInfo.hpp"
26#include "OsiSolverBranch.hpp"
27#include "CoinWarmStartBasis.hpp"
28#include "CoinTime.hpp"
29#include "CbcModel.hpp"
30#include "CbcNode.hpp"
31#include "CbcStatistics.hpp"
32#include "CbcStrategy.hpp"
33#include "CbcBranchActual.hpp"
34#include "CbcBranchDynamic.hpp"
35#include "OsiRowCut.hpp"
36#include "OsiRowCutDebugger.hpp"
37#include "OsiCuts.hpp"
38#include "CbcCountRowCut.hpp"
39#include "CbcFeasibilityBase.hpp"
40#include "CbcMessage.hpp"
41#ifdef COIN_HAS_CLP
42#include "OsiClpSolverInterface.hpp"
43#include "ClpSimplexOther.hpp"
44#endif
45using namespace std;
46#include "CglCutGenerator.hpp"
47
48CbcFullNodeInfo::CbcFullNodeInfo()
49  : CbcNodeInfo()
50  , basis_()
51  , numberIntegers_(0)
52  , lower_(NULL)
53  , upper_(NULL)
54{
55}
56CbcFullNodeInfo::CbcFullNodeInfo(CbcModel *model,
57  int numberRowsAtContinuous)
58  : CbcNodeInfo(NULL, model->currentNode())
59{
60  OsiSolverInterface *solver = model->solver();
61  numberRows_ = numberRowsAtContinuous;
62  numberIntegers_ = model->numberIntegers();
63  int numberColumns = model->getNumCols();
64  lower_ = new double[numberColumns];
65  upper_ = new double[numberColumns];
66  const double *lower = solver->getColLower();
67  const double *upper = solver->getColUpper();
68  int i;
69
70  for (i = 0; i < numberColumns; i++) {
71    lower_[i] = lower[i];
72    upper_[i] = upper[i];
73  }
74
75  basis_ = dynamic_cast<CoinWarmStartBasis *>(solver->getWarmStart());
76}
77
78CbcFullNodeInfo::CbcFullNodeInfo(const CbcFullNodeInfo &rhs)
79  : CbcNodeInfo(rhs)
80{
81  basis_ = dynamic_cast<CoinWarmStartBasis *>(rhs.basis_->clone());
82  numberIntegers_ = rhs.numberIntegers_;
83  lower_ = NULL;
84  upper_ = NULL;
85  if (rhs.lower_ != NULL) {
86    int numberColumns = basis_->getNumStructural();
87    lower_ = new double[numberColumns];
88    upper_ = new double[numberColumns];
89    assert(upper_ != NULL);
90    memcpy(lower_, rhs.lower_, numberColumns * sizeof(double));
91    memcpy(upper_, rhs.upper_, numberColumns * sizeof(double));
92  }
93}
94
95CbcNodeInfo *
96CbcFullNodeInfo::clone() const
97{
98  return (new CbcFullNodeInfo(*this));
99}
100
101CbcFullNodeInfo::~CbcFullNodeInfo()
102{
103  delete basis_;
104  delete[] lower_;
105  delete[] upper_;
106}
107
108/*
109  The basis supplied as a parameter is deleted and replaced with a new basis
110  appropriate for the node, and lower and upper bounds on variables are
111  reset according to the stored bounds arrays. Any cuts associated with this
112  node are added to the list in addCuts, but not actually added to the
113  constraint system in the model.
114
115  Why pass in a basis at all? The short answer is ``We need the parameter to
116  pass out a basis, so might as well use it to pass in the size.''
117
118  A longer answer is that in practice we take a memory allocation hit up in
119  addCuts1 (the only place applyToModel is called) when we setSize() the
120  basis that's passed in. It's immediately tossed here in favour of a clone
121  of the basis attached to this nodeInfo. This can probably be fixed, given
122  a bit of thought.
123*/
124
125void CbcFullNodeInfo::applyToModel(CbcModel *model,
126  CoinWarmStartBasis *&basis,
127  CbcCountRowCut **addCuts,
128  int &currentNumberCuts) const
129
130{
131  OsiSolverInterface *solver = model->solver();
132  // may be end game
133  if (!active_)
134    return;
135  // branch - do bounds
136  assert((active_ & ~16) == 7 || (active_ & ~16) == 15);
137  int i;
138  solver->setColLower(lower_);
139  solver->setColUpper(upper_);
140  if (basis) {
141    int numberColumns = model->getNumCols();
142    // move basis - but make sure size stays
143    // for bon-min - should not be needed int numberRows = model->getNumRows();
144    int numberRows = basis->getNumArtificial();
145    delete basis;
146    if (basis_) {
147      basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone());
148      basis->resize(numberRows, numberColumns);
149#ifdef CBC_CHECK_BASIS
150      std::cout << "Basis (after applying root " << this << ") " << std::endl;
151      basis->print();
152#endif
153    } else {
154      // We have a solver without a basis
155      basis = NULL;
156    }
157  }
158  for (i = 0; i < numberCuts_; i++)
159    addCuts[currentNumberCuts + i] = cuts_[i];
160  currentNumberCuts += numberCuts_;
161  assert(!parent_);
162  return;
163}
164// Just apply bounds to one variable (1=>infeasible)
165int CbcFullNodeInfo::applyBounds(int iColumn, double &lower, double &upper, int force)
166{
167  if ((force && 1) == 0) {
168    if (lower > lower_[iColumn])
169      COIN_DETAIL_PRINT(printf("%d odd lower going from %g to %g\n", iColumn, lower, lower_[iColumn]));
170    lower = lower_[iColumn];
171  } else {
172    lower_[iColumn] = lower;
173  }
174  if ((force && 2) == 0) {
175    if (upper < upper_[iColumn])
176      COIN_DETAIL_PRINT(printf("%d odd upper going from %g to %g\n", iColumn, upper, upper_[iColumn]));
177    upper = upper_[iColumn];
178  } else {
179    upper_[iColumn] = upper;
180  }
181  return (upper_[iColumn] >= lower_[iColumn]) ? 0 : 1;
182}
183
184/* Builds up row basis backwards (until original model).
185   Returns NULL or previous one to apply .
186   Depends on Free being 0 and impossible for cuts
187*/
188CbcNodeInfo *
189CbcFullNodeInfo::buildRowBasis(CoinWarmStartBasis &basis) const
190{
191  const unsigned int *saved = reinterpret_cast<const unsigned int *>(basis_->getArtificialStatus());
192  unsigned int *now = reinterpret_cast<unsigned int *>(basis.getArtificialStatus());
193  int number = basis_->getNumArtificial() >> 4;
194  ;
195  int i;
196  for (i = 0; i < number; i++) {
197    if (!now[i])
198      now[i] = saved[i];
199  }
200  return NULL;
201}
Note: See TracBrowser for help on using the repository browser.