Files
BMSSP/generator/gen3.cpp
2025-10-30 20:30:31 +09:00

76 lines
2.1 KiB
C++

#include "testlib.h"
#include <limits>
#include <thread>
#include <vector>
using namespace std;
using ll = unsigned long long;
using pll = pair<ll, ll>;
const double eps = 1e-3;
void generate_edges(int thread_id, unsigned int seed, ll n, double pm,
ll start_node, ll end_node,
vector<pair<pll, double>> &output) {
random_t thread_rnd;
thread_rnd.setSeed(seed);
for (ll s = start_node; s <= end_node; ++s) {
for (ll e = 1; e <= n; ++e) {
if (s == e) continue;
if (thread_rnd.next(1.0) < pm) {
double len = thread_rnd.next(eps, 1.0 / eps);
output.push_back({{s, e}, len});
}
}
}
}
int main(int argc, char *argv[]) {
registerGen(argc, argv, 1);
ll n = opt<ll>("N");
double pm = opt<double>("pm");
ensuref(0 <= pm && pm <= 1, "pm must be in [0, 1]: %lf", pm);
// ll m_approx = n * (n - 1) * pm;
unsigned int n_threads = thread::hardware_concurrency();
if (n_threads == 0) n_threads = 2;
vector<unsigned int> seeds(n_threads);
for (unsigned int i = 0; i < n_threads; ++i) {
seeds[i] = rnd.next(numeric_limits<unsigned int>::min(),
numeric_limits<unsigned int>::max());
}
vector<thread> threads;
vector<vector<pair<pll, double>>> thread_outputs(n_threads);
ll nodes_per_thread = (n + n_threads - 1) / n_threads;
for (unsigned int i = 0; i < n_threads; ++i) {
ll start_node = i * nodes_per_thread + 1;
ll end_node = min((i + 1) * nodes_per_thread, n);
if (start_node > end_node) continue;
threads.emplace_back(generate_edges, i, seeds[i], n, pm, start_node,
end_node, ref(thread_outputs[i]));
}
vector<pair<pll, double>> E;
for (unsigned int i = 0; i < threads.size(); ++i) {
threads[i].join();
E.insert(E.end(), thread_outputs[i].begin(), thread_outputs[i].end());
}
shuffle(E.begin(), E.end());
println(n, E.size());
for (auto [p, l] : E) println(p.first, p.second, l);
}