aboutsummaryrefslogtreecommitdiff
path: root/src/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java')
-rw-r--r--src/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java b/src/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java
new file mode 100644
index 0000000..d1615c7
--- /dev/null
+++ b/src/uk/ac/ox/cs/pagoda/constraints/DependencyGraph.java
@@ -0,0 +1,119 @@
1package uk.ac.ox.cs.pagoda.constraints;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.LinkedList;
6import java.util.Map;
7import java.util.Queue;
8import java.util.Set;
9
10public abstract class DependencyGraph<T> {
11
12 protected abstract void build();
13
14 protected Map<T, Set<T>> edges = new HashMap<T, Set<T>>();
15 protected Map<T, Set<T>> reverseEdges = new HashMap<T, Set<T>>();
16
17 public void addLink(T subEntity, T superEntity) {
18 Set<T> dests = edges.get(subEntity);
19 if (dests == null)
20 edges.put(subEntity, dests = new HashSet<T>());
21 dests.add(superEntity);
22
23 Set<T> srcs = reverseEdges.get(superEntity);
24 if (srcs == null)
25 reverseEdges.put(superEntity, srcs = new HashSet<T>());
26 srcs.add(subEntity);
27 }
28
29 public void output() {
30 for (Map.Entry<T, Set<T>> pair: edges.entrySet()) {
31 T src = pair.getKey();
32 for (T dest: pair.getValue())
33 System.out.println(src + " -> " + dest);
34 }
35 }
36
37 public int distance(Set<T> dsts, T src) {
38 Set<T> visited = new HashSet<T>();
39 if (dsts.contains(src)) return 0;
40 visited.add(src);
41 return distance(dsts, visited);
42 }
43
44 public int distance(Set<T> dsts, T src1, T src2) {
45 Set<T> visited = new HashSet<T>();
46 if (dsts.contains(src1)) return 0;
47 if (dsts.contains(src2)) return 0;
48 visited.add(src1);
49 visited.add(src2);
50 return distance(dsts, visited);
51 }
52
53 private int distance(Set<T> dsts, Set<T> visited) {
54 Queue<Entry> queue = new LinkedList<Entry>();
55 for (T src: visited)
56 queue.add(new Entry(src, 0, visited));
57
58 Entry entry;
59 Set<T> edge;
60 while (!queue.isEmpty()) {
61 entry = queue.poll();
62 edge = edges.get(entry.m_entity);
63 if (edge != null)
64 for (T next: edge) {
65 if (dsts.contains(next)) return entry.m_dist + 1;
66
67 if (!visited.contains(next))
68 queue.add(new Entry(next, entry.m_dist + 1, visited));
69 }
70 }
71
72 return Integer.MAX_VALUE;
73 }
74
75 public Set<T> getAncesters(T p) {
76 return getDependency(p, false);
77 }
78
79 public Set<T> getSuccessors(T p) {
80 return getDependency(p, true);
81 }
82
83 private Set<T> getDependency(T p, boolean succ) {
84 return succ ? getDependency(p, edges) : getDependency(p, reverseEdges);
85 }
86
87 private Set<T> getDependency(T p, Map<T, Set<T>> graph) {
88 Set<T> visited = new HashSet<T>();
89 Queue<T> queue = new LinkedList<T>();
90 visited.add(p);
91 queue.add(p);
92 Set<T> edge;
93
94 while (!queue.isEmpty()) {
95 if ((edge = graph.get(queue.poll())) != null)
96 for (T next: edge)
97 if (!visited.contains(next)) {
98 queue.add(next);
99 visited.add(next);
100 }
101 }
102
103 return visited;
104 }
105
106 private class Entry {
107
108 T m_entity;
109 int m_dist;
110
111 public Entry(T entity, int distance, Set<T> v) {
112 m_entity = entity;
113 m_dist = distance;
114 v.add(entity);
115 }
116
117 }
118
119}