Create struct ConvLFreeSet
This commit is contained in:
@@ -16,12 +16,6 @@
|
|||||||
#ifndef MULTIROW_GREEDY_ND_H
|
#ifndef MULTIROW_GREEDY_ND_H
|
||||||
#define 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,
|
int GREEDY_create_psi_lp(const int nrows,
|
||||||
const int nrays,
|
const int nrays,
|
||||||
const double *f,
|
const double *f,
|
||||||
@@ -49,16 +43,8 @@ int GREEDY_ND_pi(const int nrows,
|
|||||||
struct LP *lp,
|
struct LP *lp,
|
||||||
double *value);
|
double *value);
|
||||||
|
|
||||||
int GREEDY_ND_generate_cut(const struct MultiRowModel *model, double *beta);
|
int INFINITY_ND_generate_lfree(const struct MultiRowModel *model,
|
||||||
|
struct ConvLFreeSet *lfree);
|
||||||
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 GREEDY_ND_cone_bound(int nrows,
|
int GREEDY_ND_cone_bound(int nrows,
|
||||||
int nrays,
|
int nrays,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <multirow/cg.h>
|
#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
|
#endif //MULTIROW_INFINITY_2D_H
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -524,29 +524,29 @@ CLEANUP:
|
|||||||
#ifndef TEST_SOURCE
|
#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 rval = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int nrays = model->rays.nrays;
|
int nrays = model->rays.nrays;
|
||||||
double *f = model->f;
|
|
||||||
|
|
||||||
double *scale = 0;
|
double *scale = 0;
|
||||||
double *rays = 0;
|
|
||||||
|
|
||||||
double lb[2], ub[2];
|
double lb[2], ub[2];
|
||||||
|
|
||||||
for (int i = 0; i < nrays; i++)
|
double *f = lfree->f;
|
||||||
bounds[i] = GREEDY_BIG_E;
|
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));
|
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");
|
abort_if(!scale, "could not allocate scale");
|
||||||
|
|
||||||
memcpy(rays, model->rays.values, 2 * nrays * sizeof(double));
|
|
||||||
|
|
||||||
rval = scale_to_chull(rays, nrays, scale);
|
rval = scale_to_chull(rays, nrays, scale);
|
||||||
abort_if(rval, "scale_to_chull failed");
|
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");
|
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");
|
abort_if(rval, "get_bounding_box failed");
|
||||||
|
|
||||||
log_verbose(" box=[%.2lf %.2lf] [%.2lf %.2lf]\n", lb[0], ub[0], lb[1], ub[1]);
|
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]);
|
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");
|
abort_if(rval, "bound failed");
|
||||||
|
|
||||||
log_verbose(" epsilon=%.2lf\n", epsilon);
|
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);
|
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");
|
abort_if(rval, "get_bounding_box failed");
|
||||||
|
|
||||||
log_verbose(" p=%.2lf %.2lf\n", p[0], p[1]);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_verbose(" updating bounds\n");
|
log_verbose(" updating beta\n");
|
||||||
if(isinf(best_v1[0]))
|
if(isinf(best_v1[0]))
|
||||||
{
|
{
|
||||||
bounds[best_i1] = best_epsilon;
|
beta[best_i1] = best_epsilon;
|
||||||
log_verbose(" bounds[%d]=%.8lf (exact)\n", best_i1, best_epsilon);
|
log_verbose(" beta[%d]=%.8lf (exact)\n", best_i1, best_epsilon);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -646,15 +646,15 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
|
|||||||
|
|
||||||
if(!DOUBLE_geq(lambda, 0)) continue;
|
if(!DOUBLE_geq(lambda, 0)) continue;
|
||||||
|
|
||||||
bounds[i] = fmin(bounds[i], lambda);
|
beta[i] = fmin(beta[i], lambda);
|
||||||
log_verbose(" bounds[%d]=%.8lf\n", i, bounds[i]);
|
log_verbose(" beta[%d]=%.8lf\n", i, beta[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if(count > 0)
|
//if(count > 0)
|
||||||
//{
|
//{
|
||||||
// for (int i = 0; i < nrays; i++)
|
// for (int i = 0; i < nrays; i++)
|
||||||
// bounds[i] = fmin(bounds[i], best_epsilon);
|
// beta[i] = fmin(beta[i], best_epsilon);
|
||||||
|
|
||||||
// break;
|
// break;
|
||||||
//}
|
//}
|
||||||
@@ -663,7 +663,7 @@ int INFINITY_2D_generate_cut(const struct MultiRowModel *model, double *bounds)
|
|||||||
|
|
||||||
for (int k = 0; k < nrays; k++)
|
for (int k = 0; k < nrays; k++)
|
||||||
{
|
{
|
||||||
if(bounds[k] < 100) continue;
|
if(beta[k] < 100) continue;
|
||||||
is_split = 1;
|
is_split = 1;
|
||||||
|
|
||||||
double *split_direction = &rays[2 * k];
|
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];
|
const double *r = &rays[2 * i];
|
||||||
|
|
||||||
lhs = (f[0] + r[0] * bounds[i]) * pi[0];
|
lhs = (f[0] + r[0] * beta[i]) * pi[0];
|
||||||
lhs += (f[1] + r[1] * bounds[i]) * pi[1];
|
lhs += (f[1] + r[1] * beta[i]) * pi[1];
|
||||||
|
|
||||||
if (!(DOUBLE_leq(pi_zero, lhs) && DOUBLE_leq(lhs, pi_zero+1)))
|
if (!(DOUBLE_leq(pi_zero, lhs) && DOUBLE_leq(lhs, pi_zero+1)))
|
||||||
{
|
{
|
||||||
log_verbose(" point %.4lf %.4lf falls outside of the split\n",
|
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;
|
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++)
|
for(int i=0; i<nrays; i++)
|
||||||
bounds[i] *= scale[i];
|
beta[i] *= scale[i];
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if(scale) free(scale);
|
if(scale) free(scale);
|
||||||
if(rays) free(rays);
|
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,30 +85,25 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_cut(const struct Tableau *tableau,
|
static int create_cut_from_lfree(const struct Tableau *tableau,
|
||||||
const struct RayMap *map,
|
const struct RayMap *map,
|
||||||
const struct MultiRowModel *model,
|
const struct ConvLFreeSet *lfree,
|
||||||
const double *beta,
|
struct Row *cut)
|
||||||
struct Row *cut)
|
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
|
|
||||||
|
struct LP lp;
|
||||||
int nvars = map->nvars;
|
int nvars = map->nvars;
|
||||||
int nrows = tableau->nrows;
|
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);
|
rval = LP_open(&lp);
|
||||||
abort_if(rval, "LP_open failed");
|
abort_if(rval, "LP_open failed");
|
||||||
|
|
||||||
rval = GREEDY_create_psi_lp(nrows, model->rays.nrays, model->f,
|
rval = GREEDY_create_psi_lp(nrows, lfree->rays.nrays, lfree->f,
|
||||||
model->rays.values, beta, &lp);
|
lfree->rays.values, lfree->beta, &lp);
|
||||||
abort_if(rval, "create_psi_lp failed");
|
abort_if(rval, "create_psi_lp failed");
|
||||||
|
|
||||||
|
cut->nz = nvars;
|
||||||
for(int i = 0; i < nvars; i++)
|
for(int i = 0; i < nvars; i++)
|
||||||
{
|
{
|
||||||
double value;
|
double value;
|
||||||
@@ -117,15 +112,15 @@ static int create_cut(const struct Tableau *tableau,
|
|||||||
if(ENABLE_LIFTING &&
|
if(ENABLE_LIFTING &&
|
||||||
tableau->column_types[map->indices[i]] == MILP_INTEGER)
|
tableau->column_types[map->indices[i]] == MILP_INTEGER)
|
||||||
{
|
{
|
||||||
rval = GREEDY_ND_pi(nrows, model->rays.nrays, model->f,
|
rval = GREEDY_ND_pi(nrows, lfree->rays.nrays, lfree->f,
|
||||||
model->rays.values, beta, q, map->ray_scale[i], &lp,
|
lfree->rays.values, lfree->beta, q, map->ray_scale[i], &lp,
|
||||||
&value);
|
&value);
|
||||||
abort_if(rval, "GREEDY_ND_pi failed");
|
abort_if(rval, "GREEDY_ND_pi failed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rval = GREEDY_ND_psi(nrows, model->rays.nrays, model->f,
|
rval = GREEDY_ND_psi(nrows, lfree->rays.nrays, lfree->f,
|
||||||
model->rays.values, beta, q, map->ray_scale[i], &lp,
|
lfree->rays.values, lfree->beta, q, map->ray_scale[i], &lp,
|
||||||
&value);
|
&value);
|
||||||
abort_if(rval, "GREEDY_ND_psi failed");
|
abort_if(rval, "GREEDY_ND_psi failed");
|
||||||
}
|
}
|
||||||
@@ -146,7 +141,7 @@ CLEANUP:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int select_rays(const struct RayMap *map,
|
static int filter_rays(const struct RayMap *map,
|
||||||
const struct Tableau *tableau,
|
const struct Tableau *tableau,
|
||||||
struct MultiRowModel *model)
|
struct MultiRowModel *model)
|
||||||
{
|
{
|
||||||
@@ -166,8 +161,8 @@ static int select_rays(const struct RayMap *map,
|
|||||||
for(int j = 0; j < (rays->nrays); j++)
|
for(int j = 0; j < (rays->nrays); j++)
|
||||||
{
|
{
|
||||||
double *q = LFREE_get_ray(&map->rays, j);
|
double *q = LFREE_get_ray(&map->rays, j);
|
||||||
double norm = 0;
|
|
||||||
|
|
||||||
|
double norm = 0;
|
||||||
for(int k = 0; k < nrows; k++)
|
for(int k = 0; k < nrows; k++)
|
||||||
norm += fabs(r[k] - q[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,
|
log_debug(" norm_cutoff=%8.2lf nrays=%8d\n", norm_cutoff,
|
||||||
model->nrays);
|
model->rays.nrays);
|
||||||
|
|
||||||
if(rays->nrays < MAX_N_RAYS) break;
|
if(rays->nrays < MAX_N_RAYS) break;
|
||||||
}
|
}
|
||||||
@@ -253,7 +248,7 @@ CLEANUP:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int write_sage_file(const struct MultiRowModel *model,
|
static int write_sage_file(const struct MultiRowModel *model,
|
||||||
const double *beta,
|
const struct ConvLFreeSet *lfree,
|
||||||
const char *filename)
|
const char *filename)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
@@ -280,7 +275,7 @@ static int write_sage_file(const struct MultiRowModel *model,
|
|||||||
|
|
||||||
fprintf(fsage, "pi=vector([\n");
|
fprintf(fsage, "pi=vector([\n");
|
||||||
for(int k = 0; k < model->rays.nrays; k++)
|
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");
|
fprintf(fsage, "])\n");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -288,7 +283,8 @@ CLEANUP:
|
|||||||
return rval;
|
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;
|
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++);
|
sprintf(filename, "cut-%03d.sage", DUMP_CUT_N++);
|
||||||
|
|
||||||
time_printf("Writing %s...\n", filename);
|
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");
|
abort_if(rval, "write_sage_file failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -315,8 +311,8 @@ static int extract_model_from_tableau(const struct Tableau *tableau,
|
|||||||
rval = CG_extract_rays_from_tableau(tableau, map);
|
rval = CG_extract_rays_from_tableau(tableau, map);
|
||||||
abort_if(rval, "CG_extract_rays_from_rows failed");
|
abort_if(rval, "CG_extract_rays_from_rows failed");
|
||||||
|
|
||||||
rval = select_rays(map, tableau, model);
|
rval = filter_rays(map, tableau, model);
|
||||||
abort_if(rval, "select_rays failed");
|
abort_if(rval, "filter_rays failed");
|
||||||
|
|
||||||
if(ENABLE_LIFTING)
|
if(ENABLE_LIFTING)
|
||||||
{
|
{
|
||||||
@@ -339,16 +335,16 @@ 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 nrows = tableau->nrows;
|
|
||||||
int max_nrays = CG_total_nz(tableau);
|
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;
|
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");
|
abort_if(rval, "CG_init_ray_map failed");
|
||||||
|
|
||||||
rval = extract_model_from_tableau(tableau, &model, &map);
|
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)
|
if(model.rays.nrays < 3)
|
||||||
{
|
{
|
||||||
rval = ERR_NO_CUT;
|
rval = ERR_NO_CUT;
|
||||||
cut->pi = 0;
|
|
||||||
cut->indices = 0;
|
|
||||||
goto CLEANUP;
|
goto CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
beta = (double *) malloc(model.rays.nrays * sizeof(double));
|
rval = LFREE_init_conv(&lfree, tableau->nrows, model.rays.nrays);
|
||||||
abort_if(!beta, "could not allocate beta");
|
abort_if(rval, "LFREE_init_conv failed");
|
||||||
|
|
||||||
if(nrows == 2) rval = INFINITY_2D_generate_cut(&model, beta);
|
if(tableau->nrows == 2)
|
||||||
else rval = GREEDY_ND_generate_cut(&model, beta);
|
rval = INFINITY_2D_generate_lfree(&model, &lfree);
|
||||||
|
else
|
||||||
|
rval = INFINITY_ND_generate_lfree(&model, &lfree);
|
||||||
|
|
||||||
if(rval)
|
if(rval)
|
||||||
{
|
{
|
||||||
@@ -376,15 +372,15 @@ int INFINITY_generate_cut(const struct Tableau *tableau, struct Row *cut)
|
|||||||
|
|
||||||
if(SHOULD_DUMP_CUTS)
|
if(SHOULD_DUMP_CUTS)
|
||||||
{
|
{
|
||||||
rval = dump_cut(&model, beta);
|
rval = dump_cut(&model, &lfree);
|
||||||
abort_if(rval, "dump_cut failed");
|
abort_if(rval, "dump_cut failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
rval = create_cut(tableau, &map, &model, beta, cut);
|
rval = create_cut_from_lfree(tableau, &map, &lfree, cut);
|
||||||
abort_if(rval, "create_cut failed");
|
abort_if(rval, "create_cut_from_lfree failed");
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if(beta) free(beta);
|
LFREE_free_conv(&lfree);
|
||||||
CG_free_model(&model);
|
CG_free_model(&model);
|
||||||
CG_free_ray_map(&map);
|
CG_free_ray_map(&map);
|
||||||
return rval;
|
return rval;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ extern "C" {
|
|||||||
#include <multirow/lfree2d.h>
|
#include <multirow/lfree2d.h>
|
||||||
#include <multirow/cg.h>
|
#include <multirow/cg.h>
|
||||||
#include <infinity/greedy-nd.h>
|
#include <infinity/greedy-nd.h>
|
||||||
|
#include "../src/greedy-nd.c"
|
||||||
}
|
}
|
||||||
|
|
||||||
int ENABLE_LIFTING = 0;
|
int ENABLE_LIFTING = 0;
|
||||||
@@ -242,8 +243,8 @@ TEST(GreedyNDTest, bound_test_1)
|
|||||||
double epsilon;
|
double epsilon;
|
||||||
int tx[6];
|
int tx[6];
|
||||||
|
|
||||||
rval = GREEDY_ND_bound(2, 6, f, rays, x, beta1, &epsilon, tx);
|
rval = bound(2, 6, f, rays, x, beta1, &epsilon, tx);
|
||||||
abort_if(rval, "GREEDY_ND_bound failed");
|
abort_if(rval, "bound failed");
|
||||||
EXPECT_NEAR(epsilon, 0.5, 1e-6);
|
EXPECT_NEAR(epsilon, 0.5, 1e-6);
|
||||||
EXPECT_TRUE(tx[0]);
|
EXPECT_TRUE(tx[0]);
|
||||||
EXPECT_FALSE(tx[1]);
|
EXPECT_FALSE(tx[1]);
|
||||||
@@ -252,8 +253,8 @@ TEST(GreedyNDTest, bound_test_1)
|
|||||||
EXPECT_FALSE(tx[4]);
|
EXPECT_FALSE(tx[4]);
|
||||||
EXPECT_FALSE(tx[5]);
|
EXPECT_FALSE(tx[5]);
|
||||||
|
|
||||||
rval = GREEDY_ND_bound(2, 6, f, rays, x, beta2, &epsilon, tx);
|
rval = bound(2, 6, f, rays, x, beta2, &epsilon, tx);
|
||||||
abort_if(rval, "GREEDY_ND_bound failed");
|
abort_if(rval, "bound failed");
|
||||||
EXPECT_NEAR(epsilon, 1.0, 1e-6);
|
EXPECT_NEAR(epsilon, 1.0, 1e-6);
|
||||||
EXPECT_TRUE(tx[0]);
|
EXPECT_TRUE(tx[0]);
|
||||||
EXPECT_FALSE(tx[1]);
|
EXPECT_FALSE(tx[1]);
|
||||||
@@ -262,8 +263,8 @@ TEST(GreedyNDTest, bound_test_1)
|
|||||||
EXPECT_TRUE(tx[4]);
|
EXPECT_TRUE(tx[4]);
|
||||||
EXPECT_TRUE(tx[5]);
|
EXPECT_TRUE(tx[5]);
|
||||||
|
|
||||||
rval = GREEDY_ND_bound(2, 6, f, rays, x, beta3, &epsilon, tx);
|
rval = bound(2, 6, f, rays, x, beta3, &epsilon, tx);
|
||||||
abort_if(rval, "GREEDY_ND_bound failed");
|
abort_if(rval, "bound failed");
|
||||||
EXPECT_EQ(epsilon, INFINITY);
|
EXPECT_EQ(epsilon, INFINITY);
|
||||||
EXPECT_FALSE(tx[0]);
|
EXPECT_FALSE(tx[0]);
|
||||||
EXPECT_FALSE(tx[1]);
|
EXPECT_FALSE(tx[1]);
|
||||||
@@ -371,10 +372,9 @@ TEST(GreedyNDTest, generate_cut_test_1)
|
|||||||
double r3[] = { -1.0, 1.0 };
|
double r3[] = { -1.0, 1.0 };
|
||||||
double r4[] = { 0.0, 1.0 };
|
double r4[] = { 0.0, 1.0 };
|
||||||
double r5[] = { 1.0, 0.0 };
|
double r5[] = { 1.0, 0.0 };
|
||||||
double beta[6];
|
|
||||||
|
|
||||||
struct MultiRowModel model;
|
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, r0);
|
||||||
LFREE_push_ray(&model.rays, r1);
|
LFREE_push_ray(&model.rays, r1);
|
||||||
LFREE_push_ray(&model.rays, r2);
|
LFREE_push_ray(&model.rays, r2);
|
||||||
@@ -384,15 +384,18 @@ TEST(GreedyNDTest, generate_cut_test_1)
|
|||||||
model.f[0] = 0.5;
|
model.f[0] = 0.5;
|
||||||
model.f[1] = 0.5;
|
model.f[1] = 0.5;
|
||||||
|
|
||||||
rval = GREEDY_ND_generate_cut(&model, beta);
|
struct ConvLFreeSet lfree;
|
||||||
abort_if(rval, "GREEDY_ND_generate_cut failed");
|
LFREE_init_conv(&lfree, 2, 6);
|
||||||
|
|
||||||
EXPECT_NEAR(beta[0], 0.5, 1e-6);
|
rval = INFINITY_ND_generate_lfree(&model, &lfree);
|
||||||
EXPECT_NEAR(beta[1], 0.5, 1e-6);
|
abort_if(rval, "INFINITY_ND_generate_lfree failed");
|
||||||
EXPECT_NEAR(beta[2], 0.5, 1e-6);
|
|
||||||
EXPECT_NEAR(beta[3], 0.5, 1e-6);
|
EXPECT_NEAR(lfree.beta[0], 0.5, 1e-6);
|
||||||
EXPECT_NEAR(beta[4], 1.0, 1e-6);
|
EXPECT_NEAR(lfree.beta[1], 0.5, 1e-6);
|
||||||
EXPECT_NEAR(beta[5], 1.0, 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:
|
CLEANUP:
|
||||||
if(rval) FAIL();
|
if(rval) FAIL();
|
||||||
@@ -408,10 +411,9 @@ TEST(GreedyNDTest, generate_cut_test_2)
|
|||||||
double r3[] = { 0.0, -1.0, 0.0 };
|
double r3[] = { 0.0, -1.0, 0.0 };
|
||||||
double r4[] = { 0.0, 0.0, 1.0 };
|
double r4[] = { 0.0, 0.0, 1.0 };
|
||||||
double r5[] = { 0.0, 0.0, -1.0 };
|
double r5[] = { 0.0, 0.0, -1.0 };
|
||||||
double beta[6];
|
|
||||||
|
|
||||||
struct MultiRowModel model;
|
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, r0);
|
||||||
LFREE_push_ray(&model.rays, r1);
|
LFREE_push_ray(&model.rays, r1);
|
||||||
LFREE_push_ray(&model.rays, r2);
|
LFREE_push_ray(&model.rays, r2);
|
||||||
@@ -422,15 +424,18 @@ TEST(GreedyNDTest, generate_cut_test_2)
|
|||||||
model.f[1] = 0.75;
|
model.f[1] = 0.75;
|
||||||
model.f[2] = 0.75;
|
model.f[2] = 0.75;
|
||||||
|
|
||||||
rval = GREEDY_ND_generate_cut(&model, beta);
|
struct ConvLFreeSet lfree;
|
||||||
abort_if(rval, "GREEDY_ND_generate_cut failed");
|
LFREE_init_conv(&lfree, 3, 6);
|
||||||
|
|
||||||
EXPECT_NEAR(beta[0], 0.75, 1e-6);
|
rval = INFINITY_ND_generate_lfree(&model, &lfree);
|
||||||
EXPECT_NEAR(beta[1], 2.25, 1e-6);
|
abort_if(rval, "INFINITY_ND_generate_lfree failed");
|
||||||
EXPECT_NEAR(beta[2], 0.75, 1e-6);
|
|
||||||
EXPECT_NEAR(beta[3], 2.25, 1e-6);
|
EXPECT_NEAR(lfree.beta[0], 0.75, 1e-6);
|
||||||
EXPECT_NEAR(beta[4], 0.75, 1e-6);
|
EXPECT_NEAR(lfree.beta[1], 2.25, 1e-6);
|
||||||
EXPECT_NEAR(beta[5], 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:
|
CLEANUP:
|
||||||
CG_free_model(&model);
|
CG_free_model(&model);
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ extern "C" {
|
|||||||
TEST(Infinity2DTest, test_generate_cut_1)
|
TEST(Infinity2DTest, test_generate_cut_1)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
double bounds[100];
|
|
||||||
|
|
||||||
double f[] = {1 / 4.0, 3 / 4.0};
|
double f[] = {1 / 4.0, 3 / 4.0};
|
||||||
double rays[] = {
|
double rays[] = {
|
||||||
@@ -43,14 +42,17 @@ TEST(Infinity2DTest, test_generate_cut_1)
|
|||||||
|
|
||||||
const struct MultiRowModel model = {f , rays, 5, 2};
|
const struct MultiRowModel model = {f , rays, 5, 2};
|
||||||
|
|
||||||
rval = INFINITY_2D_generate_cut(&model, bounds);
|
struct ConvLFreeSet lfree;
|
||||||
abort_if(rval, "INFINITY_2D_generate_cut failed");
|
LFREE_init_conv(&lfree, 2, 5);
|
||||||
|
|
||||||
EXPECT_NEAR(23 / 50.0, bounds[0], BOUNDS_EPSILON);
|
rval = INFINITY_2D_generate_lfree(&model, &lfree);
|
||||||
EXPECT_NEAR(23 / 42.0, bounds[1], BOUNDS_EPSILON);
|
abort_if(rval, "INFINITY_2D_generate_lfree failed");
|
||||||
EXPECT_NEAR(9 / 11.0, bounds[2], BOUNDS_EPSILON);
|
|
||||||
EXPECT_NEAR(9 / 11.0, bounds[3], BOUNDS_EPSILON);
|
EXPECT_NEAR(23 / 50.0, lfree.beta[0], BOUNDS_EPSILON);
|
||||||
EXPECT_NEAR(23 / 50.0, bounds[4], 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:
|
CLEANUP:
|
||||||
if (rval) FAIL();
|
if (rval) FAIL();
|
||||||
@@ -59,7 +61,6 @@ TEST(Infinity2DTest, test_generate_cut_1)
|
|||||||
TEST(Infinity2DTest, test_generate_cut_2)
|
TEST(Infinity2DTest, test_generate_cut_2)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
double bounds[100];
|
|
||||||
double f[] = {1 / 2.0, 1 / 2.0};
|
double f[] = {1 / 2.0, 1 / 2.0};
|
||||||
double rays[] = {
|
double rays[] = {
|
||||||
-1.0, -1.0,
|
-1.0, -1.0,
|
||||||
@@ -70,15 +71,17 @@ TEST(Infinity2DTest, test_generate_cut_2)
|
|||||||
};
|
};
|
||||||
|
|
||||||
const struct MultiRowModel model = {f , rays, 5, 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);
|
rval = INFINITY_2D_generate_lfree(&model, &lfree);
|
||||||
abort_if(rval, "INFINITY_2D_generate_cut failed");
|
abort_if(rval, "INFINITY_2D_generate_lfree failed");
|
||||||
|
|
||||||
EXPECT_NEAR(0.5, bounds[0], BOUNDS_EPSILON);
|
EXPECT_NEAR(0.5, lfree.beta[0], BOUNDS_EPSILON);
|
||||||
EXPECT_NEAR(0.5, bounds[1], BOUNDS_EPSILON);
|
EXPECT_NEAR(0.5, lfree.beta[1], BOUNDS_EPSILON);
|
||||||
EXPECT_NEAR(0.5, bounds[2], BOUNDS_EPSILON);
|
EXPECT_NEAR(0.5, lfree.beta[2], BOUNDS_EPSILON);
|
||||||
EXPECT_EQ(GREEDY_BIG_E, bounds[3]);
|
EXPECT_EQ(GREEDY_BIG_E, lfree.beta[3]);
|
||||||
EXPECT_NEAR(0.5, bounds[4], BOUNDS_EPSILON);
|
EXPECT_NEAR(0.5, lfree.beta[4], BOUNDS_EPSILON);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if (rval) FAIL();
|
if (rval) FAIL();
|
||||||
@@ -87,18 +90,19 @@ TEST(Infinity2DTest, test_generate_cut_2)
|
|||||||
TEST(Infinity2DTest, test_generate_cut_3)
|
TEST(Infinity2DTest, test_generate_cut_3)
|
||||||
{
|
{
|
||||||
int rval = 0;
|
int rval = 0;
|
||||||
double bounds[100];
|
|
||||||
double f[] = {5 / 22.0, 0.0};
|
double f[] = {5 / 22.0, 0.0};
|
||||||
double rays[] = {-1 / 22.0, 0.0, 0.0, 1 / 18.0, 1 / 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};
|
const struct MultiRowModel model = {f , rays, 3, 2};
|
||||||
|
struct ConvLFreeSet lfree;
|
||||||
|
LFREE_init_conv(&lfree, 2, 5);
|
||||||
|
|
||||||
rval = INFINITY_2D_generate_cut(&model, bounds);
|
rval = INFINITY_2D_generate_lfree(&model, &lfree);
|
||||||
abort_if(rval, "INFINITY_2D_generate_cut failed");
|
abort_if(rval, "INFINITY_2D_generate_lfree failed");
|
||||||
|
|
||||||
EXPECT_NEAR(5.0, bounds[0], BOUNDS_EPSILON);
|
EXPECT_NEAR(5.0, lfree.beta[0], BOUNDS_EPSILON);
|
||||||
EXPECT_NEAR(17.0, bounds[2], BOUNDS_EPSILON);
|
EXPECT_NEAR(17.0, lfree.beta[2], BOUNDS_EPSILON);
|
||||||
EXPECT_EQ(GREEDY_BIG_E, bounds[1]);
|
EXPECT_EQ(GREEDY_BIG_E, lfree.beta[1]);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if (rval) FAIL();
|
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,
|
// 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};
|
// 0, 1 / 22.0, 0, 1 / 22.0, 1 / 38.0};
|
||||||
//
|
//
|
||||||
// rval = INFINITY_2D_generate_cut(rays, 6, f, bounds);
|
// rval = INFINITY_2D_generate_lfree(rays, 6, f, bounds);
|
||||||
// abort_if(rval, "INFINITY_2D_generate_cut failed");
|
// abort_if(rval, "INFINITY_2D_generate_lfree failed");
|
||||||
//
|
//
|
||||||
// EXPECT_NEAR(20.0, bounds[0], BOUNDS_EPSILON);
|
// EXPECT_NEAR(20.0, bounds[0], BOUNDS_EPSILON);
|
||||||
// EXPECT_NEAR(20.0, bounds[1], 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.00000000000000000000,
|
||||||
// 0.04545454545454545581, 0.02631578947368420907};
|
// 0.04545454545454545581, 0.02631578947368420907};
|
||||||
//
|
//
|
||||||
// rval = INFINITY_2D_generate_cut(rays, 6, f, bounds);
|
// rval = INFINITY_2D_generate_lfree(rays, 6, f, bounds);
|
||||||
// abort_if(rval, "INFINITY_2D_generate_cut failed");
|
// abort_if(rval, "INFINITY_2D_generate_lfree failed");
|
||||||
//
|
//
|
||||||
// EXPECT_NEAR(20.0, bounds[0], BOUNDS_EPSILON);
|
// EXPECT_NEAR(20.0, bounds[0], BOUNDS_EPSILON);
|
||||||
// EXPECT_NEAR(20.0, bounds[1], 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_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);
|
void CG_free_model(struct MultiRowModel *model);
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,15 @@ struct RayList
|
|||||||
int dim;
|
int dim;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ConvLFreeSet
|
||||||
|
{
|
||||||
|
double *f;
|
||||||
|
struct RayList rays;
|
||||||
|
int nrows;
|
||||||
|
double *beta;
|
||||||
|
};
|
||||||
|
|
||||||
int LFREE_2D_init(struct LFreeSet2D *set,
|
int LFREE_2D_init(struct LFreeSet2D *set,
|
||||||
int n_vertices,
|
int n_vertices,
|
||||||
int n_lattice_points,
|
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_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
|
#endif //LFREE_2D_H
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
* LOG_LEVEL_WARNING
|
* LOG_LEVEL_WARNING
|
||||||
* LOG_LEVEL_ERROR
|
* LOG_LEVEL_ERROR
|
||||||
*/
|
*/
|
||||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
#define LOG_LEVEL LOG_LEVEL_DEBUG
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum bounding-box size for naive algorithm
|
* Maximum bounding-box size for naive algorithm
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
*/
|
*/
|
||||||
#define N_RAYS 100
|
#define N_RAYS 100
|
||||||
|
|
||||||
#define ONLY_CUT -1
|
#define ONLY_CUT 242
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Time limit for the computation (user time, in seconds).
|
* Time limit for the computation (user time, in seconds).
|
||||||
|
|||||||
@@ -575,7 +575,10 @@ void CG_free(struct CG *cg)
|
|||||||
if (cg->tableau_rows)
|
if (cg->tableau_rows)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cg->nrows; i++)
|
for (int i = 0; i < cg->nrows; i++)
|
||||||
|
{
|
||||||
LP_free_row(cg->tableau_rows[i]);
|
LP_free_row(cg->tableau_rows[i]);
|
||||||
|
free(cg->tableau_rows[i]);
|
||||||
|
}
|
||||||
free(cg->tableau_rows);
|
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);
|
log_verbose("Generating cut %d...\n", i);
|
||||||
|
|
||||||
struct Row *cut = 0;
|
struct Row cut;
|
||||||
|
|
||||||
cut = (struct Row *) malloc(sizeof(struct Row));
|
rval = generate(row, cg->column_types, &cut);
|
||||||
abort_if(!cut, "could not allocate cut");
|
|
||||||
|
|
||||||
rval = generate(row, cg->column_types, cut);
|
|
||||||
abort_if(rval, "generate failed");
|
abort_if(rval, "generate failed");
|
||||||
|
|
||||||
int ignored;
|
int ignored;
|
||||||
rval = add_cut(cg, cut, &ignored);
|
rval = add_cut(cg, &cut, &ignored);
|
||||||
abort_if(rval, "add_cut failed");
|
abort_if(rval, "add_cut failed");
|
||||||
|
|
||||||
LP_free_row(cut);
|
LP_free_row(&cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
@@ -856,23 +856,24 @@ int CG_add_multirow_cuts(struct CG *cg,
|
|||||||
progress_increment();
|
progress_increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Row *cut = 0;
|
struct Tableau tableau = {nrows, rows, cg->column_types};
|
||||||
|
struct Row cut;
|
||||||
|
|
||||||
cut = (struct Row *) malloc(sizeof(struct Row));
|
int max_nz = CG_total_nz(&tableau);
|
||||||
abort_if(!cut, "could not allocate cut");
|
cut.pi = (double *) malloc(max_nz * sizeof(double));
|
||||||
|
cut.indices = (int *) malloc(max_nz * sizeof(int));
|
||||||
cut->pi = 0;
|
abort_if(!cut.pi, "could not allocate cut.pi");
|
||||||
cut->indices = 0;
|
abort_if(!cut.indices, "could not allocate cut.indices");
|
||||||
|
|
||||||
double initial_time = get_user_time();
|
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)
|
if (rval == ERR_NO_CUT)
|
||||||
{
|
{
|
||||||
rval = 0;
|
rval = 0;
|
||||||
log_verbose("combination does not yield cut\n");
|
log_verbose("combination does not yield cut\n");
|
||||||
LP_free_row(cut);
|
LP_free_row(&cut);
|
||||||
goto NEXT_COMBINATION;
|
goto NEXT_COMBINATION;
|
||||||
}
|
}
|
||||||
else abort_iff(rval, "generate failed (cut %d)", count);
|
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);
|
log_debug(" generate: %.2lf ms\n", elapsed_time * 1000);
|
||||||
|
|
||||||
double dynamism;
|
double dynamism;
|
||||||
rval = cut_dynamism(cut, &dynamism);
|
rval = cut_dynamism(&cut, &dynamism);
|
||||||
abort_if(rval, "cut_dynamism failed");
|
abort_if(rval, "cut_dynamism failed");
|
||||||
|
|
||||||
if (dynamism > MAX_CUT_DYNAMISM)
|
if (dynamism > MAX_CUT_DYNAMISM)
|
||||||
{
|
{
|
||||||
log_debug("Discarding cut (dynamism=%.2lf)\n", dynamism);
|
log_debug("Discarding cut (dynamism=%.2lf)\n", dynamism);
|
||||||
LP_free_row(cut);
|
LP_free_row(&cut);
|
||||||
goto NEXT_COMBINATION;
|
goto NEXT_COMBINATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ignored;
|
int ignored;
|
||||||
rval = add_cut(cg, cut, &ignored);
|
rval = add_cut(cg, &cut, &ignored);
|
||||||
if (rval)
|
if (rval)
|
||||||
{
|
{
|
||||||
log_warn("invalid cut skipped (cut %d)\n", count);
|
log_warn("invalid cut skipped (cut %d)\n", count);
|
||||||
rval = 0;
|
rval = 0;
|
||||||
|
|
||||||
LP_free_row(cut);
|
LP_free_row(&cut);
|
||||||
goto NEXT_COMBINATION;
|
goto NEXT_COMBINATION;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if_debug_level if (!ignored)
|
if_debug_level if (!ignored)
|
||||||
{
|
{
|
||||||
SHOULD_DUMP_CUTS = 1;
|
SHOULD_DUMP_CUTS = 1;
|
||||||
generate(&tableau, cut);
|
generate(&tableau, &cut);
|
||||||
SHOULD_DUMP_CUTS = 0;
|
SHOULD_DUMP_CUTS = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LP_free_row(cut);
|
LP_free_row(&cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
NEXT_COMBINATION:
|
NEXT_COMBINATION:
|
||||||
@@ -1019,7 +1020,7 @@ int CG_extract_f_from_tableau(const struct Tableau *tableau, double *f)
|
|||||||
return 0;
|
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;
|
int rval = 0;
|
||||||
model->nrows = nrows;
|
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);
|
double *dest = LFREE_get_ray(list, list->nrays);
|
||||||
memcpy(dest, ray, list->dim * sizeof(double));
|
memcpy(dest, ray, list->dim * sizeof(double));
|
||||||
list->nrays++;
|
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)
|
void LP_free_row(struct Row *row)
|
||||||
{
|
{
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
|
|
||||||
if (row->pi) free(row->pi);
|
if (row->pi) free(row->pi);
|
||||||
if (row->indices) free(row->indices);
|
if (row->indices) free(row->indices);
|
||||||
free(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LP_add_rows(struct LP *lp,
|
int LP_add_rows(struct LP *lp,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ extern "C" {
|
|||||||
|
|
||||||
int BOOST_VAR = -1;
|
int BOOST_VAR = -1;
|
||||||
double BOOST_FACTOR = 1.0;
|
double BOOST_FACTOR = 1.0;
|
||||||
|
int SHOULD_DUMP_CUTS = 0;
|
||||||
|
|
||||||
TEST(CGTest, next_combination_test_1)
|
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);
|
rval = CG_extract_rays_from_tableau(&tableau, &map);
|
||||||
abort_if(rval, "CG_extract_rays_from_rows failed");
|
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_EQ(map.nvars, 7);
|
||||||
|
|
||||||
EXPECT_DOUBLE_EQ(rays.values[0], 0.0);
|
EXPECT_DOUBLE_EQ(rays.values[0], 0.0);
|
||||||
|
|||||||
Reference in New Issue
Block a user