Commit cd44b291 authored by Tiago Peixoto's avatar Tiago Peixoto

vertex/edge_percolation(): Add support for second-largest component

parent c08bbf86
......@@ -25,7 +25,7 @@ using namespace boost;
using namespace graph_tool;
void percolate_edge(GraphInterface& gi, boost::any tree, boost::any size,
python::object edges, python::object max_size)
python::object edges, python::object max_size, bool second)
{
typedef property_map_type::apply<int64_t,
GraphInterface::vertex_index_map_t>::type
......@@ -54,13 +54,13 @@ void percolate_edge(GraphInterface& gi, boost::any tree, boost::any size,
multi_array_ref<uint64_t, 1> ms = get_array<uint64_t, 1>(max_size);
run_action<graph_tool::detail::never_directed>()
(gi, [&](auto& g){ edge_percolate(g, tree_map, size_map, ms, es); })();
(gi, [&](auto& g){ edge_percolate(g, tree_map, size_map, ms, es, second); })();
}
void percolate_vertex(GraphInterface& gi, boost::any tree, boost::any size,
boost::any visited, python::object vertices,
python::object max_size)
python::object max_size, bool second)
{
typedef property_map_type::apply<int64_t,
GraphInterface::vertex_index_map_t>::type
......@@ -104,7 +104,7 @@ void percolate_vertex(GraphInterface& gi, boost::any tree, boost::any size,
run_action<graph_tool::detail::never_directed>()
(gi, [&](auto& g){ vertex_percolate(g, tree_map, size_map, visited_map,
ms, vs); })();
ms, vs, second); })();
}
#include <boost/python.hpp>
......
......@@ -43,16 +43,21 @@ auto find_root(size_t vi, TreeMap tree, Graph& g,
template <class Graph, class TreeMap, class SizeMap>
auto join_cluster(const pair<size_t, size_t>& e, TreeMap tree, SizeMap size,
Graph& g, vector<size_t>& temp)
Graph& g, vector<size_t>& shist, vector<size_t>& temp)
{
auto rs = find_root(e.first, tree, g, temp);
auto rt = find_root(e.second, tree, g, temp);
if (rt != rs)
{
if (size[rs] < size[rt])
auto srs = size[rs];
auto srt = size[rt];
if (srs < srt)
swap(rs, rt);
tree[rt] = rs;
size[rs] += size[rt];
shist[srs]--;
shist[srt]--;
shist[size[rs]]++;
return size[rs];
}
return std::max(size[rs], size[rt]);
......@@ -61,16 +66,29 @@ auto join_cluster(const pair<size_t, size_t>& e, TreeMap tree, SizeMap size,
template <class Graph, class TreeMap, class SizeMap, class MaxSize,
class Edges>
void edge_percolate(Graph& g, TreeMap tree, SizeMap size, MaxSize& max_size,
Edges& edges)
Edges& edges, bool second)
{
vector<size_t> temp;
vector<size_t> shist(num_vertices(g) + 1);
shist[1] = num_vertices(g);
size_t ms = 0;
for (size_t i = 0; i < edges.size(); ++i)
{
size_t s = join_cluster({edges[i][0], edges[i][1]},
tree, size, g, temp);
tree, size, g, shist, temp);
ms = std::max(ms, s);
max_size[i] = ms;
if (!second)
{
max_size[i] = ms;
}
else
{
for (size_t s = 1; s < ms; ++s)
{
if (shist[s] > 0)
max_size[i] = s;
}
}
}
boost::multi_array_ref<typename Edges::element, 1>
......@@ -87,9 +105,11 @@ void edge_percolate(Graph& g, TreeMap tree, SizeMap size, MaxSize& max_size,
template <class Graph, class TreeMap, class SizeMap, class VisitedMap,
class MaxSize, class Vertices>
void vertex_percolate(Graph& g, TreeMap tree, SizeMap size, VisitedMap visited,
MaxSize& max_size, Vertices& vertices)
MaxSize& max_size, Vertices& vertices, bool second)
{
vector<size_t> temp;
vector<size_t> shist(num_vertices(g) + 1);
shist[1] = num_vertices(g);
size_t ms = 0;
for (size_t i = 0; i < vertices.size(); ++i)
{
......@@ -105,10 +125,21 @@ void vertex_percolate(Graph& g, TreeMap tree, SizeMap size, VisitedMap visited,
if (!visited[a])
continue;
size_t s = join_cluster({v, a}, tree, size, g,
temp);
shist, temp);
ms = std::max(ms, s);
}
max_size[i] = std::max(ms, size_t(1));
if (!second)
{
max_size[i] = std::max(ms, size_t(1));
}
else
{
for (size_t s = 1; s < ms; ++s)
{
if (shist[s] > 0)
max_size[i] = s;
}
}
visited[v] = true;
}
......
......@@ -1261,8 +1261,9 @@ def label_biconnected_components(g, eprop=None, vprop=None):
_prop("v", g, vprop))
return eprop, vprop, hist
def vertex_percolation(g, vertices):
"""Compute the size of the largest component as vertices are (virtually)
def vertex_percolation(g, vertices, second=False):
"""Compute the size of the largest or second-largest component as vertices
are (virtually)
removed from the graph.
Parameters
......@@ -1271,11 +1272,14 @@ def vertex_percolation(g, vertices):
Graph to be used.
vertices : :class:`numpy.ndarray` or iterable of ints
List of vertices in reversed order of removal.
second : bool (optional, default: ``False``)
If ``True``, the size of the second-largest component will be computed.
Returns
-------
size : :class:`numpy.ndarray`
Size of the largest component prior to removal of each vertex.
Size of the largest (or second-largest) component prior to removal of
each vertex.
comp : :class:`~graph_tool.PropertyMap`
Vertex property map with component labels.
......@@ -1339,13 +1343,13 @@ def vertex_percolation(g, vertices):
_prop("v", u, tree),
_prop("v", u, size),
_prop("v", u, visited),
vertices, max_size)
vertices, max_size, second)
return max_size, tree
def edge_percolation(g, edges):
"""Compute the size of the largest component as edges are (virtually)
removed from the graph.
def edge_percolation(g, edges, second=False):
"""Compute the size of the largest or second-largest component as edges are
(virtually) removed from the graph.
Parameters
----------
......@@ -1356,11 +1360,14 @@ def edge_percolation(g, edges):
:class:`numpy.ndarray`, it should have a shape ``(E, 2)``, where ``E``
is the number of edges, such that ``edges[i,0]`` and ``edges[i,1]`` are
the both endpoints of edge ``i``.
second : bool (optional, default: ``False``)
If ``True``, the size of the second-largest component will be computed.
Returns
-------
size : :class:`numpy.ndarray`
Size of the largest component prior to removal of each edge.
Size of the largest (or second-largest) component prior to removal of
each edge.
comp : :class:`~graph_tool.PropertyMap`
Vertex property map with component labels.
......@@ -1423,7 +1430,7 @@ def edge_percolation(g, edges):
percolate_edge(u._Graph__graph,
_prop("v", u, tree),
_prop("v", u, size),
edges, max_size)
edges, max_size, second)
return max_size, tree
def kcore_decomposition(g, vprop=None):
......
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