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
|
// $Id: CglDuplicateRow.hpp 1119 2013-04-06 20:24:18Z stefan $
// Copyright (C) 2004, International Business Machines
// Corporation and others. All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).
#ifndef CglDuplicateRow_H
#define CglDuplicateRow_H
#include <string>
#include "CglCutGenerator.hpp"
class CglStored;
/** DuplicateRow Cut Generator Class */
class CglDuplicateRow : public CglCutGenerator {
public:
/**@name Generate Cuts */
//@{
/** Fix variables and find duplicate/dominated rows for the model of the
solver interface, si.
This is a very simple minded idea but I (JJF) am using it in a project so thought
I might as well add it. It should really be called before first solve and I may
modify CBC to allow for that.
This is designed for problems with few rows and many integer variables where the rhs
are <= or == and all coefficients and rhs are small integers.
If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds
(effective rhs just means original with variables with nonzero lower bounds subtracted out).
If one row is a subset of another and the effective rhs are same we can fix some variables
and then the two rows are identical.
The generator marks identical rows so can be taken out in solve
*/
virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
const CglTreeInfo info = CglTreeInfo());
private:
/// Does work for modes 1,2
void generateCuts12( const OsiSolverInterface & si, OsiCuts & cs,
const CglTreeInfo info = CglTreeInfo());
/// Does work for mode 4
void generateCuts4( const OsiSolverInterface & si, OsiCuts & cs,
const CglTreeInfo info = CglTreeInfo());
/// Does work for mode 8
void generateCuts8( const OsiSolverInterface & si, OsiCuts & cs,
const CglTreeInfo info = CglTreeInfo());
public:
/** Fix variables and find duplicate/dominated rows for the model of the
solver interface, si.
This is a very simple minded idea but I (JJF) am using it in a project so thought
I might as well add it. It should really be called before first solve and I may
modify CBC to allow for that.
This is designed for problems with few rows and many integer variables where the rhs
are <= or == and all coefficients and rhs are small integers.
If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds
(effective rhs just means original with variables with nonzero lower bounds subtracted out).
If one row is a subset of another and the effective rhs are same we can fix some variables
and then the two rows are identical.
This version does deletions and fixings and may return stored cuts for
dominated columns
*/
CglStored * outDuplicates( OsiSolverInterface * solver);
//@}
/**@name Get information on size of problem */
//@{
/// Get duplicate row list, -1 means still in, -2 means out (all fixed), k>= means same as row k
inline const int * duplicate() const
{ return duplicate_;}
/// Size of dynamic program
inline int sizeDynamic() const
{ return sizeDynamic_;}
/// Number of rows in original problem
inline int numberOriginalRows() const
{ return matrix_.getNumRows();}
//@}
/**@name Get information on size of problem */
//@{
/// logLevel
inline int logLevel() const
{ return logLevel_;}
inline void setLogLevel(int value)
{ logLevel_ = value;}
//@}
/**@name We only check for duplicates amongst rows with effective rhs <= this */
//@{
/// Get
inline int maximumRhs() const
{ return maximumRhs_;}
/// Set
inline void setMaximumRhs(int value)
{ maximumRhs_=value;}
//@}
/**@name We only check for dominated amongst groups of columns whose size <= this */
//@{
/// Get
inline int maximumDominated() const
{ return maximumDominated_;}
/// Set
inline void setMaximumDominated(int value)
{ maximumDominated_=value;}
//@}
/**@name gets and sets */
//@{
/// Get mode
inline int mode() const
{ return mode_;}
/// Set mode
inline void setMode(int value)
{ mode_=value;}
//@}
/**@name Constructors and destructors */
//@{
/// Default constructor
CglDuplicateRow ();
/// Useful constructor
CglDuplicateRow (OsiSolverInterface * solver);
/// Copy constructor
CglDuplicateRow (
const CglDuplicateRow & rhs);
/// Clone
virtual CglCutGenerator * clone() const;
/// Assignment operator
CglDuplicateRow &
operator=(
const CglDuplicateRow& rhs);
/// Destructor
virtual
~CglDuplicateRow ();
/// Create C++ lines to get to current state
virtual std::string generateCpp( FILE * fp);
/// This can be used to refresh any information
virtual void refreshSolver(OsiSolverInterface * solver);
//@}
protected:
// Protected member data
/**@name Protected member data */
//@{
/// Matrix
CoinPackedMatrix matrix_;
/// Matrix by row
CoinPackedMatrix matrixByRow_;
/// Possible rhs (if 0 then not possible)
int * rhs_;
/// Marks duplicate rows
int * duplicate_;
/// To allow for <= rows
int * lower_;
/// Stored cuts if we found dominance cuts
CglStored * storedCuts_;
/// Check dominated columns if less than this number of candidates
int maximumDominated_;
/// Check duplicates if effective rhs <= this
int maximumRhs_;
/// Size of dynamic program
int sizeDynamic_;
/// 1 do rows, 2 do columns, 3 do both
int mode_;
/// Controls print out
int logLevel_;
//@}
};
#endif
|