CglTwomir.hpp

Go to the documentation of this file.
00001 // $Id: CglTwomir.hpp 1123 2013-04-06 20:47:24Z stefan $
00002 // Copyright (C) 2002, International Business Machines
00003 // Corporation and others.  All Rights Reserved.
00004 // This code is licensed under the terms of the Eclipse Public License (EPL).
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;             /* current length of arrays index[] and coeff[] */
00017   int max_nz;         /* max length of arrays index[] and coeff[] */
00018   double *coeff;      /* coefficient of each variable in the constraint */
00019   int *index;         /* index of the variable (value in 0 ... nrow+ncol) */
00020   double rhs;         /* rhs of the constraint */
00021   char sense;         /* ?? is it necessary */
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 /******************** BASIS INFORMATION ADTs **********************************/
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; /* factional variable must be this away from int */
00045   int ncol,        /* number of columns in LP */
00046     nrow,        /* number of constaints in LP */
00047     ninteger;    /* number of integer variables in LP */
00048 
00049   int nbasic_col,  /* number of basic columns in the LP */
00050     nbasic_row;  /* number of basic rows in the LP */
00051 
00052   /* the following arrays are all of size (ncol+nrow) */
00053   int *info;       /* description of each variable (see below) */
00054   double *lb;      /* specifies the lower bound (if any) of each variable */
00055   double *ub;      /* specifies the upper bound (if any) of each variable */
00056   double *x;       /* current solution */
00057   double *rc;      /* current reduced cost */
00058   double *opt_x;
00059 
00060   cutParams cparams;
00061 } DGG_data_t;
00062 
00063 /* the following macros allow us to decode the info of the DGG_data
00064    type. The encoding is as follows,
00065    bit 1 : if the variable is basic or not (non-basic).
00066    bit 2 : if the variable is integer or or not (rational).
00067    bit 3 : if the variable is structural or not (artifical). 
00068    bit 4 : if the variable is non-basic and at its upper bound 
00069    (else if non-basic at lower bound). */
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   // Private member data
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_; //number of rows on which formulation cuts will be generated
00220 };
00221 
00222 //#############################################################################
00223 
00224 /*
00225 #include <stdlib.h>
00226 #include <stdio.h>
00227 #include <stdarg.h>
00228 #include <math.h>
00229 #include <float.h>
00230 #include <cassert>
00231 #include <iostream.h>
00232 */
00233 
00234 /******************** DEBUG DEFINITIONS ***************************************/
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 /******************** CONFIGURATION DEFAULTS **********************************/
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 /******************** SOLVER CONFIGURATION DEFINITIONS ************************/
00263 
00264 #define DGG_OSI 0
00265 #define DGG_CPX 1
00266 #define DGG_QSO 2
00267 
00268 /* determines the solver to be used */
00269 #define DGG_SOLVER DGG_OSI
00270 
00271 /* adds checking routines to make sure solver works as expected */
00272 #define DGG_DEBUG_SOLVER 0
00273 
00274 /* turn off screen output from solver */
00275 #define DGG_SOLVER_SCREEN_FLAG 0
00276 
00277 /******************** CUT DEFINITIONS *****************************************/
00278 
00279 /* internal names for cut types */
00280 #define DGG_TMIR_CUT 1
00281 #define DGG_2STEP_CUT 2
00282 
00283 /* internal names for alpha-selection rules */
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 /******************** PRECISION & NUMERICAL ISSUES DEFINITIONS ****************/
00291 
00292 /* how steep a cut must be before adding it to the lp */
00293 #define DGG_MIN_STEEPNESS 1.0e-4
00294 #define DGG_MAX_L2NORM 1.0e7
00295 
00296 /* 0 = min steepness, 1 = max norm */
00297 #define DGG_NORM_CRITERIA 1
00298 
00299 /* internal representation of +infinity */
00300 #define UB_MAX DBL_MAX
00301 
00302 /* used to define how fractional a basic-integer variable must be
00303    before choosing to use it to generate a TMIR cut on.
00304    OSI's default is 1.0e-7 */
00305 #define DGG_GOMORY_THRESH 0.005
00306 
00307 #define DGG_RHS_THRESH 0.005
00308 
00309 /* used for comparing variables to their upper bounds.
00310    OSI's default is 1.0e-7.
00311    We set it to 1.0e6 because e-7 seems too sensitive. 
00312    In fact, with e-7 the problem dsbmip.mps complains. */
00313 #define DGG_BOUND_THRESH 1.0e-6
00314 
00315 /* used for comparing the lhs (activity) value of a tableau row
00316    with the rhs. This is only used for debugging purposes. */
00317 #define DGG_EQUALITY_THRESH 1.0e-5
00318 
00319 /* used for comparing a variable's lower bound to 0.0
00320    and determining if we need to shift the variable    */
00321 #define DGG_SHIFT_THRESH 1.0e-6
00322 
00323 /* used for determing how far from an integer is still an integer.
00324    This value is used for comparing coefficients to integers.
00325    OSI's default is 1.0e-10.                               */
00326 #define DGG_INTEGRALITY_THRESH 1.0e-10
00327 
00328 /* the min value that a coeff can have in the tableau row
00329    before being set to zero. */
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 /* smallest value rho is allowed to have for a simple 2-step MIR
00338    (ie: not an extended two-step MIR) */
00339 #define DGG_MIN_RHO 1.0e-7
00340 #define DGG_MIN_ALPHA 1.0e-7
00341 
00342 /* when a slack is null: used to check if a cut is satisfied or not. */
00343 #define DGG_NULL_SLACK 1.0e-5
00344 
00345 /* nicefy constants */
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 /******************** ERROR-CATCHING MACROS ***********************************/
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 /******************** SIMPLE MACROS AND FUNCTIONS *****************************/
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 /* free function for DGG_data_t. Frees internal arrays and data structure */
00421 int DGG_freeData( DGG_data_t *data );
00422 
00423 /******************** CONSTRAINT ADTs *****************************************/
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 /******************** CONFIGURATION *******************************************/
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 /******************* SOLVER SPECIFIC METHODS **********************************/
00436 DGG_data_t *DGG_getData(const void *solver_ptr);
00437 
00438 /******************* CONSTRAINT MANIPULATION **********************************/
00439 
00440 /* DGG_transformConstraint: manipulates a constraint in the following way: 
00441 
00442 packs everything in output
00443 
00444 1 - variables at their upper bounds are substituted for their 
00445 complements. This is done by adjusting the coefficients and 
00446 the right hand side (simple substitution). 
00447 
00448 2 - variables with non-zero lower bounds are shifted.            */
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 /* DGG_unTransformConstraint : 
00457 
00458 1 - Undoes step (1) of DGG_transformConstraint 
00459 2 - Undoes step (2) of DGG_transformConstraint                  */
00460  
00461 int DGG_unTransformConstraint( DGG_data_t *data, 
00462                                DGG_constraint_t *constraint );
00463 
00464 /* substitutes each slack variable by the structural variables which 
00465    define it. This function, hence, changes the constraint 'cut'.    */
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 /******************* CUT GENERATION *******************************************/
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 /******************* CUT INFORMATION ******************************************/
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 /******************* TEST / DEBUGGING ROUTINES ********************************/
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 19 Jan 2015 for Cgl by  doxygen 1.6.1