diff options
| author | Gloria Mundi <gloria@gloria-mundi.eu> | 2024-03-10 19:58:50 +0100 |
|---|---|---|
| committer | Gloria Mundi <gloria@gloria-mundi.eu> | 2024-03-10 19:58:50 +0100 |
| commit | 0f29ac59c2bf0e5eafc2a6fa436e3070085e3a1d (patch) | |
| tree | 76ee14d540722a15007aaaa51e751650024a8bca /graph | |
| parent | ffa3fde34b667dff3ffe011e1f80f43ee02d2f82 (diff) | |
improvde tests
Diffstat (limited to 'graph')
| -rw-r--r-- | graph/test/LCA_sparse.cpp | 53 | ||||
| -rw-r--r-- | graph/test/binary_lifting.cpp | 54 | ||||
| -rw-r--r-- | graph/test/util.cpp | 67 |
3 files changed, 93 insertions, 81 deletions
diff --git a/graph/test/LCA_sparse.cpp b/graph/test/LCA_sparse.cpp index 53af57b..c45111c 100644 --- a/graph/test/LCA_sparse.cpp +++ b/graph/test/LCA_sparse.cpp @@ -1,26 +1,9 @@ -#include <bits/stdc++.h> -using namespace std; -using ll = long long; - -#define sz(x) ((int)(x).size()) -#define all(x) (x).begin(), (x).end() +#include "util.cpp" #include "../../datastructures/sparseTable.cpp" #include "../LCA_sparse.cpp" -mt19937 rd(0); - -void test(const vector<vector<int>> &old_adj, int root) { - int n = old_adj.size(); - vector<int> perm(n); - iota(perm.begin(), perm.end(), 0); - ranges::shuffle(perm, rd); - vector<vector<int>> adj(n); - for (int i = 0; i < n; i++) { - auto &a = adj[perm[i]] = old_adj[i]; - for (int &v: a) v = perm[v]; - ranges::shuffle(a, rd); - } - root = perm[root]; +void test(vector<vector<int>> &adj, int root) { + int n = adj.size(); vector<int> parent(n); function<void(int,int)> dfs = [&](int u, int p) { @@ -42,10 +25,9 @@ void test(const vector<vector<int>> &old_adj, int root) { LCA lca; lca.init(adj, root); for (int i = 0; i < n; i++) assert(lca.getDepth(i) == depth(i)); - uniform_int_distribution<int> distrib(0, n-1); for (int i = 0; i < 1000; i++) { - int u = distrib(rd); - int v = distrib(rd); + int u = util::randint(n); + int v = util::randint(n); int l = lca.getLCA(u, v); assert(is_ancestor(l, u)); assert(is_ancestor(l, v)); @@ -64,27 +46,16 @@ int main() { } { // Path - vector<vector<int>> adj(100); - for (int i = 1; i < 100; i++) { - adj[i-1].push_back(i); - adj[i].push_back(i-1); - } - test(adj, 0); - test(adj, 99); - test(adj, 40); + vector<vector<int>> adj = util::path(100); + int left = 0, mid = 40, right = 99; + util::shuffle_graph(adj, left, mid, right); + test(adj, left); + test(adj, mid); + test(adj, right); } { // Random - vector<vector<int>> adj(1000); - for (int i = 1; i < 1000; i++) { - uniform_int_distribution<int> distrib(0, i-1); - int p = distrib(rd); - adj[p].push_back(i); - adj[i].push_back(p); - } + vector<vector<int>> adj = util::random_tree(1000); test(adj, 0); - test(adj, 300); - test(adj, 600); - test(adj, 900); } } diff --git a/graph/test/binary_lifting.cpp b/graph/test/binary_lifting.cpp index e1cf7d2..05b903a 100644 --- a/graph/test/binary_lifting.cpp +++ b/graph/test/binary_lifting.cpp @@ -1,22 +1,8 @@ -#include <bits/stdc++.h> -using namespace std; - +#include "util.cpp" #include "../binary_lifting.cpp" -mt19937 rd(0); - -void test(const vector<vector<int>> &old_adj, int root) { - int n = old_adj.size(); - vector<int> perm(n); - iota(perm.begin(), perm.end(), 0); - ranges::shuffle(perm, rd); - vector<vector<int>> adj(n); - for (int i = 0; i < n; i++) { - auto &a = adj[perm[i]] = old_adj[i]; - for (int &v: a) v = perm[v]; - ranges::shuffle(a, rd); - } - root = perm[root]; +void test(vector<vector<int>> &adj, int root) { + int n = adj.size(); vector<int> parent(n); function<void(int,int)> dfs = [&](int u, int p) { @@ -37,18 +23,17 @@ void test(const vector<vector<int>> &old_adj, int root) { Lift lift(adj, root); for (int i = 0; i < n; i++) assert(lift.depth(i) == depth(i)); - uniform_int_distribution<int> distrib(0, n-1); for (int i = 0; i < 1000; i++) { - int v = distrib(rd); - int d = distrib(rd); + int v = util::randint(n); + int d = util::randint(n); int u = lift.lift(v, d); assert(is_ancestor(u, v)); if (d <= depth(v)) assert(depth(u) == d); else assert(u == v); } for (int i = 0; i < 1000; i++) { - int u = distrib(rd); - int v = distrib(rd); + int u = util::randint(n); + int v = util::randint(n); int lca = lift.lca(u, v); assert(is_ancestor(lca, u)); assert(is_ancestor(lca, v)); @@ -67,27 +52,16 @@ int main() { } { // Path - vector<vector<int>> adj(100); - for (int i = 1; i < 100; i++) { - adj[i-1].push_back(i); - adj[i].push_back(i-1); - } - test(adj, 0); - test(adj, 99); - test(adj, 40); + vector<vector<int>> adj = util::path(100); + int left = 0, mid = 40, right = 99; + util::shuffle_graph(adj, left, mid, right); + test(adj, left); + test(adj, mid); + test(adj, right); } { // Random - vector<vector<int>> adj(1000); - for (int i = 1; i < 1000; i++) { - uniform_int_distribution<int> distrib(0, i-1); - int p = distrib(rd); - adj[p].push_back(i); - adj[i].push_back(p); - } + vector<vector<int>> adj = util::random_tree(1000); test(adj, 0); - test(adj, 300); - test(adj, 600); - test(adj, 900); } } diff --git a/graph/test/util.cpp b/graph/test/util.cpp new file mode 100644 index 0000000..8bec1ee --- /dev/null +++ b/graph/test/util.cpp @@ -0,0 +1,67 @@ + +namespace util { + +mt19937 rd(0); + +int randint(int x) { + assert(x > 0); + return uniform_int_distribution<int>(0, x-1)(rd); +} + +void shuffle_adj_lists(vector<vector<int>> &adj) { + for (auto &a: adj) ranges::shuffle(a, rd); +} + +vector<vector<int>> random_tree(int n) { + vector<vector<int>> adj(n); + + vector<vector<int>> components(n); + for (int i = 0; i < n; i++) components[i].push_back(i); + while (components.size() > 1) { + int c1 = randint(components.size()); + int c2 = randint(components.size()-1); + c2 += (c2 >= c1); + + int v1 = components[c1][randint(components[c1].size())]; + int v2 = components[c2][randint(components[c2].size())]; + + adj[v1].push_back(v2); + adj[v2].push_back(v1); + + if (components[c1].size() < components[c2].size()) swap(c1, c2); + for (int v: components[c2]) components[c1].push_back(v); + swap(components[c2], components.back()); + components.pop_back(); + } + + shuffle_adj_lists(adj); + return adj; +} + +vector<vector<int>> path(int n) { + vector<vector<int>> adj(n); + for (int i = 1; i < n; i++) { + adj[i-1].push_back(i); + adj[i].push_back(i-1); + } + return adj; +} + +template<typename... Ts> +void shuffle_graph(vector<vector<int>> &adj, Ts &...vertex) { + int n = adj.size(); + vector<int> perm(n); + iota(perm.begin(), perm.end(), 0); + ranges::shuffle(perm, rd); + + vector<vector<int>> new_adj(n); + for (int i = 0; i < n; i++) { + auto &a = new_adj[perm[i]] = move(adj[i]); + for (int &v: a) v = perm[v]; + } + adj = move(new_adj); + shuffle_adj_lists(adj); + ((vertex = perm[vertex]), ...); +} + +} |
