Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

breaking up undirected graphs

by nosbod (Scribe)
on Mar 15, 2007 at 17:07 UTC ( [id://605025]=perlquestion: print w/replies, xml ) Need Help??

nosbod has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I have an undirected graph containing interacting pairs. This graph is huge.

I want to break the graph into clusters.

All I have is a list of interacting pairs eg.

1,2
1,4
2,3
3,4
4,7
7,8
7,10
8,9
9,10

In this example everything is linked. It could be made into 2 clusters however if we broke the connection between pairs 4 and 7 as this is the single link between hubs containing 1,2,3,4 and 7,8,9,10.

Is there some standard method for performing such I task. It has to be a common problem I imagine?

TIA

UPDATE: thanks, lots of useful stuff here.
Graph::undirected works a treat. One slight issue though. Each time I run the script I have to create the graph. The graph has ~50,000 edges which means it takes over 10 minutes to build. Is there some way of writing the graph to disk so that it can be loaded back into memory quicker that recreating the graph from fresh?

Replies are listed 'Best First'.
Re: breaking up undirected graphs
by blokhead (Monsignor) on Mar 15, 2007 at 18:50 UTC
    It sounds like you are looking for an edge whose removal disconnects the graph (edge 4,7 in your case). This is called a "cut-edge" or a "bridge". Fortunately, Graph has a simple way to find all the bridges:
    use Graph::Undirected; my $g = Graph::Undirected->new; $g->add_edges( map [ split /,/, $_ ], qw[ 1,2 1,4 2,3 3,4 4,7 7,8 7,10 8,9 9,10 ] ); my @bridges = $g->bridges; print "Found bridge(s):\n"; print " - @$_\n" for @bridges; $g->delete_edge(@$_) for @bridges; print "Resulting components:\n"; print " - @$_\n" for $g->connected_components; __END__ Found bridge(s): - 4 7 Resulting components: - 4 1 2 3 - 8 9 10 7
    I'm not sure, but the bridges method may not work if the graph is not connected (the biconnectivity method computes the same information and has such a warning in the documentation).

    Update: showed how to remove bridges to obtain list of "clusters" that is induced.

    blokhead

Re: breaking up undirected graphs
by jettero (Monsignor) on Mar 15, 2007 at 17:12 UTC

    The standard method probably involves using the methods exported by Graph and it's child modules. It is a remarkably complete suite of graph packages (Graph::Undirected in particular).

    Despite numerous re-readings, I'm not sure I understand how you wish to cluster them. If I understand the question, you wish to group neighbors into clusters without disconnecting the graph? You can try removing things and use the is_connected method to see if you broke it.

    UPDATE: I deleted some of this post because I think blokhead "solved" the question 100% ... a few posts down from here.

    -Paul

Re: breaking up undirected graphs
by jdporter (Paladin) on Mar 15, 2007 at 17:38 UTC

    You want the connected_components method of the Graph module. That's exactly what it does.

    A word spoken in Mind will reach its own level, in the objective world, by its own weight
Re: breaking up undirected graphs
by Anonymous Monk on Mar 16, 2007 at 00:04 UTC
    if I understand you correctly this seems to be the answer: www.inf.ufpr.br/info/techrep/RT_DINF003_2004.ps.gz
Re: breaking up undirected graphs
by Moron (Curate) on Mar 19, 2007 at 15:14 UTC
    This reminds me more than a bit of the TSP, or rather a subtask for solving the TSP, being to generate and test paths through a network until a certain type of solution is found. The most standard algorithm I know is the Neural Network, albeit that the TSP itself was eventually solved by just a better brute force algorithm than had been found earlier and I suspect the same to be true of this variant. But whereas there are modules like Math:Combinatorics and Algorithm::Loops to get you started, finding the best solution will still require some hard grind I think.

    -M

    Free your mind

Re: breaking up undirected graphs
by agianni (Hermit) on Mar 18, 2007 at 19:58 UTC
    This isn't a Perl solution, but if you are primarily interested in identifying clusters in your graph, you might consider using a network analysis tool, like UCINET which does cluster analysis. It depends on what you mean by large (do you have over 200 nodes in your graph?) UCINET and many of the other tools I'm aware of have limitations as to the size of the graph they can analyze.
    split//,q{john hurl, pest caretaker}and(map{print @_[$_]}(join(q{},map +{sprintf(qq{%010u},$_)}(2**2*307*4993,5*101*641*5261,7*59*79*36997,13 +*17*71*45131,3**2*67*89*167*181))=~/\d{2}/g));
Re: breaking up undirected graphs
by hatter (Pilgrim) on Mar 20, 2007 at 13:03 UTC

    You could try something like FreezeThaw for caching the object to disk.

    the hatter

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://605025]
Approved by ikegami
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2024-04-25 11:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found