1/* $Id: ClpSolve.hpp 1665 2011-01-04 17:55:54Z lou $ */
2// Copyright (C) 2003, 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 Authors
7
8 John Forrest
9
10 */
11#ifndef ClpSolve_H
12#define ClpSolve_H
13
14/**
15 This is a very simple class to guide algorithms. It is used to tidy up
16 passing parameters to initialSolve and maybe for output from that
17
18*/
19
20class ClpSolve {
21
22public:
23
24 /** enums for solve function */
25 enum SolveType {
26 useDual = 0,
27 usePrimal,
28 usePrimalorSprint,
29 useBarrier,
30 useBarrierNoCross,
31 automatic,
32 notImplemented
33 };
34 enum PresolveType {
35 presolveOn = 0,
36 presolveOff,
37 presolveNumber,
38 presolveNumberCost
39 };
40
41 /**@name Constructors and destructor and copy */
42 //@{
43 /// Default constructor
44 ClpSolve ( );
45 /// Constructor when you really know what you are doing
46 ClpSolve ( SolveType method, PresolveType presolveType,
47 int numberPasses, int options[6],
48 int extraInfo[6], int independentOptions[3]);
49 /// Generates code for above constructor
50 void generateCpp(FILE * fp);
51 /// Copy constructor.
52 ClpSolve(const ClpSolve &);
53 /// Assignment operator. This copies the data
54 ClpSolve & operator=(const ClpSolve & rhs);
55 /// Destructor
56 ~ClpSolve ( );
57 //@}
58
59 /**@name Functions most useful to user */
60 //@{
61 /** Special options - bits
62 0 4 - use crash (default allslack in dual, idiot in primal)
63 8 - all slack basis in primal
64 2 16 - switch off interrupt handling
65 3 32 - do not try and make plus minus one matrix
66 64 - do not use sprint even if problem looks good
67 */
68 /** which translation is:
69 which:
70 0 - startup in Dual (nothing if basis exists).:
71 0 - no basis
72 1 - crash
73 2 - use initiative about idiot! but no crash
74 1 - startup in Primal (nothing if basis exists):
75 0 - use initiative
76 1 - use crash
77 2 - use idiot and look at further info
78 3 - use sprint and look at further info
79 4 - use all slack
80 5 - use initiative but no idiot
81 6 - use initiative but no sprint
82 7 - use initiative but no crash
83 8 - do allslack or idiot
84 9 - do allslack or sprint
85 10 - slp before
86 11 - no nothing and primal(0)
87 2 - interrupt handling - 0 yes, 1 no (for threadsafe)
88 3 - whether to make +- 1matrix - 0 yes, 1 no
89 4 - for barrier
90 0 - dense cholesky
91 1 - Wssmp allowing some long columns
92 2 - Wssmp not allowing long columns
93 3 - Wssmp using KKT
94 4 - Using Florida ordering
95 8 - bit set to do scaling
96 16 - set to be aggressive with gamma/delta?
97 32 - Use KKT
98 5 - for presolve
99 1 - switch off dual stuff
100 6 - for detailed printout (initially just presolve)
101 1 - presolve statistics
102 */
103 void setSpecialOption(int which, int value, int extraInfo = -1);
104 int getSpecialOption(int which) const;
105
106 /// Solve types
107 void setSolveType(SolveType method, int extraInfo = -1);
108 SolveType getSolveType();
109
110 // Presolve types
111 void setPresolveType(PresolveType amount, int extraInfo = -1);
112 PresolveType getPresolveType();
113 int getPresolvePasses() const;
114 /// Extra info for idiot (or sprint)
115 int getExtraInfo(int which) const;
116 /** Say to return at once if infeasible,
117 default is to solve */
118 void setInfeasibleReturn(bool trueFalse);
119 inline bool infeasibleReturn() const {
120 return independentOptions_[0] != 0;
121 }
122 /// Whether we want to do dual part of presolve
123 inline bool doDual() const {
124 return (independentOptions_[1] & 1) == 0;
125 }
126 inline void setDoDual(bool doDual_) {
127 if (doDual_) independentOptions_[1] &= ~1;
128 else independentOptions_[1] |= 1;
129 }
130 /// Whether we want to do singleton part of presolve
131 inline bool doSingleton() const {
132 return (independentOptions_[1] & 2) == 0;
133 }
134 inline void setDoSingleton(bool doSingleton_) {
135 if (doSingleton_) independentOptions_[1] &= ~2;
136 else independentOptions_[1] |= 2;
137 }
138 /// Whether we want to do doubleton part of presolve
139 inline bool doDoubleton() const {
140 return (independentOptions_[1] & 4) == 0;
141 }
142 inline void setDoDoubleton(bool doDoubleton_) {
143 if (doDoubleton_) independentOptions_[1] &= ~4;
144 else independentOptions_[1] |= 4;
145 }
146 /// Whether we want to do tripleton part of presolve
147 inline bool doTripleton() const {
148 return (independentOptions_[1] & 8) == 0;
149 }
150 inline void setDoTripleton(bool doTripleton_) {
151 if (doTripleton_) independentOptions_[1] &= ~8;
152 else independentOptions_[1] |= 8;
153 }
154 /// Whether we want to do tighten part of presolve
155 inline bool doTighten() const {
156 return (independentOptions_[1] & 16) == 0;
157 }
158 inline void setDoTighten(bool doTighten_) {
159 if (doTighten_) independentOptions_[1] &= ~16;
160 else independentOptions_[1] |= 16;
161 }
162 /// Whether we want to do forcing part of presolve
163 inline bool doForcing() const {
164 return (independentOptions_[1] & 32) == 0;
165 }
166 inline void setDoForcing(bool doForcing_) {
167 if (doForcing_) independentOptions_[1] &= ~32;
168 else independentOptions_[1] |= 32;
169 }
170 /// Whether we want to do impliedfree part of presolve
171 inline bool doImpliedFree() const {
172 return (independentOptions_[1] & 64) == 0;
173 }
174 inline void setDoImpliedFree(bool doImpliedfree) {
175 if (doImpliedfree) independentOptions_[1] &= ~64;
176 else independentOptions_[1] |= 64;
177 }
178 /// Whether we want to do dupcol part of presolve
179 inline bool doDupcol() const {
180 return (independentOptions_[1] & 128) == 0;
181 }
182 inline void setDoDupcol(bool doDupcol_) {
183 if (doDupcol_) independentOptions_[1] &= ~128;
184 else independentOptions_[1] |= 128;
185 }
186 /// Whether we want to do duprow part of presolve
187 inline bool doDuprow() const {
188 return (independentOptions_[1] & 256) == 0;
189 }
190 inline void setDoDuprow(bool doDuprow_) {
191 if (doDuprow_) independentOptions_[1] &= ~256;
192 else independentOptions_[1] |= 256;
193 }
194 /// Whether we want to do singleton column part of presolve
195 inline bool doSingletonColumn() const {
196 return (independentOptions_[1] & 512) == 0;
197 }
198 inline void setDoSingletonColumn(bool doSingleton_) {
199 if (doSingleton_) independentOptions_[1] &= ~512;
200 else independentOptions_[1] |= 512;
201 }
202 /// Set whole group
203 inline int presolveActions() const {
204 return independentOptions_[1] & 0xffff;
205 }
206 inline void setPresolveActions(int action) {
207 independentOptions_[1] = (independentOptions_[1] & 0xffff0000) | (action & 0xffff);
208 }
209 /// Largest column for substitution (normally 3)
210 inline int substitution() const {
211 return independentOptions_[2];
212 }
213 inline void setSubstitution(int value) {
214 independentOptions_[2] = value;
215 }
216 //@}
217
218////////////////// data //////////////////
219private:
220
221 /**@name data.
222 */
223 //@{
224 /// Solve type
225 SolveType method_;
226 /// Presolve type
227 PresolveType presolveType_;
228 /// Amount of presolve
229 int numberPasses_;
230 /// Options - last is switch for OsiClp
231 int options_[7];
232 /// Extra information
233 int extraInfo_[7];
234 /** Extra algorithm dependent options
235 0 - if set return from clpsolve if infeasible
236 1 - To be copied over to presolve options
237 2 - max substitution level
238 */
239 int independentOptions_[3];
240 //@}
241};
242
243/// For saving extra information to see if looping.
244class ClpSimplexProgress {
245
246public:
247
248
249 /**@name Constructors and destructor and copy */
250 //@{
251 /// Default constructor
252 ClpSimplexProgress ( );
253
254 /// Constructor from model
255 ClpSimplexProgress ( ClpSimplex * model );
256
257 /// Copy constructor.
258 ClpSimplexProgress(const ClpSimplexProgress &);
259
260 /// Assignment operator. This copies the data
261 ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs);
262 /// Destructor
263 ~ClpSimplexProgress ( );
264 /// Resets as much as possible
265 void reset();
266 /// Fill from model
267 void fillFromModel ( ClpSimplex * model );
268
269 //@}
270
271 /**@name Check progress */
272 //@{
273 /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken,
274 >=0 if give up and use as problem status
275 */
276 int looping ( );
277 /// Start check at beginning of whileIterating
278 void startCheck();
279 /// Returns cycle length in whileIterating
280 int cycle(int in, int out, int wayIn, int wayOut);
281
282 /// Returns previous objective (if -1) - current if (0)
283 double lastObjective(int back = 1) const;
284 /// Set real primal infeasibility and move back
285 void setInfeasibility(double value);
286 /// Returns real primal infeasibility (if -1) - current if (0)
287 double lastInfeasibility(int back = 1) const;
288 /// Modify objective e.g. if dual infeasible in dual
289 void modifyObjective(double value);
290 /// Returns previous iteration number (if -1) - current if (0)
291 int lastIterationNumber(int back = 1) const;
292 /// clears all iteration numbers (to switch off panic)
293 void clearIterationNumbers();
294 /// Odd state
295 inline void newOddState() {
296 oddState_ = - oddState_ - 1;
297 }
298 inline void endOddState() {
299 oddState_ = abs(oddState_);
300 }
301 inline void clearOddState() {
302 oddState_ = 0;
303 }
304 inline int oddState() const {
305 return oddState_;
306 }
307 /// number of bad times
308 inline int badTimes() const {
309 return numberBadTimes_;
310 }
311 inline void clearBadTimes() {
312 numberBadTimes_ = 0;
313 }
314 /// number of really bad times
315 inline int reallyBadTimes() const {
316 return numberReallyBadTimes_;
317 }
318 inline void incrementReallyBadTimes() {
319 numberReallyBadTimes_++;
320 }
321 /// number of times flagged
322 inline int timesFlagged() const {
323 return numberTimesFlagged_;
324 }
325 inline void clearTimesFlagged() {
326 numberTimesFlagged_ = 0;
327 }
328 inline void incrementTimesFlagged() {
329 numberTimesFlagged_++;
330 }
331
332 //@}
333 /**@name Data */
334#define CLP_PROGRESS 5
335 //#define CLP_PROGRESS_WEIGHT 10
336 //@{
337 /// Objective values
338 double objective_[CLP_PROGRESS];
339 /// Sum of infeasibilities for algorithm
340 double infeasibility_[CLP_PROGRESS];
341 /// Sum of real primal infeasibilities for primal
342 double realInfeasibility_[CLP_PROGRESS];
343#ifdef CLP_PROGRESS_WEIGHT
344 /// Objective values for weights
345 double objectiveWeight_[CLP_PROGRESS_WEIGHT];
346 /// Sum of infeasibilities for algorithm for weights
347 double infeasibilityWeight_[CLP_PROGRESS_WEIGHT];
348 /// Sum of real primal infeasibilities for primal for weights
349 double realInfeasibilityWeight_[CLP_PROGRESS_WEIGHT];
350 /// Drop for weights
351 double drop_;
352 /// Best? for weights
353 double best_;
354#endif
355 /// Initial weight for weights
356 double initialWeight_;
357#define CLP_CYCLE 12
358 /// For cycle checking
359 //double obj_[CLP_CYCLE];
360 int in_[CLP_CYCLE];
361 int out_[CLP_CYCLE];
362 char way_[CLP_CYCLE];
363 /// Pointer back to model so we can get information
364 ClpSimplex * model_;
365 /// Number of infeasibilities
366 int numberInfeasibilities_[CLP_PROGRESS];
367 /// Iteration number at which occurred
368 int iterationNumber_[CLP_PROGRESS];
369#ifdef CLP_PROGRESS_WEIGHT
370 /// Number of infeasibilities for weights
371 int numberInfeasibilitiesWeight_[CLP_PROGRESS_WEIGHT];
372 /// Iteration number at which occurred for weights
373 int iterationNumberWeight_[CLP_PROGRESS_WEIGHT];
374#endif
375 /// Number of times checked (so won't stop too early)
376 int numberTimes_;
377 /// Number of times it looked like loop
378 int numberBadTimes_;
379 /// Number really bad times
380 int numberReallyBadTimes_;
381 /// Number of times no iterations as flagged
382 int numberTimesFlagged_;
383 /// If things are in an odd state
384 int oddState_;
385 //@}
386};
387#endif
388