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

Last change on this file since 1899 was 1899, checked in by stefan, 5 years ago

fixup svn properties

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1// $Id: CbcSubProblem.cpp 1899 2013-04-09 18:12:08Z 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/10/2009-- carved out of CbcBranchActual
7
8#include <cassert>
9#include <cstdlib>
10#include <cmath>
11#include <cfloat>
12//#define CBC_DEBUG
13
14#include "CoinPragma.hpp"
15#include "CoinTypes.hpp"
16#include "OsiSolverInterface.hpp"
17#include "OsiSolverBranch.hpp"
18#include "CbcModel.hpp"
19#include "CbcMessage.hpp"
20#include "CbcSubProblem.hpp"
21#include "CbcBranchActual.hpp"
22#include "CoinSort.hpp"
23#include "CoinError.hpp"
24
25#ifdef COIN_HAS_CLP
26#include "OsiClpSolverInterface.hpp"
27#endif
28
29// Default Constructor
30CbcSubProblem::CbcSubProblem()
31  : objectiveValue_(0.0),
32    sumInfeasibilities_(0.0),
33    branchValue_(0.0),
34    djValue_(0.0),
35    variables_(NULL),
36    newBounds_(NULL),
37    status_(NULL),
38    depth_(0),
39    numberChangedBounds_(0),
40    numberInfeasibilities_(0),
41    problemStatus_(0),
42    branchVariable_(0)
43{
44}
45
46// Useful constructor
47CbcSubProblem::CbcSubProblem (const OsiSolverInterface * solver,
48                              const double * lastLower,
49                              const double * lastUpper,
50                              const unsigned char * status,
51                              int depth)
52  : objectiveValue_(0.0),
53    sumInfeasibilities_(0.0),
54    branchValue_(0.0),
55    djValue_(0.0),
56    variables_(NULL),
57    newBounds_(NULL),
58    status_(NULL),
59    depth_(depth),
60    numberChangedBounds_(0),
61    numberInfeasibilities_(0),
62    problemStatus_(0),
63    branchVariable_(0)
64{
65    const double * lower = solver->getColLower();
66    const double * upper = solver->getColUpper();
67
68    numberChangedBounds_ = 0;
69    int numberColumns = solver->getNumCols();
70    int i;
71    for (i = 0; i < numberColumns; i++) {
72        if (lower[i] != lastLower[i])
73            numberChangedBounds_++;
74        if (upper[i] != lastUpper[i])
75            numberChangedBounds_++;
76    }
77    if (numberChangedBounds_) {
78        newBounds_ = new double [numberChangedBounds_] ;
79        variables_ = new int [numberChangedBounds_] ;
80        numberChangedBounds_ = 0;
81        for (i = 0; i < numberColumns; i++) {
82            if (lower[i] != lastLower[i]) {
83                variables_[numberChangedBounds_] = i;
84                newBounds_[numberChangedBounds_++] = lower[i];
85            }
86            if (upper[i] != lastUpper[i]) {
87                variables_[numberChangedBounds_] = i | 0x80000000;
88                newBounds_[numberChangedBounds_++] = upper[i];
89            }
90#ifdef CBC_DEBUG
91            if (lower[i] != lastLower[i]) {
92                std::cout
93                    << "lower on " << i << " changed from "
94                    << lastLower[i] << " to " << lower[i] << std::endl ;
95            }
96            if (upper[i] != lastUpper[i]) {
97                std::cout
98                    << "upper on " << i << " changed from "
99                    << lastUpper[i] << " to " << upper[i] << std::endl ;
100            }
101#endif
102        }
103#ifdef CBC_DEBUG
104        std::cout << numberChangedBounds_ << " changed bounds." << std::endl ;
105#endif
106    }
107    const OsiClpSolverInterface * clpSolver
108    = dynamic_cast<const OsiClpSolverInterface *> (solver);
109    assert (clpSolver);
110    // Do difference
111    // Current basis
112    status_ = clpSolver->getBasis(status);
113    assert (status_->fullBasis());
114    //status_->print();
115}
116
117// Copy constructor
118CbcSubProblem::CbcSubProblem ( const CbcSubProblem & rhs)
119        : objectiveValue_(rhs.objectiveValue_),
120          sumInfeasibilities_(rhs.sumInfeasibilities_),
121          branchValue_(rhs.branchValue_),
122          djValue_(rhs.djValue_),
123          variables_(NULL),
124          newBounds_(NULL),
125          status_(NULL),
126          depth_(rhs.depth_),
127          numberChangedBounds_(rhs.numberChangedBounds_),
128          numberInfeasibilities_(rhs.numberInfeasibilities_),
129          problemStatus_(rhs.problemStatus_),
130          branchVariable_(rhs.branchVariable_)
131{
132    if (numberChangedBounds_) {
133        variables_ = CoinCopyOfArray(rhs.variables_, numberChangedBounds_);
134        newBounds_ = CoinCopyOfArray(rhs.newBounds_, numberChangedBounds_);
135    }
136    if (rhs.status_) {
137        status_ = new CoinWarmStartBasis(*rhs.status_);
138    }
139}
140
141// Assignment operator
142CbcSubProblem &
143CbcSubProblem::operator=( const CbcSubProblem & rhs)
144{
145    if (this != &rhs) {
146        delete [] variables_;
147        delete [] newBounds_;
148        delete status_;
149        objectiveValue_ = rhs.objectiveValue_;
150        sumInfeasibilities_ = rhs.sumInfeasibilities_;
151        branchValue_ = rhs.branchValue_;
152        djValue_ = rhs.djValue_;
153        depth_ = rhs.depth_;
154        numberChangedBounds_ = rhs.numberChangedBounds_;
155        numberInfeasibilities_ = rhs.numberInfeasibilities_;
156        problemStatus_ = rhs.problemStatus_; 
157        branchVariable_ = rhs.branchVariable_;
158        if (numberChangedBounds_) {
159            variables_ = CoinCopyOfArray(rhs.variables_, numberChangedBounds_);
160            newBounds_ = CoinCopyOfArray(rhs.newBounds_, numberChangedBounds_);
161        } else {
162            variables_ = NULL;
163            newBounds_ = NULL;
164        }
165        if (rhs.status_) {
166            status_ = new CoinWarmStartBasis(*rhs.status_);
167        } else {
168            status_ = NULL;
169        }
170    }
171    return *this;
172}
173// Take over
174void
175CbcSubProblem::takeOver( CbcSubProblem & rhs, bool cleanUp)
176{
177    if (this != &rhs) {
178        delete [] variables_;
179        delete [] newBounds_;
180        delete status_;
181        objectiveValue_ = rhs.objectiveValue_;
182        sumInfeasibilities_ = rhs.sumInfeasibilities_;
183        branchValue_ = rhs.branchValue_;
184        djValue_ = rhs.djValue_;
185        depth_ = rhs.depth_;
186        numberChangedBounds_ = rhs.numberChangedBounds_;
187        numberInfeasibilities_ = rhs.numberInfeasibilities_;
188        problemStatus_ = rhs.problemStatus_; 
189        branchVariable_ = rhs.branchVariable_;
190        variables_ = rhs.variables_;
191        newBounds_ = rhs.newBounds_;
192        rhs.variables_ = NULL;
193        rhs.newBounds_ = NULL;
194        status_ = rhs.status_;
195        rhs.status_ = NULL;
196        if (cleanUp) {
197          delete [] variables_;
198          delete [] newBounds_;
199          variables_ = new int [1];
200          newBounds_ = new double [1];
201          // swap way and make only fix
202          numberChangedBounds_=1;
203          if ((problemStatus_&1)==0) {
204            // last way was down
205            newBounds_[0] = ceil(branchValue_);
206            variables_[0] = branchVariable_;
207          } else {
208            // last way was up
209            newBounds_[0] = floor(branchValue_);
210            variables_[0] = branchVariable_ | 0x80000000;
211          }
212        }
213    }
214}
215
216// Destructor
217CbcSubProblem::~CbcSubProblem ()
218{
219    delete [] variables_;
220    delete [] newBounds_;
221    delete status_;
222}
223// Apply subproblem
224void
225CbcSubProblem::apply(OsiSolverInterface * solver, int what) const
226{
227    int i;
228    if ((what&1) != 0) {
229    printf("CbcSubapply depth %d column %d way %d bvalue %g obj %g\n",
230                 this->depth_,this->branchVariable_,this->problemStatus_,
231                 this->branchValue_,this->objectiveValue_);
232    printf("current bounds %g <= %g <= %g\n",solver->getColLower()[branchVariable_],branchValue_,solver->getColUpper()[branchVariable_]);
233#ifndef NDEBUG
234        int nSame = 0;
235#endif
236        for (i = 0; i < numberChangedBounds_; i++) {
237            int variable = variables_[i];
238            int k = variable & 0x3fffffff;
239            if ((variable&0x80000000) == 0) {
240                // lower bound changing
241                //#define CBC_PRINT2
242#ifdef CBC_PRINT2
243                if (solver->getColLower()[k] != newBounds_[i])
244                    printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
245#endif
246#ifndef NDEBUG
247                if ((variable&0x40000000) == 0 && true) {
248                    double oldValue = solver->getColLower()[k];
249                    assert (newBounds_[i] > oldValue - 1.0e-8);
250                    if (newBounds_[i] < oldValue + 1.0e-8) {
251#ifdef CBC_PRINT2
252                        printf("bad null lower change for column %d - bound %g\n", k, oldValue);
253#endif
254                        if (newBounds_[i] == oldValue)
255                            nSame++;
256                    }
257                }
258#endif
259                solver->setColLower(k, newBounds_[i]);
260            } else {
261                // upper bound changing
262#ifdef CBC_PRINT2
263                if (solver->getColUpper()[k] != newBounds_[i])
264                    printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
265#endif
266#ifndef NDEBUG
267                if ((variable&0x40000000) == 0 && true) {
268                    double oldValue = solver->getColUpper()[k];
269                    assert (newBounds_[i] < oldValue + 1.0e-8);
270                    if (newBounds_[i] > oldValue - 1.0e-8) {
271#ifdef CBC_PRINT2
272                        printf("bad null upper change for column %d - bound %g\n", k, oldValue);
273#endif
274                        if (newBounds_[i] == oldValue)
275                            nSame++;
276                    }
277                }
278#endif
279                solver->setColUpper(k, newBounds_[i]);
280            }
281        }
282#ifndef NDEBUG
283#ifdef CBC_PRINT2
284        if (nSame && (nSame < numberChangedBounds_ || (what&3) != 3))
285            printf("%d changes out of %d redundant %d\n",
286                   nSame, numberChangedBounds_, what);
287        else if (numberChangedBounds_ && what == 7 && !nSame)
288            printf("%d good changes %d\n",
289                   numberChangedBounds_, what);
290#endif
291#endif
292    printf("new bounds %g <= %g <= %g\n",solver->getColLower()[branchVariable_],branchValue_,solver->getColUpper()[branchVariable_]);
293    }
294#ifdef JJF_ZERO
295    if ((what&2) != 0) {
296        OsiClpSolverInterface * clpSolver
297        = dynamic_cast<OsiClpSolverInterface *> (solver);
298        assert (clpSolver);
299        //assert (clpSolver->getNumRows()==numberRows_);
300        //clpSolver->setBasis(*status_);
301        // Current basis
302        CoinWarmStartBasis * basis = clpSolver->getPointerToWarmStart();
303        printf("BBBB\n");
304        basis->print();
305        assert (basis->fullBasis());
306        basis->applyDiff(status_);
307        printf("diff applied %x\n", status_);
308        printf("CCCC\n");
309        basis->print();
310        assert (basis->fullBasis());
311#ifndef NDEBUG
312        if (!basis->fullBasis())
313            printf("Debug this basis!!\n");
314#endif
315        clpSolver->setBasis(*basis);
316    }
317#endif
318    if ((what&8) != 0) {
319        OsiClpSolverInterface * clpSolver
320        = dynamic_cast<OsiClpSolverInterface *> (solver);
321        assert (clpSolver);
322        clpSolver->setBasis(*status_);
323        if ((what&16)==0) {
324          delete status_;
325          status_ = NULL;
326        }
327    }
328}
329
Note: See TracBrowser for help on using the repository browser.