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

Last change on this file since 2048 was 2048, checked in by forrest, 4 years ago

First try at orbital branching

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