Commit c11b6af7 authored by Tiago Peixoto's avatar Tiago Peixoto

Improve price_network() seeding semantics

Now, if 'm' is larger than the seed graph, it is set to the size of the
seed graph, and is increased progressively until it matches the desired
value. This removes the need to start with a random seed graph of the
appropriate size.

This also includes modifications which make the code more robust
against parameter choices which don't make much sense, e.g. lead to
negative probabilites.
parent 197fa68c
......@@ -53,23 +53,30 @@ struct get_price
map<double, typename graph_traits<Graph>::vertex_descriptor> probs;
double p = 0;
size_t n_possible = 0;
double cp = 0, p = 0;
typename graph_traits<Graph>::vertex_iterator vi, vi_end;
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
{
p += pow(DegSelector()(*vi, g) + c, gamma);
probs.insert(make_pair(p, *vi));
p = pow(DegSelector()(*vi, g) + c, gamma);
cp += p;
if (p > 0)
{
probs.insert(make_pair(cp, *vi));
++n_possible;
}
}
if (probs.rbegin()->first <= 0)
if (probs.empty() || probs.rbegin()->first <= 0)
throw GraphException("Cannot connect edges: probabilities are <= 0!");
tr1::unordered_set<typename graph_traits<Graph>::vertex_descriptor>
visited;
for (size_t i = 0; i < N; ++i)
{
tr1::unordered_set<typename graph_traits<Graph>::vertex_descriptor>
visited;
visited.clear();
typename graph_traits<Graph>::vertex_descriptor v = add_vertex(g);
for (size_t j = 0; j < m; ++j)
for (size_t j = 0; j < min(m, n_possible); ++j)
{
tr1::variate_generator<rng_t&, tr1::uniform_real<> >
sample(rng, tr1::uniform_real<>(0, probs.rbegin()->first));
......@@ -88,10 +95,15 @@ struct get_price
p = abs(pow(DegSelector()(w, g) + c, gamma)
- pow(DegSelector()(w, g) + c - 1, gamma));
probs.insert(make_pair(probs.rbegin()->first + p, w));
if (p > 0)
probs.insert(make_pair(probs.rbegin()->first + p, w));
}
p = pow(DegSelector()(v, g) + c, gamma);
probs.insert(make_pair(probs.rbegin()->first + p, v));
if (p > 0)
{
probs.insert(make_pair(probs.rbegin()->first + p, v));
n_possible += 1;
}
}
}
};
......
......@@ -865,11 +865,11 @@ def price_network(N, m=1, c=None, gamma=1, directed=True, seed_graph=None):
The (generalized) [price]_ network is either a directed or undirected graph
(the latter is called a Barabási-Albert network), generated dynamically by
at each step adding a new vertex, and connecting it to :math:`m` other
vertices, chosen with probability:
vertices, chosen with probability :math:`\pi` defined as:
.. math::
P \propto k^\gamma + c
\pi \propto k^\gamma + c
where :math:`k` is the in-degree of the vertex (or simply the degree in the
undirected case). If :math:`\gamma=1`, the tail of resulting in-degree
......@@ -888,6 +888,13 @@ def price_network(N, m=1, c=None, gamma=1, directed=True, seed_graph=None):
However, if :math:`\gamma \ne 1`, the in-degree distribution is not
scale-free (see [dorogovtsev-evolution]_ for details).
Note that if `seed_graph` is not given, the algorithm will *always* start
with one node if :math:`c > 0`, or with two nodes with a link between them
otherwise. If :math:`m > 1`, the degree of the newly added vertices will be
vary dynamically as :math:`m'(t) = \min(m, N(t))`, where :math:`N(t)` is the
number of vertices added so far. If this behaviour is undesired, a proper
seed graph with :math:`N \ge m` vertices must be provided.
This algorithm runs in :math:`O(N\log N)` time.
See Also
......@@ -940,17 +947,15 @@ def price_network(N, m=1, c=None, gamma=1, directed=True, seed_graph=None):
c = 1 if directed else 0
if seed_graph is None:
if directed:
g = Graph()
g.add_vertex(m)
g = Graph(directed=directed)
if c > 0:
g.add_vertex()
else:
N_s = m + 1 if m % 2 != 0 else m + 2
g = random_graph(N_s, lambda: 1, directed=False)
g.add_vertex(2)
g.add_edge(g.vertex(1), g.vertex(0))
N -= g.num_vertices()
else:
g = seed_graph
if g.num_vertices() < m:
raise ValueError("seed_graph has number of vertices < m!")
seed = numpy.random.randint(0, sys.maxint)
libgraph_tool_generation.price(g._Graph__graph, N, gamma, c, m, seed)
return g
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment