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

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

changes to fix bug on max nodes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1// $Id: CbcPartialNodeInfo.cpp 1951 2013-08-02 14:26:23Z forrest $
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// Constructor from current state
56CbcPartialNodeInfo::CbcPartialNodeInfo (CbcNodeInfo *parent, CbcNode *owner,
57                                        int numberChangedBounds,
58                                        const int *variables,
59                                        const double *boundChanges,
60                                        const CoinWarmStartDiff *basisDiff)
61        : CbcNodeInfo(parent, owner)
62{
63    basisDiff_ = basisDiff->clone() ;
64#ifdef CBC_CHECK_BASIS
65    std::cout << "Constructor (" << this << ") " << std::endl ;
66#endif
67
68    numberChangedBounds_ = numberChangedBounds;
69    size_t size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
70    char * temp = new char [size];
71    newBounds_ = reinterpret_cast<double *> (temp);
72    variables_ = reinterpret_cast<int *> (newBounds_ + numberChangedBounds_);
73
74    int i ;
75    for (i = 0; i < numberChangedBounds_; i++) {
76        variables_[i] = variables[i];
77        newBounds_[i] = boundChanges[i];
78    }
79}
80
81CbcPartialNodeInfo::CbcPartialNodeInfo (const CbcPartialNodeInfo & rhs)
82
83        : CbcNodeInfo(rhs)
84
85{
86    basisDiff_ = rhs.basisDiff_->clone() ;
87
88#ifdef CBC_CHECK_BASIS
89    std::cout << "Copy constructor (" << this << ") from " << this << std::endl ;
90#endif
91    numberChangedBounds_ = rhs.numberChangedBounds_;
92    size_t size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
93    char * temp = new char [size];
94    newBounds_ = reinterpret_cast<double *> (temp);
95    variables_ = reinterpret_cast<int *> (newBounds_ + numberChangedBounds_);
96
97    int i ;
98    for (i = 0; i < numberChangedBounds_; i++) {
99        variables_[i] = rhs.variables_[i];
100        newBounds_[i] = rhs.newBounds_[i];
101    }
102}
103
104CbcNodeInfo *
105CbcPartialNodeInfo::clone() const
106{
107    return (new CbcPartialNodeInfo(*this));
108}
109
110
111CbcPartialNodeInfo::~CbcPartialNodeInfo ()
112{
113    delete basisDiff_ ;
114    delete [] newBounds_;
115}
116
117
118/**
119   The basis supplied as a parameter is incrementally modified, and lower and
120   upper bounds on variables in the model are incrementally modified. Any
121   cuts associated with this node are added to the list in addCuts.
122*/
123
124void CbcPartialNodeInfo::applyToModel (CbcModel *model,
125                                       CoinWarmStartBasis *&basis,
126                                       CbcCountRowCut **addCuts,
127                                       int &currentNumberCuts) const
128
129{
130    OsiSolverInterface *solver = model->solver();
131    if ((active_&4) != 0 && basis) {
132        basis->applyDiff(basisDiff_) ;
133#ifdef CBC_CHECK_BASIS
134        std::cout << "Basis (after applying " << this << ") " << std::endl ;
135        basis->print() ;
136#endif
137    }
138
139    // branch - do bounds
140    int i;
141    if ((active_&1) != 0) {
142        for (i = 0; i < numberChangedBounds_; i++) {
143            int variable = variables_[i];
144            int k = variable & 0x3fffffff;
145            if ((variable&0x80000000) == 0) {
146                // lower bound changing
147              //#define CBC_PRINT2
148#ifdef CBC_PRINT2
149                if (solver->getColLower()[k] != newBounds_[i])
150                    printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
151#endif
152#ifndef NDEBUG
153                if ((variable&0x40000000) == 0 && false) {
154                    double oldValue = solver->getColLower()[k];
155                    assert (newBounds_[i] > oldValue - 1.0e-8);
156                    if (newBounds_[i] < oldValue + 1.0e-8)
157                        printf("bad null lower change for column %d - bound %g\n", k, oldValue);
158                }
159#endif
160                solver->setColLower(k, newBounds_[i]);
161            } else {
162                // upper bound changing
163#ifdef CBC_PRINT2
164                if (solver->getColUpper()[k] != newBounds_[i])
165                    printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
166#endif
167#ifndef NDEBUG
168                if ((variable&0x40000000) == 0 && false) {
169                    double oldValue = solver->getColUpper()[k];
170                    assert (newBounds_[i] < oldValue + 1.0e-8);
171                    if (newBounds_[i] > oldValue - 1.0e-8)
172                        printf("bad null upper change for column %d - bound %g\n", k, oldValue);
173                }
174#endif
175                solver->setColUpper(k, newBounds_[i]);
176            }
177        }
178    }
179    if ((active_&2) != 0) {
180        for (i = 0; i < numberCuts_; i++) {
181            addCuts[currentNumberCuts+i] = cuts_[i];
182            if (cuts_[i] && model->messageHandler()->logLevel() > 4) {
183                cuts_[i]->print();
184            }
185        }
186
187        currentNumberCuts += numberCuts_;
188    }
189    return ;
190}
191// Just apply bounds to one variable (1=>infeasible)
192int
193CbcPartialNodeInfo::applyBounds(int iColumn, double & lower, double & upper, int force)
194{
195    // branch - do bounds
196    int i;
197    int found = 0;
198    double newLower = -COIN_DBL_MAX;
199    double newUpper = COIN_DBL_MAX;
200    for (i = 0; i < numberChangedBounds_; i++) {
201        int variable = variables_[i];
202        int k = variable & 0x3fffffff;
203        if (k == iColumn) {
204            if ((variable&0x80000000) == 0) {
205                // lower bound changing
206                found |= 1;
207                newLower = CoinMax(newLower, newBounds_[i]);
208                if ((force&1) == 0) {
209                    if (lower > newBounds_[i])
210                      COIN_DETAIL_PRINT(printf("%d odd lower going from %g to %g\n", iColumn, lower, newBounds_[i]));
211                    lower = newBounds_[i];
212                } else {
213                    newBounds_[i] = lower;
214                    variables_[i] |= 0x40000000; // say can go odd way
215                }
216            } else {
217                // upper bound changing
218                found |= 2;
219                newUpper = CoinMin(newUpper, newBounds_[i]);
220                if ((force&2) == 0) {
221                    if (upper < newBounds_[i])
222                      COIN_DETAIL_PRINT(printf("%d odd upper going from %g to %g\n", iColumn, upper, newBounds_[i]));
223                    upper = newBounds_[i];
224                } else {
225                    newBounds_[i] = upper;
226                    variables_[i] |= 0x40000000; // say can go odd way
227                }
228            }
229        }
230    }
231    newLower = CoinMax(newLower, lower);
232    newUpper = CoinMin(newUpper, upper);
233    int nAdd = 0;
234    if ((force&2) != 0 && (found&2) == 0) {
235        // need to add new upper
236        nAdd++;
237    }
238    if ((force&1) != 0 && (found&1) == 0) {
239        // need to add new lower
240        nAdd++;
241    }
242    if (nAdd) {
243        size_t size = (numberChangedBounds_ + nAdd) * (sizeof(double) + sizeof(int));
244        char * temp = new char [size];
245        double * newBounds = reinterpret_cast<double *> (temp);
246        int * variables = reinterpret_cast<int *> (newBounds + numberChangedBounds_ + nAdd);
247
248        int i ;
249        for (i = 0; i < numberChangedBounds_; i++) {
250            variables[i] = variables_[i];
251            newBounds[i] = newBounds_[i];
252        }
253        delete [] newBounds_;
254        newBounds_ = newBounds;
255        variables_ = variables;
256        if ((force&2) != 0 && (found&2) == 0) {
257            // need to add new upper
258            int variable = iColumn | 0x80000000;
259            variables_[numberChangedBounds_] = variable;
260            newBounds_[numberChangedBounds_++] = newUpper;
261        }
262        if ((force&1) != 0 && (found&1) == 0) {
263            // need to add new lower
264            int variable = iColumn;
265            variables_[numberChangedBounds_] = variable;
266            newBounds_[numberChangedBounds_++] = newLower;
267        }
268    }
269
270    return (newUpper >= newLower) ? 0 : 1;
271}
272
273/* Builds up row basis backwards (until original model).
274   Returns NULL or previous one to apply .
275   Depends on Free being 0 and impossible for cuts
276*/
277
278CbcNodeInfo *
279CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
280
281{
282    basis.applyDiff(basisDiff_) ;
283
284    return parent_ ;
285}
286
Note: See TracBrowser for help on using the repository browser.