diff options
author | Jeffrey Straszheim <straszheimjeffrey@gmail.com> | 2009-02-24 04:56:19 +0000 |
---|---|---|
committer | Jeffrey Straszheim <straszheimjeffrey@gmail.com> | 2009-02-24 04:56:19 +0000 |
commit | 62f3f77fc90f82dadafbf2971ca0c4c1ee7cdcb7 (patch) | |
tree | eb98583c7f7438c09f0c651dc5235811527d4df7 | |
parent | f4f34fb7112b54ffae63ef166e832b90daaa428c (diff) |
Added component-graph
-rw-r--r-- | src/clojure/contrib/graph.clj | 20 | ||||
-rw-r--r-- | src/clojure/contrib/test_contrib/test_graph.clj | 18 |
2 files changed, 37 insertions, 1 deletions
diff --git a/src/clojure/contrib/graph.clj b/src/clojure/contrib/graph.clj index 1979c0db..94199893 100644 --- a/src/clojure/contrib/graph.clj +++ b/src/clojure/contrib/graph.clj @@ -13,7 +13,8 @@ ;; straszheimjeffrey (gmail) ;; Created 23 June 2009 -(ns clojure.contrib.graph) +(ns clojure.contrib.graph + (use [clojure.set :only (union)])) (defstruct directed-graph @@ -77,6 +78,23 @@ (recur ns nv (conj acc comp)))))] (step po #{} []))) +(defn component-graph + "Given a graph, perhaps with cycles, return a reduced graph that is acyclic. + Each node in the new graph will be a set of nodes from the old. + These sets are the strongly connected components. Each edge will + be the union of all the edges of the prior graph." + [g] + (let [sccs (scc g) + find-node-set (fn [n] + (some #(if (% n) % nil) sccs)) + find-neighbors (fn [ns] + (let [nbs1 (map (partial get-neighbors g) ns) + nbs2 (map set nbs1) + nbs3 (apply union nbs2)] + (set (map find-node-set nbs3)))) + nm (into {} (map (fn [ns] [ns (find-neighbors ns)]) sccs))] + (struct directed-graph (set sccs) nm))) + (defn self-recursive-sets "Returns, as a sequence of sets, the components of a graph that are self-recursive." diff --git a/src/clojure/contrib/test_contrib/test_graph.clj b/src/clojure/contrib/test_contrib/test_graph.clj index 248203fd..6638fa4c 100644 --- a/src/clojure/contrib/test_contrib/test_graph.clj +++ b/src/clojure/contrib/test_contrib/test_graph.clj @@ -67,6 +67,24 @@ #{#{:h} #{:g} #{:i :j} #{:b :c :a :d :e} #{:f}})) (is (empty? (scc empty-graph)))) +(deftest test-component-graph + (let [cg (component-graph test-graph-2) + ecg (component-graph empty-graph)] + (is (= (:nodes cg) (set (scc test-graph-2)))) + (is (= (get-neighbors cg #{:a :b :c :d :e}) + #{#{:a :b :c :d :e}})) + (is (= (get-neighbors cg #{:g}) + #{#{:a :b :c :d :e} #{:f}})) + (is (= (get-neighbors cg #{:i :j}) + #{#{:i :j}})) + (is (= (get-neighbors cg #{:h}) + #{})) + (is (= ecg empty-graph)))) + +(comment + (run-tests) +) + (deftest test-self-recursive-sets (is (= (set (self-recursive-sets test-graph-2)) |