|
|
|
@ -21,7 +21,6 @@
|
|
|
|
|
#include <multirow/double.h>
|
|
|
|
|
#include <multirow/util.h>
|
|
|
|
|
|
|
|
|
|
#include <infinity/greedy-bsearch.h>
|
|
|
|
|
#include <infinity/greedy-nd.h>
|
|
|
|
|
|
|
|
|
|
static long lp_count = 0;
|
|
|
|
@ -81,9 +80,12 @@ int find_interior_point_enum(const int nrows,
|
|
|
|
|
for(int x3 = -M; x3 <= M; x3++)
|
|
|
|
|
{
|
|
|
|
|
double value;
|
|
|
|
|
double q[3] = {x1 - f[0], x2 - f[1], x3 - f[2]};
|
|
|
|
|
double q[3] = {x1 - f[0],
|
|
|
|
|
x2 - f[1],
|
|
|
|
|
x3 - f[2]};
|
|
|
|
|
|
|
|
|
|
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta2, q, 1, &lp, &value);
|
|
|
|
|
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta2, q, 1, &lp,
|
|
|
|
|
&value);
|
|
|
|
|
abort_if(rval, "GREEDY_ND_psi failed");
|
|
|
|
|
|
|
|
|
|
if(value < best_value)
|
|
|
|
@ -102,6 +104,7 @@ CLEANUP:
|
|
|
|
|
LP_free(&lp);
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int find_interior_point_cplex(const int nrows,
|
|
|
|
|
const int nrays,
|
|
|
|
|
const double *f,
|
|
|
|
@ -217,8 +220,7 @@ int GREEDY_create_psi_lp(const int nrows,
|
|
|
|
|
nz++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -259,7 +261,8 @@ int GREEDY_ND_pi(const int nrows,
|
|
|
|
|
for(int k0 = -M; k0 <= M; k0++)
|
|
|
|
|
for(int k1 = -M; k1 <= M; k1++)
|
|
|
|
|
{
|
|
|
|
|
double qk[] = { frac(q[0] * q_scale) + k0, frac(q[1] * q_scale) + k1 };
|
|
|
|
|
double qk[] = {frac(q[0] * q_scale) + k0,
|
|
|
|
|
frac(q[1] * q_scale) + k1};
|
|
|
|
|
double value;
|
|
|
|
|
|
|
|
|
|
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta, qk, 1, lp,
|
|
|
|
@ -277,11 +280,9 @@ int GREEDY_ND_pi(const int nrows,
|
|
|
|
|
for(int k1 = -M; k1 <= M; k1++)
|
|
|
|
|
for(int k2 = -M; k2 <= M; k2++)
|
|
|
|
|
{
|
|
|
|
|
double qk[] = {
|
|
|
|
|
frac(q[0] * q_scale) + k0,
|
|
|
|
|
double qk[] = {frac(q[0] * q_scale) + k0,
|
|
|
|
|
frac(q[1] * q_scale) + k1,
|
|
|
|
|
frac(q[2] * q_scale) + k2
|
|
|
|
|
};
|
|
|
|
|
frac(q[2] * q_scale) + k2};
|
|
|
|
|
double value;
|
|
|
|
|
|
|
|
|
|
rval = GREEDY_ND_psi(nrows, nrays, f, rays, beta, qk, 1, lp,
|
|
|
|
@ -339,14 +340,12 @@ CLEANUP:
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
int nrays,
|
|
|
|
|
const double *f,
|
|
|
|
|
const double *rays,
|
|
|
|
|
double *beta)
|
|
|
|
|
int GREEDY_ND_generate_cut(const struct MultiRowModel *model, double *beta)
|
|
|
|
|
{
|
|
|
|
|
log_debug("GREEDY_ND_generate_cut\n");
|
|
|
|
|
int rval = 0;
|
|
|
|
|
int nrows = model->nrows;
|
|
|
|
|
int nrays = model->rays.nrays;
|
|
|
|
|
double *f = model->f;
|
|
|
|
|
|
|
|
|
|
double *x = 0;
|
|
|
|
|
|
|
|
|
@ -386,7 +385,6 @@ int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
|
|
|
|
|
long x_count = 0;
|
|
|
|
|
double epsilon;
|
|
|
|
|
double previous_epsilon = -INFINITY;
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < nrows; i++)
|
|
|
|
|
log_verbose(" f[%d] = %.12lf\n", i, f[i]);
|
|
|
|
@ -413,13 +411,15 @@ int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
|
|
|
|
|
if(nrows == 3)
|
|
|
|
|
{
|
|
|
|
|
rval = find_interior_point_enum(nrows, nrays, f, rays, beta, epsilon, x, &found);
|
|
|
|
|
rval = find_interior_point_enum(nrows, nrays, f,
|
|
|
|
|
model->rays.values, beta, epsilon, x, &found);
|
|
|
|
|
abort_if(rval, "find_interior_point_enum failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!found)
|
|
|
|
|
{
|
|
|
|
|
rval = find_interior_point_cplex(nrows, nrays, f, rays, beta, epsilon, x, &found);
|
|
|
|
|
rval = find_interior_point_cplex(nrows, nrays, f,
|
|
|
|
|
model->rays.values, beta, epsilon, x, &found);
|
|
|
|
|
if(rval == ERR_MIP_TIMEOUT) goto CLEANUP;
|
|
|
|
|
abort_if(rval, "find_interior_point_cplex failed");
|
|
|
|
|
if(!found) break;
|
|
|
|
@ -432,8 +432,8 @@ int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
abort_if(x_count > 1000, "infinite loop");
|
|
|
|
|
|
|
|
|
|
double epsilon_x;
|
|
|
|
|
rval = GREEDY_ND_bound(nrows, nrays, f, rays, x, beta, &epsilon_x,
|
|
|
|
|
tx);
|
|
|
|
|
rval = GREEDY_ND_bound(nrows, nrays, f, model->rays.values, x, beta,
|
|
|
|
|
&epsilon_x, tx);
|
|
|
|
|
abort_if(rval, "GREEDY_ND_bound failed");
|
|
|
|
|
// epsilon_x *= 0.999;
|
|
|
|
|
|
|
|
|
@ -469,10 +469,10 @@ int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
else if(!skip_ahull)
|
|
|
|
|
{
|
|
|
|
|
double alpha;
|
|
|
|
|
const double *d = &rays[i * nrows];
|
|
|
|
|
const double *d = LFREE_get_ray(&model->rays, i);
|
|
|
|
|
|
|
|
|
|
rval = GREEDY_ND_scale_to_ahull(nrows, nrays, rays, t, beta,
|
|
|
|
|
epsilon, d, &alpha);
|
|
|
|
|
rval = GREEDY_ND_scale_to_ahull(nrows, nrays,
|
|
|
|
|
model->rays.values, t, beta, epsilon, d, &alpha);
|
|
|
|
|
abort_if(rval, "GREEDY_ND_scale_to_ahull failed");
|
|
|
|
|
|
|
|
|
|
if(DOUBLE_iszero(alpha))
|
|
|
|
@ -488,7 +488,6 @@ int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
log_debug(" beta[%2d] = %.4lf\n", i, beta[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
previous_epsilon = epsilon;
|
|
|
|
|
log_debug("epsilon = %.6lf\n", epsilon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -497,24 +496,30 @@ int GREEDY_ND_generate_cut(int nrows,
|
|
|
|
|
log_debug(" %6ld MIPs (%.2lf ms per call, %.0lf ms total)\n", lp_count,
|
|
|
|
|
lp_time * 1000 / lp_count, lp_time * 1000);
|
|
|
|
|
|
|
|
|
|
log_debug(" %6ld S-free MIPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
log_debug(
|
|
|
|
|
" %6ld S-free MIPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
sfree_mip_count, sfree_mip_time * 1000 / sfree_mip_count,
|
|
|
|
|
sfree_mip_time * 1000);
|
|
|
|
|
|
|
|
|
|
log_debug(" %6ld epsilon LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
log_debug(
|
|
|
|
|
" %6ld epsilon LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
epsilon_lp_count, epsilon_lp_time * 1000 / epsilon_lp_count,
|
|
|
|
|
epsilon_lp_time * 1000);
|
|
|
|
|
|
|
|
|
|
log_debug(" %6ld tight-rays LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
log_debug(
|
|
|
|
|
" %6ld tight-rays LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
tight_lp_count, tight_lp_time * 1000 / tight_lp_count,
|
|
|
|
|
tight_lp_time * 1000);
|
|
|
|
|
|
|
|
|
|
log_debug(" %6ld violated-cone LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
log_debug(
|
|
|
|
|
" %6ld violated-cone LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
violated_lp_count, violated_lp_time * 1000 / violated_lp_count,
|
|
|
|
|
violated_lp_time * 1000);
|
|
|
|
|
|
|
|
|
|
log_debug(" %6ld scale-to-ahull LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
scale_ahull_lp_count, scale_ahull_lp_time * 1000 / scale_ahull_lp_count,
|
|
|
|
|
log_debug(
|
|
|
|
|
" %6ld scale-to-ahull LPs (%.2lf ms per call, %.0lf ms total)\n",
|
|
|
|
|
scale_ahull_lp_count,
|
|
|
|
|
scale_ahull_lp_time * 1000 / scale_ahull_lp_count,
|
|
|
|
|
scale_ahull_lp_time * 1000);
|
|
|
|
|
|
|
|
|
|
CLEANUP:
|
|
|
|
@ -588,7 +593,6 @@ int GREEDY_ND_bound(int nrows,
|
|
|
|
|
abort_if(prev_epsilon < *epsilon, "epsilon should never increase");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(int i = 0; i < nrays; i++)
|
|
|
|
|
tx[i] = 0;
|
|
|
|
|
|
|
|
|
@ -599,7 +603,8 @@ int GREEDY_ND_bound(int nrows,
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rval = GREEDY_ND_find_tight_rays(nrows, nrays, fbar, rays, x, beta, *epsilon, tx);
|
|
|
|
|
rval = GREEDY_ND_find_tight_rays(nrows, nrays, fbar, rays, x, beta,
|
|
|
|
|
*epsilon, tx);
|
|
|
|
|
abort_if(rval, "GREEDY_ND_find_tight_rays failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -610,7 +615,6 @@ CLEANUP:
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int create_find_epsilon_lp(int nrows,
|
|
|
|
|
int nrays,
|
|
|
|
|
const double *f,
|
|
|
|
@ -700,8 +704,7 @@ static int create_find_epsilon_lp(int nrows,
|
|
|
|
|
rmatval[nz] = -1.0;
|
|
|
|
|
nz++;
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -726,8 +729,7 @@ static int create_find_epsilon_lp(int nrows,
|
|
|
|
|
rmatval[nz] = 1.0;
|
|
|
|
|
nz++;
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -748,8 +750,7 @@ static int create_find_epsilon_lp(int nrows,
|
|
|
|
|
rmatval[nz] = 1.0;
|
|
|
|
|
nz++;
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
|
|
|
|
|
rval = LP_relax(lp);
|
|
|
|
@ -798,7 +799,8 @@ int GREEDY_ND_cone_bound(int nrows,
|
|
|
|
|
rval = LP_open(&lp);
|
|
|
|
|
abort_if(rval, "LP_open failed");
|
|
|
|
|
|
|
|
|
|
rval = create_find_epsilon_lp(nrows, nrays, f, rays, t, rx, x, beta, &lp);
|
|
|
|
|
rval = create_find_epsilon_lp(nrows, nrays, f, rays, t, rx, x, beta,
|
|
|
|
|
&lp);
|
|
|
|
|
abort_if(rval, "create_find_epsilon_lp failed");
|
|
|
|
|
|
|
|
|
|
int infeasible;
|
|
|
|
@ -874,7 +876,6 @@ CLEANUP:
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int create_scale_to_ahull_lp(int nrows,
|
|
|
|
|
int nrays,
|
|
|
|
|
const double *rays,
|
|
|
|
@ -937,8 +938,7 @@ static int create_scale_to_ahull_lp(int nrows,
|
|
|
|
|
nz++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -956,8 +956,7 @@ static int create_scale_to_ahull_lp(int nrows,
|
|
|
|
|
nz++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nz, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
|
|
|
|
|
rval = LP_relax(lp);
|
|
|
|
@ -996,8 +995,8 @@ int GREEDY_ND_scale_to_ahull(int nrows,
|
|
|
|
|
rval = LP_open(&lp);
|
|
|
|
|
abort_if(rval, "LP_open failed");
|
|
|
|
|
|
|
|
|
|
rval = create_scale_to_ahull_lp(nrows, nrays, rays, rx, beta, epsilon,
|
|
|
|
|
d, &lp);
|
|
|
|
|
rval = create_scale_to_ahull_lp(nrows, nrays, rays, rx, beta, epsilon, d,
|
|
|
|
|
&lp);
|
|
|
|
|
abort_if(rval, "create_scale_to_ahull_lp failed");
|
|
|
|
|
|
|
|
|
|
int infeasible;
|
|
|
|
@ -1024,7 +1023,6 @@ CLEANUP:
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int create_tight_rays_lp(int nrows,
|
|
|
|
|
int nrays,
|
|
|
|
|
const double *f,
|
|
|
|
@ -1095,8 +1093,7 @@ static int create_tight_rays_lp(int nrows,
|
|
|
|
|
rmatval[i] = 1.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, nrays, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
|
|
|
|
|
// create constraints \lambda_r + s_r \geq \delta
|
|
|
|
@ -1111,8 +1108,7 @@ static int create_tight_rays_lp(int nrows,
|
|
|
|
|
rmatind[1] = nrays + i;
|
|
|
|
|
rmatval[1] = 1.0;
|
|
|
|
|
|
|
|
|
|
rval = LP_add_rows(lp, 1, 2, &rhs, &sense, &rmatbeg, rmatind,
|
|
|
|
|
rmatval);
|
|
|
|
|
rval = LP_add_rows(lp, 1, 2, &rhs, &sense, &rmatbeg, rmatind, rmatval);
|
|
|
|
|
abort_if(rval, "LP_add_rows failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1152,8 +1148,8 @@ int GREEDY_ND_find_tight_rays(int nrows,
|
|
|
|
|
rval = LP_open(&lp);
|
|
|
|
|
abort_if(rval, "LP_open failed");
|
|
|
|
|
|
|
|
|
|
rval = create_tight_rays_lp(nrows, nrays, f, rays, x, beta, epsilon,
|
|
|
|
|
delta, &lp);
|
|
|
|
|
rval = create_tight_rays_lp(nrows, nrays, f, rays, x, beta, epsilon, delta,
|
|
|
|
|
&lp);
|
|
|
|
|
abort_if(rval, "create_tight_rays_lp failed");
|
|
|
|
|
|
|
|
|
|
int infeasible = 0;
|
|
|
|
@ -1183,7 +1179,6 @@ CLEANUP:
|
|
|
|
|
return rval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int create_violated_cone_lp(int nrows,
|
|
|
|
|
int nrays,
|
|
|
|
|
const double *f,
|
|
|
|
@ -1270,7 +1265,8 @@ int GREEDY_ND_find_violated_cone(int nrows,
|
|
|
|
|
rval = LP_open(&lp);
|
|
|
|
|
abort_if(rval, "LP_open failed");
|
|
|
|
|
|
|
|
|
|
rval = create_violated_cone_lp(nrows, nrays, f, rays, x, beta, epsilon, &lp);
|
|
|
|
|
rval = create_violated_cone_lp(nrows, nrays, f, rays, x, beta, epsilon,
|
|
|
|
|
&lp);
|
|
|
|
|
abort_if(rval, "create_violated_cone_lp failed");
|
|
|
|
|
|
|
|
|
|
int infeasible;
|
|
|
|
|