// graph-tool -- a general graph modification and manipulation thingy // // Copyright (C) 2007-2012 Tiago de Paula Peixoto // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 3 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . #ifndef GRAPH_PRICE_HH #define GRAPH_PRICE_HH #include #include #include "graph_util.hh" #if (GCC_VERSION >= 40400) # include # include #else # include # include #endif #include #include namespace graph_tool { using namespace std; using namespace boost; typedef tr1::mt19937 rng_t; struct get_price { template void operator()(Graph& g, size_t N, double gamma, double c, size_t m, size_t seed) const { rng_t rng(static_cast(seed)); typedef typename mpl::if_::type, in_degreeS, out_degreeS>::type DegSelector; map::vertex_descriptor> probs; size_t n_possible = 0; double cp = 0, p = 0; typename graph_traits::vertex_iterator vi, vi_end; for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi) { p = pow(DegSelector()(*vi, g) + c, gamma); cp += p; if (p > 0) { probs.insert(make_pair(cp, *vi)); ++n_possible; } } if (probs.empty() || probs.rbegin()->first <= 0) throw GraphException("Cannot connect edges: probabilities are <= 0!"); tr1::unordered_set::vertex_descriptor> visited; for (size_t i = 0; i < N; ++i) { visited.clear(); typename graph_traits::vertex_descriptor v = add_vertex(g); for (size_t j = 0; j < min(m, n_possible); ++j) { tr1::variate_generator > sample(rng, tr1::uniform_real<>(0, probs.rbegin()->first)); double r = sample(); typeof(probs.begin()) iter = probs.lower_bound(r); typename graph_traits::vertex_descriptor w = iter->second; if (visited.find(w) != visited.end()) { --j; continue; } visited.insert(w); add_edge(v, w, g); p = abs(pow(DegSelector()(w, g) + c, gamma) - pow(DegSelector()(w, g) + c - 1, gamma)); if (p > 0) probs.insert(make_pair(probs.rbegin()->first + p, w)); } p = pow(DegSelector()(v, g) + c, gamma); if (p > 0) { probs.insert(make_pair(probs.rbegin()->first + p, v)); n_possible += 1; } } } }; } // namespace graph_tool #endif // GRAPH_PRICE_HH