Create struct ConvLFreeSet
This commit is contained in:
@@ -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 MultiRowModel model;
|
||||
rval = CG_malloc_model(&model, nrows, max_nrays + 100);
|
||||
abort_if(rval, "CG_malloc_model failed");
|
||||
|
||||
struct RayMap map;
|
||||
rval = CG_init_ray_map(&map, max_nrays, nrows);
|
||||
struct MultiRowModel model;
|
||||
struct ConvLFreeSet lfree;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
rval = INFINITY_ND_generate_lfree(&model, &lfree);
|
||||
abort_if(rval, "INFINITY_ND_generate_lfree failed");
|
||||
|
||||
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;
|
||||
struct Row cut;
|
||||
|
||||
cut = (struct Row *) malloc(sizeof(struct Row));
|
||||
abort_if(!cut, "could not allocate 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;
|
||||
struct Tableau tableau = {nrows, rows, cg->column_types};
|
||||
struct Row cut;
|
||||
|
||||
cut = (struct Row *) malloc(sizeof(struct Row));
|
||||
abort_if(!cut, "could not allocate 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);
|
||||
|
||||
Reference in New Issue
Block a user