source: branches/sandbox/Cbc/src/CbcObject.hpp @ 1357

Last change on this file since 1357 was 1357, checked in by coin, 10 years ago

run 'astyle -A4 -p' and dos2unix

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