source: branches/sandbox/Cbc/src/CbcGeneralBranchingObject.cpp @ 1293

Last change on this file since 1293 was 1293, checked in by EdwinStraver, 10 years ago
File size: 7.6 KB
Line 
1// Edwin 11/10/2009-- carved out of CbcBranchActual
2#if defined(_MSC_VER)
3// Turn off compiler warning about long names
4#  pragma warning(disable:4786)
5#endif
6#include <cassert>
7#include <cstdlib>
8#include <cmath>
9#include <cfloat>
10//#define CBC_DEBUG
11
12#include "CoinTypes.hpp"
13#include "OsiSolverInterface.hpp"
14#include "OsiSolverBranch.hpp"
15#include "CbcModel.hpp"
16#include "CbcMessage.hpp"
17#include "CbcGeneralBranchingObject.hpp"
18#include "CbcBranchActual.hpp"
19#include "CoinSort.hpp"
20#include "CoinError.hpp"
21
22
23#ifdef COIN_HAS_CLP
24#include "OsiClpSolverInterface.hpp"
25
26
27// Default Constructor
28CbcGeneralBranchingObject::CbcGeneralBranchingObject()
29        : CbcBranchingObject(),
30        subProblems_(NULL),
31        node_(NULL),
32        numberSubProblems_(0),
33        numberSubLeft_(0),
34        whichNode_(-1),
35        numberRows_(0)
36{
37    //  printf("CbcGeneral %x default constructor\n",this);
38}
39
40// Useful constructor
41CbcGeneralBranchingObject::CbcGeneralBranchingObject (CbcModel * model)
42        : CbcBranchingObject(model, -1, -1, 0.5),
43        subProblems_(NULL),
44        node_(NULL),
45        numberSubProblems_(0),
46        numberSubLeft_(0),
47        whichNode_(-1),
48        numberRows_(0)
49{
50    //printf("CbcGeneral %x useful constructor\n",this);
51}
52
53// Copy constructor
54CbcGeneralBranchingObject::CbcGeneralBranchingObject ( const CbcGeneralBranchingObject & rhs)
55        : CbcBranchingObject(rhs),
56        subProblems_(NULL),
57        node_(rhs.node_),
58        numberSubProblems_(rhs.numberSubProblems_),
59        numberSubLeft_(rhs.numberSubLeft_),
60        whichNode_(rhs.whichNode_),
61        numberRows_(rhs.numberRows_)
62{
63    abort();
64    if (numberSubProblems_) {
65        subProblems_ = new CbcSubProblem[numberSubProblems_];
66        for (int i = 0; i < numberSubProblems_; i++)
67            subProblems_[i] = rhs.subProblems_[i];
68    }
69}
70
71// Assignment operator
72CbcGeneralBranchingObject &
73CbcGeneralBranchingObject::operator=( const CbcGeneralBranchingObject & rhs)
74{
75    if (this != &rhs) {
76        abort();
77        CbcBranchingObject::operator=(rhs);
78        delete [] subProblems_;
79        numberSubProblems_ = rhs.numberSubProblems_;
80        numberSubLeft_ = rhs.numberSubLeft_;
81        whichNode_ = rhs.whichNode_;
82        numberRows_ = rhs.numberRows_;
83        if (numberSubProblems_) {
84            subProblems_ = new CbcSubProblem[numberSubProblems_];
85            for (int i = 0; i < numberSubProblems_; i++)
86                subProblems_[i] = rhs.subProblems_[i];
87        } else {
88            subProblems_ = NULL;
89        }
90        node_ = rhs.node_;
91    }
92    return *this;
93}
94CbcBranchingObject *
95CbcGeneralBranchingObject::clone() const
96{
97    return (new CbcGeneralBranchingObject(*this));
98}
99
100
101// Destructor
102CbcGeneralBranchingObject::~CbcGeneralBranchingObject ()
103{
104    //printf("CbcGeneral %x destructor\n",this);
105    delete [] subProblems_;
106}
107bool doingDoneBranch = false;
108double
109CbcGeneralBranchingObject::branch()
110{
111    double cutoff = model_->getCutoff();
112    //printf("GenB %x whichNode %d numberLeft %d which %d\n",
113    // this,whichNode_,numberBranchesLeft(),branchIndex());
114    if (whichNode_ < 0) {
115        assert (node_);
116        bool applied = false;
117        while (numberBranchesLeft()) {
118            int which = branchIndex();
119            decrementNumberBranchesLeft();
120            CbcSubProblem * thisProb = subProblems_ + which;
121            if (thisProb->objectiveValue_ < cutoff) {
122                //printf("branch %x (sub %x) which now %d\n",this,
123                //     subProblems_,which);
124                OsiSolverInterface * solver = model_->solver();
125                thisProb->apply(solver);
126                OsiClpSolverInterface * clpSolver
127                = dynamic_cast<OsiClpSolverInterface *> (solver);
128                assert (clpSolver);
129                // Move status to basis
130                clpSolver->setWarmStart(NULL);
131                //ClpSimplex * simplex = clpSolver->getModelPtr();
132                node_->setObjectiveValue(thisProb->objectiveValue_);
133                node_->setSumInfeasibilities(thisProb->sumInfeasibilities_);
134                node_->setNumberUnsatisfied(thisProb->numberInfeasibilities_);
135                applied = true;
136                doingDoneBranch = true;
137                break;
138            } else if (numberBranchesLeft()) {
139                node_->nodeInfo()->branchedOn() ;
140            }
141        }
142        if (!applied) {
143            // no good one
144            node_->setObjectiveValue(cutoff + 1.0e20);
145            node_->setSumInfeasibilities(1.0);
146            node_->setNumberUnsatisfied(1);
147            assert (whichNode_ < 0);
148        }
149    } else {
150        decrementNumberBranchesLeft();
151        CbcSubProblem * thisProb = subProblems_ + whichNode_;
152        assert (thisProb->objectiveValue_ < cutoff);
153        OsiSolverInterface * solver = model_->solver();
154        thisProb->apply(solver);
155        //OsiClpSolverInterface * clpSolver
156        //= dynamic_cast<OsiClpSolverInterface *> (solver);
157        //assert (clpSolver);
158        // Move status to basis
159        //clpSolver->setWarmStart(NULL);
160    }
161    return 0.0;
162}
163/* Double checks in case node can change its mind!
164   Can change objective etc */
165void
166CbcGeneralBranchingObject::checkIsCutoff(double cutoff)
167{
168    assert (node_);
169    int first = branchIndex();
170    int last = first + numberBranchesLeft();
171    for (int which = first; which < last; which++) {
172        CbcSubProblem * thisProb = subProblems_ + which;
173        if (thisProb->objectiveValue_ < cutoff) {
174            node_->setObjectiveValue(thisProb->objectiveValue_);
175            node_->setSumInfeasibilities(thisProb->sumInfeasibilities_);
176            node_->setNumberUnsatisfied(thisProb->numberInfeasibilities_);
177            break;
178        }
179    }
180}
181// Print what would happen
182void
183CbcGeneralBranchingObject::print()
184{
185    //printf("CbcGeneralObject has %d subproblems\n",numberSubProblems_);
186}
187// Fill in current objective etc
188void
189CbcGeneralBranchingObject::state(double & objectiveValue,
190                                 double & sumInfeasibilities,
191                                 int & numberUnsatisfied, int which) const
192{
193    assert (which >= 0 && which < numberSubProblems_);
194    const CbcSubProblem * thisProb = subProblems_ + which;
195    objectiveValue = thisProb->objectiveValue_;
196    sumInfeasibilities = thisProb->sumInfeasibilities_;
197    numberUnsatisfied = thisProb->numberInfeasibilities_;
198}
199/** Compare the original object of \c this with the original object of \c
200    brObj. Assumes that there is an ordering of the original objects.
201    This method should be invoked only if \c this and brObj are of the same
202    type.
203    Return negative/0/positive depending on whether \c this is
204    smaller/same/larger than the argument.
205*/
206int
207CbcGeneralBranchingObject::compareOriginalObject
208(const CbcBranchingObject* /*brObj*/) const
209{
210    throw("must implement");
211}
212
213/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
214    same type and must have the same original object, but they may have
215    different feasible regions.
216    Return the appropriate CbcRangeCompare value (first argument being the
217    sub/superset if that's the case). In case of overlap (and if \c
218    replaceIfOverlap is true) replace the current branching object with one
219    whose feasible region is the overlap.
220*/
221CbcRangeCompare
222CbcGeneralBranchingObject::compareBranchingObject
223(const CbcBranchingObject* /*brObj*/, const bool /*replaceIfOverlap*/)
224{
225    throw("must implement");
226}
227#endif
Note: See TracBrowser for help on using the repository browser.