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

Last change on this file since 1641 was 1641, checked in by forrest, 8 years ago

out some printf statements

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