I have an array of pairs like this:
[["a", "b"], ["b", "d"], ["a", "c"], ["e", "d"], ["a", "d"], ..., ["s", "f"]]
-
What is an efficient way to check if the given array can express a partial ordering? That is, there is no “loop” in the given array like
["a", "b"], ["b", "c"], ["c", "a"]. -
If it is confirmed that the array expresses a partial order, I want to normalize this by removing all of the pairs that can be derived by reflexivity or transitivity. For example, in the above, since there is
["a", "b"]and["b", "d"], the pair["a", "d"]is redundant, and should be removed.
The order between 1 and 2 does not matter. If 2 should be done before or within the process of 1, then, that is fine.
Preferably I want it in Ruby 1.9.3, but just pseudo-code will suffice.
For the first part of the question, I came up with my own answer here with the help of an answer at a mathematics site.
For the second part of the question, after following the suggestions given in the other answers, I implemented in Ruby (i) Floyd-Warshall algorithm to calculate the transitive closure, (ii) composition, and (iii) transitive reduction using the formula R^- = R – R \cdot R^+.
Usage examples: