views:

475

answers:

2

I have been looking for an algorithm to perform a transitive reduction on a graph, but without success. There's nothing in my algorithms bible (Introduction To Algorithms by Cormen et al) and whilst I've seen plenty of transitive closure pseudocode, I haven't been able to track down anything for a reduction. The closest I've got is that there is one in "Algorithmische Graphentheorie" by Volker Turau (ISBN:978-3-486-59057-9), but unfortunately I don't have access to this book! Wikipedia is unhelpful and Google is yet to turn up anything. :^(

Does anyone know of an algorithm for performing a transitive reduction?

+1  A: 

The Wikipedia article on transitive reduction points to an implementation within GraphViz (which is open source). Not exactly pseudocode, but maybe someplace to start?

LEDA includes a transitive reduction algorithm. I don't have a copy of the LEDA book anymore, and this function might have been added after the book was published. But if it's in there, then there will be a good description of the algorithm.

Google points to an algorithm that somebody suggested for inclusion in Boost. I didn't try to read it, so maybe not correct?

Also, this might be worth a look.

Eric
Thanks (belatedly!) for your response. In the end, I emailed the author of an algorithms book and asked him to verify whether some pseudocode I'd written was correct, which he kindly did.
girlwithglasses
A: 

The basic gist of the transitive reduction algorithm I used is


foreach x in graph.vertices
   foreach y in graph.vertices
      foreach z in graph.vertices
         delete edge xz if edges xy and yz exist

The transitive closure algorithm I used in the same script is very similar but the last line is


         add edge xz if edges xy and yz OR edge xz exist
girlwithglasses
Joey Adams
Also, if the graph has cycles, this algorithm won't always produce the *minimal* transitive reduction. For instance, try it on `[0,1,2,3,4,5]` where A points to B for all A and B (even when they're the same). It should produce something like 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 0, but running this algorithm (with my tweak) brings in 5 -> 2 and 5 -> 4 in addition to 0 -> ... -> 5 -> 0. Running it without my tweak produces no edges at all.
Joey Adams
I should have stated that my code included checks for the identical edges you mentioned, and also that I'm working solely with DAGs, so the cycles aren't an issue.
girlwithglasses