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