Refactor infinity.c

selection
Alinson S. Xavier 9 years ago
parent 3ba88644c0
commit 2825766643

@ -86,7 +86,8 @@ CLEANUP:
} }
static int create_cut_from_lfree(const struct Tableau *tableau, static int create_cut_from_lfree(const struct Tableau *tableau,
const struct RayMap *map, const struct TableauModelMap *map,
const struct MultiRowModel *model,
const struct ConvLFreeSet *lfree, const struct ConvLFreeSet *lfree,
struct Row *cut) struct Row *cut)
{ {
@ -95,6 +96,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
struct LP lp; struct LP lp;
int nvars = map->nvars; int nvars = map->nvars;
int nrows = tableau->nrows; int nrows = tableau->nrows;
struct RayList *rays = &model->rays;
rval = LP_open(&lp); rval = LP_open(&lp);
abort_if(rval, "LP_open failed"); abort_if(rval, "LP_open failed");
@ -107,7 +109,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
for(int i = 0; i < nvars; i++) for(int i = 0; i < nvars; i++)
{ {
double value; double value;
const double *q = LFREE_get_ray(&map->rays, map->variable_to_ray[i]); const double *q = LFREE_get_ray(rays, map->variable_to_ray[i]);
if(ENABLE_LIFTING && if(ENABLE_LIFTING &&
tableau->column_types[map->indices[i]] == MILP_INTEGER) tableau->column_types[map->indices[i]] == MILP_INTEGER)
@ -141,26 +143,28 @@ CLEANUP:
return rval; return rval;
} }
static int filter_rays(const struct RayMap *map, static int filter_model(const struct MultiRowModel *original_model,
const struct Tableau *tableau, struct MultiRowModel *filtered_model)
struct MultiRowModel *model)
{ {
int rval = 0; int rval = 0;
int nrows = tableau->nrows; int nrows = original_model->nrows;
struct RayList *rays = &model->rays; struct RayList *filtered_rays = &filtered_model->rays;
struct RayList *original_rays = &original_model->rays;
memcpy(filtered_model->f, original_model->f, 2 * sizeof(double));
for(double norm_cutoff = 0.00; norm_cutoff <= 5.0; norm_cutoff += 0.1) for(double norm_cutoff = 0.00; norm_cutoff <= 5.0; norm_cutoff += 0.1)
{ {
rays->nrays = 0; filtered_rays->nrays = 0;
for(int i = 0; i < map->rays.nrays; i++) for(int i = 0; i < original_rays->nrays; i++)
{ {
int keep = 1; int keep = 1;
double *r = LFREE_get_ray(&map->rays, i); double *r = LFREE_get_ray(original_rays, i);
for(int j = 0; j < (rays->nrays); j++) for(int j = 0; j < (filtered_rays->nrays); j++)
{ {
double *q = LFREE_get_ray(&map->rays, j); double *q = LFREE_get_ray(filtered_rays, j);
double norm = 0; double norm = 0;
for(int k = 0; k < nrows; k++) for(int k = 0; k < nrows; k++)
@ -173,13 +177,13 @@ static int filter_rays(const struct RayMap *map,
} }
} }
if(keep) LFREE_push_ray(rays, r); if(keep) LFREE_push_ray(filtered_rays, r);
} }
log_debug(" norm_cutoff=%8.2lf nrays=%8d\n", norm_cutoff, log_debug(" norm_cutoff=%8.2lf nrays=%8d\n", norm_cutoff,
model->rays.nrays); filtered_model->rays.nrays);
if(rays->nrays < MAX_N_RAYS) break; if(filtered_rays->nrays < MAX_N_RAYS) break;
} }
CLEANUP: CLEANUP:
@ -187,7 +191,7 @@ CLEANUP:
} }
static int append_extra_rays(const struct Tableau *tableau, static int append_extra_rays(const struct Tableau *tableau,
struct RayList *rays) struct MultiRowModel *model)
{ {
int rval = 0; int rval = 0;
int nrows = tableau->nrows; int nrows = tableau->nrows;
@ -237,10 +241,10 @@ static int append_extra_rays(const struct Tableau *tableau,
double scale; double scale;
int found, index; int found, index;
rval = CG_find_ray(rays, r, &found, &scale, &index); rval = CG_find_ray(&model->rays, r, &found, &scale, &index);
abort_if(rval, "CG_find_ray failed"); abort_if(rval, "CG_find_ray failed");
if(!found) LFREE_push_ray(rays, r); if(!found) LFREE_push_ray(&model->rays, r);
} }
CLEANUP: CLEANUP:
@ -299,30 +303,31 @@ CLEANUP:
return rval; return rval;
} }
static int extract_model_from_tableau(const struct Tableau *tableau, static int extract_models(const struct Tableau *tableau,
struct MultiRowModel *model, struct MultiRowModel *original_model,
struct RayMap *map) struct MultiRowModel *filtered_model,
struct TableauModelMap *original_map)
{ {
int rval = 0; int rval = 0;
rval = CG_extract_f_from_tableau(tableau, model->f); rval = CG_extract_f_from_tableau(tableau, original_model->f);
abort_if(rval, "CG_extract_f_from_tableau failed"); abort_if(rval, "CG_extract_f_from_tableau failed");
rval = CG_extract_rays_from_tableau(tableau, map); rval = CG_extract_model(tableau, original_map, original_model);
abort_if(rval, "CG_extract_rays_from_rows failed"); abort_if(rval, "CG_extract_rays_from_rows failed");
rval = filter_rays(map, tableau, model); rval = filter_model(original_model, filtered_model);
abort_if(rval, "filter_rays failed"); abort_if(rval, "filter_model failed");
if(ENABLE_LIFTING) if(ENABLE_LIFTING)
{ {
rval = append_extra_rays(tableau, &model->rays); rval = append_extra_rays(tableau, filtered_model);
abort_if(rval, "append_extra_rays failed"); abort_if(rval, "append_extra_rays failed");
} }
if(tableau->nrows == 2) if(tableau->nrows == 2)
{ {
rval = sort_rays_by_angle(&model->rays); rval = sort_rays_by_angle(&filtered_model->rays);
abort_if(rval, "sort_rays_by_angle failed"); abort_if(rval, "sort_rays_by_angle failed");
} }
@ -335,34 +340,39 @@ CLEANUP:
int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut) int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
{ {
int rval = 0; int rval = 0;
int max_nrays = CG_total_nz(tableau); int max_nrays = CG_total_nz(tableau) + 100;
struct RayMap map; struct MultiRowModel original_model;
struct MultiRowModel model; struct MultiRowModel filtered_model;
struct TableauModelMap original_map;
struct ConvLFreeSet lfree; struct ConvLFreeSet lfree;
rval = CG_init_model(&model, tableau->nrows, max_nrays + 100); rval = CG_init_model(&original_model, tableau->nrows, max_nrays);
abort_if(rval, "CG_init_model failed");
rval = CG_init_model(&filtered_model, tableau->nrows, max_nrays);
abort_if(rval, "CG_init_model failed"); abort_if(rval, "CG_init_model failed");
rval = CG_init_ray_map(&map, max_nrays, tableau->nrows); rval = CG_init_map(&original_map, max_nrays, tableau->nrows);
abort_if(rval, "CG_init_ray_map failed"); abort_if(rval, "CG_init_map failed");
rval = extract_model_from_tableau(tableau, &model, &map); rval = extract_models(tableau, &original_model, &filtered_model,
abort_if(rval, "extract_model_from_tableau failed"); &original_map);
abort_if(rval, "extract_models failed");
if(model.rays.nrays < 3) if(filtered_model.rays.nrays < 3)
{ {
rval = ERR_NO_CUT; rval = ERR_NO_CUT;
goto CLEANUP; goto CLEANUP;
} }
rval = LFREE_init_conv(&lfree, tableau->nrows, model.rays.nrays); rval = LFREE_init_conv(&lfree, tableau->nrows, filtered_model.rays.nrays);
abort_if(rval, "LFREE_init_conv failed"); abort_if(rval, "LFREE_init_conv failed");
if(tableau->nrows == 2) if(tableau->nrows == 2)
rval = INFINITY_2D_generate_lfree(&model, &lfree); rval = INFINITY_2D_generate_lfree(&filtered_model, &lfree);
else else
rval = INFINITY_ND_generate_lfree(&model, &lfree); rval = INFINITY_ND_generate_lfree(&filtered_model, &lfree);
if(rval) if(rval)
{ {
@ -372,17 +382,19 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
if(SHOULD_DUMP_CUTS) if(SHOULD_DUMP_CUTS)
{ {
rval = dump_cut(&model, &lfree); rval = dump_cut(&filtered_model, &lfree);
abort_if(rval, "dump_cut failed"); abort_if(rval, "dump_cut failed");
} }
rval = create_cut_from_lfree(tableau, &map, &lfree, cut); rval = create_cut_from_lfree(tableau, &original_map, &original_model,
&lfree, cut);
abort_if(rval, "create_cut_from_lfree failed"); abort_if(rval, "create_cut_from_lfree failed");
CLEANUP: CLEANUP:
LFREE_free_conv(&lfree); LFREE_free_conv(&lfree);
CG_free_model(&model); CG_free_model(&original_model);
CG_free_ray_map(&map); CG_free_model(&filtered_model);
CG_free_map(&original_map);
return rval; return rval;
} }

@ -47,9 +47,8 @@ struct Tableau
char *column_types; char *column_types;
}; };
struct RayMap struct TableauModelMap
{ {
struct RayList rays;
int *variable_to_ray; int *variable_to_ray;
double *ray_scale; double *ray_scale;
int *indices; int *indices;
@ -84,8 +83,9 @@ int CG_set_integral_solution(struct CG *cg, double *valid_solution);
int CG_set_basic_solution(struct CG *cg, double *basic_solution); int CG_set_basic_solution(struct CG *cg, double *basic_solution);
int CG_extract_rays_from_tableau(const struct Tableau *tableau, int CG_extract_model(const struct Tableau *tableau,
struct RayMap *map); struct TableauModelMap *map,
struct MultiRowModel *model);
int CG_boost_variable(int var, int CG_boost_variable(int var,
double factor, double factor,
@ -102,9 +102,9 @@ int CG_find_ray(const struct RayList *rays,
double *scale, double *scale,
int *index); int *index);
int CG_init_ray_map(struct RayMap *map, int max_nrays, int nrows); int CG_init_map(struct TableauModelMap *map, int max_nrays, int nrows);
void CG_free_ray_map(struct RayMap *map); void CG_free_map(struct TableauModelMap *map);
int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f); int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f);

@ -440,8 +440,9 @@ CLEANUP:
return 0; return 0;
} }
int CG_extract_rays_from_tableau(const struct Tableau *tableau, int CG_extract_model(const struct Tableau *tableau,
struct RayMap *map) struct TableauModelMap *map,
struct MultiRowModel *model)
{ {
int rval = 0; int rval = 0;
@ -463,7 +464,7 @@ int CG_extract_rays_from_tableau(const struct Tableau *tableau,
while (1) while (1)
{ {
double *r = LFREE_get_ray(&map->rays, map->rays.nrays); double *r = LFREE_get_ray(&model->rays, model->rays.nrays);
int idx_min = INT_MAX; int idx_min = INT_MAX;
@ -501,19 +502,19 @@ int CG_extract_rays_from_tableau(const struct Tableau *tableau,
for (int j = 0; j < nrows; j++) for (int j = 0; j < nrows; j++)
log_verbose(" r[%d] = %.12lf\n", j, r[j]); log_verbose(" r[%d] = %.12lf\n", j, r[j]);
rval = CG_find_ray(&map->rays, r, &found, &scale, &ray_index); rval = CG_find_ray(&model->rays, r, &found, &scale, &ray_index);
abort_if(rval, "CG_find_ray failed"); abort_if(rval, "CG_find_ray failed");
if (!found) if (!found)
{ {
log_verbose(" ray is new\n"); log_verbose(" ray is new\n");
scale = 1.0; scale = 1.0;
ray_index = map->rays.nrays++; ray_index = model->rays.nrays++;
} }
else else
{ {
log_verbose(" ray equals:\n"); log_verbose(" ray equals:\n");
double *q = LFREE_get_ray(&map->rays, ray_index); double *q = LFREE_get_ray(&model->rays, ray_index);
for (int j = 0; j < nrows; j++) for (int j = 0; j < nrows; j++)
log_verbose(" r[%d] = %.12lf\n", j, q[j]); log_verbose(" r[%d] = %.12lf\n", j, q[j]);
} }
@ -526,9 +527,9 @@ int CG_extract_rays_from_tableau(const struct Tableau *tableau,
NEXT_RAY:; NEXT_RAY:;
} }
for (int j = 0; j < map->rays.nrays; j++) for (int j = 0; j < model->rays.nrays; j++)
{ {
double *r = LFREE_get_ray(&map->rays, j); double *r = LFREE_get_ray(&model->rays, j);
double max_scale = 0.0; double max_scale = 0.0;
for (int k = 0; k < map->nvars; k++) for (int k = 0; k < map->nvars; k++)
@ -1045,7 +1046,7 @@ CLEANUP:
return rval; return rval;
} }
int CG_init_ray_map(struct RayMap *map, int max_nrays, int nrows) int CG_init_map(struct TableauModelMap *map, int max_nrays, int nrows)
{ {
int rval = 0; int rval = 0;
@ -1056,20 +1057,16 @@ int CG_init_ray_map(struct RayMap *map, int max_nrays, int nrows)
abort_if(!map->indices, "could not allocate indices"); abort_if(!map->indices, "could not allocate indices");
abort_if(!map->ray_scale, "could not allocate ray_scale"); abort_if(!map->ray_scale, "could not allocate ray_scale");
rval = LFREE_init_ray_list(&map->rays, nrows, max_nrays);
abort_if(rval, "LFREE_init_ray_list failed");
CLEANUP: CLEANUP:
return rval; return rval;
} }
void CG_free_ray_map(struct RayMap *map) void CG_free_map(struct TableauModelMap *map)
{ {
if(!map) return; if(!map) return;
free(map->variable_to_ray); free(map->variable_to_ray);
free(map->indices); free(map->indices);
free(map->ray_scale); free(map->ray_scale);
LFREE_free_ray_list(&map->rays);
} }
int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f) int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f)

@ -113,75 +113,49 @@ TEST(CGTest, extract_rays_from_rows_test)
char column_types[16] = {0}; char column_types[16] = {0};
double pi1[] = { 1.0, 1.0, 1.0, 2.0, 1.0 }; double pi1[] = { 1.0, 1.0, 1.0, 2.0, 1.0 };
int indices1[] = { 1, 7, 8, 12, 14 }; int indices1[] = { 1, 7, 8, 12, 14 };
struct Row row1 = struct Row row1 = {.nz = 5, .head = 1, .pi_zero = 1.0, .pi = pi1, .indices = indices1};
{
.nz = 5,
.head = 1,
.pi_zero = 1.0,
.pi = pi1,
.indices = indices1
};
double pi2[] = { 1.0, 1.0, 2.0, 1.0, 1.0, 1.0 }; double pi2[] = { 1.0, 1.0, 2.0, 1.0, 1.0, 1.0 };
int indices2[] = { 5, 8, 12, 13, 14, 16 }; int indices2[] = { 5, 8, 12, 13, 14, 16 };
struct Row row2 = struct Row row2 = {.nz = 6, .head = 13, .pi_zero = 1.0, .pi = pi2, .indices = indices2};
{
.nz = 6,
.head = 13,
.pi_zero = 1.0,
.pi = pi2,
.indices = indices2
};
double pi3[] = { 1.0, 1.0, 1.0, 1.0 }; double pi3[] = { 1.0, 1.0, 1.0, 1.0 };
int indices3[] = { 3, 7, 10, 16 }; int indices3[] = { 3, 7, 10, 16 };
struct Row row3 = struct Row row3 = {.nz = 4, .head = 7, .pi_zero = 1.0, .pi = pi3, .indices = indices3};
{
.nz = 4,
.head = 7,
.pi_zero = 1.0,
.pi = pi3,
.indices = indices3
};
struct Row *rows[] = { &row1, &row2, &row3 }; struct Row *rows[] = { &row1, &row2, &row3 };
struct Tableau tableau = struct Tableau tableau = {.ncols = 16, .nrows = 3, .rows = rows, .column_types = column_types};
{
.ncols = 16,
.nrows = 3,
.rows = rows,
.column_types = column_types
};
int indices[1000]; int indices[1000];
int variable_to_ray[1000]; int variable_to_ray[1000];
double ray_scale[1000]; double ray_scale[1000];
struct RayList rays; struct TableauModelMap map = {variable_to_ray, ray_scale, indices, 0};
LFREE_init_ray_list(&rays, 3, 1000);
struct RayMap map = {rays, variable_to_ray, ray_scale, indices, 0}; struct MultiRowModel model;
CG_init_model(&model, 3, 1000);
rval = CG_extract_rays_from_tableau(&tableau, &map); rval = CG_extract_model(&tableau, &map, &model);
abort_if(rval, "CG_extract_rays_from_rows failed"); abort_if(rval, "CG_extract_rays_from_rows failed");
EXPECT_EQ(map.rays.nrays, 4);
EXPECT_EQ(map.nvars, 7); EXPECT_EQ(map.nvars, 7);
EXPECT_DOUBLE_EQ(rays.values[0], 0.0); EXPECT_EQ(model.rays.nrays, 4);
EXPECT_DOUBLE_EQ(rays.values[1], 0.0); EXPECT_DOUBLE_EQ(model.rays.values[0], 0.0);
EXPECT_DOUBLE_EQ(rays.values[2], -1.0); EXPECT_DOUBLE_EQ(model.rays.values[1], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[2], -1.0);
EXPECT_DOUBLE_EQ(rays.values[3], 0.0); EXPECT_DOUBLE_EQ(model.rays.values[3], 0.0);
EXPECT_DOUBLE_EQ(rays.values[4], -1.0); EXPECT_DOUBLE_EQ(model.rays.values[4], -1.0);
EXPECT_DOUBLE_EQ(rays.values[5], 0.0); EXPECT_DOUBLE_EQ(model.rays.values[5], 0.0);
EXPECT_DOUBLE_EQ(rays.values[6], -2.0); EXPECT_DOUBLE_EQ(model.rays.values[6], -2.0);
EXPECT_DOUBLE_EQ(rays.values[7], -2.0); EXPECT_DOUBLE_EQ(model.rays.values[7], -2.0);
EXPECT_DOUBLE_EQ(rays.values[8], 0.0); EXPECT_DOUBLE_EQ(model.rays.values[8], 0.0);
EXPECT_DOUBLE_EQ(rays.values[ 9], 0.0); EXPECT_DOUBLE_EQ(model.rays.values[ 9], 0.0);
EXPECT_DOUBLE_EQ(rays.values[10], -1.0); EXPECT_DOUBLE_EQ(model.rays.values[10], -1.0);
EXPECT_DOUBLE_EQ(rays.values[11], -1.0); EXPECT_DOUBLE_EQ(model.rays.values[11], -1.0);
EXPECT_EQ(indices[0], 3); EXPECT_EQ(indices[0], 3);
EXPECT_EQ(indices[1], 5); EXPECT_EQ(indices[1], 5);