1 /* $Id: ClpSolve.hpp 2385 2019-01-06 19:43:06Z unxusr $ */
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   /** enums for solve function */
24   enum SolveType {
25     useDual = 0,
26     usePrimal,
27     usePrimalorSprint,
28     useBarrier,
29     useBarrierNoCross,
30     automatic,
31     tryDantzigWolfe,
32     tryBenders,
33     notImplemented
34   };
35   enum PresolveType {
36     presolveOn = 0,
37     presolveOff,
38     presolveNumber,
39     presolveNumberCost
40   };
41 
42   /**@name Constructors and destructor and copy */
43   //@{
44   /// Default constructor
45   ClpSolve();
46   /// Constructor when you really know what you are doing
47   ClpSolve(SolveType method, PresolveType presolveType,
48     int numberPasses, int options[6],
49     int extraInfo[6], int independentOptions[3]);
50   /// Generates code for above constructor
51   void generateCpp(FILE *fp);
52   /// Copy constructor.
53   ClpSolve(const ClpSolve &);
54   /// Assignment operator. This copies the data
55   ClpSolve &operator=(const ClpSolve &rhs);
56   /// Destructor
57   ~ClpSolve();
58   //@}
59 
60   /**@name Functions most useful to user */
61   //@{
62   /** Special options - bits
63      0      4 - use crash (default allslack in dual, idiot in primal)
64          8 - all slack basis in primal
65      2      16 - switch off interrupt handling
66      3      32 - do not try and make plus minus one matrix
67          64 - do not use sprint even if problem looks good
68       */
69   /** which translation is:
70          which:
71          0 - startup in Dual  (nothing if basis exists).:
72                       0 - no basis
73        	   1 - crash
74        	   2 - use initiative about idiot! but no crash
75          1 - startup in Primal (nothing if basis exists):
76                       0 - use initiative
77        	   1 - use crash
78        	   2 - use idiot and look at further info
79        	   3 - use sprint and look at further info
80        	   4 - use all slack
81        	   5 - use initiative but no idiot
82        	   6 - use initiative but no sprint
83        	   7 - use initiative but no crash
84                       8 - do allslack or idiot
85                       9 - do allslack or sprint
86        	   10 - slp before
87        	   11 - no nothing and primal(0)
88          2 - interrupt handling - 0 yes, 1 no (for threadsafe)
89          3 - whether to make +- 1matrix - 0 yes, 1 no
90          4 - for barrier
91                       0 - dense cholesky
92        	   1 - Wssmp allowing some long columns
93        	   2 - Wssmp not allowing long columns
94        	   3 - Wssmp using KKT
95                       4 - Using Florida ordering
96        	   8 - bit set to do scaling
97        	   16 - set to be aggressive with gamma/delta?
98                       32 - Use KKT
99          5 - for presolve
100                       1 - switch off dual stuff
101          6 - extra switches
102 
103      */
104   void setSpecialOption(int which, int value, int extraInfo = -1);
105   int getSpecialOption(int which) const;
106 
107   /// Solve types
108   void setSolveType(SolveType method, int extraInfo = -1);
109   SolveType getSolveType();
110 
111   // Presolve types
112   void setPresolveType(PresolveType amount, int extraInfo = -1);
113   PresolveType getPresolveType();
114   int getPresolvePasses() const;
115   /// Extra info for idiot (or sprint)
116   int getExtraInfo(int which) const;
117   /** Say to return at once if infeasible,
118          default is to solve */
119   void setInfeasibleReturn(bool trueFalse);
infeasibleReturn() const120   inline bool infeasibleReturn() const
121   {
122     return independentOptions_[0] != 0;
123   }
124   /// Whether we want to do dual part of presolve
doDual() const125   inline bool doDual() const
126   {
127     return (independentOptions_[1] & 1) == 0;
128   }
setDoDual(bool doDual_)129   inline void setDoDual(bool doDual_)
130   {
131     if (doDual_)
132       independentOptions_[1] &= ~1;
133     else
134       independentOptions_[1] |= 1;
135   }
136   /// Whether we want to do singleton part of presolve
doSingleton() const137   inline bool doSingleton() const
138   {
139     return (independentOptions_[1] & 2) == 0;
140   }
setDoSingleton(bool doSingleton_)141   inline void setDoSingleton(bool doSingleton_)
142   {
143     if (doSingleton_)
144       independentOptions_[1] &= ~2;
145     else
146       independentOptions_[1] |= 2;
147   }
148   /// Whether we want to do doubleton part of presolve
doDoubleton() const149   inline bool doDoubleton() const
150   {
151     return (independentOptions_[1] & 4) == 0;
152   }
setDoDoubleton(bool doDoubleton_)153   inline void setDoDoubleton(bool doDoubleton_)
154   {
155     if (doDoubleton_)
156       independentOptions_[1] &= ~4;
157     else
158       independentOptions_[1] |= 4;
159   }
160   /// Whether we want to do tripleton part of presolve
doTripleton() const161   inline bool doTripleton() const
162   {
163     return (independentOptions_[1] & 8) == 0;
164   }
setDoTripleton(bool doTripleton_)165   inline void setDoTripleton(bool doTripleton_)
166   {
167     if (doTripleton_)
168       independentOptions_[1] &= ~8;
169     else
170       independentOptions_[1] |= 8;
171   }
172   /// Whether we want to do tighten part of presolve
doTighten() const173   inline bool doTighten() const
174   {
175     return (independentOptions_[1] & 16) == 0;
176   }
setDoTighten(bool doTighten_)177   inline void setDoTighten(bool doTighten_)
178   {
179     if (doTighten_)
180       independentOptions_[1] &= ~16;
181     else
182       independentOptions_[1] |= 16;
183   }
184   /// Whether we want to do forcing part of presolve
doForcing() const185   inline bool doForcing() const
186   {
187     return (independentOptions_[1] & 32) == 0;
188   }
setDoForcing(bool doForcing_)189   inline void setDoForcing(bool doForcing_)
190   {
191     if (doForcing_)
192       independentOptions_[1] &= ~32;
193     else
194       independentOptions_[1] |= 32;
195   }
196   /// Whether we want to do impliedfree part of presolve
doImpliedFree() const197   inline bool doImpliedFree() const
198   {
199     return (independentOptions_[1] & 64) == 0;
200   }
setDoImpliedFree(bool doImpliedfree)201   inline void setDoImpliedFree(bool doImpliedfree)
202   {
203     if (doImpliedfree)
204       independentOptions_[1] &= ~64;
205     else
206       independentOptions_[1] |= 64;
207   }
208   /// Whether we want to do dupcol part of presolve
doDupcol() const209   inline bool doDupcol() const
210   {
211     return (independentOptions_[1] & 128) == 0;
212   }
setDoDupcol(bool doDupcol_)213   inline void setDoDupcol(bool doDupcol_)
214   {
215     if (doDupcol_)
216       independentOptions_[1] &= ~128;
217     else
218       independentOptions_[1] |= 128;
219   }
220   /// Whether we want to do duprow part of presolve
doDuprow() const221   inline bool doDuprow() const
222   {
223     return (independentOptions_[1] & 256) == 0;
224   }
setDoDuprow(bool doDuprow_)225   inline void setDoDuprow(bool doDuprow_)
226   {
227     if (doDuprow_)
228       independentOptions_[1] &= ~256;
229     else
230       independentOptions_[1] |= 256;
231   }
232   /// Whether we want to do singleton column part of presolve
doSingletonColumn() const233   inline bool doSingletonColumn() const
234   {
235     return (independentOptions_[1] & 512) == 0;
236   }
setDoSingletonColumn(bool doSingleton_)237   inline void setDoSingletonColumn(bool doSingleton_)
238   {
239     if (doSingleton_)
240       independentOptions_[1] &= ~512;
241     else
242       independentOptions_[1] |= 512;
243   }
244   /// Whether we want to kill small substitutions
doKillSmall() const245   inline bool doKillSmall() const
246   {
247     return (independentOptions_[1] & 8192) == 0;
248   }
setDoKillSmall(bool doKill)249   inline void setDoKillSmall(bool doKill)
250   {
251     if (doKill)
252       independentOptions_[1] &= ~8192;
253     else
254       independentOptions_[1] |= 8192;
255   }
256   /// Set whole group
presolveActions() const257   inline int presolveActions() const
258   {
259     return independentOptions_[1] & 0xffffff;
260   }
setPresolveActions(int action)261   inline void setPresolveActions(int action)
262   {
263     independentOptions_[1] = (independentOptions_[1] & 0xff000000) | (action & 0xffffff);
264   }
265   /// Largest column for substitution (normally 3)
substitution() const266   inline int substitution() const
267   {
268     return independentOptions_[2];
269   }
setSubstitution(int value)270   inline void setSubstitution(int value)
271   {
272     independentOptions_[2] = value;
273   }
setIndependentOption(int type,int value)274   inline void setIndependentOption(int type, int value)
275   {
276     independentOptions_[type] = value;
277   }
independentOption(int type) const278   inline int independentOption(int type) const
279   {
280     return independentOptions_[type];
281   }
282   //@}
283 
284   ////////////////// data //////////////////
285 private:
286   /**@name data.
287      */
288   //@{
289   /// Solve type
290   SolveType method_;
291   /// Presolve type
292   PresolveType presolveType_;
293   /// Amount of presolve
294   int numberPasses_;
295   /// Options - last is switch for OsiClp
296   int options_[7];
297   /// Extra information
298   int extraInfo_[7];
299   /** Extra algorithm dependent options
300          0 - if set return from clpsolve if infeasible
301          1 - To be copied over to presolve options
302          2 - max substitution level
303 	 If Dantzig Wolfe/benders 0 is number blocks, 2 is #passes (notional)
304      */
305   int independentOptions_[3];
306   //@}
307 };
308 
309 /// For saving extra information to see if looping.
310 class ClpSimplexProgress {
311 
312 public:
313   /**@name Constructors and destructor and copy */
314   //@{
315   /// Default constructor
316   ClpSimplexProgress();
317 
318   /// Constructor from model
319   ClpSimplexProgress(ClpSimplex *model);
320 
321   /// Copy constructor.
322   ClpSimplexProgress(const ClpSimplexProgress &);
323 
324   /// Assignment operator. This copies the data
325   ClpSimplexProgress &operator=(const ClpSimplexProgress &rhs);
326   /// Destructor
327   ~ClpSimplexProgress();
328   /// Resets as much as possible
329   void reset();
330   /// Fill from model
331   void fillFromModel(ClpSimplex *model);
332 
333   //@}
334 
335   /**@name Check progress */
336   //@{
337   /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken,
338          >=0 if give up and use as problem status
339      */
340   int looping();
341   /// Start check at beginning of whileIterating
342   void startCheck();
343   /// Returns cycle length in whileIterating
344   int cycle(int in, int out, int wayIn, int wayOut);
345 
346   /// Returns previous objective (if -1) - current if (0)
347   double lastObjective(int back = 1) const;
348   /// Set real primal infeasibility and move back
349   void setInfeasibility(double value);
350   /// Returns real primal infeasibility (if -1) - current if (0)
351   double lastInfeasibility(int back = 1) const;
352   /// Returns number of primal infeasibilities (if -1) - current if (0)
353   int numberInfeasibilities(int back = 1) const;
354   /// Modify objective e.g. if dual infeasible in dual
355   void modifyObjective(double value);
356   /// Returns previous iteration number (if -1) - current if (0)
357   int lastIterationNumber(int back = 1) const;
358   /// clears all iteration numbers (to switch off panic)
359   void clearIterationNumbers();
360   /// Odd state
newOddState()361   inline void newOddState()
362   {
363     oddState_ = -oddState_ - 1;
364   }
endOddState()365   inline void endOddState()
366   {
367     oddState_ = abs(oddState_);
368   }
clearOddState()369   inline void clearOddState()
370   {
371     oddState_ = 0;
372   }
oddState() const373   inline int oddState() const
374   {
375     return oddState_;
376   }
377   /// number of bad times
badTimes() const378   inline int badTimes() const
379   {
380     return numberBadTimes_;
381   }
clearBadTimes()382   inline void clearBadTimes()
383   {
384     numberBadTimes_ = 0;
385   }
386   /// number of really bad times
reallyBadTimes() const387   inline int reallyBadTimes() const
388   {
389     return numberReallyBadTimes_;
390   }
incrementReallyBadTimes()391   inline void incrementReallyBadTimes()
392   {
393     numberReallyBadTimes_++;
394   }
395   /// number of times flagged
timesFlagged() const396   inline int timesFlagged() const
397   {
398     return numberTimesFlagged_;
399   }
clearTimesFlagged()400   inline void clearTimesFlagged()
401   {
402     numberTimesFlagged_ = 0;
403   }
incrementTimesFlagged()404   inline void incrementTimesFlagged()
405   {
406     numberTimesFlagged_++;
407   }
408 
409   //@}
410   /**@name Data  */
411 #define CLP_PROGRESS 5
412   //#define CLP_PROGRESS_WEIGHT 10
413   //@{
414   /// Objective values
415   double objective_[CLP_PROGRESS];
416   /// Sum of infeasibilities for algorithm
417   double infeasibility_[CLP_PROGRESS];
418   /// Sum of real primal infeasibilities for primal
419   double realInfeasibility_[CLP_PROGRESS];
420 #ifdef CLP_PROGRESS_WEIGHT
421   /// Objective values for weights
422   double objectiveWeight_[CLP_PROGRESS_WEIGHT];
423   /// Sum of infeasibilities for algorithm for weights
424   double infeasibilityWeight_[CLP_PROGRESS_WEIGHT];
425   /// Sum of real primal infeasibilities for primal for weights
426   double realInfeasibilityWeight_[CLP_PROGRESS_WEIGHT];
427   /// Drop  for weights
428   double drop_;
429   /// Best? for weights
430   double best_;
431 #endif
432   /// Initial weight for weights
433   double initialWeight_;
434 #define CLP_CYCLE 12
435   /// For cycle checking
436   //double obj_[CLP_CYCLE];
437   int in_[CLP_CYCLE];
438   int out_[CLP_CYCLE];
439   char way_[CLP_CYCLE];
440   /// Pointer back to model so we can get information
441   ClpSimplex *model_;
442   /// Number of infeasibilities
443   int numberInfeasibilities_[CLP_PROGRESS];
444   /// Iteration number at which occurred
445   int iterationNumber_[CLP_PROGRESS];
446 #ifdef CLP_PROGRESS_WEIGHT
447   /// Number of infeasibilities for weights
448   int numberInfeasibilitiesWeight_[CLP_PROGRESS_WEIGHT];
449   /// Iteration number at which occurred for weights
450   int iterationNumberWeight_[CLP_PROGRESS_WEIGHT];
451 #endif
452   /// Number of times checked (so won't stop too early)
453   int numberTimes_;
454   /// Number of times it looked like loop
455   int numberBadTimes_;
456   /// Number really bad times
457   int numberReallyBadTimes_;
458   /// Number of times no iterations as flagged
459   int numberTimesFlagged_;
460   /// If things are in an odd state
461   int oddState_;
462   //@}
463 };
464 
465 #include "ClpConfig.h"
466 #if CLP_HAS_ABC
467 #include "AbcCommon.hpp"
468 /// For saving extra information to see if looping.
469 class AbcSimplexProgress : public ClpSimplexProgress {
470 
471 public:
472   /**@name Constructors and destructor and copy */
473   //@{
474   /// Default constructor
475   AbcSimplexProgress();
476 
477   /// Constructor from model
478   AbcSimplexProgress(ClpSimplex *model);
479 
480   /// Copy constructor.
481   AbcSimplexProgress(const AbcSimplexProgress &);
482 
483   /// Assignment operator. This copies the data
484   AbcSimplexProgress &operator=(const AbcSimplexProgress &rhs);
485   /// Destructor
486   ~AbcSimplexProgress();
487 
488   //@}
489 
490   /**@name Check progress */
491   //@{
492   /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken,
493          >=0 if give up and use as problem status
494      */
495   int looping();
496 
497   //@}
498   /**@name Data  */
499   //@}
500 };
501 #endif
502 #endif
503 
504 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
505 */
506