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

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

more options, copy statistics structure analysis
start coding of "switch" variables i.e. badly scaled ints or hi/lo
changes to allow more influence on small branch and bound
changes to get correct printout with threads

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.1 KB
Line 
1// $Id: CbcFullNodeInfo.cpp 1943 2013-07-21 09:05:45Z 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#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_ == 7 || active_ == 15);
137    int i;
138    solver->setColLower(lower_);
139    solver->setColUpper(upper_);
140    int numberColumns = model->getNumCols();
141    // move basis - but make sure size stays
142    // for bon-min - should not be needed int numberRows = model->getNumRows();
143    int numberRows = basis->getNumArtificial();
144    delete basis ;
145    if (basis_) {
146        basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone()) ;
147        basis->resize(numberRows, numberColumns);
148#ifdef CBC_CHECK_BASIS
149        std::cout << "Basis (after applying root " << this << ") " << std::endl ;
150        basis->print() ;
151#endif
152    } else {
153        // We have a solver without a basis
154        basis = NULL;
155    }
156    for (i = 0; i < numberCuts_; i++)
157        addCuts[currentNumberCuts+i] = cuts_[i];
158    currentNumberCuts += numberCuts_;
159    assert(!parent_);
160    return ;
161}
162// Just apply bounds to one variable (1=>infeasible)
163int
164CbcFullNodeInfo::applyBounds(int iColumn, double & lower, double & upper, int force)
165{
166    if ((force && 1) == 0) {
167      if (lower > lower_[iColumn])
168        COIN_DETAIL_PRINT(printf("%d odd lower going from %g to %g\n", iColumn, lower, lower_[iColumn]));
169        lower = lower_[iColumn];
170    } else {
171        lower_[iColumn] = lower;
172    }
173    if ((force && 2) == 0) {
174      if (upper < upper_[iColumn])
175        COIN_DETAIL_PRINT(printf("%d odd upper going from %g to %g\n", iColumn, upper, upper_[iColumn]));
176        upper = upper_[iColumn];
177    } else {
178        upper_[iColumn] = upper;
179    }
180    return (upper_[iColumn] >= lower_[iColumn]) ? 0 : 1;
181}
182
183/* Builds up row basis backwards (until original model).
184   Returns NULL or previous one to apply .
185   Depends on Free being 0 and impossible for cuts
186*/
187CbcNodeInfo *
188CbcFullNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
189{
190    const unsigned int * saved =
191        reinterpret_cast<const unsigned int *> (basis_->getArtificialStatus());
192    unsigned int * now =
193        reinterpret_cast<unsigned int *> (basis.getArtificialStatus());
194    int number = basis_->getNumArtificial() >> 4;;
195    int i;
196    for (i = 0; i < number; i++) {
197        if (!now[i])
198            now[i] = saved[i];
199    }
200    return NULL;
201}
202
Note: See TracBrowser for help on using the repository browser.