00001
00002
00003 #ifndef CglSimpleRounding_H
00004 #define CglSimpleRounding_H
00005
00006 #include <string>
00007
00008 #include "CglCutGenerator.hpp"
00009 #include "CoinPackedMatrix.hpp"
00010
00026 class CglSimpleRounding : public CglCutGenerator {
00027 friend void CglSimpleRoundingUnitTest(const OsiSolverInterface * siP,
00028 const std::string mpdDir );
00029
00030 public:
00031
00037 virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs ) const;
00039
00042
00043 CglSimpleRounding ();
00044
00046 CglSimpleRounding (
00047 const CglSimpleRounding &);
00048
00050 CglSimpleRounding &
00051 operator=(
00052 const CglSimpleRounding& rhs);
00053
00055 virtual
00056 ~CglSimpleRounding ();
00058
00059 private:
00060
00061
00062
00065
00067 bool deriveAnIntegerRow(
00068 const OsiSolverInterface & si,
00069 int rowIndex,
00070 const CoinShallowPackedVector & matrixRow,
00071 CoinPackedVector & irow,
00072 double & b,
00073 bool * negative) const;
00074
00075
00091 int power10ToMakeDoubleAnInt(
00092 int size,
00093 const double * x,
00094 double dataTol ) const;
00095
00096
00099
00100 inline int gcd(int a, int b) const;
00101
00105 inline int gcdv(int n, const int * const vi) const;
00107
00109
00112
00113 double epsilon_;
00115 };
00116
00117
00118
00119
00120
00121
00122 int
00123 CglSimpleRounding::gcd(int a, int b) const
00124 {
00125 if(a > b) {
00126
00127 int temp = a;
00128 a = b;
00129 b = temp;
00130 }
00131 int remainder = b % a;
00132 if (remainder == 0) return a;
00133 else return gcd(remainder,a);
00134 }
00135
00136
00137
00138
00139
00140 int
00141 CglSimpleRounding::gcdv(int n, const int* const vi) const
00142 {
00143 if (n==0)
00144 abort();
00145
00146 if (n==1)
00147 return vi[0];
00148
00149 int retval=gcd(vi[0], vi[1]);
00150 for (int i=2; i<n; i++){
00151 retval=gcd(retval,vi[i]);
00152 }
00153 return retval;
00154 }
00155
00156
00162 void CglSimpleRoundingUnitTest(const OsiSolverInterface * siP,
00163 const std::string mpdDir );
00164
00165 #endif