// Initialize for edge generation rmat_iterator(RandomGenerator& gen, vertices_size_type n, edges_size_type m, double a, double b, double c, double d, bool permute_vertices = true) : gen(), n(n), a(a), b(b), c(c), d(d), edge(m), permute_vertices(permute_vertices), SCALE(int_log2(n)) { this->gen.reset(new uniform_01<RandomGenerator>(gen)); assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5))); if (permute_vertices) generate_permutation_vector(gen, vertexPermutation, n); // TODO: Generate the entire adjacency matrix then "Clip and flip" if undirected graph // Generate the first edge vertices_size_type u, v; boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d); if (permute_vertices) current = std::make_pair(vertexPermutation[u], vertexPermutation[v]); else current = std::make_pair(u, v); --edge; }
// Initialize for edge generation unique_rmat_iterator(RandomGenerator& gen, vertices_size_type n, edges_size_type m, double a, double b, double c, double d, bool permute_vertices = true, EdgePredicate ep = keep_all_edges()) : gen(), done(false) { assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5))); this->gen.reset(new uniform_01<RandomGenerator>(gen)); std::vector<vertices_size_type> vertexPermutation; if (permute_vertices) generate_permutation_vector(gen, vertexPermutation, n); int SCALE = int_log2(n); std::map<value_type, bool> edge_map; edges_size_type edges = 0; do { vertices_size_type u, v; boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d); // Lowest vertex number always comes first // (this means we don't have to worry about i->j and j->i being in the edge list) if (u > v && is_same<directed_category, undirected_tag>::value) std::swap(u, v); if (edge_map.find(std::make_pair(u, v)) == edge_map.end()) { edge_map[std::make_pair(u, v)] = true; if (permute_vertices) { if (ep(vertexPermutation[u], vertexPermutation[v])) values.push_back(std::make_pair(vertexPermutation[u], vertexPermutation[v])); } else { if (ep(u, v)) values.push_back(std::make_pair(u, v)); } edges++; } } while (edges < m); // NGE - Asking for more than n^2 edges will result in an infinite loop here // Asking for a value too close to n^2 edges may as well current = values.back(); values.pop_back(); }
// Initialize for edge generation sorted_rmat_iterator(RandomGenerator& gen, vertices_size_type n, edges_size_type m, double a, double b, double c, double d, bool permute_vertices = true, EdgePredicate ep = keep_all_edges()) : gen(), permute_vertices(permute_vertices), values(sort_pair<vertices_size_type>()), done(false) { assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5))); this->gen.reset(new uniform_01<RandomGenerator>(gen)); std::vector<vertices_size_type> vertexPermutation; if (permute_vertices) generate_permutation_vector(gen, vertexPermutation, n); // TODO: "Clip and flip" if undirected graph int SCALE = int_log2(n); for (edges_size_type i = 0; i < m; ++i) { vertices_size_type u, v; boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d); if (permute_vertices) { if (ep(vertexPermutation[u], vertexPermutation[v])) values.push(std::make_pair(vertexPermutation[u], vertexPermutation[v])); } else { if (ep(u, v)) values.push(std::make_pair(u, v)); } } current = values.top(); values.pop(); }
// Initialize for edge generation scalable_rmat_iterator(ProcessGroup pg, Distribution distrib, RandomGenerator& gen, vertices_size_type n, edges_size_type m, double a, double b, double c, double d, bool permute_vertices = true) : gen(), done(false) { BOOST_ASSERT(a + b + c + d == 1); int id = process_id(pg); this->gen.reset(new uniform_01<RandomGenerator>(gen)); std::vector<vertices_size_type> vertexPermutation; if (permute_vertices) generate_permutation_vector(gen, vertexPermutation, n); int SCALE = int(floor(log(double(n))/log(2.))); boost::uniform_01<RandomGenerator> prob(gen); std::map<value_type, bool> edge_map; edges_size_type generated = 0, local_edges = 0; do { edges_size_type tossed = 0; do { vertices_size_type u, v; boost::tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d); if (permute_vertices) { u = vertexPermutation[u]; v = vertexPermutation[v]; } // Lowest vertex number always comes first (this // means we don't have to worry about i->j and j->i // being in the edge list) if (u > v && is_same<directed_category, undirected_tag>::value) std::swap(u, v); if (distrib(u) == id || distrib(v) == id) { if (edge_map.find(std::make_pair(u, v)) == edge_map.end()) { edge_map[std::make_pair(u, v)] = true; local_edges++; } else { tossed++; // special case - if both u and v are on same // proc, ++ twice, since we divide by two (to // cover the two process case) if (distrib(u) == id && distrib(v) == id) tossed++; } } generated++; } while (generated < m); tossed = all_reduce(pg, tossed, boost::parallel::sum<vertices_size_type>()); generated -= (tossed / 2); } while (generated < m); // NGE - Asking for more than n^2 edges will result in an infinite loop here // Asking for a value too close to n^2 edges may as well values.reserve(local_edges); typename std::map<value_type, bool>::reverse_iterator em_end = edge_map.rend(); for (typename std::map<value_type, bool>::reverse_iterator em_i = edge_map.rbegin(); em_i != em_end ; ++em_i) { values.push_back(em_i->first); } current = values.back(); values.pop_back(); }