small_world_iterator& operator++() { target = (target + 1) % n; if (target == (source + k/2 + 1) % n) { ++source; if (allow_self_loops) target = source; else target = (source + 1) % n; } current.first = source; uniform_01<RandomGenerator, double> rand01(*gen); uniform_int<vertices_size_type> rand_vertex_gen(0, n-1); double x = rand01(); *gen = rand01.base(); // GRRRR if (x < prob) { vertices_size_type lower = (source + n - k/2) % n; vertices_size_type upper = (source + k/2) % n; do { current.second = rand_vertex_gen(*gen); } while ((current.second >= lower && current.second <= upper) || (upper < lower && (current.second >= lower || current.second <= upper))); } else { current.second = target; } return *this; }
small_world_iterator(RandomGenerator& gen, vertices_size_type n, vertices_size_type k, double prob = 0.0, bool allow_self_loops = false, bool allow_multiple_edges = true) : gen(&gen), n(n), k(k+k%2), prob(prob), source(0), target(allow_self_loops? 0 : 1), allow_self_loops(allow_self_loops), allow_multiple_edges(allow_multiple_edges), current(0, allow_self_loops? 0 : 1), #if !defined BOOST_NO_HASH edges(allow_multiple_edges? 0 : (k + k%2)*n/2) #else edges() #endif {} reference operator*() const { return current; } pointer operator->() const { return ¤t; } small_world_iterator& operator++() { current.first = source; uniform_01<RandomGenerator, double> rand01(*gen); uniform_int<vertices_size_type> rand_vertex_gen(0, n-1); double x = rand01(); *gen = rand01.base(); // GRRRR vertices_size_type larger_v = 0; vertices_size_type smaller_v = 0; if (x < prob) { do { current.second = rand_vertex_gen(*gen); if (!allow_multiple_edges) { larger_v = current.first; smaller_v = current.second; if (current.first < current.second) { smaller_v = current.first; larger_v = current.second; } } // std::cout << "swg " << current.first << " " << current.second << " " << smaller_v*n + larger_v << std::endl; } while ((!allow_self_loops && current.first == current.second) || (!allow_multiple_edges && (current.first < k/2 && current.second >= n - k/2 + current.first)) || (!allow_multiple_edges && (edges.find(smaller_v*n + larger_v) != edges.end()))); } else { current.second = target; if (!allow_multiple_edges) { larger_v = current.first; smaller_v = current.second; if (current.first < current.second) { smaller_v = current.first; larger_v = current.second; } } } if (!allow_multiple_edges) { edges.insert(smaller_v*n + larger_v); // std::cout << "added " << current.first << " " << current.second << " " << smaller_v*n + larger_v << std::endl; } target = (target + 1) % n; if (target == (source + k/2 + 1) % n) { ++source; if (allow_self_loops) target = source; else target = (source + 1) % n; } return *this; } small_world_iterator operator++(int) { small_world_iterator temp(*this); ++(*this); return temp; }