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 | |
20 | class ClpSolve { |
21 | |
22 | public: |
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 [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 = -1); |
104 | int getSpecialOption(int which) const; |
105 | |
106 | /// Solve types |
107 | void setSolveType(SolveType method, int = -1); |
108 | SolveType getSolveType(); |
109 | |
110 | // Presolve types |
111 | void setPresolveType(PresolveType amount, int = -1); |
112 | PresolveType getPresolveType(); |
113 | int getPresolvePasses() const; |
114 | /// Extra info for idiot (or sprint) |
115 | int (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 ////////////////// |
219 | private: |
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 [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. |
244 | class ClpSimplexProgress { |
245 | |
246 | public: |
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 | |