I am using igraph (via python) for graph clustering.
I have a tree (a minimal spanning tree of a geometric graph) with weighted-edges, and want to calculate weight times
the smaller number of vertices of the two components if the edge is
deleted:
def sep(graph, e):
h = copy(graph)
w = h.es[e]['weight']
h.delete_edges(e)
return w * min(h.components().sizes())
# 'graph' is the tree I am dealing with
ss = [sep(graph,x) for x in range(len(graph.es))]
My questiones are:
-
Is this a known (and named) property in graph theory? If so, what is
it? -
My piece of code is very inefficient if I calculate this for all the
edges, as shown above. If the graph becomes 50000 edges and vertices,
memory consumption becomes huge. Do you have some suggestions for
optimizing?
Elaborating a bit more on yurib’s answer, I would do something like this (also posted on the igraph mailing list):
I will use two attributes, one for the vertices and one for the edges. The edge attribute is simple, it will be called
cut_valueand it is eitherNoneor contains the value you are looking for. Initially, all these values areNones. We will call edges withcut_value=Noneunprocessed and edges where “cut_value is not None“` processed.The vertex attribute will be called
cut_size, and it will be valid only for vertices for which there exists exactly one unprocessed incident edge. Since you have a tree, you will always have at least one such vertex unless all the edges are processed (where you can terminate the algorithm). Initially,cut_sizewill be 1 for all the vertices (but remember, they are valid only for vertices with exactly one unprocessed incident edge).We will also have a list
degthat contains the number of unprocessed edges incident on a given node. Initially all the edges are unprocessed, hence this list contains the degrees of the vertices.So far we have this:
We will always process vertices with exactly one incident unprocessed edge. Initially, we put these in a queue:
Then we process the vertices in the queue one by one as follows, until the queue becomes empty:
First, we remove a vertex v from the queue and find its only incident edge that is unprocessed. Let this edge be denoted by e
The
cut_valueof e is the weight of e multiplied bymin(cut_size[v], n - cut_size[v]).Let the other endpoint of e be denoted by u. Since e now became processed, the number of unprocessed edges incident on u decreased by one, so we have to decrease
deg[u]by 1. Ifdeg[u]became 1, we put u in the queue. We also increase itscut_sizeby one because v is now part of the part of the graph that will be separated when we later remove the last edge incident on u.In Python, this should look like the following code (untested):