Refactor infinity.c

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

@ -86,15 +86,17 @@ CLEANUP:
}
static int create_cut_from_lfree(const struct Tableau *tableau,
const struct RayMap *map,
const struct ConvLFreeSet *lfree,
struct Row *cut)
const struct TableauModelMap *map,
const struct MultiRowModel *model,
const struct ConvLFreeSet *lfree,
struct Row *cut)
{
int rval = 0;
struct LP lp;
int nvars = map->nvars;
int nrows = tableau->nrows;
struct RayList *rays = &model->rays;
rval = LP_open(&lp);
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++)
{
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 &&
tableau->column_types[map->indices[i]] == MILP_INTEGER)
@ -141,26 +143,28 @@ CLEANUP:
return rval;
}
static int filter_rays(const struct RayMap *map,
const struct Tableau *tableau,
struct MultiRowModel *model)
static int filter_model(const struct MultiRowModel *original_model,
struct MultiRowModel *filtered_model)
{
int rval = 0;
int nrows = tableau->nrows;
struct RayList *rays = &model->rays;
int nrows = original_model->nrows;
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)
{
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;
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;
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,
model->rays.nrays);
filtered_model->rays.nrays);
if(rays->nrays < MAX_N_RAYS) break;
if(filtered_rays->nrays < MAX_N_RAYS) break;
}
CLEANUP:
@ -187,7 +191,7 @@ CLEANUP:
}
static int append_extra_rays(const struct Tableau *tableau,
struct RayList *rays)
struct MultiRowModel *model)
{
int rval = 0;
int nrows = tableau->nrows;
@ -237,10 +241,10 @@ static int append_extra_rays(const struct Tableau *tableau,
double scale;
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");
if(!found) LFREE_push_ray(rays, r);
if(!found) LFREE_push_ray(&model->rays, r);
}
CLEANUP:
@ -299,30 +303,31 @@ CLEANUP:
return rval;
}
static int extract_model_from_tableau(const struct Tableau *tableau,
struct MultiRowModel *model,
struct RayMap *map)
static int extract_models(const struct Tableau *tableau,
struct MultiRowModel *original_model,
struct MultiRowModel *filtered_model,
struct TableauModelMap *original_map)
{
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");
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");
rval = filter_rays(map, tableau, model);
abort_if(rval, "filter_rays failed");
rval = filter_model(original_model, filtered_model);
abort_if(rval, "filter_model failed");
if(ENABLE_LIFTING)
{
rval = append_extra_rays(tableau, &model->rays);
rval = append_extra_rays(tableau, filtered_model);
abort_if(rval, "append_extra_rays failed");
}
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");
}
@ -335,34 +340,39 @@ CLEANUP:
int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
{
int rval = 0;
int max_nrays = CG_total_nz(tableau);
int max_nrays = CG_total_nz(tableau) + 100;
struct RayMap map;
struct MultiRowModel model;
struct MultiRowModel original_model;
struct MultiRowModel filtered_model;
struct TableauModelMap original_map;
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");
rval = CG_init_ray_map(&map, max_nrays, tableau->nrows);
abort_if(rval, "CG_init_ray_map failed");
rval = CG_init_map(&original_map, max_nrays, tableau->nrows);
abort_if(rval, "CG_init_map failed");
rval = extract_model_from_tableau(tableau, &model, &map);
abort_if(rval, "extract_model_from_tableau failed");
rval = extract_models(tableau, &original_model, &filtered_model,
&original_map);
abort_if(rval, "extract_models failed");
if(model.rays.nrays < 3)
if(filtered_model.rays.nrays < 3)
{
rval = ERR_NO_CUT;
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");
if(tableau->nrows == 2)
rval = INFINITY_2D_generate_lfree(&model, &lfree);
rval = INFINITY_2D_generate_lfree(&filtered_model, &lfree);
else
rval = INFINITY_ND_generate_lfree(&model, &lfree);
rval = INFINITY_ND_generate_lfree(&filtered_model, &lfree);
if(rval)
{
@ -372,17 +382,19 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
if(SHOULD_DUMP_CUTS)
{
rval = dump_cut(&model, &lfree);
rval = dump_cut(&filtered_model, &lfree);
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");
CLEANUP:
LFREE_free_conv(&lfree);
CG_free_model(&model);
CG_free_ray_map(&map);
CG_free_model(&original_model);
CG_free_model(&filtered_model);
CG_free_map(&original_map);
return rval;
}

@ -47,9 +47,8 @@ struct Tableau
char *column_types;
};
struct RayMap
struct TableauModelMap
{
struct RayList rays;
int *variable_to_ray;
double *ray_scale;
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_extract_rays_from_tableau(const struct Tableau *tableau,
struct RayMap *map);
int CG_extract_model(const struct Tableau *tableau,
struct TableauModelMap *map,
struct MultiRowModel *model);
int CG_boost_variable(int var,
double factor,
@ -102,9 +102,9 @@ int CG_find_ray(const struct RayList *rays,
double *scale,
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);

@ -440,8 +440,9 @@ CLEANUP:
return 0;
}
int CG_extract_rays_from_tableau(const struct Tableau *tableau,
struct RayMap *map)
int CG_extract_model(const struct Tableau *tableau,
struct TableauModelMap *map,
struct MultiRowModel *model)
{
int rval = 0;
@ -463,7 +464,7 @@ int CG_extract_rays_from_tableau(const struct Tableau *tableau,
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;
@ -501,19 +502,19 @@ int CG_extract_rays_from_tableau(const struct Tableau *tableau,
for (int j = 0; j < nrows; 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");
if (!found)
{
log_verbose(" ray is new\n");
scale = 1.0;
ray_index = map->rays.nrays++;
ray_index = model->rays.nrays++;
}
else
{
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++)
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:;
}
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;
for (int k = 0; k < map->nvars; k++)
@ -1045,7 +1046,7 @@ CLEANUP:
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;
@ -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->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:
return rval;
}
void CG_free_ray_map(struct RayMap *map)
void CG_free_map(struct TableauModelMap *map)
{
if(!map) return;
free(map->variable_to_ray);
free(map->indices);
free(map->ray_scale);
LFREE_free_ray_list(&map->rays);
}
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};
double pi1[] = { 1.0, 1.0, 1.0, 2.0, 1.0 };
int indices1[] = { 1, 7, 8, 12, 14 };
struct Row row1 =
{
.nz = 5,
.head = 1,
.pi_zero = 1.0,
.pi = pi1,
.indices = indices1
};
struct Row row1 = {.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 };
int indices2[] = { 5, 8, 12, 13, 14, 16 };
struct Row row2 =
{
.nz = 6,
.head = 13,
.pi_zero = 1.0,
.pi = pi2,
.indices = indices2
};
struct Row row2 = {.nz = 6, .head = 13, .pi_zero = 1.0, .pi = pi2, .indices = indices2};
double pi3[] = { 1.0, 1.0, 1.0, 1.0 };
int indices3[] = { 3, 7, 10, 16 };
struct Row row3 =
{
.nz = 4,
.head = 7,
.pi_zero = 1.0,
.pi = pi3,
.indices = indices3
};
struct Row row3 = {.nz = 4, .head = 7, .pi_zero = 1.0, .pi = pi3, .indices = indices3};
struct Row *rows[] = { &row1, &row2, &row3 };
struct Tableau tableau =
{
.ncols = 16,
.nrows = 3,
.rows = rows,
.column_types = column_types
};
struct Tableau tableau = {.ncols = 16, .nrows = 3, .rows = rows, .column_types = column_types};
int indices[1000];
int variable_to_ray[1000];
double ray_scale[1000];
struct RayList rays;
LFREE_init_ray_list(&rays, 3, 1000);
struct RayMap map = {rays, variable_to_ray, ray_scale, indices, 0};
struct TableauModelMap map = {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");
EXPECT_EQ(map.rays.nrays, 4);
EXPECT_EQ(map.nvars, 7);
EXPECT_DOUBLE_EQ(rays.values[0], 0.0);
EXPECT_DOUBLE_EQ(rays.values[1], 0.0);
EXPECT_DOUBLE_EQ(rays.values[2], -1.0);
EXPECT_EQ(model.rays.nrays, 4);
EXPECT_DOUBLE_EQ(model.rays.values[0], 0.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(rays.values[4], -1.0);
EXPECT_DOUBLE_EQ(rays.values[5], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[3], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[4], -1.0);
EXPECT_DOUBLE_EQ(model.rays.values[5], 0.0);
EXPECT_DOUBLE_EQ(rays.values[6], -2.0);
EXPECT_DOUBLE_EQ(rays.values[7], -2.0);
EXPECT_DOUBLE_EQ(rays.values[8], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[6], -2.0);
EXPECT_DOUBLE_EQ(model.rays.values[7], -2.0);
EXPECT_DOUBLE_EQ(model.rays.values[8], 0.0);
EXPECT_DOUBLE_EQ(rays.values[ 9], 0.0);
EXPECT_DOUBLE_EQ(rays.values[10], -1.0);
EXPECT_DOUBLE_EQ(rays.values[11], -1.0);
EXPECT_DOUBLE_EQ(model.rays.values[ 9], 0.0);
EXPECT_DOUBLE_EQ(model.rays.values[10], -1.0);
EXPECT_DOUBLE_EQ(model.rays.values[11], -1.0);
EXPECT_EQ(indices[0], 3);
EXPECT_EQ(indices[1], 5);