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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
|
/* $Id: ClpSolve.hpp 2078 2015-01-05 12:39:49Z forrest $ */
// Copyright (C) 2003, International Business Machines
// Corporation and others. All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).
/*
Authors
John Forrest
*/
#ifndef ClpSolve_H
#define ClpSolve_H
/**
This is a very simple class to guide algorithms. It is used to tidy up
passing parameters to initialSolve and maybe for output from that
*/
class ClpSolve {
public:
/** enums for solve function */
enum SolveType {
useDual = 0,
usePrimal,
usePrimalorSprint,
useBarrier,
useBarrierNoCross,
automatic,
tryDantzigWolfe,
tryBenders,
notImplemented
};
enum PresolveType {
presolveOn = 0,
presolveOff,
presolveNumber,
presolveNumberCost
};
/**@name Constructors and destructor and copy */
//@{
/// Default constructor
ClpSolve ( );
/// Constructor when you really know what you are doing
ClpSolve ( SolveType method, PresolveType presolveType,
int numberPasses, int options[6],
int extraInfo[6], int independentOptions[3]);
/// Generates code for above constructor
void generateCpp(FILE * fp);
/// Copy constructor.
ClpSolve(const ClpSolve &);
/// Assignment operator. This copies the data
ClpSolve & operator=(const ClpSolve & rhs);
/// Destructor
~ClpSolve ( );
//@}
/**@name Functions most useful to user */
//@{
/** Special options - bits
0 4 - use crash (default allslack in dual, idiot in primal)
8 - all slack basis in primal
2 16 - switch off interrupt handling
3 32 - do not try and make plus minus one matrix
64 - do not use sprint even if problem looks good
*/
/** which translation is:
which:
0 - startup in Dual (nothing if basis exists).:
0 - no basis
1 - crash
2 - use initiative about idiot! but no crash
1 - startup in Primal (nothing if basis exists):
0 - use initiative
1 - use crash
2 - use idiot and look at further info
3 - use sprint and look at further info
4 - use all slack
5 - use initiative but no idiot
6 - use initiative but no sprint
7 - use initiative but no crash
8 - do allslack or idiot
9 - do allslack or sprint
10 - slp before
11 - no nothing and primal(0)
2 - interrupt handling - 0 yes, 1 no (for threadsafe)
3 - whether to make +- 1matrix - 0 yes, 1 no
4 - for barrier
0 - dense cholesky
1 - Wssmp allowing some long columns
2 - Wssmp not allowing long columns
3 - Wssmp using KKT
4 - Using Florida ordering
8 - bit set to do scaling
16 - set to be aggressive with gamma/delta?
32 - Use KKT
5 - for presolve
1 - switch off dual stuff
6 - extra switches
*/
void setSpecialOption(int which, int value, int extraInfo = -1);
int getSpecialOption(int which) const;
/// Solve types
void setSolveType(SolveType method, int extraInfo = -1);
SolveType getSolveType();
// Presolve types
void setPresolveType(PresolveType amount, int extraInfo = -1);
PresolveType getPresolveType();
int getPresolvePasses() const;
/// Extra info for idiot (or sprint)
int getExtraInfo(int which) const;
/** Say to return at once if infeasible,
default is to solve */
void setInfeasibleReturn(bool trueFalse);
inline bool infeasibleReturn() const {
return independentOptions_[0] != 0;
}
/// Whether we want to do dual part of presolve
inline bool doDual() const {
return (independentOptions_[1] & 1) == 0;
}
inline void setDoDual(bool doDual_) {
if (doDual_) independentOptions_[1] &= ~1;
else independentOptions_[1] |= 1;
}
/// Whether we want to do singleton part of presolve
inline bool doSingleton() const {
return (independentOptions_[1] & 2) == 0;
}
inline void setDoSingleton(bool doSingleton_) {
if (doSingleton_) independentOptions_[1] &= ~2;
else independentOptions_[1] |= 2;
}
/// Whether we want to do doubleton part of presolve
inline bool doDoubleton() const {
return (independentOptions_[1] & 4) == 0;
}
inline void setDoDoubleton(bool doDoubleton_) {
if (doDoubleton_) independentOptions_[1] &= ~4;
else independentOptions_[1] |= 4;
}
/// Whether we want to do tripleton part of presolve
inline bool doTripleton() const {
return (independentOptions_[1] & 8) == 0;
}
inline void setDoTripleton(bool doTripleton_) {
if (doTripleton_) independentOptions_[1] &= ~8;
else independentOptions_[1] |= 8;
}
/// Whether we want to do tighten part of presolve
inline bool doTighten() const {
return (independentOptions_[1] & 16) == 0;
}
inline void setDoTighten(bool doTighten_) {
if (doTighten_) independentOptions_[1] &= ~16;
else independentOptions_[1] |= 16;
}
/// Whether we want to do forcing part of presolve
inline bool doForcing() const {
return (independentOptions_[1] & 32) == 0;
}
inline void setDoForcing(bool doForcing_) {
if (doForcing_) independentOptions_[1] &= ~32;
else independentOptions_[1] |= 32;
}
/// Whether we want to do impliedfree part of presolve
inline bool doImpliedFree() const {
return (independentOptions_[1] & 64) == 0;
}
inline void setDoImpliedFree(bool doImpliedfree) {
if (doImpliedfree) independentOptions_[1] &= ~64;
else independentOptions_[1] |= 64;
}
/// Whether we want to do dupcol part of presolve
inline bool doDupcol() const {
return (independentOptions_[1] & 128) == 0;
}
inline void setDoDupcol(bool doDupcol_) {
if (doDupcol_) independentOptions_[1] &= ~128;
else independentOptions_[1] |= 128;
}
/// Whether we want to do duprow part of presolve
inline bool doDuprow() const {
return (independentOptions_[1] & 256) == 0;
}
inline void setDoDuprow(bool doDuprow_) {
if (doDuprow_) independentOptions_[1] &= ~256;
else independentOptions_[1] |= 256;
}
/// Whether we want to do singleton column part of presolve
inline bool doSingletonColumn() const {
return (independentOptions_[1] & 512) == 0;
}
inline void setDoSingletonColumn(bool doSingleton_) {
if (doSingleton_) independentOptions_[1] &= ~512;
else independentOptions_[1] |= 512;
}
/// Whether we want to kill small substitutions
inline bool doKillSmall() const {
return (independentOptions_[1] & 8192) == 0;
}
inline void setDoKillSmall(bool doKill) {
if (doKill) independentOptions_[1] &= ~8192;
else independentOptions_[1] |= 8192;
}
/// Set whole group
inline int presolveActions() const {
return independentOptions_[1] & 0xffff;
}
inline void setPresolveActions(int action) {
independentOptions_[1] = (independentOptions_[1] & 0xffff0000) | (action & 0xffff);
}
/// Largest column for substitution (normally 3)
inline int substitution() const {
return independentOptions_[2];
}
inline void setSubstitution(int value) {
independentOptions_[2] = value;
}
inline void setIndependentOption(int type,int value) {
independentOptions_[type] = value;
}
inline int independentOption(int type) const {
return independentOptions_[type];
}
//@}
////////////////// data //////////////////
private:
/**@name data.
*/
//@{
/// Solve type
SolveType method_;
/// Presolve type
PresolveType presolveType_;
/// Amount of presolve
int numberPasses_;
/// Options - last is switch for OsiClp
int options_[7];
/// Extra information
int extraInfo_[7];
/** Extra algorithm dependent options
0 - if set return from clpsolve if infeasible
1 - To be copied over to presolve options
2 - max substitution level
If Dantzig Wolfe/benders 0 is number blocks, 2 is #passes (notional)
*/
int independentOptions_[3];
//@}
};
/// For saving extra information to see if looping.
class ClpSimplexProgress {
public:
/**@name Constructors and destructor and copy */
//@{
/// Default constructor
ClpSimplexProgress ( );
/// Constructor from model
ClpSimplexProgress ( ClpSimplex * model );
/// Copy constructor.
ClpSimplexProgress(const ClpSimplexProgress &);
/// Assignment operator. This copies the data
ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs);
/// Destructor
~ClpSimplexProgress ( );
/// Resets as much as possible
void reset();
/// Fill from model
void fillFromModel ( ClpSimplex * model );
//@}
/**@name Check progress */
//@{
/** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken,
>=0 if give up and use as problem status
*/
int looping ( );
/// Start check at beginning of whileIterating
void startCheck();
/// Returns cycle length in whileIterating
int cycle(int in, int out, int wayIn, int wayOut);
/// Returns previous objective (if -1) - current if (0)
double lastObjective(int back = 1) const;
/// Set real primal infeasibility and move back
void setInfeasibility(double value);
/// Returns real primal infeasibility (if -1) - current if (0)
double lastInfeasibility(int back = 1) const;
/// Returns number of primal infeasibilities (if -1) - current if (0)
int numberInfeasibilities(int back = 1) const;
/// Modify objective e.g. if dual infeasible in dual
void modifyObjective(double value);
/// Returns previous iteration number (if -1) - current if (0)
int lastIterationNumber(int back = 1) const;
/// clears all iteration numbers (to switch off panic)
void clearIterationNumbers();
/// Odd state
inline void newOddState() {
oddState_ = - oddState_ - 1;
}
inline void endOddState() {
oddState_ = abs(oddState_);
}
inline void clearOddState() {
oddState_ = 0;
}
inline int oddState() const {
return oddState_;
}
/// number of bad times
inline int badTimes() const {
return numberBadTimes_;
}
inline void clearBadTimes() {
numberBadTimes_ = 0;
}
/// number of really bad times
inline int reallyBadTimes() const {
return numberReallyBadTimes_;
}
inline void incrementReallyBadTimes() {
numberReallyBadTimes_++;
}
/// number of times flagged
inline int timesFlagged() const {
return numberTimesFlagged_;
}
inline void clearTimesFlagged() {
numberTimesFlagged_ = 0;
}
inline void incrementTimesFlagged() {
numberTimesFlagged_++;
}
//@}
/**@name Data */
#define CLP_PROGRESS 5
//#define CLP_PROGRESS_WEIGHT 10
//@{
/// Objective values
double objective_[CLP_PROGRESS];
/// Sum of infeasibilities for algorithm
double infeasibility_[CLP_PROGRESS];
/// Sum of real primal infeasibilities for primal
double realInfeasibility_[CLP_PROGRESS];
#ifdef CLP_PROGRESS_WEIGHT
/// Objective values for weights
double objectiveWeight_[CLP_PROGRESS_WEIGHT];
/// Sum of infeasibilities for algorithm for weights
double infeasibilityWeight_[CLP_PROGRESS_WEIGHT];
/// Sum of real primal infeasibilities for primal for weights
double realInfeasibilityWeight_[CLP_PROGRESS_WEIGHT];
/// Drop for weights
double drop_;
/// Best? for weights
double best_;
#endif
/// Initial weight for weights
double initialWeight_;
#define CLP_CYCLE 12
/// For cycle checking
//double obj_[CLP_CYCLE];
int in_[CLP_CYCLE];
int out_[CLP_CYCLE];
char way_[CLP_CYCLE];
/// Pointer back to model so we can get information
ClpSimplex * model_;
/// Number of infeasibilities
int numberInfeasibilities_[CLP_PROGRESS];
/// Iteration number at which occurred
int iterationNumber_[CLP_PROGRESS];
#ifdef CLP_PROGRESS_WEIGHT
/// Number of infeasibilities for weights
int numberInfeasibilitiesWeight_[CLP_PROGRESS_WEIGHT];
/// Iteration number at which occurred for weights
int iterationNumberWeight_[CLP_PROGRESS_WEIGHT];
#endif
/// Number of times checked (so won't stop too early)
int numberTimes_;
/// Number of times it looked like loop
int numberBadTimes_;
/// Number really bad times
int numberReallyBadTimes_;
/// Number of times no iterations as flagged
int numberTimesFlagged_;
/// If things are in an odd state
int oddState_;
//@}
};
#include "ClpConfig.h"
#if CLP_HAS_ABC
#include "AbcCommon.hpp"
/// For saving extra information to see if looping.
class AbcSimplexProgress : public ClpSimplexProgress {
public:
/**@name Constructors and destructor and copy */
//@{
/// Default constructor
AbcSimplexProgress ( );
/// Constructor from model
AbcSimplexProgress ( ClpSimplex * model );
/// Copy constructor.
AbcSimplexProgress(const AbcSimplexProgress &);
/// Assignment operator. This copies the data
AbcSimplexProgress & operator=(const AbcSimplexProgress & rhs);
/// Destructor
~AbcSimplexProgress ( );
//@}
/**@name Check progress */
//@{
/** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken,
>=0 if give up and use as problem status
*/
int looping ( );
//@}
/**@name Data */
//@}
};
#endif
#endif
|