From c65ac7d8b92278b17ea1739026414dc6f204ae52 Mon Sep 17 00:00:00 2001 From: Tim King Date: Sun, 29 Dec 2013 14:38:37 -0500 Subject: [PATCH] Adding GLP_ICUTSELECT callback: - ios_process_cuts marks the cuts as selected after turning the cut into a row. - This callback happens after ios_process_cuts marks and before the pool is cleared by ios_clear_pool. --- src/cutlog01.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- src/glpapi13.c | 10 ++++++++-- src/glpios.h | 8 ++++++++ src/glpios03.c | 8 ++++++++ src/glpios11.c | 3 +++ src/glpk.h | 5 +++++ 6 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/cutlog01.c b/src/cutlog01.c index bdebedd..4751532 100644 --- a/src/cutlog01.c +++ b/src/cutlog01.c @@ -48,6 +48,7 @@ IOSAUX *ios_create_aux(int n, const int rows[], const double coeffs[]){ aux->nrows = n; aux->rows = xcalloc(1+n, sizeof(int)); aux->mult = xcalloc(1+n, sizeof(double)); + aux->selected = -1; aux->mir_cset = NULL; for ( i = 1; i <= n; i++) @@ -93,7 +94,7 @@ static void cut_set_aux_mir(IOSAUX *aux, double delta, for ( i = 1; i <= n; i++) { aux->mir_cset[i] = cset[i]; } - + aux->mir_delta = delta; } @@ -192,3 +193,51 @@ void glp_ios_cut_get_aux_mir(glp_tree *tree, int ord, } } } + +void ios_cut_set_selected(IOSCUT *cut, int sel){ +#ifdef CUT_DEBUG + static int i = 0; + ++i; + printf("ios_cut_set_selected: %d %d %p\n", i, sel, cut); +#endif + + IOSAUX *aux; + aux = cut->aux; + if ( aux != NULL ){ + aux->selected = sel; + } +} + +int glp_ios_selected_cuts(glp_tree *tree, int ords[], int sel[]){ + int len, j, N, s; + IOSPOOL* pool; + IOSCUT* cut; + IOSAUX* aux; + if ( tree == NULL ){ + xerror("glp_ios_selected_cuts: not called with a valid tree.\n"); + } + if ( tree->reason != GLP_ICUTSELECT ){ + xerror("glp_ios_selected_cuts: not called during cut selected.\n"); + } + + pool = tree->local; + if ( pool == NULL ){ + xerror("glp_ios_selected_cuts: called on a malformed tree.\n"); + } + + for (len = 0, j = 1, cut = pool->head; cut != NULL; cut = cut->next, j++) + { aux = cut->aux; +#ifdef CUT_DEBUG + printf("glp_ios_selected_cuts: %d %p\n", j, cut); +#endif + if ( aux != NULL ) + { s = aux->selected; + if ( s >= 0 ) + { len++; + if (ords != NULL) { ords[len] = j; } + if (sel != NULL) { sel[len] = s; } + } + } + } + return len; +} diff --git a/src/glpapi13.c b/src/glpapi13.c index e0c7c73..55adf44 100644 --- a/src/glpapi13.c +++ b/src/glpapi13.c @@ -453,8 +453,14 @@ void glp_ios_row_attr(glp_tree *tree, int i, glp_attr *attr) int glp_ios_pool_size(glp_tree *tree) { /* determine current size of the cut pool */ - if (tree->reason != GLP_ICUTGEN && tree->reason != GLP_ICUTADDED ) - xerror("glp_ios_pool_size: operation not allowed\n"); + switch(tree->reason) + { case GLP_ICUTGEN: + case GLP_ICUTADDED: + case GLP_ICUTSELECT: + break; + default: + xerror("glp_ios_pool_size: operation not allowed\n"); + } xassert(tree->local != NULL); return tree->local->size; } diff --git a/src/glpios.h b/src/glpios.h index 1a1d786..9c6b5b0 100644 --- a/src/glpios.h +++ b/src/glpios.h @@ -422,6 +422,9 @@ struct IOSAUX int *rows; double *mult; + int selected; + /* when < 0 this has not yet been turned into a row + when >=0 this is the id of the row added. */ char *mir_cset; /* complimented set */ @@ -661,8 +664,13 @@ void ios_cut_set_single_aux(glp_tree *T, int ord, int j); void ios_cut_set_aux(glp_tree *T, int ord, int n, const int rows[], const double coeffs[]); /* sets an arbitrary aux sum */ + void ios_cut_set_aux_mir(glp_tree *T, int ord, double delta, int n, const char cset[]); +/* sets the extra mir information */ + +void ios_cut_set_selected(IOSCUT *cut, int i); +/* the cut has been added as row i */ #endif diff --git a/src/glpios03.c b/src/glpios03.c index 80d701b..d31a5af 100644 --- a/src/glpios03.c +++ b/src/glpios03.c @@ -1219,6 +1219,14 @@ int ios_driver(glp_tree *T) ios_process_cuts(T); T->reason = 0; } + /* if the local cut pool is not empty and the callback func is there, + this gives the callback the chance to see what was selected. */ + if (T->parm->cb_func != NULL && T->local->size > 0) + { xassert(T->reason == 0); + T->reason = GLP_ICUTSELECT; + T->parm->cb_func(T, T->parm->cb_info); + T->reason = 0; + } /* clear the local cut pool */ ios_clear_pool(T, T->local); /* perform re-optimization, if necessary */ diff --git a/src/glpios11.c b/src/glpios11.c index c40e9a5..82d5698 100644 --- a/src/glpios11.c +++ b/src/glpios11.c @@ -193,6 +193,9 @@ void ios_process_cuts(glp_tree *T) glp_set_mat_row(T->mip, i, len, ind, val); xassert(cut->type == GLP_LO || cut->type == GLP_UP); glp_set_row_bnds(T->mip, i, cut->type, cut->rhs, cut->rhs); + + /* setting this as selected */ + ios_cut_set_selected(cut, i); } /* free working arrays */ xfree(info); diff --git a/src/glpk.h b/src/glpk.h index 37264e1..99482c1 100644 --- a/src/glpk.h +++ b/src/glpk.h @@ -230,6 +230,7 @@ typedef struct #define GLP_ISELECT 0x06 /* request for subproblem selection */ #define GLP_IPREPRO 0x07 /* request for preprocessing */ #define GLP_ICUTADDED 0x08 /* cut was added to the pool */ +#define GLP_ICUTSELECT 0x09 /* cuts were selected as rows */ /* branch selection indicator: */ #define GLP_NO_BRNCH 0 /* select no branch */ @@ -1082,6 +1083,10 @@ void glp_ios_cut_get_aux_mir(glp_tree *tree, int ord, char cset[], double *delta); /* gets mir cut specific information. */ +int glp_ios_selected_cuts(glp_tree *tree, int ords[], int sel[]); +/* gets the list of selected cuts. + Can only be called when GLP_ICUTSELECT */ + #ifdef __cplusplus } #endif