Commit 804c0d89 authored by Chuanren Wu's avatar Chuanren Wu

enable refinement

parent 06bf18dc
......@@ -34,10 +34,10 @@ static bool redist(
const double d = vl[i]*factor*n + rem;
const double x = std::floor(d);
if (x < minRes[i]) {
changed |= res[i] != minRes[i];
changed = changed || res[i] != minRes[i];
res[i] = minRes[i];
} else {
changed |= res[i] != x;
changed = changed || res[i] != x;
res[i] = x;
rem = d-x;
assert(rem < 1);
......@@ -46,7 +46,7 @@ static bool redist(
});
const int idFirst = *s.cbegin();
const int first =std::max(minRes[idFirst], atLeast1(rest));
changed |= res[idFirst] != first;
changed = changed || res[idFirst] != first;
res[idFirst] = first;
return changed;
}
......@@ -80,7 +80,7 @@ static bool balance(
std::vector<int> &res
)
{
const long maxIter = 100;
const long maxIter = 1000;
long iterations = 0;
bool trigger = true;
while (trigger && iterations < maxIter) {
......@@ -105,6 +105,26 @@ static bool balance(
}
}
static bool refine(
const std::vector<Constraint> &vc,
const std::vector<int> &minRes,
const std::vector<double> &vl,
std::vector<int> &res
)
{
bool changed = false;
auto sumFunction = [&res](int s, int i) { return s + res[i]; };
for (auto const &c : vc) {
const int sumPlus = std::accumulate(
c.plus().cbegin(), c.plus().cend(), 0, sumFunction);
changed = changed || redist(sumPlus, c.plus(), minRes, vl, res);
const int sumMinus = std::accumulate(
c.minus().cbegin(), c.minus().cend(), 0, sumFunction);
changed = changed || redist(sumMinus, c.minus(), minRes, vl, res);
}
return changed;
}
std::vector<int> discretizeImpl(
const std::vector<double> &vl,
const std::vector<Constraint> &vc
......@@ -114,9 +134,24 @@ std::vector<int> discretizeImpl(
std::transform(vl.begin(), vl.end(), minRes.begin(), atLeast1<double>);
// sort(vc) before the iterations?
auto res = minRes;
if (balance(vc, minRes, vl, res)) {
return res;
} else {
return std::vector<int>();
bool needRefine = true;
const int MAX_REFINE_ITER = 1000;
int refineIterations = 0;
while (needRefine) {
if (balance(vc, minRes, vl, res)) {
if (refineIterations >= MAX_REFINE_ITER) {
break;
}
needRefine = refine(vc, minRes, vl, res);
if (needRefine) {
#ifndef NDEBUG
std::cout << "refine!\n";
#endif
++refineIterations;
}
} else {
return std::vector<int>();
}
}
return res;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment