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/9/2009-- carved out of CbcBranchActual
7 
8 #ifndef CbcSimpleInteger_H
9 #define CbcSimpleInteger_H
10 
11 #include "CbcBranchingObject.hpp"
12 
13 /** Simple branching object for an integer variable
14 
15   This object can specify a two-way branch on an integer variable. For each
16   arm of the branch, the upper and lower bounds on the variable can be
17   independently specified.
18 
19   Variable_ holds the index of the integer variable in the integerVariable_
20   array of the model.
21 */
22 
23 class CbcIntegerBranchingObject : public CbcBranchingObject {
24 
25 public:
26   /// Default constructor
27   CbcIntegerBranchingObject();
28 
29   /** Create a standard floor/ceiling branch object
30 
31       Specifies a simple two-way branch. Let \p value = x*. One arm of the
32       branch will be lb <= x <= floor(x*), the other ceil(x*) <= x <= ub.
33       Specify way = -1 to set the object state to perform the down arm first,
34       way = 1 for the up arm.
35     */
36   CbcIntegerBranchingObject(CbcModel *model, int variable,
37     int way, double value);
38 
39   /** Create a degenerate branch object
40 
41       Specifies a `one-way branch'. Calling branch() for this object will
42       always result in lowerValue <= x <= upperValue. Used to fix a variable
43       when lowerValue = upperValue.
44     */
45 
46   CbcIntegerBranchingObject(CbcModel *model, int variable, int way,
47     double lowerValue, double upperValue);
48 
49   /// Copy constructor
50   CbcIntegerBranchingObject(const CbcIntegerBranchingObject &);
51 
52   /// Assignment operator
53   CbcIntegerBranchingObject &operator=(const CbcIntegerBranchingObject &rhs);
54 
55   /// Clone
56   virtual CbcBranchingObject *clone() const;
57 
58   /// Destructor
59   virtual ~CbcIntegerBranchingObject();
60 
61   /// Does part of constructor
62   void fillPart(int variable, int way, double value);
63   using CbcBranchingObject::branch;
64   /** \brief Sets the bounds for the variable according to the current arm
65            of the branch and advances the object state to the next arm.
66            Returns change in guessed objective on next branch
67     */
68   virtual double branch();
69   /** Update bounds in solver as in 'branch' and update given bounds.
70         branchState is -1 for 'down' +1 for 'up' */
71   virtual void fix(OsiSolverInterface *solver,
72     double *lower, double *upper,
73     int branchState) const;
74   /** Change (tighten) bounds in object to reflect bounds in solver.
75 	Return true if now fixed */
76   virtual bool tighten(OsiSolverInterface *);
77 
78 #ifdef JJF_ZERO
79   // No need to override. Default works fine.
80   /** Reset every information so that the branching object appears to point to
81         the previous child. This method does not need to modify anything in any
82         solver. */
83   virtual void previousBranch();
84 #endif
85 
86   using CbcBranchingObject::print;
87   /** \brief Print something about branch - only if log level high
88     */
89   virtual void print();
90 
91   /// Lower and upper bounds for down branch
downBounds() const92   inline const double *downBounds() const
93   {
94     return down_;
95   }
96   /// Lower and upper bounds for up branch
upBounds() const97   inline const double *upBounds() const
98   {
99     return up_;
100   }
101   /// Set lower and upper bounds for down branch
setDownBounds(const double bounds[2])102   inline void setDownBounds(const double bounds[2])
103   {
104     memcpy(down_, bounds, 2 * sizeof(double));
105   }
106   /// Set lower and upper bounds for up branch
setUpBounds(const double bounds[2])107   inline void setUpBounds(const double bounds[2])
108   {
109     memcpy(up_, bounds, 2 * sizeof(double));
110   }
111 #ifdef FUNNY_BRANCHING
112   /** Which variable (top bit if upper bound changing,
113         next bit if on down branch */
variables() const114   inline const int *variables() const
115   {
116     return variables_;
117   }
118   // New bound
newBounds() const119   inline const double *newBounds() const
120   {
121     return newBounds_;
122   }
123   /// Number of bound changes
numberExtraChangedBounds() const124   inline int numberExtraChangedBounds() const
125   {
126     return numberExtraChangedBounds_;
127   }
128   /// Just apply extra bounds to one variable - COIN_DBL_MAX ignore
129   int applyExtraBounds(int iColumn, double lower, double upper, int way);
130   /// Deactivate bounds for branching
131   void deactivate();
132   /// Are active bounds for branching
active() const133   inline bool active() const
134   {
135     return (down_[1] != -COIN_DBL_MAX);
136   }
137 #endif
138 
139   /** Return the type (an integer identifier) of \c this */
type() const140   virtual CbcBranchObjType type() const
141   {
142     return SimpleIntegerBranchObj;
143   }
144 
145   /** Compare the \c this with \c brObj. \c this and \c brObj must be os the
146         same type and must have the same original object, but they may have
147         different feasible regions.
148         Return the appropriate CbcRangeCompare value (first argument being the
149         sub/superset if that's the case). In case of overlap (and if \c
150         replaceIfOverlap is true) replace the current branching object with one
151         whose feasible region is the overlap.
152      */
153   virtual CbcRangeCompare compareBranchingObject(const CbcBranchingObject *brObj, const bool replaceIfOverlap = false);
154 
155 protected:
156   /// Lower [0] and upper [1] bounds for the down arm (way_ = -1)
157   double down_[2];
158   /// Lower [0] and upper [1] bounds for the up arm (way_ = 1)
159   double up_[2];
160 #ifdef FUNNY_BRANCHING
161   /** Which variable (top bit if upper bound changing)
162         next bit if changing on down branch only */
163   int *variables_;
164   // New bound
165   double *newBounds_;
166   /// Number of Extra bound changes
167   int numberExtraChangedBounds_;
168 #endif
169 };
170 
171 /// Define a single integer class
172 
173 class CbcSimpleInteger : public CbcObject {
174 
175 public:
176   // Default Constructor
177   CbcSimpleInteger();
178 
179   // Useful constructor - passed model and index
180   CbcSimpleInteger(CbcModel *model, int iColumn, double breakEven = 0.5);
181 
182   // Useful constructor - passed model and Osi object
183   CbcSimpleInteger(CbcModel *model, const OsiSimpleInteger *object);
184 
185   // Copy constructor
186   CbcSimpleInteger(const CbcSimpleInteger &);
187 
188   /// Clone
189   virtual CbcObject *clone() const;
190 
191   // Assignment operator
192   CbcSimpleInteger &operator=(const CbcSimpleInteger &rhs);
193 
194   // Destructor
195   virtual ~CbcSimpleInteger();
196   /// Construct an OsiSimpleInteger object
197   OsiSimpleInteger *osiObject() const;
198   /// Infeasibility - large is 0.5
199   virtual double infeasibility(const OsiBranchingInformation *info,
200     int &preferredWay) const;
201 
202   using CbcObject::feasibleRegion;
203   /** Set bounds to fix the variable at the current (integer) value.
204 
205       Given an integer value, set the lower and upper bounds to fix the
206       variable. Returns amount it had to move variable.
207     */
208   virtual double feasibleRegion(OsiSolverInterface *solver, const OsiBranchingInformation *info) const;
209 
210   /** Create a branching object and indicate which way to branch first.
211 
212         The branching object has to know how to create branches (fix
213         variables, etc.)
214     */
215   virtual CbcBranchingObject *createCbcBranch(OsiSolverInterface *solver, const OsiBranchingInformation *info, int way);
216   /// Fills in a created branching object
217   /*virtual*/ void fillCreateBranch(CbcIntegerBranchingObject *branching, const OsiBranchingInformation *info, int way);
218 
219   using CbcObject::solverBranch;
220   /** Create an OsiSolverBranch object
221 
222         This returns NULL if branch not represented by bound changes
223     */
224   virtual OsiSolverBranch *solverBranch(OsiSolverInterface *solver, const OsiBranchingInformation *info) const;
225 
226   /** Set bounds to fix the variable at the current (integer) value.
227 
228       Given an integer value, set the lower and upper bounds to fix the
229       variable. The algorithm takes a bit of care in order to compensate for
230       minor numerical inaccuracy.
231     */
232   virtual void feasibleRegion();
233 
234   /** Column number if single column object -1 otherwise,
235         so returns >= 0
236         Used by heuristics
237     */
238   virtual int columnNumber() const;
239   /// Set column number
setColumnNumber(int value)240   inline void setColumnNumber(int value)
241   {
242     columnNumber_ = value;
243   }
244 
245   /** Reset variable bounds to their original values.
246 
247       Bounds may be tightened, so it may be good to be able to set this info in object.
248      */
249   virtual void resetBounds(const OsiSolverInterface *solver);
250 
251   /**  Change column numbers after preprocessing
252      */
253   virtual void resetSequenceEtc(int numberColumns, const int *originalColumns);
254   /// Original bounds
originalLowerBound() const255   inline double originalLowerBound() const
256   {
257     return originalLower_;
258   }
setOriginalLowerBound(double value)259   inline void setOriginalLowerBound(double value)
260   {
261     originalLower_ = value;
262   }
originalUpperBound() const263   inline double originalUpperBound() const
264   {
265     return originalUpper_;
266   }
setOriginalUpperBound(double value)267   inline void setOriginalUpperBound(double value)
268   {
269     originalUpper_ = value;
270   }
271   /// Breakeven e.g 0.7 -> >= 0.7 go up first
breakEven() const272   inline double breakEven() const
273   {
274     return breakEven_;
275   }
276   /// Set breakeven e.g 0.7 -> >= 0.7 go up first
setBreakEven(double value)277   inline void setBreakEven(double value)
278   {
279     breakEven_ = value;
280   }
281 
282 protected:
283   /// data
284 
285   /// Original lower bound
286   double originalLower_;
287   /// Original upper bound
288   double originalUpper_;
289   /// Breakeven i.e. >= this preferred is up
290   double breakEven_;
291   /// Column number in model
292   int columnNumber_;
293   /// If -1 down always chosen first, +1 up always, 0 normal
294   int preferredWay_;
295 };
296 #endif
297 
298 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
299 */
300