source: stable/2.7/Cbc/src/CbcSubProblem.cpp @ 1995

Last change on this file since 1995 was 1675, checked in by stefan, 8 years ago

sync with trunk rev1674

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