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

Last change on this file since 1623 was 1573, checked in by lou, 9 years ago

Change to EPL license notice.

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