From 5d64d24ad6b40249f18e90d33ce62b9c160cec3a Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Tue, 8 Aug 2017 11:25:11 -0400 Subject: [PATCH] infinity: Scale up rays with very small norm --- infinity/library/src/infinity.c | 24 ++++++++++++---- infinity/library/tests/infinity-test.cpp | 36 ++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/infinity/library/src/infinity.c b/infinity/library/src/infinity.c index 68d27b7..8ad2186 100644 --- a/infinity/library/src/infinity.c +++ b/infinity/library/src/infinity.c @@ -108,6 +108,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau, struct Row *cut) { int rval = 0; + double *ray = 0; struct LP lp; int nvars = map->nvars; @@ -122,22 +123,34 @@ static int create_cut_from_lfree(const struct Tableau *tableau, rval = INFINITY_create_psi_lp(lfree, &lp); abort_if(rval, "create_psi_lp failed"); + ray = (double*) malloc(nrows * sizeof(double)); + abort_if(!ray, "could not allocate ray"); + cut->nz = nvars; for(int i = 0; i < nvars; i++) { - double value; - const double *q = LFREE_get_ray(rays, map->variable_to_ray[i]); + double value, norm = 0; + double *original_ray = LFREE_get_ray(rays, map->variable_to_ray[i]); char type = tableau->column_types[map->indices[i]]; + for (int j = 0; j < nrows; j++) + { + ray[j] = original_ray[j]; + norm += fabs(ray[j]); + } + + if (norm < 0.001) + for (int j = 0; j < nrows; j++) + ray[j] *= 0.001 / norm; if(ENABLE_LIFTING && type == MILP_INTEGER) { - rval = INFINITY_pi(nrows, q, map->ray_scale[i], &lp, &value); + rval = INFINITY_pi(nrows, ray, map->ray_scale[i], &lp, &value); abort_if(rval, "INFINITY_pi failed"); } else { - rval = INFINITY_psi(nrows, q, map->ray_scale[i], &lp, &value); + rval = INFINITY_psi(nrows, ray, map->ray_scale[i], &lp, &value); abort_if(rval, "INFINITY_psi failed"); } @@ -147,7 +160,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau, { time_printf(" q=["); for(int j = 0; j < nrows; j++) - printf("%25.20lf ", q[j] * map->ray_scale[i]); + printf("%25.20lf ", ray[j] * map->ray_scale[i]); printf("] value=%25.20lf\n", value); } @@ -163,6 +176,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau, cut->pi_zero = -1.0; CLEANUP: + if(ray) free(ray); LP_free(&lp); return rval; } diff --git a/infinity/library/tests/infinity-test.cpp b/infinity/library/tests/infinity-test.cpp index 867ed5a..69225a7 100644 --- a/infinity/library/tests/infinity-test.cpp +++ b/infinity/library/tests/infinity-test.cpp @@ -375,6 +375,42 @@ TEST(InfinityTest, generate_cut_test_3) for(int i = 0; i < tableau.nrows; i++) log_debug("s[%d] = %20.12lf\n", i, s[i]); +CLEANUP: + if (rval) FAIL(); +} + +TEST(InfinityTest, generate_cut_test_4) +{ + int rval = 0; + + // Extracted from instance bell5.pre.mps (MIPLIB 3) + double pi0[] = { 0.5000000000, 1.0000000000, 0.0007440476, 0.0007440476, -0.0007440476, -0.0007440476, }; + double pi1[] = { 1.0000000000, -0.0250000000, 0.0000372024, 0.0000372024, -0.0500000000, -0.0000372024, -0.0000372024, }; + int indices0[] = { 22, 36, 64, 77, 129, 156, }; + int indices1[] = { 8, 22, 64, 77, 115, 129, 156, }; + struct Row row0 = {.nz = 6, .head = 36, .pi_zero = 0.7440476190, .pi = pi0, .indices = indices0 }; + struct Row row1 = {.nz = 7, .head = 8, .pi_zero = 0.0372023810, .pi = pi1, .indices = indices1 }; + struct Row* rows[] = {&row0, &row1, }; + char column_types[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + struct Tableau tableau = {.ncols = 169, .nrows = 2, .rows = rows, .column_types = column_types }; + double x[169] = {1.0000000000, 1.0000000000, 1.0000000000, 1.0000000000, 1.0000000000, 0.0000000000, 1.0000000000, 0.0000000000, 0.0000000000, 1.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 1.0000000000, 1.0000000000, 0.0000000000, 11.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 2.0000000000, 38.0000000000, 2.0000000000, 498.0000000000, 125.0000000000, 10.0000000000, 17.0000000000, 41.0000000000, 0.0000000000, 19.0000000000, 0.0000000000, 8318.0000000000, 7494.0000000000, 60.0000000000, 10.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 18.0000000000, 8.0000000000, 16.0000000000, 334.0000000000, 24.0000000000, 792.0000000000, 792.0000000000, 336.0000000000, 336.0000000000, 0.0000000000, 40.0000000000, 166.0000000000, 3000.0000000000, 1632.0000000000, 1392.0000000000, 984.0000000000, 456.0000000000, 456.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 48.0000000000, 900.0000000000, 40.0000000000, 11950.0000000000, 240.0000000000, 408.0000000000, 984.0000000000, 0.0000000000, 456.0000000000, 0.0000000000, -0.0000000000, -0.0000000000, -0.0000000000, -0.0000000000, 1.0000000000, 0.0000000000, 1.0000000000, 1.0000000000, 0.0000000000, 1.0000000000, 1.0000000000, 20.0000000000, 20.0000000000, 20.0000000000, 19.0000000000, 19.0000000000, 0.0000000000, 9.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 20.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 238.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 12.0000000000, 8.0000000000, 2.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, 0.0053700000, 0.6917620000, 6.9221320000, 0.0000000000, 0.9966800000, 11.9862220000, 0.7510000000, 0.8495500000, 3.3519300000, 266583.5900000000, }; + + double lhs, s[2]; + struct Row cut; + LP_init_row(&cut, CG_total_nz(&tableau)); + + rval = INFINITY_generate_cut(&tableau, &cut); + abort_if(rval, "INFINITY_generate_cut failed"); + + rval = get_lattice_point(&tableau, x, s); + abort_if(rval, "get_lattice_point failed"); + + for(int i = 0; i < tableau.nrows; i++) + log_debug("s[%d] = %20.12lf\n", i, s[i]); + + lhs = CG_replace_x(&cut, x); + EXPECT_LE(lhs, cut.pi_zero); + CLEANUP: if (rval) FAIL(); } \ No newline at end of file