1 // Copyright (C) 2002, International Business Machines
2 // Corporation and others.  All Rights Reserved.
3 // This code is licensed under the terms of the Eclipse Public License (EPL).
4 
5 #ifndef CglGomory_H
6 #define CglGomory_H
7 
8 #include <string>
9 
10 #include "CglCutGenerator.hpp"
11 
12 class CoinWarmStartBasis;
13 /** Gomory Cut Generator Class */
14 class CglGomory : public CglCutGenerator {
15    friend void CglGomoryUnitTest(const OsiSolverInterface * siP,
16 				  const std::string mpdDir );
17 
18 public:
19 
20 
21   /**@name Generate Cuts */
22   //@{
23   /** Generate Mixed Integer Gomory cuts for the model of the
24       solver interface, si.
25 
26       Insert the generated cuts into OsiCut, cs.
27 
28       There is a limit option, which will only generate cuts with
29       less than this number of entries.
30 
31       We can also only look at 0-1 variables a certain distance
32       from integer.
33   */
34   virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
35 			     const CglTreeInfo info = CglTreeInfo());
36   /** Generates cuts given matrix and solution etc,
37       returns number of cuts generated */
38   int generateCuts( const OsiRowCutDebugger * debugger,
39 		    OsiCuts & cs,
40 		    const CoinPackedMatrix & columnCopy,
41 		    const CoinPackedMatrix & rowCopy,
42 		    const double * colsol,
43 		    const double * colLower, const double * colUpper,
44 		    const double * rowLower, const double * rowUpper,
45 		    const char * intVar ,
46 		    const CoinWarmStartBasis* warm,
47                     const CglTreeInfo info = CglTreeInfo());
48   /** Generates cuts given matrix and solution etc,
49       returns number of cuts generated (no row copy passed in) */
50   int generateCuts( const OsiRowCutDebugger * debugger,
51 		    OsiCuts & cs,
52 		    const CoinPackedMatrix & columnCopy,
53 		    const double * colsol,
54 		    const double * colLower, const double * colUpper,
55 		    const double * rowLower, const double * rowUpper,
56 		    const char * intVar ,
57 		    const CoinWarmStartBasis* warm,
58                     const CglTreeInfo info = CglTreeInfo());
59 
60   /// Return true if needs optimal basis to do cuts (will return true)
needsOptimalBasis() const61   virtual bool needsOptimalBasis() const { return true; }
62   //@}
63 
64   /**@name Change way Gomory works */
65   //@{
66   /// Pass in a copy of original solver (clone it)
67   void passInOriginalSolver(OsiSolverInterface * solver);
68   /// Returns original solver
originalSolver() const69   inline OsiSolverInterface * originalSolver() const
70   { return originalSolver_;}
71   /// Set type - 0 normal, 1 add original matrix one, 2 replace
setGomoryType(int type)72   inline void setGomoryType(int type)
73   { gomoryType_=type;}
74   /// Return type
gomoryType() const75   inline int gomoryType() const
76   { return gomoryType_;}
77   //@}
78 
79   /**@name Change limit on how many variables in cut (default 50) */
80   //@{
81   /// Set
82   void setLimit(int limit);
83   /// Get
84   int getLimit() const;
85   /// Set at root (if <normal then use normal)
86   void setLimitAtRoot(int limit);
87   /// Get at root
88   int getLimitAtRoot() const;
89   /// Return maximum length of cut in tree
90   virtual int maximumLengthOfCutInTree() const;
91   //@}
92 
93   /**@name Change criterion on which variables to look at.  All ones
94    more than "away" away from integrality will be investigated
95   (default 0.05) */
96   //@{
97   /// Set away
98   void setAway(double value);
99   /// Get away
100   double getAway() const;
101   /// Set away at root
102   void setAwayAtRoot(double value);
103   /// Get away at root
104   double getAwayAtRoot() const;
105   //@}
106 
107   /**@name Change criterion on which the cut id relaxed if the code
108            thinks the factorization has inaccuracies.  The relaxation to
109 	   RHS is smallest of -
110 	   1) 1.0e-4
111 	   2) conditionNumberMultiplier * condition number of factorization
112 	   3) largestFactorMultiplier * largest (dual*element) forming tableau
113 	      row
114   */
115   //@{
116   /// Set ConditionNumberMultiplier
117   void setConditionNumberMultiplier(double value);
118   /// Get ConditionNumberMultiplier
119   double getConditionNumberMultiplier() const;
120   /// Set LargestFactorMultiplier
121   void setLargestFactorMultiplier(double value);
122   /// Get LargestFactorMultiplier
123   double getLargestFactorMultiplier() const;
124   //@}
125 
126   /**@name change factorization */
127   //@{
128    /// Set/unset alternative factorization
useAlternativeFactorization(bool yes=true)129    inline void useAlternativeFactorization(bool yes=true)
130    { alternateFactorization_= (yes) ? 1 : 0;}
131    /// Get whether alternative factorization being used
alternativeFactorization() const132    inline bool alternativeFactorization() const
133    { return (alternateFactorization_!=0);}
134   //@}
135 
136   /**@name Constructors and destructors */
137   //@{
138   /// Default constructor
139   CglGomory ();
140 
141   /// Copy constructor
142   CglGomory (
143     const CglGomory &);
144 
145   /// Clone
146   virtual CglCutGenerator * clone() const;
147 
148   /// Assignment operator
149   CglGomory &
150     operator=(
151     const CglGomory& rhs);
152 
153   /// Destructor
154   virtual
155     ~CglGomory ();
156   /// Create C++ lines to get to current state
157   virtual std::string generateCpp( FILE * fp);
158   /// This can be used to refresh any inforamtion
159   virtual void refreshSolver(OsiSolverInterface * solver);
160   //@}
161 
162 private:
163 
164  // Private member methods
165 
166   // Private member data
167 
168   /**@name Private member data */
169   //@{
170   /// Only investigate if more than this away from integrality
171   double away_;
172   /// Only investigate if more than this away from integrality (at root)
173   double awayAtRoot_;
174   /// Multiplier for conditionNumber cut relaxation
175   double conditionNumberMultiplier_;
176   /// Multiplier for largest factor cut relaxation
177   double largestFactorMultiplier_;
178   /// Original solver
179   OsiSolverInterface * originalSolver_;
180   /// Limit - only generate if fewer than this in cut
181   int limit_;
182   /// Limit - only generate if fewer than this in cut (at root)
183   int limitAtRoot_;
184   /// Dynamic limit in tree
185   int dynamicLimitInTree_;
186   /// Number of times stalled
187   int numberTimesStalled_;
188   /// nonzero to use alternative factorization
189   int alternateFactorization_;
190   /// Type - 0 normal, 1 add original matrix one, 2 replace
191   int gomoryType_; // note could add in cutoff as constraint
192   //@}
193 };
194 
195 //#############################################################################
196 /** A function that tests the methods in the CglGomory class. The
197     only reason for it not to be a member method is that this way it doesn't
198     have to be compiled into the library. And that's a gain, because the
199     library should be compiled with optimization on, but this method should be
200     compiled with debugging. */
201 void CglGomoryUnitTest(const OsiSolverInterface * siP,
202 			const std::string mpdDir );
203 
204 #endif
205