source: stable/2.5/Cbc/src/CbcSubProblem.cpp @ 1510

Last change on this file since 1510 was 1432, checked in by bjarni, 10 years ago

Added extra return at end of each source file where needed, to remove possible linefeed conflicts (NightlyBuild? errors)

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}
255
Note: See TracBrowser for help on using the repository browser.