Cgl012cut.hpp

Go to the documentation of this file.
00001 // $Id: Cgl012cut.hpp 1149 2013-10-21 18:23:53Z tkr $
00002 // Copyright (C) 2010, International Business Machines
00003 // Corporation and others.  All Rights Reserved.
00004 // This code is licensed under the terms of the Eclipse Public License (EPL).
00006 #ifndef CGL012CUT
00007 #define CGL012CUT
00008 #include <cstdio>
00009 #include <cstdlib>
00010 #include <cmath>
00011 
00012 #define CGL_NEW_SHORT
00013 #ifndef CGL_NEW_SHORT
00014 typedef  /* arc */
00015    struct arc_st
00016 {
00017    int              len;            /* length of the arc */
00018    struct node_st   *head;           /* head node */
00019 }
00020   arc;
00021 
00022 typedef  /* node */
00023    struct node_st
00024 {
00025    arc              *first;           /* first outgoing arc */
00026    int              dist;             /* tentative shortest path length */
00027    struct node_st   *parent;          /* parent pointer */
00028    struct node_st   *next;            /* next node in queue */
00029    struct node_st   *prev;            /* previous node in queue */
00030    int               status;          /* status of node */
00031    int               temp;            /* for temporary labels */
00032    int               index;           /* index of the node in the graph */
00033 } node;
00034 #endif
00035 typedef struct 
00036 {
00037   int length; // Length of arc
00038   int to; // To node
00039 } cgl_arc;
00040 
00041 typedef struct
00042 {
00043   cgl_arc * firstArc; // First outgoing arc 
00044   int parentNode; // Parent node in shortest path 
00045   int index; // Which node I am
00046   int distanceBack; // Distance back to source
00047 } cgl_node;
00048 
00049 typedef struct 
00050 {
00051   int nnodes; // Number of nodes in graph
00052   int narcs; // Number of arcs in graph
00053   cgl_node * nodes;
00054   cgl_arc * arcs;
00055 } cgl_graph;
00056 /* #define PRINT */
00057 /* #define PRINT_CUTS */
00058 #define REDUCTION
00059 
00060 typedef struct {
00061 int mr; /* number of rows in the ILP matrix */
00062 int mc; /* number of columns in the ILP matrix */
00063 int mnz; /* number of nonzero's in the ILP matrix */
00064 int *mtbeg; /* starting position of each row in arrays mtind and mtval */
00065 int *mtcnt; /* number of entries of each row in arrays mtind and mtval */
00066 int *mtind; /* column indices of the nonzero entries of the ILP matrix */
00067 int *mtval; /* values of the nonzero entries of the ILP matrix */
00068 int *vlb; /* lower bounds on the variables */
00069 int *vub; /* upper bounds on the variables */
00070 int *mrhs; /* right hand sides of the constraints */
00071 char *msense; /* senses of the constraints: 'L', 'G' or 'E' */
00072 const double *xstar; /* current optimal solution of the LP relaxation */
00073 } ilp; 
00074 
00075 typedef struct {
00076 int mr; /* number of rows in the parity ILP matrix */
00077 int mc; /* number of columns in the parity ILP matrix */
00078 int mnz; /* number of 1's in the parity ILP matrix */
00079 int *mtbeg; /* starting position of each row in arrays mtind and mtval */
00080 int *mtcnt; /* number of entries of each row in arrays mtind and mtval */
00081 int *mtind; /* column indices of the 1's of the parity ILP matrix */
00082 short int *mrhs; /* right hand side parity of the constraints */
00083 double *xstar; /* current optimal solution of the LP relaxation */
00084 double *slack; /* slack of the constraints w.r.t. xstar */
00085 short int *row_to_delete; /* flag for marking rows not to be considered */
00086 short int *col_to_delete; /* flag for marking columns not to be considered */
00087 int *gcd; /* greatest common divisor of each row in the input ILP matrix */
00088 short int *possible_weak; /* possible weakening types of each column */
00089 short int *type_even_weak; /* type of even weakening of each column 
00090                               (lower or upper bound weakening) */
00091 short int *type_odd_weak; /* type of odd weakening of each column 
00092                               (lower or upper bound weakening) */
00093 double *loss_even_weak; /* loss for the even weakening of each column */
00094 double *loss_odd_weak; /* loss for the odd weakening of each column */
00095 double *min_loss_by_weak; /* minimum loss for the weakening of each column */
00096 } parity_ilp; 
00097 
00098 typedef struct {
00099 int nweak; /* number of variables weakened */
00100 int *var; /* list of variables weakened */
00101 short int *type; /* type of weakening (lower or upper bound weakening) */
00102 } info_weak;
00103 
00104 typedef struct {
00105 int endpoint1, endpoint2; /* endpoints of the edge */
00106 double weight; /* edge weight */
00107 short int parity; /* edge parity (even or odd) */
00108 int constr; /* constraint associated with the edge */
00109 info_weak *weak; /* weakening information */
00110 } edge;
00111 
00112 typedef struct {
00113 int nnodes; /* number of nodes */
00114 int nedges; /* number of edges */
00115 int *nodes; /* indexes of the ILP columns corresponding to the nodes */
00116 int *ind; /* indexes of the nodes corresponding to the ILP columns */
00117 edge **even_adj_list; /* pointers to the even edges */ 
00118 edge **odd_adj_list; /* pointers to the odd edges */ 
00119 } separation_graph;
00120 
00121 #ifndef CGL_NEW_SHORT
00122 typedef struct {
00123 int nnodes; /* number of nodes */
00124 int narcs; /* number of arcs */
00125 node *nodes; /* array of the nodes - see "types_db.h" */ 
00126 arc *arcs; /* array of the arcs - see "types_db.h" */ 
00127 } auxiliary_graph;
00128 #else
00129 typedef struct {
00130 int nnodes; /* number of nodes */
00131 int narcs; /* number of arcs */
00132 cgl_node *nodes; /* array of the nodes - see "types_db.h" */ 
00133 cgl_arc *arcs; /* array of the arcs - see "types_db.h" */ 
00134 } auxiliary_graph;
00135 #endif
00136 
00137 typedef struct {
00138 long dist; /* distance from/to root */
00139 int pred; /* index of the predecessor */
00140 } short_path_node;
00141 
00142 typedef struct {
00143 double weight; /* overall weight of the cycle */
00144 int length; /* number of edges in the cycle */
00145 edge **edge_list; /* list of edges in the cycle */
00146 } cycle;
00147 
00148 typedef struct {
00149 int cnum; /* overall number of cycles */
00150 cycle **list; /* pointers to the cycles in the list */
00151 } cycle_list;
00152 
00153 typedef struct {
00154 int n_of_constr; /* number of constraints combined to get the cut */
00155 int *constr_list; /* list of the constraints combined */
00156 short int *in_constr_list; /* flag saying whether a given constraint is
00157                               in the list of constraints of the cut (IN)
00158                               or not (OUT) */
00159 int cnzcnt; /* overall number of nonzero's in the cut */
00160 int *cind; /* column indices of the nonzero entries of the cut */
00161 int *cval; /* values of the nonzero entries of the cut */
00162 int crhs; /* right hand side of the cut */
00163 char csense; /* sense of the cut: 'L', 'G' or 'E' */
00164 double violation; /* violation of the cut w.r.t. the current LP solution */
00165 } cut;
00166 
00167 typedef struct {
00168 int cnum; /* overall number of cuts */
00169 cut **list; /* pointers to the cuts in the list */
00170 } cut_list;
00171 
00172 typedef struct {
00173 int n_of_constr; /* number of constraints combined to get the cut */
00174 int *constr_list; /* list of the constraints combined */
00175 int code; /* identifier of the cut */
00176 int n_it_violated; /* number of consecutive iterations (starting from the
00177                       last and going backward) in which the cut was
00178                       violated by the LP solution */
00179 int it_found; /* iteration in which the cut was separated */
00180 double score; /* score of the cut, used to choose wich cut should be 
00181                  added to the current LP (if any) */
00182 } pool_cut;
00183  
00184 typedef struct {
00185 int cnum; /* overall number of cuts */
00186 pool_cut **list; /* pointers to the cuts in the list */
00187 int *ncod; /* number of cuts with a given code in the pool */
00188 } pool_cut_list;
00189 
00190 typedef struct {
00191 int *ccoef; /* coefficients of the cut */
00192 int crhs; /* right hand side of the cut */
00193 int pool_index; /* index of the cut in the pool */
00194 double score; /* cut score (to be maximized) */
00195 } select_cut;
00196 
00197 typedef struct {
00198 int n_it_zero; /* number of consecutive iterations (starting from the
00199                    last and going backward) in which each variable took
00200                    the value 0 in the LP solution */
00201 } log_var;
00207 class Cgl012Cut {
00208  
00209 public:
00210 
00213 int sep_012_cut(
00214 /*
00215   INPUT parameters:
00216 */
00217 int mr, /* number of rows in the ILP matrix */
00218 int mc, /* number of columns in the ILP matrix */
00219 int mnz, /* number of nonzero's in the ILP matrix */
00220 int *mtbeg, /* starting position of each row in arrays mtind and mtval */
00221 int *mtcnt, /* number of entries of each row in arrays mtind and mtval */
00222 int *mtind, /* column indices of the nonzero entries of the ILP matrix */
00223 int *mtval, /* values of the nonzero entries of the ILP matrix */
00224 int *vlb, /* lower bounds on the variables */
00225 int *vub, /* upper bounds on the variables */
00226 int *mrhs, /* right hand sides of the constraints */
00227 char *msense, /* senses of the constraints: 'L', 'G' or 'E' */
00228 const double *xstar, /* current optimal solution of the LP relaxation */
00229 bool aggressive, /* flag asking whether as many cuts as possible are
00230                          required on output (TRUE) or not (FALSE) */
00231 /*
00232   OUTPUT parameters (the memory for the vectors is allocated INTERNALLY
00233   by the procedure: if some memory is already allocated, it is FREED):
00234 */
00235 int *cnum, /* number of violated 0-1/2 cuts identified by the procedure */
00236 int *cnzcnt, /* overall number of nonzero's in the cuts */
00237 int **cbeg, /* starting position of each cut in arrays cind and cval */
00238 int **ccnt, /* number of entries of each cut in arrays cind and cval */
00239 int **cind, /* column indices of the nonzero entries of the cuts */
00240 int **cval, /* values of the nonzero entries of the cuts */
00241 int **crhs, /* right hand sides of the cuts */
00242 char **csense /* senses of the cuts: 'L', 'G' or 'E' */
00243 /* 
00244   NOTE that all the numerical input/output vectors are INTEGER (with
00245   the exception of xstar), since the procedure is intended to work
00246   with pure ILP's, and that the ILP matrix has to be given on input
00247   in ROW format.
00248 */
00249                 );
00250 void ilp_load(
00251               int mr, /* number of rows in the ILP matrix */
00252               int mc, /* number of columns in the ILP matrix */
00253               int mnz, /* number of nonzero's in the ILP matrix */
00254               int *mtbeg, /* starting position of each row in arrays mtind and mtval */
00255               int *mtcnt, /* number of entries of each row in arrays mtind and mtval */
00256               int *mtind, /* column indices of the nonzero entries of the ILP matrix */
00257               int *mtval, /* values of the nonzero entries of the ILP matrix */
00258               int *vlb, /* lower bounds on the variables */
00259               int *vub, /* upper bounds on the variables */
00260               int *mrhs, /* right hand sides of the constraints */
00261               char *msense /* senses of the constraints: 'L', 'G' or 'E' */
00262               );
00263 void free_ilp();
00264 /* alloc_parity_ilp: allocate the memory for the parity ILP data structure */
00265 
00266 void alloc_parity_ilp(
00267                       int mr, /* number of rows in the ILP matrix */
00268                       int mc, /* number of columns in the ILP matrix */
00269                       int mnz /* number of nonzero's in the ILP matrix */
00270                       );
00271 void free_parity_ilp();
00272   void initialize_log_var();
00273 /* free_log_var */
00274   void free_log_var();
00275 private:
00276 /* best_weakening: find the best upper/lower bound weakening of a set
00277    of variables */
00278 
00279 int best_weakening(
00280                    int n_to_weak, /* number of variables to weaken */
00281 int *vars_to_weak, /* indices of the variables to weaken */
00282 short int original_parity, /* original parity of the constraint to weaken */
00283 double original_slack, /* original slack of the constraint to weaken */
00284 double *best_even_slack, /* best possible slack of a weakened constraint 
00285                            with even right-hand-side */
00286 double *best_odd_slack, /* best possible slack of a weakened constraint 
00287                           with odd right-hand-side */
00288 info_weak **info_even_weak, /* weakening information about the best possible
00289                                even weakened constraint */ 
00290 info_weak **info_odd_weak, /* weakening information about the best possible
00291                               odd weakened constraint */ 
00292 short int only_odd, /* flag which tells whether only an odd weakening is of
00293                        interest (TRUE) or both weakenings are (FALSE) */
00294 short int only_viol /* flag which tells whether only an inequality of
00295                         slack smaller than MAX_SLACK is of interest (TRUE)
00296                         otherwise (FALSE) */
00297                    );
00298 
00299 /* best_cut: find the coefficients, the rhs and the violation of the
00300    best possible cut that can be obtained by weakening a given set of
00301    coefficients to even and a rhs to odd, dividing by 2 and rounding */
00302 
00303 short int best_cut(
00304                    int *ccoef, /* vector of the coefficients */
00305                    int *crhs, /* pointer to rhs value */
00306                    double *violation, /* violation of the cut */
00307                    short int update, /* TRUE/FALSE: if TRUE, the new ccoef and crhs are 
00308                                         given on output */ 
00309                    short int only_viol /* flag which tells whether only an inequality of
00310                         slack smaller than MAX_SLACK is of interest (TRUE)
00311                         otherwise (FALSE) */
00312                               );
00313 /* get_cut: extract a hopefully violated cut from an odd cycle of the
00314    separation graph */
00315 
00316 cut *get_cut(
00317              cycle *s_cyc /* shortest odd cycles identified in the separation graph */
00318              );
00319 
00320 /* update_log_var: update the log information for the problem variables */
00321   void update_log_var();
00322 
00323 /* basic_separation: try to identify violated 0-1/2 cuts by using the 
00324    original procedure described in Caprara and Fischetti's MP paper */
00325 
00326   cut_list *basic_separation();
00327 
00328 /* score_by_moving: compute the score of the best cut obtainable from 
00329    the current local search solution by inserting/deleting a constraint */
00330 
00331 double score_by_moving(
00332                        int i, /* constraint to be moved */
00333                        short int itype, /* type of move - ADD or DEL */
00334                        double thresh /* minimum value of an interesting score */
00335                        );
00336 /* modify_current: update the current local search solution by inserting/
00337    deleting a constraint */
00338 
00339 void modify_current(
00340                     int i, /* constraint to be moved */
00341                     short int itype /* type of move - ADD or DEL */
00342                     );
00343 
00344 /* best neighbour: find the cut to be added/deleted from the current
00345    solution among those allowed by the tabu rules */
00346 
00347   short int best_neighbour(cut_list *out_cuts /* list of the violated cuts found */);
00348 
00349 /* add_tight_constraint: initialize the current cut by adding a tight 
00350    constraint to it */
00351        
00352   void add_tight_constraint();
00353 
00354 /* tabu_012: try to identify violated 0-1/2 cuts by a simple tabu search
00355    procedure adapted from that used by Battiti and Protasi for finding
00356    large cliques */
00357 
00358   cut_list *tabu_012();
00359 /* initialize: initialize the data structures for local search */
00360 
00361   void initialize();
00362 /* restart: perform a restart of the search - IMPORTANT: in the current
00363    implementation vector last_moved is not cleared at restart */
00364        
00365   void restart(short int failure /* flag forcing the restart if some trouble occurred */);
00366   void print_constr(int i /* constraint to be printed */);
00367   void print_parity_ilp();
00368 
00369 /* get_parity_ilp: construct an internal data structure containing all the 
00370    information which can be useful for  0-1/2 cut separation */
00371 
00372   void get_parity_ilp();
00373 /* initialize_sep_graph: allocate and initialize the data structure
00374    to contain the information associated with a separation graph */
00375 
00376   separation_graph *initialize_sep_graph();
00377   void print_cut(cut *v_cut);
00378 /* get_ori_cut_coef: get the coefficients of a cut, before dividing by 2 and
00379    rounding, starting from the list of the constraints combined to get 
00380    the cut */
00381 
00382 short int get_ori_cut_coef(
00383                            int n_of_constr, /* number of constraints combined */
00384                            int *constr_list, /* list of the constraints combined */
00385                            int *ccoef, /* cut left hand side coefficients */
00386                            int *crhs, /* cut right hand side */
00387                            short int only_viol /* flag which tells whether only an inequality of
00388                         slack smaller than MAX_SLACK is of interest (TRUE)
00389                         otherwise (FALSE) */
00390                            );
00391 /* define_cut: construct a cut data structure from a vector of
00392    coefficients and a right-hand-side */
00393 
00394 cut *define_cut(
00395                 int *ccoef, /* coefficients of the cut */
00396                 int crhs /* right hand side of the cut */
00397                 );
00398 
00399 /* cut_score: define the score of a (violated) cut */
00400 
00401 double cut_score(
00402                  int *ccoef, /* cut left hand side coefficients */
00403                  int crhs, /* cut right hand side */
00404                  double viol, /* cut violation */
00405                  short int only_viol /* flag which tells whether only an inequality of
00406                         slack smaller than MAX_SLACK is of interest (TRUE)
00407                         otherwise (FALSE) */
00408                  );
00409 /* get_current_cut: return a cut data type with the information about
00410    the current cut of the search procedure */
00411 
00412   cut *get_current_cut();
00413 /* print_cur_cut: display cur_cut on output */
00414 
00415   void print_cur_cut();
00416   void print_cut_list(cut_list *cuts);
00418 public:
00421 
00422   Cgl012Cut ();
00423  
00425   Cgl012Cut (
00426     const Cgl012Cut &);
00427 
00429   Cgl012Cut &
00430     operator=(
00431     const Cgl012Cut& rhs);
00432   
00434   virtual ~Cgl012Cut ();
00436 
00437 private:
00438   
00439   // Private member methods
00440    
00443 
00444   
00445   
00448 
00449 ilp *inp_ilp; /* input ILP data structure */
00450 parity_ilp *p_ilp; /* parity ILP data structure */
00451 int iter;
00452 double gap;
00453 double maxgap;
00454 int errorNo;
00455 int sep_iter; /* number of the current separation iteration */
00456 log_var **vlog; /* information about the value attained
00457                                   by the variables in the last iterations,
00458                                   used to possibly set to 0 some coefficient
00459                                   > 0 in a cut to be added */ 
00460 bool aggr; /* flag saying whether as many cuts as possible are required
00461                    from the separation procedure (TRUE) or not (FALSE) */
00463 };
00464 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 8 Mar 2015 for Cgl by  doxygen 1.6.1