Refactor infinity.c
This commit is contained in:
@@ -86,7 +86,8 @@ CLEANUP:
|
||||
}
|
||||
|
||||
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,
|
||||
struct Row *cut)
|
||||
{
|
||||
@@ -95,6 +96,7 @@ static int create_cut_from_lfree(const struct Tableau *tableau,
|
||||
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_ray_map(&map, max_nrays, tableau->nrows);
|
||||
abort_if(rval, "CG_init_ray_map failed");
|
||||
rval = CG_init_model(&filtered_model, tableau->nrows, max_nrays);
|
||||
abort_if(rval, "CG_init_model failed");
|
||||
|
||||
rval = extract_model_from_tableau(tableau, &model, &map);
|
||||
abort_if(rval, "extract_model_from_tableau failed");
|
||||
rval = CG_init_map(&original_map, max_nrays, tableau->nrows);
|
||||
abort_if(rval, "CG_init_map failed");
|
||||
|
||||
if(model.rays.nrays < 3)
|
||||
rval = extract_models(tableau, &original_model, &filtered_model,
|
||||
&original_map);
|
||||
abort_if(rval, "extract_models failed");
|
||||
|
||||
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};
|
||||
|
||||
rval = CG_extract_rays_from_tableau(&tableau, &map);
|
||||
struct MultiRowModel model;
|
||||
CG_init_model(&model, 3, 1000);
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user