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

Last change on this file since 1869 was 1854, checked in by stefan, 7 years ago

fix svn keywords property

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