source: trunk/Cbc/src/CbcFullNodeInfo.cpp @ 1424

Last change on this file since 1424 was 1357, checked in by coin, 10 years ago

run 'astyle -A4 -p' and dos2unix

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