Create struct ConvLFreeSet

selection
Alinson S. Xavier 9 years ago
parent 3ded5cd96f
commit 1e45817d76

@ -16,12 +16,6 @@
#ifndef MULTIROW_GREEDY_ND_H
#define MULTIROW_GREEDY_ND_H
int GREEDY_ND_next_lattice_point(int dim,
const double *lb,
const double *ub,
double *p,
int *finished);
int GREEDY_create_psi_lp(const int nrows,
const int nrays,
const double *f,
@ -49,16 +43,8 @@ int GREEDY_ND_pi(const int nrows,
struct LP *lp,
double *value);
int GREEDY_ND_generate_cut(const struct MultiRowModel *model, double *beta);
int GREEDY_ND_bound(int nrows,
int nrays,
const double *f,
const double *rays,
const double *x,
const double *beta,
double *epsilon,
int *tx);
int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
struct ConvLFreeSet *lfree);
int GREEDY_ND_cone_bound(int nrows,
int nrays,

@ -19,6 +19,7 @@
#include <multirow/cg.h>
int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds);
int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
struct ConvLFreeSet *lfree);
#endif //MULTIROW_INFINITY_2D_H

File diff suppressed because it is too large Load Diff

@ -524,29 +524,29 @@ CLEANUP:
#ifndef TEST_SOURCE
int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
int INFINITY_2D_generate_lfree(const struct MultiRowModel *model,
struct ConvLFreeSet *lfree)
{
log_verbose("INFINITY_2D_generate_cut\n");
int rval = 0;
int count = 0;
int nrays = model->rays.nrays;
double *f = model->f;
double *scale = 0;
double *rays = 0;
double lb[2], ub[2];
for (int i = 0; i < nrays; i++)
bounds[i] = GREEDY_BIG_E;
double *f = lfree->f;
double *beta = lfree->beta;
double *rays = lfree->rays.values;
lfree->nrows = 2;
lfree->rays.nrays = nrays;
memcpy(f, model->f, 2 * sizeof(double));
memcpy(rays, model->rays.values, 2 * nrays * sizeof(double));
for (int i = 0; i < nrays; i++) beta[i] = GREEDY_BIG_E;
scale = (double*) malloc(nrays * sizeof(double));
rays = (double*) malloc(2 * nrays * sizeof(double));
abort_if(!rays, "could not allocate rays");
abort_if(!scale, "could not allocate scale");
memcpy(rays, model->rays.values, 2 * nrays * sizeof(double));
rval = scale_to_chull(rays, nrays, scale);
abort_if(rval, "scale_to_chull failed");
@ -558,7 +558,7 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
abort_if(count++ > 2 * nrays, "infinite loop");
rval = get_bounding_box(2, nrays, rays, bounds, GREEDY_BIG_E, lb, ub);
rval = get_bounding_box(2, nrays, rays, beta, GREEDY_BIG_E, lb, ub);
abort_if(rval, "get_bounding_box failed");
log_verbose(" box=[%.2lf %.2lf] [%.2lf %.2lf]\n", lb[0], ub[0], lb[1], ub[1]);
@ -581,7 +581,7 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
log_verbose(" p=%.2lf %.2lf\n", p[0], p[1]);
rval = bound(rays, bounds, nrays, f, p, &epsilon, v1, v2, &i1, &i2);
rval = bound(rays, beta, nrays, f, p, &epsilon, v1, v2, &i1, &i2);
abort_if(rval, "bound failed");
log_verbose(" epsilon=%.2lf\n", epsilon);
@ -590,7 +590,7 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
{
log_verbose(" found smaller epsilon: %.8lf\n", epsilon);
rval = get_bounding_box(2, nrays, rays, bounds, epsilon, lb, ub);
rval = get_bounding_box(2, nrays, rays, beta, epsilon, lb, ub);
abort_if(rval, "get_bounding_box failed");
log_verbose(" p=%.2lf %.2lf\n", p[0], p[1]);
@ -625,11 +625,11 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
break;
}
log_verbose(" updating bounds\n");
log_verbose(" updating beta\n");
if(isinf(best_v1[0]))
{
bounds[best_i1] = best_epsilon;
log_verbose(" bounds[%d]=%.8lf (exact)\n", best_i1, best_epsilon);
beta[best_i1] = best_epsilon;
log_verbose(" beta[%d]=%.8lf (exact)\n", best_i1, best_epsilon);
}
else
{
@ -646,15 +646,15 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
if(!DOUBLE_geq(lambda, 0)) continue;
bounds[i] = fmin(bounds[i], lambda);
log_verbose(" bounds[%d]=%.8lf\n", i, bounds[i]);
beta[i] = fmin(beta[i], lambda);
log_verbose(" beta[%d]=%.8lf\n", i, beta[i]);
}
}
//if(count > 0)
//{
// for (int i = 0; i < nrays; i++)
// bounds[i] = fmin(bounds[i], best_epsilon);
// beta[i] = fmin(beta[i], best_epsilon);
// break;
//}
@ -663,7 +663,7 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
for (int k = 0; k < nrays; k++)
{
if(bounds[k] < 100) continue;
if(beta[k] < 100) continue;
is_split = 1;
double *split_direction = &rays[2 * k];
@ -700,13 +700,13 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
{
const double *r = &rays[2 * i];
lhs = (f[0] + r[0] * bounds[i]) * pi[0];
lhs += (f[1] + r[1] * bounds[i]) * pi[1];
lhs = (f[0] + r[0] * beta[i]) * pi[0];
lhs += (f[1] + r[1] * beta[i]) * pi[1];
if (!(DOUBLE_leq(pi_zero, lhs) && DOUBLE_leq(lhs, pi_zero+1)))
{
log_verbose(" point %.4lf %.4lf falls outside of the split\n",
f[0] + r[0]*bounds[i], f[1] + r[1] * bounds[i]);
f[0] + r[0]*beta[i], f[1] + r[1] * beta[i]);
is_split = 0;
}
}
@ -722,11 +722,10 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
}
for(int i=0; i<nrays; i++)
bounds[i] *= scale[i];
beta[i] *= scale[i];
CLEANUP:
if(scale) free(scale);
if(rays) free(rays);
return rval;
}

@ -85,30 +85,25 @@ CLEANUP:
return rval;
}
static int create_cut(const struct Tableau *tableau,
const struct RayMap *map,
const struct MultiRowModel *model,
const double *beta,
struct Row *cut)
static int create_cut_from_lfree(const struct Tableau *tableau,
const struct RayMap *map,
const struct ConvLFreeSet *lfree,
struct Row *cut)
{
int rval = 0;
struct LP lp;
int nvars = map->nvars;
int nrows = tableau->nrows;
cut->nz = nvars;
cut->pi = (double *) malloc(nvars * sizeof(double));
cut->indices = (int *) malloc(nvars * sizeof(int));
abort_if(!cut->pi, "could not allocate cut->pi");
abort_if(!cut->indices, "could not allocate cut->indices");
struct LP lp;
rval = LP_open(&lp);
abort_if(rval, "LP_open failed");
rval = GREEDY_create_psi_lp(nrows, model->rays.nrays, model->f,
model->rays.values, beta, &lp);
rval = GREEDY_create_psi_lp(nrows, lfree->rays.nrays, lfree->f,
lfree->rays.values, lfree->beta, &lp);
abort_if(rval, "create_psi_lp failed");
cut->nz = nvars;
for(int i = 0; i < nvars; i++)
{
double value;
@ -117,15 +112,15 @@ static int create_cut(const struct Tableau *tableau,
if(ENABLE_LIFTING &&
tableau->column_types[map->indices[i]] == MILP_INTEGER)
{
rval = GREEDY_ND_pi(nrows, model->rays.nrays, model->f,
model->rays.values, beta, q, map->ray_scale[i], &lp,
rval = GREEDY_ND_pi(nrows, lfree->rays.nrays, lfree->f,
lfree->rays.values, lfree->beta, q, map->ray_scale[i], &lp,
&value);
abort_if(rval, "GREEDY_ND_pi failed");
}
else
{
rval = GREEDY_ND_psi(nrows, model->rays.nrays, model->f,
model->rays.values, beta, q, map->ray_scale[i], &lp,
rval = GREEDY_ND_psi(nrows, lfree->rays.nrays, lfree->f,
lfree->rays.values, lfree->beta, q, map->ray_scale[i], &lp,
&value);
abort_if(rval, "GREEDY_ND_psi failed");
}
@ -146,7 +141,7 @@ CLEANUP:
return rval;
}
static int select_rays(const struct RayMap *map,
static int filter_rays(const struct RayMap *map,
const struct Tableau *tableau,
struct MultiRowModel *model)
{
@ -166,8 +161,8 @@ static int select_rays(const struct RayMap *map,
for(int j = 0; j < (rays->nrays); j++)
{
double *q = LFREE_get_ray(&map->rays, j);
double norm = 0;
double norm = 0;
for(int k = 0; k < nrows; k++)
norm += fabs(r[k] - q[k]);
@ -182,7 +177,7 @@ static int select_rays(const struct RayMap *map,
}
log_debug(" norm_cutoff=%8.2lf nrays=%8d\n", norm_cutoff,
model->nrays);
model->rays.nrays);
if(rays->nrays < MAX_N_RAYS) break;
}
@ -253,7 +248,7 @@ CLEANUP:
}
static int write_sage_file(const struct MultiRowModel *model,
const double *beta,
const struct ConvLFreeSet *lfree,
const char *filename)
{
int rval = 0;
@ -280,7 +275,7 @@ static int write_sage_file(const struct MultiRowModel *model,
fprintf(fsage, "pi=vector([\n");
for(int k = 0; k < model->rays.nrays; k++)
fprintf(fsage, " %.12lf,\n", 1 / beta[k]);
fprintf(fsage, " %.12lf,\n", 1 / lfree->beta[k]);
fprintf(fsage, "])\n");
CLEANUP:
@ -288,7 +283,8 @@ CLEANUP:
return rval;
}
static int dump_cut(const struct MultiRowModel *model, const double *beta)
static int dump_cut(const struct MultiRowModel *model,
const struct ConvLFreeSet *lfree)
{
int rval = 0;
@ -296,7 +292,7 @@ static int dump_cut(const struct MultiRowModel *model, const double *beta)
sprintf(filename, "cut-%03d.sage", DUMP_CUT_N++);
time_printf("Writing %s...\n", filename);
rval = write_sage_file(model, beta, filename);
rval = write_sage_file(model, lfree, filename);
abort_if(rval, "write_sage_file failed");
CLEANUP:
@ -315,8 +311,8 @@ static int extract_model_from_tableau(const struct Tableau *tableau,
rval = CG_extract_rays_from_tableau(tableau, map);
abort_if(rval, "CG_extract_rays_from_rows failed");
rval = select_rays(map, tableau, model);
abort_if(rval, "select_rays failed");
rval = filter_rays(map, tableau, model);
abort_if(rval, "filter_rays failed");
if(ENABLE_LIFTING)
{
@ -339,16 +335,16 @@ CLEANUP:
int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
{
int rval = 0;
int nrows = tableau->nrows;
int max_nrays = CG_total_nz(tableau);
double *beta = 0;
struct RayMap map;
struct MultiRowModel model;
rval = CG_malloc_model(&model, nrows, max_nrays + 100);
abort_if(rval, "CG_malloc_model failed");
struct ConvLFreeSet lfree;
struct RayMap map;
rval = CG_init_ray_map(&map, max_nrays, nrows);
rval = CG_init_model(&model, tableau->nrows, max_nrays + 100);
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 = extract_model_from_tableau(tableau, &model, &map);
@ -357,16 +353,16 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
if(model.rays.nrays < 3)
{
rval = ERR_NO_CUT;
cut->pi = 0;
cut->indices = 0;
goto CLEANUP;
}
beta = (double *) malloc(model.rays.nrays * sizeof(double));
abort_if(!beta, "could not allocate beta");
rval = LFREE_init_conv(&lfree, tableau->nrows, model.rays.nrays);
abort_if(rval, "LFREE_init_conv failed");
if(nrows == 2) rval = INFINITY_2D_generate_cut(&model, beta);
else rval = GREEDY_ND_generate_cut(&model, beta);
if(tableau->nrows == 2)
rval = INFINITY_2D_generate_lfree(&model, &lfree);
else
rval = INFINITY_ND_generate_lfree(&model, &lfree);
if(rval)
{
@ -376,15 +372,15 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
if(SHOULD_DUMP_CUTS)
{
rval = dump_cut(&model, beta);
rval = dump_cut(&model, &lfree);
abort_if(rval, "dump_cut failed");
}
rval = create_cut(tableau, &map, &model, beta, cut);
abort_if(rval, "create_cut failed");
rval = create_cut_from_lfree(tableau, &map, &lfree, cut);
abort_if(rval, "create_cut_from_lfree failed");
CLEANUP:
if(beta) free(beta);
LFREE_free_conv(&lfree);
CG_free_model(&model);
CG_free_ray_map(&map);
return rval;

@ -25,6 +25,7 @@ extern "C" {
#include <multirow/lfree2d.h>
#include <multirow/cg.h>
#include <infinity/greedy-nd.h>
#include "../src/greedy-nd.c"
}
int ENABLE_LIFTING = 0;
@ -242,8 +243,8 @@ TEST(GreedyNDTest, bound_test_1)
double epsilon;
int tx[6];
rval = GREEDY_ND_bound(2, 6, f, rays, x, beta1, &epsilon, tx);
abort_if(rval, "GREEDY_ND_bound failed");
rval = bound(2, 6, f, rays, x, beta1, &epsilon, tx);
abort_if(rval, "bound failed");
EXPECT_NEAR(epsilon, 0.5, 1e-6);
EXPECT_TRUE(tx[0]);
EXPECT_FALSE(tx[1]);
@ -252,8 +253,8 @@ TEST(GreedyNDTest, bound_test_1)
EXPECT_FALSE(tx[4]);
EXPECT_FALSE(tx[5]);
rval = GREEDY_ND_bound(2, 6, f, rays, x, beta2, &epsilon, tx);
abort_if(rval, "GREEDY_ND_bound failed");
rval = bound(2, 6, f, rays, x, beta2, &epsilon, tx);
abort_if(rval, "bound failed");
EXPECT_NEAR(epsilon, 1.0, 1e-6);
EXPECT_TRUE(tx[0]);
EXPECT_FALSE(tx[1]);
@ -262,8 +263,8 @@ TEST(GreedyNDTest, bound_test_1)
EXPECT_TRUE(tx[4]);
EXPECT_TRUE(tx[5]);
rval = GREEDY_ND_bound(2, 6, f, rays, x, beta3, &epsilon, tx);
abort_if(rval, "GREEDY_ND_bound failed");
rval = bound(2, 6, f, rays, x, beta3, &epsilon, tx);
abort_if(rval, "bound failed");
EXPECT_EQ(epsilon, INFINITY);
EXPECT_FALSE(tx[0]);
EXPECT_FALSE(tx[1]);
@ -371,10 +372,9 @@ TEST(GreedyNDTest, generate_cut_test_1)
double r3[] = { -1.0, 1.0 };
double r4[] = { 0.0, 1.0 };
double r5[] = { 1.0, 0.0 };
double beta[6];
struct MultiRowModel model;
CG_malloc_model(&model, 2, 6);
CG_init_model(&model, 2, 6);
LFREE_push_ray(&model.rays, r0);
LFREE_push_ray(&model.rays, r1);
LFREE_push_ray(&model.rays, r2);
@ -384,15 +384,18 @@ TEST(GreedyNDTest, generate_cut_test_1)
model.f[0] = 0.5;
model.f[1] = 0.5;
rval = GREEDY_ND_generate_cut(&model, beta);
abort_if(rval, "GREEDY_ND_generate_cut failed");
struct ConvLFreeSet lfree;
LFREE_init_conv(&lfree, 2, 6);
EXPECT_NEAR(beta[0], 0.5, 1e-6);
EXPECT_NEAR(beta[1], 0.5, 1e-6);
EXPECT_NEAR(beta[2], 0.5, 1e-6);
EXPECT_NEAR(beta[3], 0.5, 1e-6);
EXPECT_NEAR(beta[4], 1.0, 1e-6);
EXPECT_NEAR(beta[5], 1.0, 1e-6);
rval = INFINITY_ND_generate_lfree(&model, &lfree);
abort_if(rval, "INFINITY_ND_generate_lfree failed");
EXPECT_NEAR(lfree.beta[0], 0.5, 1e-6);
EXPECT_NEAR(lfree.beta[1], 0.5, 1e-6);
EXPECT_NEAR(lfree.beta[2], 0.5, 1e-6);
EXPECT_NEAR(lfree.beta[3], 0.5, 1e-6);
EXPECT_NEAR(lfree.beta[4], 1.0, 1e-6);
EXPECT_NEAR(lfree.beta[5], 1.0, 1e-6);
CLEANUP:
if(rval) FAIL();
@ -408,10 +411,9 @@ TEST(GreedyNDTest, generate_cut_test_2)
double r3[] = { 0.0, -1.0, 0.0 };
double r4[] = { 0.0, 0.0, 1.0 };
double r5[] = { 0.0, 0.0, -1.0 };
double beta[6];
struct MultiRowModel model;
CG_malloc_model(&model, 3, 6);
CG_init_model(&model, 3, 6);
LFREE_push_ray(&model.rays, r0);
LFREE_push_ray(&model.rays, r1);
LFREE_push_ray(&model.rays, r2);
@ -422,15 +424,18 @@ TEST(GreedyNDTest, generate_cut_test_2)
model.f[1] = 0.75;
model.f[2] = 0.75;
rval = GREEDY_ND_generate_cut(&model, beta);
abort_if(rval, "GREEDY_ND_generate_cut failed");
struct ConvLFreeSet lfree;
LFREE_init_conv(&lfree, 3, 6);
rval = INFINITY_ND_generate_lfree(&model, &lfree);
abort_if(rval, "INFINITY_ND_generate_lfree failed");
EXPECT_NEAR(beta[0], 0.75, 1e-6);
EXPECT_NEAR(beta[1], 2.25, 1e-6);
EXPECT_NEAR(beta[2], 0.75, 1e-6);
EXPECT_NEAR(beta[3], 2.25, 1e-6);
EXPECT_NEAR(beta[4], 0.75, 1e-6);
EXPECT_NEAR(beta[5], 2.25, 1e-6);
EXPECT_NEAR(lfree.beta[0], 0.75, 1e-6);
EXPECT_NEAR(lfree.beta[1], 2.25, 1e-6);
EXPECT_NEAR(lfree.beta[2], 0.75, 1e-6);
EXPECT_NEAR(lfree.beta[3], 2.25, 1e-6);
EXPECT_NEAR(lfree.beta[4], 0.75, 1e-6);
EXPECT_NEAR(lfree.beta[5], 2.25, 1e-6);
CLEANUP:
CG_free_model(&model);

@ -30,7 +30,6 @@ extern "C" {
TEST(Infinity2DTest, test_generate_cut_1)
{
int rval = 0;
double bounds[100];
double f[] = {1 / 4.0, 3 / 4.0};
double rays[] = {
@ -43,14 +42,17 @@ TEST(Infinity2DTest, test_generate_cut_1)
const struct MultiRowModel model = {f , rays, 5, 2};
rval = INFINITY_2D_generate_cut(&model, bounds);
abort_if(rval, "INFINITY_2D_generate_cut failed");
struct ConvLFreeSet lfree;
LFREE_init_conv(&lfree, 2, 5);
EXPECT_NEAR(23 / 50.0, bounds[0], BOUNDS_EPSILON);
EXPECT_NEAR(23 / 42.0, bounds[1], BOUNDS_EPSILON);
EXPECT_NEAR(9 / 11.0, bounds[2], BOUNDS_EPSILON);
EXPECT_NEAR(9 / 11.0, bounds[3], BOUNDS_EPSILON);
EXPECT_NEAR(23 / 50.0, bounds[4], BOUNDS_EPSILON);
rval = INFINITY_2D_generate_lfree(&model, &lfree);
abort_if(rval, "INFINITY_2D_generate_lfree failed");
EXPECT_NEAR(23 / 50.0, lfree.beta[0], BOUNDS_EPSILON);
EXPECT_NEAR(23 / 42.0, lfree.beta[1], BOUNDS_EPSILON);
EXPECT_NEAR(9 / 11.0, lfree.beta[2], BOUNDS_EPSILON);
EXPECT_NEAR(9 / 11.0, lfree.beta[3], BOUNDS_EPSILON);
EXPECT_NEAR(23 / 50.0, lfree.beta[4], BOUNDS_EPSILON);
CLEANUP:
if (rval) FAIL();
@ -59,7 +61,6 @@ TEST(Infinity2DTest, test_generate_cut_1)
TEST(Infinity2DTest, test_generate_cut_2)
{
int rval = 0;
double bounds[100];
double f[] = {1 / 2.0, 1 / 2.0};
double rays[] = {
-1.0, -1.0,
@ -70,15 +71,17 @@ TEST(Infinity2DTest, test_generate_cut_2)
};
const struct MultiRowModel model = {f , rays, 5, 2};
struct ConvLFreeSet lfree;
LFREE_init_conv(&lfree, 2, 5);
rval = INFINITY_2D_generate_cut(&model, bounds);
abort_if(rval, "INFINITY_2D_generate_cut failed");
rval = INFINITY_2D_generate_lfree(&model, &lfree);
abort_if(rval, "INFINITY_2D_generate_lfree failed");
EXPECT_NEAR(0.5, bounds[0], BOUNDS_EPSILON);
EXPECT_NEAR(0.5, bounds[1], BOUNDS_EPSILON);
EXPECT_NEAR(0.5, bounds[2], BOUNDS_EPSILON);
EXPECT_EQ(GREEDY_BIG_E, bounds[3]);
EXPECT_NEAR(0.5, bounds[4], BOUNDS_EPSILON);
EXPECT_NEAR(0.5, lfree.beta[0], BOUNDS_EPSILON);
EXPECT_NEAR(0.5, lfree.beta[1], BOUNDS_EPSILON);
EXPECT_NEAR(0.5, lfree.beta[2], BOUNDS_EPSILON);
EXPECT_EQ(GREEDY_BIG_E, lfree.beta[3]);
EXPECT_NEAR(0.5, lfree.beta[4], BOUNDS_EPSILON);
CLEANUP:
if (rval) FAIL();
@ -87,18 +90,19 @@ TEST(Infinity2DTest, test_generate_cut_2)
TEST(Infinity2DTest, test_generate_cut_3)
{
int rval = 0;
double bounds[100];
double f[] = {5 / 22.0, 0.0};
double rays[] = {-1 / 22.0, 0.0, 0.0, 1 / 18.0, 1 / 22.0, 0.0};
const struct MultiRowModel model = {f , rays, 3, 2};
struct ConvLFreeSet lfree;
LFREE_init_conv(&lfree, 2, 5);
rval = INFINITY_2D_generate_cut(&model, bounds);
abort_if(rval, "INFINITY_2D_generate_cut failed");
rval = INFINITY_2D_generate_lfree(&model, &lfree);
abort_if(rval, "INFINITY_2D_generate_lfree failed");
EXPECT_NEAR(5.0, bounds[0], BOUNDS_EPSILON);
EXPECT_NEAR(17.0, bounds[2], BOUNDS_EPSILON);
EXPECT_EQ(GREEDY_BIG_E, bounds[1]);
EXPECT_NEAR(5.0, lfree.beta[0], BOUNDS_EPSILON);
EXPECT_NEAR(17.0, lfree.beta[2], BOUNDS_EPSILON);
EXPECT_EQ(GREEDY_BIG_E, lfree.beta[1]);
CLEANUP:
if (rval) FAIL();
@ -277,8 +281,8 @@ TEST(Infinity2DTest, find_containing_cone_test_3)
// double rays[] = {0, -1 / 38.0, -1 / 22.0, -1 / 38.0, 0, 1 / 38.0, -1 / 22.0,
// 0, 1 / 22.0, 0, 1 / 22.0, 1 / 38.0};
//
// rval = INFINITY_2D_generate_cut(rays, 6, f, bounds);
// abort_if(rval, "INFINITY_2D_generate_cut failed");
// rval = INFINITY_2D_generate_lfree(rays, 6, f, bounds);
// abort_if(rval, "INFINITY_2D_generate_lfree failed");
//
// EXPECT_NEAR(20.0, bounds[0], BOUNDS_EPSILON);
// EXPECT_NEAR(20.0, bounds[1], BOUNDS_EPSILON);
@ -303,8 +307,8 @@ TEST(Infinity2DTest, find_containing_cone_test_3)
// 0.04545454545454545581, 0.00000000000000000000,
// 0.04545454545454545581, 0.02631578947368420907};
//
// rval = INFINITY_2D_generate_cut(rays, 6, f, bounds);
// abort_if(rval, "INFINITY_2D_generate_cut failed");
// rval = INFINITY_2D_generate_lfree(rays, 6, f, bounds);
// abort_if(rval, "INFINITY_2D_generate_lfree failed");
//
// EXPECT_NEAR(20.0, bounds[0], BOUNDS_EPSILON);
// EXPECT_NEAR(20.0, bounds[1], BOUNDS_EPSILON);

@ -107,7 +107,7 @@ void CG_free_ray_map(struct RayMap *map);
int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f);
int CG_malloc_model(struct MultiRowModel *model, int nrows, int rays_capacity);
int CG_init_model(struct MultiRowModel *model, int nrows, int rays_capacity);
void CG_free_model(struct MultiRowModel *model);

@ -40,6 +40,15 @@ struct RayList
int dim;
};
struct ConvLFreeSet
{
double *f;
struct RayList rays;
int nrows;
double *beta;
};
int LFREE_2D_init(struct LFreeSet2D *set,
int n_vertices,
int n_lattice_points,
@ -69,4 +78,8 @@ void LFREE_free_ray_list(struct RayList *list);
int LFREE_init_ray_list(struct RayList *list, int dim, int capacity);
int LFREE_init_conv(struct ConvLFreeSet *lfree, int dim, int max_nrays);
void LFREE_free_conv(struct ConvLFreeSet *lfree);
#endif //LFREE_2D_H

@ -31,7 +31,7 @@
* LOG_LEVEL_WARNING
* LOG_LEVEL_ERROR
*/
#define LOG_LEVEL LOG_LEVEL_INFO
#define LOG_LEVEL LOG_LEVEL_DEBUG
/*
* Maximum bounding-box size for naive algorithm
@ -48,7 +48,7 @@
*/
#define N_RAYS 100
#define ONLY_CUT -1
#define ONLY_CUT 242
/*
* Time limit for the computation (user time, in seconds).

@ -575,7 +575,10 @@ void CG_free(struct CG *cg)
if (cg->tableau_rows)
{
for (int i = 0; i < cg->nrows; i++)
{
LP_free_row(cg->tableau_rows[i]);
free(cg->tableau_rows[i]);
}
free(cg->tableau_rows);
}
@ -598,19 +601,16 @@ int CG_add_single_row_cuts(struct CG *cg, SingleRowGeneratorCallback generate)
log_verbose("Generating cut %d...\n", i);
struct Row *cut = 0;
cut = (struct Row *) malloc(sizeof(struct Row));
abort_if(!cut, "could not allocate cut");
struct Row cut;
rval = generate(row, cg->column_types, cut);
rval = generate(row, cg->column_types, &cut);
abort_if(rval, "generate failed");
int ignored;
rval = add_cut(cg, cut, &ignored);
rval = add_cut(cg, &cut, &ignored);
abort_if(rval, "add_cut failed");
LP_free_row(cut);
LP_free_row(&cut);
}
CLEANUP:
@ -856,23 +856,24 @@ int CG_add_multirow_cuts(struct CG *cg,
progress_increment();
}
struct Row *cut = 0;
cut = (struct Row *) malloc(sizeof(struct Row));
abort_if(!cut, "could not allocate cut");
struct Tableau tableau = {nrows, rows, cg->column_types};
struct Row cut;
cut->pi = 0;
cut->indices = 0;
int max_nz = CG_total_nz(&tableau);
cut.pi = (double *) malloc(max_nz * sizeof(double));
cut.indices = (int *) malloc(max_nz * sizeof(int));
abort_if(!cut.pi, "could not allocate cut.pi");
abort_if(!cut.indices, "could not allocate cut.indices");
double initial_time = get_user_time();
struct Tableau tableau = {nrows, rows, cg->column_types};
rval = generate(&tableau, cut);
SHOULD_DUMP_CUTS = 1;
rval = generate(&tableau, &cut);
if (rval == ERR_NO_CUT)
{
rval = 0;
log_verbose("combination does not yield cut\n");
LP_free_row(cut);
LP_free_row(&cut);
goto NEXT_COMBINATION;
}
else abort_iff(rval, "generate failed (cut %d)", count);
@ -881,36 +882,36 @@ int CG_add_multirow_cuts(struct CG *cg,
log_debug(" generate: %.2lf ms\n", elapsed_time * 1000);
double dynamism;
rval = cut_dynamism(cut, &dynamism);
rval = cut_dynamism(&cut, &dynamism);
abort_if(rval, "cut_dynamism failed");
if (dynamism > MAX_CUT_DYNAMISM)
{
log_debug("Discarding cut (dynamism=%.2lf)\n", dynamism);
LP_free_row(cut);
LP_free_row(&cut);
goto NEXT_COMBINATION;
}
int ignored;
rval = add_cut(cg, cut, &ignored);
rval = add_cut(cg, &cut, &ignored);
if (rval)
{
log_warn("invalid cut skipped (cut %d)\n", count);
rval = 0;
LP_free_row(cut);
LP_free_row(&cut);
goto NEXT_COMBINATION;
}
if_debug_level if (!ignored)
{
SHOULD_DUMP_CUTS = 1;
generate(&tableau, cut);
SHOULD_DUMP_CUTS = 0;
}
{
SHOULD_DUMP_CUTS = 1;
generate(&tableau, &cut);
SHOULD_DUMP_CUTS = 0;
}
LP_free_row(cut);
LP_free_row(&cut);
}
NEXT_COMBINATION:
@ -1019,7 +1020,7 @@ int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f)
return 0;
}
int CG_malloc_model(struct MultiRowModel *model, int nrows, int rays_capacity)
int CG_init_model(struct MultiRowModel *model, int nrows, int rays_capacity)
{
int rval = 0;
model->nrows = nrows;

@ -540,4 +540,29 @@ void LFREE_push_ray(struct RayList *list, const double *ray)
double *dest = LFREE_get_ray(list, list->nrays);
memcpy(dest, ray, list->dim * sizeof(double));
list->nrays++;
}
int LFREE_init_conv(struct ConvLFreeSet *lfree, int dim, int max_nrays)
{
int rval = 0;
lfree->nrows = dim;
lfree->f = (double*) malloc(dim * sizeof(double));
lfree->beta = (double*) malloc(max_nrays * sizeof(double));
abort_if(!lfree->f, "could not allocate lfree->f");
abort_if(!lfree->beta, "could not allocate lfree->beta");
rval = LFREE_init_ray_list(&lfree->rays, dim, max_nrays);
abort_if(rval, "LFREE_init_ray_list failed");
CLEANUP:
return rval;
}
void LFREE_free_conv(struct ConvLFreeSet *lfree)
{
if(!lfree) return;
free(lfree->f);
free(lfree->beta);
LFREE_free_ray_list(&lfree->rays);
}

@ -80,10 +80,8 @@ void LP_free(struct LP *lp)
void LP_free_row(struct Row *row)
{
if (!row) return;
if (row->pi) free(row->pi);
if (row->indices) free(row->indices);
free(row);
}
int LP_add_rows(struct LP *lp,

@ -26,6 +26,7 @@ extern "C" {
int BOOST_VAR = -1;
double BOOST_FACTOR = 1.0;
int SHOULD_DUMP_CUTS = 0;
TEST(CGTest, next_combination_test_1)
{
@ -157,7 +158,7 @@ TEST(CGTest, extract_rays_from_rows_test)
rval = CG_extract_rays_from_tableau(&tableau, &map);
abort_if(rval, "CG_extract_rays_from_rows failed");
EXPECT_EQ(rays.nrays, 4);
EXPECT_EQ(map.rays.nrays, 4);
EXPECT_EQ(map.nvars, 7);
EXPECT_DOUBLE_EQ(rays.values[0], 0.0);