source: trunk/Cbc/src/CbcSubProblem.cpp

Last change on this file was 2467, checked in by unxusr, 4 months ago

spaces after angles

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
Line 
1// $Id: CbcSubProblem.cpp 2467 2019-01-03 21:26:29Z 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 CbcSubProblem::takeOver(CbcSubProblem &rhs, bool cleanUp)
175{
176  if (this != &rhs) {
177    delete[] variables_;
178    delete[] newBounds_;
179    delete status_;
180    objectiveValue_ = rhs.objectiveValue_;
181    sumInfeasibilities_ = rhs.sumInfeasibilities_;
182    branchValue_ = rhs.branchValue_;
183    djValue_ = rhs.djValue_;
184    depth_ = rhs.depth_;
185    numberChangedBounds_ = rhs.numberChangedBounds_;
186    numberInfeasibilities_ = rhs.numberInfeasibilities_;
187    problemStatus_ = rhs.problemStatus_;
188    branchVariable_ = rhs.branchVariable_;
189    variables_ = rhs.variables_;
190    newBounds_ = rhs.newBounds_;
191    rhs.variables_ = NULL;
192    rhs.newBounds_ = NULL;
193    status_ = rhs.status_;
194    rhs.status_ = NULL;
195    if (cleanUp) {
196      delete[] variables_;
197      delete[] newBounds_;
198      variables_ = new int[1];
199      newBounds_ = new double[1];
200      // swap way and make only fix
201      numberChangedBounds_ = 1;
202      if ((problemStatus_ & 1) == 0) {
203        // last way was down
204        newBounds_[0] = ceil(branchValue_);
205        variables_[0] = branchVariable_;
206      } else {
207        // last way was up
208        newBounds_[0] = floor(branchValue_);
209        variables_[0] = branchVariable_ | 0x80000000;
210      }
211    }
212  }
213}
214
215// Destructor
216CbcSubProblem::~CbcSubProblem()
217{
218  delete[] variables_;
219  delete[] newBounds_;
220  delete status_;
221}
222// Apply subproblem
223void CbcSubProblem::apply(OsiSolverInterface *solver, int what) const
224{
225  int i;
226  if ((what & 1) != 0) {
227    printf("CbcSubapply depth %d column %d way %d bvalue %g obj %g\n",
228      this->depth_, this->branchVariable_, this->problemStatus_,
229      this->branchValue_, this->objectiveValue_);
230    printf("current bounds %g <= %g <= %g\n", solver->getColLower()[branchVariable_], branchValue_, solver->getColUpper()[branchVariable_]);
231#ifndef NDEBUG
232    int nSame = 0;
233#endif
234    for (i = 0; i < numberChangedBounds_; i++) {
235      int variable = variables_[i];
236      int k = variable & 0x3fffffff;
237      if ((variable & 0x80000000) == 0) {
238        // lower bound changing
239        //#define CBC_PRINT2
240#ifdef CBC_PRINT2
241        if (solver->getColLower()[k] != newBounds_[i])
242          printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
243#endif
244#ifndef NDEBUG
245        if ((variable & 0x40000000) == 0 && true) {
246          double oldValue = solver->getColLower()[k];
247          assert(newBounds_[i] > oldValue - 1.0e-8);
248          if (newBounds_[i] < oldValue + 1.0e-8) {
249#ifdef CBC_PRINT2
250            printf("bad null lower change for column %d - bound %g\n", k, oldValue);
251#endif
252            if (newBounds_[i] == oldValue)
253              nSame++;
254          }
255        }
256#endif
257        solver->setColLower(k, newBounds_[i]);
258      } else {
259        // upper bound changing
260#ifdef CBC_PRINT2
261        if (solver->getColUpper()[k] != newBounds_[i])
262          printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
263#endif
264#ifndef NDEBUG
265        if ((variable & 0x40000000) == 0 && true) {
266          double oldValue = solver->getColUpper()[k];
267          assert(newBounds_[i] < oldValue + 1.0e-8);
268          if (newBounds_[i] > oldValue - 1.0e-8) {
269#ifdef CBC_PRINT2
270            printf("bad null upper change for column %d - bound %g\n", k, oldValue);
271#endif
272            if (newBounds_[i] == oldValue)
273              nSame++;
274          }
275        }
276#endif
277        solver->setColUpper(k, newBounds_[i]);
278      }
279    }
280#ifndef NDEBUG
281#ifdef CBC_PRINT2
282    if (nSame && (nSame < numberChangedBounds_ || (what & 3) != 3))
283      printf("%d changes out of %d redundant %d\n",
284        nSame, numberChangedBounds_, what);
285    else if (numberChangedBounds_ && what == 7 && !nSame)
286      printf("%d good changes %d\n",
287        numberChangedBounds_, what);
288#endif
289#endif
290    printf("new bounds %g <= %g <= %g\n", solver->getColLower()[branchVariable_], branchValue_, solver->getColUpper()[branchVariable_]);
291  }
292#ifdef JJF_ZERO
293  if ((what & 2) != 0) {
294    OsiClpSolverInterface *clpSolver
295      = dynamic_cast< OsiClpSolverInterface * >(solver);
296    assert(clpSolver);
297    //assert (clpSolver->getNumRows()==numberRows_);
298    //clpSolver->setBasis(*status_);
299    // Current basis
300    CoinWarmStartBasis *basis = clpSolver->getPointerToWarmStart();
301    printf("BBBB\n");
302    basis->print();
303    assert(basis->fullBasis());
304    basis->applyDiff(status_);
305    printf("diff applied %x\n", status_);
306    printf("CCCC\n");
307    basis->print();
308    assert(basis->fullBasis());
309#ifndef NDEBUG
310    if (!basis->fullBasis())
311      printf("Debug this basis!!\n");
312#endif
313    clpSolver->setBasis(*basis);
314  }
315#endif
316  if ((what & 8) != 0) {
317    OsiClpSolverInterface *clpSolver
318      = dynamic_cast< OsiClpSolverInterface * >(solver);
319    assert(clpSolver);
320    clpSolver->setBasis(*status_);
321    if ((what & 16) == 0) {
322      delete status_;
323      status_ = NULL;
324    }
325  }
326}
327
328/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
329*/
Note: See TracBrowser for help on using the repository browser.