source: trunk/Cbc/src/CbcSubProblem.cpp @ 1424

Last change on this file since 1424 was 1393, checked in by lou, 10 years ago

Mark #if 0 with JJF_ZERO and #if 1 with JJF_ONE as a historical reference
point.

File size: 8.1 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 "CbcSubProblem.hpp"
18#include "CbcBranchActual.hpp"
19#include "CoinSort.hpp"
20#include "CoinError.hpp"
21
22#ifdef COIN_HAS_CLP
23#include "OsiClpSolverInterface.hpp"
24#endif
25
26// Default Constructor
27CbcSubProblem::CbcSubProblem()
28        : objectiveValue_(0.0),
29        sumInfeasibilities_(0.0),
30        variables_(NULL),
31        newBounds_(NULL),
32        status_(NULL),
33        depth_(0),
34        numberChangedBounds_(0),
35        numberInfeasibilities_(0)
36{
37}
38
39// Useful constructor
40CbcSubProblem::CbcSubProblem (const OsiSolverInterface * solver,
41                              const double * lastLower,
42                              const double * lastUpper,
43                              const unsigned char * status,
44                              int depth)
45        : objectiveValue_(0.0),
46        sumInfeasibilities_(0.0),
47        variables_(NULL),
48        newBounds_(NULL),
49        status_(NULL),
50        depth_(depth),
51        numberChangedBounds_(0),
52        numberInfeasibilities_(0)
53{
54    const double * lower = solver->getColLower();
55    const double * upper = solver->getColUpper();
56
57    numberChangedBounds_ = 0;
58    int numberColumns = solver->getNumCols();
59    int i;
60    for (i = 0; i < numberColumns; i++) {
61        if (lower[i] != lastLower[i])
62            numberChangedBounds_++;
63        if (upper[i] != lastUpper[i])
64            numberChangedBounds_++;
65    }
66    if (numberChangedBounds_) {
67        newBounds_ = new double [numberChangedBounds_] ;
68        variables_ = new int [numberChangedBounds_] ;
69        numberChangedBounds_ = 0;
70        for (i = 0; i < numberColumns; i++) {
71            if (lower[i] != lastLower[i]) {
72                variables_[numberChangedBounds_] = i;
73                newBounds_[numberChangedBounds_++] = lower[i];
74            }
75            if (upper[i] != lastUpper[i]) {
76                variables_[numberChangedBounds_] = i | 0x80000000;
77                newBounds_[numberChangedBounds_++] = upper[i];
78            }
79#ifdef CBC_DEBUG
80            if (lower[i] != lastLower[i]) {
81                std::cout
82                    << "lower on " << i << " changed from "
83                    << lastLower[i] << " to " << lower[i] << std::endl ;
84            }
85            if (upper[i] != lastUpper[i]) {
86                std::cout
87                    << "upper on " << i << " changed from "
88                    << lastUpper[i] << " to " << upper[i] << std::endl ;
89            }
90#endif
91        }
92#ifdef CBC_DEBUG
93        std::cout << numberChangedBounds_ << " changed bounds." << std::endl ;
94#endif
95    }
96    const OsiClpSolverInterface * clpSolver
97    = dynamic_cast<const OsiClpSolverInterface *> (solver);
98    assert (clpSolver);
99    // Do difference
100    // Current basis
101    status_ = clpSolver->getBasis(status);
102    assert (status_->fullBasis());
103    //status_->print();
104}
105
106// Copy constructor
107CbcSubProblem::CbcSubProblem ( const CbcSubProblem & rhs)
108        : objectiveValue_(rhs.objectiveValue_),
109        sumInfeasibilities_(rhs.sumInfeasibilities_),
110        variables_(NULL),
111        newBounds_(NULL),
112        status_(NULL),
113        depth_(rhs.depth_),
114        numberChangedBounds_(rhs.numberChangedBounds_),
115        numberInfeasibilities_(rhs.numberInfeasibilities_)
116{
117    if (numberChangedBounds_) {
118        variables_ = CoinCopyOfArray(rhs.variables_, numberChangedBounds_);
119        newBounds_ = CoinCopyOfArray(rhs.newBounds_, numberChangedBounds_);
120    }
121    if (rhs.status_) {
122        status_ = new CoinWarmStartBasis(*rhs.status_);
123    }
124}
125
126// Assignment operator
127CbcSubProblem &
128CbcSubProblem::operator=( const CbcSubProblem & rhs)
129{
130    if (this != &rhs) {
131        delete [] variables_;
132        delete [] newBounds_;
133        delete status_;
134        objectiveValue_ = rhs.objectiveValue_;
135        sumInfeasibilities_ = rhs.sumInfeasibilities_;
136        depth_ = rhs.depth_;
137        numberChangedBounds_ = rhs.numberChangedBounds_;
138        numberInfeasibilities_ = rhs.numberInfeasibilities_;
139        if (numberChangedBounds_) {
140            variables_ = CoinCopyOfArray(rhs.variables_, numberChangedBounds_);
141            newBounds_ = CoinCopyOfArray(rhs.newBounds_, numberChangedBounds_);
142        } else {
143            variables_ = NULL;
144            newBounds_ = NULL;
145        }
146        if (rhs.status_) {
147            status_ = new CoinWarmStartBasis(*rhs.status_);
148        } else {
149            status_ = NULL;
150        }
151    }
152    return *this;
153}
154
155// Destructor
156CbcSubProblem::~CbcSubProblem ()
157{
158    delete [] variables_;
159    delete [] newBounds_;
160    delete status_;
161}
162// Apply subproblem
163void
164CbcSubProblem::apply(OsiSolverInterface * solver, int what) const
165{
166    int i;
167    if ((what&1) != 0) {
168        int nSame = 0;
169        for (i = 0; i < numberChangedBounds_; i++) {
170            int variable = variables_[i];
171            int k = variable & 0x3fffffff;
172            if ((variable&0x80000000) == 0) {
173                // lower bound changing
174                //#define CBC_PRINT2
175#ifdef CBC_PRINT2
176                if (solver->getColLower()[k] != newBounds_[i])
177                    printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
178#endif
179#ifndef NDEBUG
180                if ((variable&0x40000000) == 0 && true) {
181                    double oldValue = solver->getColLower()[k];
182                    assert (newBounds_[i] > oldValue - 1.0e-8);
183                    if (newBounds_[i] < oldValue + 1.0e-8) {
184#ifdef CBC_PRINT2
185                        printf("bad null lower change for column %d - bound %g\n", k, oldValue);
186#endif
187                        if (newBounds_[i] == oldValue)
188                            nSame++;
189                    }
190                }
191#endif
192                solver->setColLower(k, newBounds_[i]);
193            } else {
194                // upper bound changing
195#ifdef CBC_PRINT2
196                if (solver->getColUpper()[k] != newBounds_[i])
197                    printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
198#endif
199#ifndef NDEBUG
200                if ((variable&0x40000000) == 0 && true) {
201                    double oldValue = solver->getColUpper()[k];
202                    assert (newBounds_[i] < oldValue + 1.0e-8);
203                    if (newBounds_[i] > oldValue - 1.0e-8) {
204#ifdef CBC_PRINT2
205                        printf("bad null upper change for column %d - bound %g\n", k, oldValue);
206#endif
207                        if (newBounds_[i] == oldValue)
208                            nSame++;
209                    }
210                }
211#endif
212                solver->setColUpper(k, newBounds_[i]);
213            }
214        }
215        if (nSame && (nSame < numberChangedBounds_ || (what&3) != 3))
216            printf("%d changes out of %d redundant %d\n",
217                   nSame, numberChangedBounds_, what);
218        else if (numberChangedBounds_ && what == 7 && !nSame)
219            printf("%d good changes %d\n",
220                   numberChangedBounds_, what);
221    }
222#ifdef JJF_ZERO
223    if ((what&2) != 0) {
224        OsiClpSolverInterface * clpSolver
225        = dynamic_cast<OsiClpSolverInterface *> (solver);
226        assert (clpSolver);
227        //assert (clpSolver->getNumRows()==numberRows_);
228        //clpSolver->setBasis(*status_);
229        // Current basis
230        CoinWarmStartBasis * basis = clpSolver->getPointerToWarmStart();
231        printf("BBBB\n");
232        basis->print();
233        assert (basis->fullBasis());
234        basis->applyDiff(status_);
235        printf("diff applied %x\n", status_);
236        printf("CCCC\n");
237        basis->print();
238        assert (basis->fullBasis());
239#ifndef NDEBUG
240        if (!basis->fullBasis())
241            printf("Debug this basis!!\n");
242#endif
243        clpSolver->setBasis(*basis);
244    }
245#endif
246    if ((what&8) != 0) {
247        OsiClpSolverInterface * clpSolver
248        = dynamic_cast<OsiClpSolverInterface *> (solver);
249        assert (clpSolver);
250        clpSolver->setBasis(*status_);
251        delete status_;
252        status_ = NULL;
253    }
254}
Note: See TracBrowser for help on using the repository browser.