9 #include <boost/test/data/test_case.hpp>
10 #include <boost/test/unit_test.hpp>
25 #include <boost/functional/hash.hpp>
32 std::vector<Rectangle>
concat(std::vector<std::vector<Rectangle>> vecs) {
33 std::vector<Rectangle> flat;
34 for (std::vector<Rectangle>&
v : vecs) {
38 flat.reserve(flat.size() +
v.size());
39 std::move(
v.begin(),
v.end(), std::back_inserter(flat));
46 template <
typename RNG>
47 std::vector<Rectangle>
segment(
int x0,
int y0,
int x1,
int y1, RNG&
rng) {
55 if (xmax < xmin or ymax < ymin) {
56 return {{
x0, y0, x1, y1}};
59 std::bernoulli_distribution cointoss;
60 bool splitx = cointoss(rng);
61 bool splity = cointoss(rng);
64 if (not(splitx or splity)) {
65 return {{
x0, y0, x1, y1}};
68 int x_ = std::uniform_int_distribution(xmin, xmax)(
rng);
69 int y_ = std::uniform_int_distribution(ymin, ymax)(
rng);
71 if (splitx and not splity) {
73 }
else if (not splitx and splity) {
75 }
else if (splitx and splity) {
76 return concat({
segment(x0, y0, x_, y_, rng),
segment(x_, y0, x1, y_, rng),
79 throw std::runtime_error(
"unreachable");
114 cl.
cells.push_back(cell);
121 boost::hash_combine(cl.
hash, c.
col);
129 template <
typename RNG>
131 std::vector<Cell2D>& cells, RNG&
rng,
double startp = 0.5,
132 double decayp = 0.9) {
133 std::vector<Cell2D> add;
135 auto maybe_add = [&](
int x_,
int y_) {
137 if (std::uniform_real_distribution<double>()(rng) < startp and
138 std::find(cells.begin(), cells.end(),
c) == cells.end()) {
149 if (x < x1 and y < y1) {
150 maybe_add(x + 1, y + 1);
157 if (x < x1 and y > y0) {
158 maybe_add(x + 1, y - 1);
165 if (x > x0 and y > y0) {
166 maybe_add(x - 1, y - 1);
173 if (x > x0 and y < y1) {
174 maybe_add(x - 1, y + 1);
178 genclusterw(
c.row,
c.col, x0, y0, x1, y1, cells, rng, startp * decayp,
183 template <
typename RNG>
185 double startp = 0.5,
double decayp = 0.9) {
191 int x = std::uniform_int_distribution(x0_, x1_)(
rng);
192 int y = std::uniform_int_distribution(y0_, y1_)(
rng);
194 std::vector<Cell2D> cells = {
Cell2D(x, y)};
195 genclusterw(x, y, x0_, y0_, x1_, y1_, cells, rng, startp, decayp);
205 using CellC = std::vector<Cell>;
207 using ClusterC = std::vector<Cluster>;
211 size_t startSeed = 71902647;
214 std::cout <<
"Grid_2D_rand test with parameters: " << std::endl;
215 std::cout <<
" sizeX = " << sizeX << std::endl;
216 std::cout <<
" sizeY = " << sizeY << std::endl;
217 std::cout <<
" startSeed = " << startSeed << std::endl;
218 std::cout <<
" ntries = " << ntries << std::endl;
220 while (ntries-- > 0) {
221 std::mt19937_64
rnd(startSeed++);
223 std::vector<Cluster> cls;
224 std::vector<Cell> cells;
226 auto& [
x0, y0, x1, y1] = rect;
229 cells.insert(cells.end(), cl.cells.begin(), cl.cells.end());
233 std::shuffle(cells.begin(), cells.end(),
rnd);
235 ClusterC newCls = Ccl::createClusters<CellC, ClusterC>(cells);
237 for (Cluster& cl : newCls) {
244 BOOST_CHECK_EQUAL(cls.size(), newCls.size());
245 for (
size_t i = 0;
i < cls.size();
i++) {
246 BOOST_CHECK_EQUAL(cls.at(
i).hash, newCls.at(
i).hash);