source: trunk/Cbc/src/CbcObject.hpp @ 1573

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

Change to EPL license notice.

File size: 9.1 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/12/2009 carved from CbcBranchBase
7
8#ifndef CbcObject_H
9#define CbcObject_H
10
11#include <string>
12#include <vector>
13#include "OsiBranchingObject.hpp"
14class OsiSolverInterface;
15class OsiSolverBranch;
16
17class CbcModel;
18class CbcNode;
19class CbcNodeInfo;
20class CbcBranchingObject;
21class OsiChooseVariable;
22class CbcObjectUpdateData;
23//#############################################################################
24
25/** Abstract base class for `objects'.
26    It now just has stuff that OsiObject does not have
27
28  The branching model used in Cbc is based on the idea of an <i>object</i>.
29  In the abstract, an object is something that has a feasible region, can be
30  evaluated for infeasibility, can be branched on (<i>i.e.</i>, there's some
31  constructive action to be taken to move toward feasibility), and allows
32  comparison of the effect of branching.
33
34  This class (CbcObject) is the base class for an object. To round out the
35  branching model, the class CbcBranchingObject describes how to perform a
36  branch, and the class CbcBranchDecision describes how to compare two
37  CbcBranchingObjects.
38
39  To create a new type of object you need to provide three methods:
40  #infeasibility(), #feasibleRegion(), and #createCbcBranch(), described below.
41
42  This base class is primarily virtual to allow for any form of structure.
43  Any form of discontinuity is allowed.
44
45  \todo The notion that all branches are binary (two arms) is wired into the
46        implementation of CbcObject, CbcBranchingObject, and
47        CbcBranchDecision. Changing this will require a moderate amount of
48        recoding.
49 */
50// This can be used if object wants to skip strong branching
51typedef struct {
52    CbcBranchingObject * possibleBranch; // what a branch would do
53    double upMovement; // cost going up (and initial away from feasible)
54    double downMovement; // cost going down
55    int numIntInfeasUp ; // without odd ones
56    int numObjInfeasUp ; // just odd ones
57    bool finishedUp; // true if solver finished
58    int numItersUp ; // number of iterations in solver
59    int numIntInfeasDown ; // without odd ones
60    int numObjInfeasDown ; // just odd ones
61    bool finishedDown; // true if solver finished
62    int numItersDown; // number of iterations in solver
63    int objectNumber; // Which object it is
64    int fix; // 0 if no fix, 1 if we can fix up, -1 if we can fix down
65} CbcStrongInfo;
66
67class CbcObject : public OsiObject {
68
69public:
70
71    // Default Constructor
72    CbcObject ();
73
74    // Useful constructor
75    CbcObject (CbcModel * model);
76
77    // Copy constructor
78    CbcObject ( const CbcObject &);
79
80    // Assignment operator
81    CbcObject & operator=( const CbcObject& rhs);
82
83    /// Clone
84    virtual CbcObject * clone() const = 0;
85
86    /// Destructor
87    virtual ~CbcObject ();
88
89    /** Infeasibility of the object
90
91        This is some measure of the infeasibility of the object. It should be
92        scaled to be in the range [0.0, 0.5], with 0.0 indicating the object
93        is satisfied.
94
95        The preferred branching direction is returned in preferredWay,
96
97        This is used to prepare for strong branching but should also think of
98        case when no strong branching
99
100        The object may also compute an estimate of cost of going "up" or "down".
101        This will probably be based on pseudo-cost ideas
102    */
103#ifdef CBC_NEW_STYLE_BRANCH
104    virtual double infeasibility(const OsiBranchingInformation * info,
105                                 int &preferredWay) const = 0;
106#else
107    virtual double infeasibility(const OsiBranchingInformation * /*info*/,
108                                 int &preferredWay) const {
109        return infeasibility(preferredWay);
110    }
111    virtual double infeasibility(int &/*preferredWay*/) const {
112        throw CoinError("Need code", "infeasibility", "CbcBranchBase");
113    }
114#endif
115
116    /** For the variable(s) referenced by the object,
117        look at the current solution and set bounds to match the solution.
118    */
119    virtual void feasibleRegion() = 0;
120    /// Dummy one for compatibility
121    virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
122
123    /** For the variable(s) referenced by the object,
124        look at the current solution and set bounds to match the solution.
125        Returns measure of how much it had to move solution to make feasible
126    */
127    virtual double feasibleRegion(OsiSolverInterface * solver) const ;
128
129    /** Create a branching object and indicate which way to branch first.
130
131        The branching object has to know how to create branches (fix
132        variables, etc.)
133    */
134#ifdef CBC_NEW_STYLE_BRANCH
135    virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) = 0;
136#else
137    virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) {
138        return createBranch(solver, info, way);
139    }
140    virtual CbcBranchingObject * createBranch(OsiSolverInterface * /*solver*/,
141            const OsiBranchingInformation * /*info*/, int /*way*/) {
142        throw CoinError("Need code", "createBranch", "CbcBranchBase");
143    }
144#endif
145    /** Create an Osibranching object and indicate which way to branch first.
146
147        The branching object has to know how to create branches (fix
148        variables, etc.)
149    */
150    virtual OsiBranchingObject * createOsiBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
151    /** Create an OsiSolverBranch object
152
153        This returns NULL if branch not represented by bound changes
154    */
155    virtual OsiSolverBranch * solverBranch() const;
156
157    /** \brief Given a valid solution (with reduced costs, etc.),
158        return a branching object which would give a new feasible
159        point in a good direction.
160
161        If the method cannot generate a feasible point (because there aren't
162        any, or because it isn't bright enough to find one), it should
163        return null.
164    */
165    virtual CbcBranchingObject * preferredNewFeasible() const {
166        return NULL;
167    }
168
169    /** \brief Given a valid solution (with reduced costs, etc.),
170        return a branching object which would give a new feasible
171        point in a bad direction.
172
173        If the method cannot generate a feasible point (because there aren't
174        any, or because it isn't bright enough to find one), it should
175        return null.
176    */
177    virtual CbcBranchingObject * notPreferredNewFeasible() const {
178        return NULL;
179    }
180
181    /** Reset variable bounds to their original values.
182
183      Bounds may be tightened, so it may be good to be able to set this info in object.
184     */
185    virtual void resetBounds(const OsiSolverInterface * ) {}
186
187    /** Returns floor and ceiling i.e. closest valid points
188    */
189    virtual void floorCeiling(double & floorValue, double & ceilingValue, double value,
190                              double tolerance) const;
191
192    /** Pass in information on branch just done and create CbcObjectUpdateData instance.
193        If object does not need data then backward pointer will be NULL.
194        Assumes can get information from solver */
195    virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver,
196            const CbcNode * node,
197            const CbcBranchingObject * branchingObject);
198
199    /// Update object by CbcObjectUpdateData
200    virtual void updateInformation(const CbcObjectUpdateData & ) {}
201
202    /// Identifier (normally column number in matrix)
203    inline int id() const {
204        return id_;
205    }
206
207    /** Set identifier (normally column number in matrix)
208        but 1000000000 to 1100000000 means optional branching object
209        i.e. code would work without it */
210    inline void setId(int value) {
211        id_ = value;
212    }
213
214    /** Return true if optional branching object
215        i.e. code would work without it */
216    inline bool optionalObject() const {
217        return (id_ >= 1000000000 && id_ < 1100000000);
218    }
219
220    /// Get position in object_ list
221    inline int position() const {
222        return position_;
223    }
224
225    /// Set position in object_ list
226    inline void setPosition(int position) {
227        position_ = position;
228    }
229
230    /// update model
231    inline void setModel(CbcModel * model) {
232        model_ = model;
233    }
234
235    /// Return model
236    inline CbcModel * model() const {
237        return  model_;
238    }
239
240    /// If -1 down always chosen first, +1 up always, 0 normal
241    inline int preferredWay() const {
242        return preferredWay_;
243    }
244    /// Set -1 down always chosen first, +1 up always, 0 normal
245    inline void setPreferredWay(int value) {
246        preferredWay_ = value;
247    }
248    /// Redoes data when sequence numbers change
249    virtual void redoSequenceEtc(CbcModel * , int , const int * ) {}
250
251protected:
252    /// data
253
254    /// Model
255    CbcModel * model_;
256    /// Identifier (normally column number in matrix)
257    int id_;
258    /// Position in object list
259    int position_;
260    /// If -1 down always chosen first, +1 up always, 0 normal
261    int preferredWay_;
262
263};
264
265#endif
266
Note: See TracBrowser for help on using the repository browser.