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