From f04d9a1d60b0fe243b40060481ce050aa963c2a3 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Tue, 31 Mar 2015 14:19:11 -0400 Subject: [PATCH] Cut pool compression --- src/lp.c | 64 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/src/lp.c b/src/lp.c index d254f7b..5660120 100644 --- a/src/lp.c +++ b/src/lp.c @@ -23,6 +23,18 @@ int LP_open(struct LP *lp) return rval; } +void LP_free_cut_pool(struct LP *lp) +{ + for (int i = 0; i < lp->cut_pool_size; i++) + { + free(lp->cut_pool[i]->rmatind); + free(lp->cut_pool[i]->rmatval); + free(lp->cut_pool[i]); + } + + if (lp->cut_pool) free(lp->cut_pool); +} + void LP_free(struct LP *lp) { if (!lp) return; @@ -34,14 +46,33 @@ void LP_free(struct LP *lp) CPXcloseCPLEX(&lp->cplex_env); lp->cplex_env = 0; + LP_free_cut_pool(lp); +} + +int LP_compress_cut_pool(struct LP *lp) +{ + int rval = 0; + + int delete_count = 0; for (int i = 0; i < lp->cut_pool_size; i++) { - free(lp->cut_pool[i]->rmatind); - free(lp->cut_pool[i]->rmatval); - free(lp->cut_pool[i]); + if (lp->cut_pool[i]->cplex_row_index < 0) + { + free(lp->cut_pool[i]->rmatind); + free(lp->cut_pool[i]->rmatval); + free(lp->cut_pool[i]); + delete_count++; + } + else + { + lp->cut_pool[i - delete_count] = lp->cut_pool[i]; + } } - if (lp->cut_pool) free(lp->cut_pool); + lp->cut_pool_size -= delete_count; + + CLEANUP: + return rval; } int LP_create(struct LP *lp, const char *name) @@ -209,6 +240,7 @@ int LP_optimize(struct LP *lp, int *infeasible) rval = LP_update_cut_ages(lp); abort_if(rval, "LP_update_cut_ages failed"); + log_debug("Removing old cuts...\n"); rval = LP_remove_old_cuts(lp); abort_if(rval, "LP_remove_old_cuts failed"); @@ -299,18 +331,26 @@ int LP_remove_old_cuts(struct LP *lp) numrows = CPXgetnumrows(lp->cplex_env, lp->cplex_lp); log_verbose(" new numrows=%d\n", numrows); + log_debug(" removed %d old cuts\n", count); + + rval = CPXdualopt(lp->cplex_env, lp->cplex_lp); + abort_if(rval, "CPXoptimize failed"); + + log_debug("Compressing cut pool...\n"); + LP_compress_cut_pool(lp); + + + long nz = 0; + long size = 0; for (int i = 0; i < lp->cut_pool_size; i++) { - struct Row *cut = lp->cut_pool[i]; - assert(cut->cplex_row_index < numrows); + size += sizeof(struct Row); + nz += lp->cut_pool[i]->nz; + size += lp->cut_pool[i]->nz * sizeof(double); + size += lp->cut_pool[i]->nz * sizeof(int); } - if (count > 0) - { - log_debug("Found and removed %d old cuts\n", count); - rval = CPXdualopt(lp->cplex_env, lp->cplex_lp); - abort_if(rval, "CPXoptimize failed"); - } + log_debug(" %ld cuts (%ld nz, %ld MiB)\n", lp->cut_pool_size, nz, size/1024/1024); CLEANUP: if (should_remove) free(should_remove);