00001
00002
00003
00004
00005
00006 #ifndef CglTwomir_H
00007 #define CglTwomir_H
00008 #include <string>
00009
00010 #include "CglCutGenerator.hpp"
00011 #include "CoinFactorization.hpp"
00012
00013 typedef struct
00014 {
00015
00016 int nz;
00017 int max_nz;
00018 double *coeff;
00019 int *index;
00020 double rhs;
00021 char sense;
00022
00023 } DGG_constraint_t;
00024
00025 typedef struct{
00026 int n;
00027 DGG_constraint_t **c;
00028 int *ctype;
00029 double *alpha;
00030 } DGG_list_t;
00031
00032
00033 typedef struct{
00034 int q_min;
00035 int q_max;
00036 int t_min;
00037 int t_max;
00038 int a_max;
00039 int max_elements;
00040 } cutParams;
00041
00042 typedef struct
00043 {
00044 double gomory_threshold;
00045 int ncol,
00046 nrow,
00047 ninteger;
00048
00049 int nbasic_col,
00050 nbasic_row;
00051
00052
00053 int *info;
00054 double *lb;
00055 double *ub;
00056 double *x;
00057 double *rc;
00058 double *opt_x;
00059
00060 cutParams cparams;
00061 } DGG_data_t;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 #define DGG_isBasic(data,idx) ((data->info[idx])&1)
00072 #define DGG_isInteger(data,idx) ((data->info[idx] >> 1)&1)
00073 #define DGG_isStructural(data,idx) ((data->info[idx] >> 2)&1)
00074 #define DGG_isEqualityConstraint(data,idx) ((data->info[idx] >> 3)&1)
00075 #define DGG_isNonBasicAtUB(data,idx) ((data->info[idx] >> 4)&1)
00076 #define DGG_isNonBasicAtLB(data,idx) ((data->info[idx] >> 5)&1)
00077 #define DGG_isConstraintBoundedAbove(data,idx) ((data->info[idx] >> 6)&1)
00078 #define DGG_isConstraintBoundedBelow(data,idx) ((data->info[idx] >> 7)&1)
00079
00080 #define DGG_setIsBasic(data,idx) ((data->info[idx]) |= 1)
00081 #define DGG_setIsInteger(data,idx) ((data->info[idx]) |= (1<<1))
00082 #define DGG_setIsStructural(data,idx) ((data->info[idx]) |= (1<<2))
00083 #define DGG_setEqualityConstraint(data,idx) ((data->info[idx]) |= (1<<3))
00084 #define DGG_setIsNonBasicAtUB(data,idx) ((data->info[idx]) |= (1<<4))
00085 #define DGG_setIsNonBasicAtLB(data,idx) ((data->info[idx]) |= (1<<5))
00086 #define DGG_setIsConstraintBoundedAbove(data,idx) ((data->info[idx]) |= (1<<6))
00087 #define DGG_setIsConstraintBoundedBelow(data,idx) ((data->info[idx]) |= (1<<7))
00088
00089 class CoinWarmStartBasis;
00091 class CglTwomir : public CglCutGenerator {
00092
00093 friend void CglTwomirUnitTest(const OsiSolverInterface * siP,
00094 const std::string mpdDir );
00095
00096
00097 public:
00098
00100 std::string probname_;
00101
00107 virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
00108 const CglTreeInfo info = CglTreeInfo());
00110 virtual bool needsOptimalBasis() const;
00111
00114
00115 void setMirScale (int tmin, int tmax) {t_min_ = tmin; t_max_ = tmax;}
00116 void setTwomirScale (int qmin, int qmax) {q_min_ = qmin; q_max_ = qmax;}
00117 void setAMax (int a) {a_max_ = a;}
00118 void setMaxElements (int n) {max_elements_ = n;}
00119 void setMaxElementsRoot (int n) {max_elements_root_ = n;}
00120 void setCutTypes (bool mir, bool twomir, bool tab, bool form)
00121 { do_mir_ = mir; do_2mir_ = twomir; do_tab_ = tab; do_form_ = form;}
00122 void setFormulationRows (int n) {form_nrows_ = n;}
00123
00125 int getTmin() const {return t_min_;}
00126 int getTmax() const {return t_max_;}
00127 int getQmin() const {return q_min_;}
00128 int getQmax() const {return q_max_;}
00129 int getAmax() const {return a_max_;}
00130 int getMaxElements() const {return max_elements_;}
00131 int getMaxElementsRoot() const {return max_elements_root_;}
00132 int getIfMir() const { return do_mir_;}
00133 int getIfTwomir() const { return do_2mir_;}
00134 int getIfTableau() const { return do_tab_;}
00135 int getIfFormulation() const { return do_form_;}
00137
00142
00143 void setAway(double value);
00145 double getAway() const;
00147 void setAwayAtRoot(double value);
00149 double getAwayAtRoot() const;
00151 virtual int maximumLengthOfCutInTree() const
00152 { return max_elements_;}
00154
00157
00158 void passInOriginalSolver(OsiSolverInterface * solver);
00160 inline OsiSolverInterface * originalSolver() const
00161 { return originalSolver_;}
00163 inline void setTwomirType(int type)
00164 { twomirType_=type;}
00166 inline int twomirType() const
00167 { return twomirType_;}
00169
00172
00173 CglTwomir ();
00174
00176 CglTwomir (const CglTwomir &);
00177
00179 virtual CglCutGenerator * clone() const;
00180
00182 CglTwomir & operator=(const CglTwomir& rhs);
00183
00185 virtual ~CglTwomir ();
00187 virtual std::string generateCpp( FILE * fp);
00189 virtual void refreshSolver(OsiSolverInterface * solver);
00191
00192 private:
00193
00196
00197 CoinThreadRandom randomNumberGenerator_;
00199 OsiSolverInterface * originalSolver_;
00201 double away_;
00203 double awayAtRoot_;
00205 int twomirType_;
00206 bool do_mir_;
00207 bool do_2mir_;
00208 bool do_tab_;
00209 bool do_form_;
00210
00211 int t_min_;
00212 int t_max_;
00213 int q_min_;
00214 int q_max_;
00215 int a_max_;
00216 int max_elements_;
00217 int max_elements_root_;
00218 int form_nrows_;
00220 };
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 #define DGG_DEBUG_DGG 1
00237 #define DGG_TRACE_ERRORS 0
00238 #define DGG_DISPLAY 0
00239 #define DGG_AUTO_CHECK_CUT_OFF_OPTIMAL 1
00240
00241
00242
00243 #define DGG_DEFAULT_METHOD 2
00244 #define DGG_DEFAULT_TMIN 1
00245 #define DGG_DEFAULT_TMAX 1
00246 #define DGG_DEFAULT_TAUMIN 2
00247 #define DGG_DEFAULT_TAUMAX 6
00248 #define DGG_DEFAULT_MAX_CUTS 500
00249 #define DGG_DEFAULT_IMPROVEMENT_THRESH 0.001
00250 #define DGG_DEFAULT_NBELOW_THRESH INT_MAX
00251 #define DGG_DEFAULT_NROOT_ROUNDS 2
00252 #define DGG_DEFAULT_NEGATIVE_SCALED_TWOSTEPS 0
00253 #define DGG_DEFAULT_ALPHA_RULE 0
00254 #define DGG_DEFAULT_CUT_INC 250
00255 #define DGG_DEFAULT_CUT_FORM 0
00256 #define DGG_DEFAULT_NICEFY 0
00257 #define DGG_DEFAULT_ONLY_DELAYED 0
00258 #define DGG_DEFAULT_DELAYED_FREQ 9999999
00259 #define DGG_DEFAULT_LPROWS_FREQ 9999999
00260 #define DGG_DEFAULT_WHICH_FORMULATION_CUTS 2
00261
00262
00263
00264 #define DGG_OSI 0
00265 #define DGG_CPX 1
00266 #define DGG_QSO 2
00267
00268
00269 #define DGG_SOLVER DGG_OSI
00270
00271
00272 #define DGG_DEBUG_SOLVER 0
00273
00274
00275 #define DGG_SOLVER_SCREEN_FLAG 0
00276
00277
00278
00279
00280 #define DGG_TMIR_CUT 1
00281 #define DGG_2STEP_CUT 2
00282
00283
00284 #define DGG_ALPHA_MIN_SUM 0
00285 #define DGG_ALPHA_RANDOM_01 1
00286 #define DGG_ALPHA_RANDOM_COEFF 2
00287 #define DGG_ALPHA_ALL 3
00288 #define DGG_ALPHA_MAX_STEEP 5
00289
00290
00291
00292
00293 #define DGG_MIN_STEEPNESS 1.0e-4
00294 #define DGG_MAX_L2NORM 1.0e7
00295
00296
00297 #define DGG_NORM_CRITERIA 1
00298
00299
00300 #define UB_MAX DBL_MAX
00301
00302
00303
00304
00305 #define DGG_GOMORY_THRESH 0.005
00306
00307 #define DGG_RHS_THRESH 0.005
00308
00309
00310
00311
00312
00313 #define DGG_BOUND_THRESH 1.0e-6
00314
00315
00316
00317 #define DGG_EQUALITY_THRESH 1.0e-5
00318
00319
00320
00321 #define DGG_SHIFT_THRESH 1.0e-6
00322
00323
00324
00325
00326 #define DGG_INTEGRALITY_THRESH 1.0e-10
00327
00328
00329
00330 #define CBC_CHECK_CUT
00331 #ifndef CBC_CHECK_CUT
00332 #define DGG_MIN_TABLEAU_COEFFICIENT 1.0e-8
00333 #else
00334 #define DGG_MIN_TABLEAU_COEFFICIENT 1.0e-12
00335 #endif
00336
00337
00338
00339 #define DGG_MIN_RHO 1.0e-7
00340 #define DGG_MIN_ALPHA 1.0e-7
00341
00342
00343 #define DGG_NULL_SLACK 1.0e-5
00344
00345
00346 #define DGG_NICEFY_MIN_ABSVALUE 1.0e-13
00347 #define DGG_NICEFY_MIN_FIX 1.0e-7
00348 #define DGG_NICEFY_MAX_PADDING 1.0e-6
00349 #define DGG_NICEFY_MAX_RATIO 1.0e9
00350
00351
00352
00353 #if DGG_TRACE_ERRORS > 0
00354
00355 #define __DGG_PRINT_LOC__(F) fprintf(((F==0)?stdout:F), " in %s (%s:%d)\n", __func__, __FILE__, __LINE__)
00356
00357 #define DGG_THROW(A,REST...) {\
00358 fprintf(stdout, ##REST); \
00359 __DGG_PRINT_LOC__(stdout); \
00360 return (A);}
00361
00362 #define DGG_IF_EXIT(A,B,REST...) {\
00363 if(A) {\
00364 fprintf(stdout, ##REST); \
00365 __DGG_PRINT_LOC__(stdout); \
00366 exit(B);}}
00367
00368 #define DGG_CHECKRVAL(A,B) {\
00369 if(A) {\
00370 __DGG_PRINT_LOC__(stdout); \
00371 return B; } }
00372
00373 #define DGG_CHECKRVAL1(A,B) {\
00374 if(A) {\
00375 __DGG_PRINT_LOC__(stdout); \
00376 rval = B; goto CLEANUP; } }
00377
00378 #define DGG_WARNING(A, REST...) {\
00379 if(A) {\
00380 fprintf(stdout, ##REST); \
00381 __DGG_PRINT_LOC__(stdout); \
00382 }}
00383
00384 #define DGG_TEST(A,B,REST...) {\
00385 if(A) DGG_THROW(B,##REST) }
00386
00387 #define DGG_TEST2(A,B,C,REST) {DGG_TEST(A,B,C,REST) }
00388 #define DGG_TEST3(A,B,C,D,REST) {DGG_TEST(A,B,C,D,REST) }
00389
00390 #else
00391
00392 #define DGG_IF_EXIT(A,B,REST) {if(A) {fprintf(stdout, REST);exit(B);}}
00393
00394 #define DGG_THROW(A,B) return(A)
00395
00396 #define DGG_CHECKRVAL(A,B) { if(A) return(B); }
00397 #define DGG_CHECKRVAL1(A,B){ if(A) { rval = B; goto CLEANUP; } }
00398
00399 #define DGG_TEST(A,B,REST) { if(A) return(B);}
00400 #define DGG_TEST2(A,B,REST,C) { DGG_TEST(A,B,REST) }
00401 #define DGG_TEST3(A,B,REST,C,D) { DGG_TEST(A,B,REST) }
00402
00403 #endif
00404
00405
00406
00407 #define DGG_MIN(a,b) ( (a<b)?a:b )
00408 #define DGG_MAX(a,b) ( (a>b)?a:b )
00409 #define KREM(vht,alpha,tau) (DGG_MIN( ceil(vht / alpha), tau ) - 1)
00410 #define LMIN(vht, d, bht) (DGG_MIN( floor(d*bht/bht), d))
00411 #define ABOV(v) (v - floor(v))
00412 #define QINT(vht,bht,tau) ( (int)floor( (vht*(tau-1))/bht ) )
00413 #define V2I(bht,tau,i) ( ((i+1)*bht / tau) )
00414
00415 int DGG_is_even(double vht, double bht, int tau, int q);
00416 double frac_part(double value);
00417 int DGG_is_a_multiple_of_b(double a, double b);
00418
00419
00420
00421 int DGG_freeData( DGG_data_t *data );
00422
00423
00424 DGG_constraint_t* DGG_newConstraint(int max_arrays);
00425 void DGG_freeConstraint(DGG_constraint_t *c);
00426 DGG_constraint_t *DGG_copyConstraint(DGG_constraint_t *c);
00427 void DGG_scaleConstraint(DGG_constraint_t *c, int t);
00428
00429
00430 void DGG_list_init (DGG_list_t *l);
00431 int DGG_list_addcut (DGG_list_t *l, DGG_constraint_t *cut, int ctype, double alpha);
00432 void DGG_list_delcut (DGG_list_t *l, int i);
00433 void DGG_list_free(DGG_list_t *l);
00434
00435
00436 DGG_data_t *DGG_getData(const void *solver_ptr);
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 int DGG_transformConstraint( DGG_data_t *data,
00451 double **x_out,
00452 double **rc_out,
00453 char **isint_out,
00454 DGG_constraint_t *constraint );
00455
00456
00457
00458
00459
00460
00461 int DGG_unTransformConstraint( DGG_data_t *data,
00462 DGG_constraint_t *constraint );
00463
00464
00465
00466
00467 int DGG_substituteSlacks( const void *solver_ptr,
00468 DGG_data_t *data,
00469 DGG_constraint_t *cut );
00470
00471 int DGG_nicefyConstraint( const void *solver_ptr,
00472 DGG_data_t *data,
00473 DGG_constraint_t *cut);
00474
00475
00476 int DGG_getFormulaConstraint( int row_idx,
00477 const void *solver_ptr,
00478 DGG_data_t *data,
00479 DGG_constraint_t* row );
00480
00481 int DGG_getTableauConstraint( int index,
00482 const void *solver_ptr,
00483 DGG_data_t *data,
00484 DGG_constraint_t* tabrow,
00485 const int * colIsBasic,
00486 const int * rowIsBasic,
00487 CoinFactorization & factorization,
00488 int mode );
00489
00490 DGG_constraint_t* DGG_getSlackExpression(const void *solver_ptr, DGG_data_t* data, int row_index);
00491
00492 int DGG_generateTabRowCuts( DGG_list_t *list,
00493 DGG_data_t *data,
00494 const void *solver_ptr );
00495
00496 int DGG_generateFormulationCuts( DGG_list_t *list,
00497 DGG_data_t *data,
00498 const void *solver_ptr,
00499 int nrows,
00500 CoinThreadRandom & generator);
00501
00502
00503 int DGG_generateFormulationCutsFromBase( DGG_constraint_t *base,
00504 double slack,
00505 DGG_list_t *list,
00506 DGG_data_t *data,
00507 const void *solver_ptr,
00508 CoinThreadRandom & generator);
00509
00510 int DGG_generateCutsFromBase( DGG_constraint_t *base,
00511 DGG_list_t *list,
00512 DGG_data_t *data,
00513 const void *solver_ptr );
00514
00515 int DGG_buildMir( char *isint,
00516 DGG_constraint_t *base,
00517 DGG_constraint_t **cut_out );
00518
00519 int DGG_build2step( double alpha,
00520 char *isint,
00521 DGG_constraint_t *base,
00522 DGG_constraint_t **cut_out );
00523
00524 int DGG_addMirToList ( DGG_constraint_t *base,
00525 char *isint,
00526 double *x,
00527 DGG_list_t *list,
00528 DGG_data_t *data,
00529 DGG_constraint_t *orig_base );
00530
00531 int DGG_add2stepToList ( DGG_constraint_t *base,
00532 char *isint,
00533 double *x,
00534 double *rc,
00535 DGG_list_t *list,
00536 DGG_data_t *data,
00537 DGG_constraint_t *orig_base );
00538
00539
00540
00541 double DGG_cutLHS(DGG_constraint_t *c, double *x);
00542 int DGG_isCutDesirable(DGG_constraint_t *c, DGG_data_t *d);
00543
00544
00545
00546 int DGG_isConstraintViolated(DGG_data_t *d, DGG_constraint_t *c);
00547
00548 int DGG_isBaseTrivial(DGG_data_t *d, DGG_constraint_t* c);
00549 int DGG_is2stepValid(double alpha, double bht);
00550
00551 int DGG_cutsOffPoint(double *x, DGG_constraint_t *cut);
00552
00553
00559 void CglTwomirUnitTest(const OsiSolverInterface * siP,
00560 const std::string mpdDir);
00561
00562
00563 #endif
00564
00565