1
2
3
4
5
6
7
8
9
10
11
12 package edu.uci.ics.jung.graph;
13
14 import java.io.Serializable;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.Map;
21 import java.util.Set;
22
23 import com.google.common.base.Supplier;
24
25 import edu.uci.ics.jung.graph.util.EdgeType;
26
27
28
29
30
31 @SuppressWarnings("serial")
32 public class SetHypergraph<V,H>
33 implements Hypergraph<V,H>, MultiGraph<V,H>, Serializable
34 {
35 protected Map<V, Set<H>> vertices;
36 protected Map<H, Set<V>> edges;
37
38
39
40
41
42
43
44 public static <V,H> Supplier<Hypergraph<V,H>> getFactory() {
45 return new Supplier<Hypergraph<V,H>> () {
46 public Hypergraph<V,H> get() {
47 return new SetHypergraph<V,H>();
48 }
49 };
50 }
51
52
53
54
55 public SetHypergraph()
56 {
57 vertices = new HashMap<V, Set<H>>();
58 edges = new HashMap<H, Set<V>>();
59 }
60
61
62
63
64
65
66
67
68 public boolean addEdge(H hyperedge, Collection<? extends V> to_attach)
69 {
70 if (hyperedge == null)
71 throw new IllegalArgumentException("input hyperedge may not be null");
72
73 if (to_attach == null)
74 throw new IllegalArgumentException("endpoints may not be null");
75
76 if(to_attach.contains(null))
77 throw new IllegalArgumentException("cannot add an edge with a null endpoint");
78
79 Set<V> new_endpoints = new HashSet<V>(to_attach);
80 if (edges.containsKey(hyperedge))
81 {
82 Collection<V> attached = edges.get(hyperedge);
83 if (!attached.equals(new_endpoints))
84 {
85 throw new IllegalArgumentException("Edge " + hyperedge +
86 " exists in this graph with endpoints " + attached);
87 }
88 else
89 return false;
90 }
91 edges.put(hyperedge, new_endpoints);
92 for (V v : to_attach)
93 {
94
95 addVertex(v);
96
97
98 vertices.get(v).add(hyperedge);
99 }
100 return true;
101 }
102
103
104
105
106 public boolean addEdge(H hyperedge, Collection<? extends V> to_attach,
107 EdgeType edge_type)
108 {
109 if (edge_type != EdgeType.UNDIRECTED)
110 throw new IllegalArgumentException("Edge type for this " +
111 "implementation must be EdgeType.HYPER, not " +
112 edge_type);
113 return addEdge(hyperedge, to_attach);
114 }
115
116
117
118
119 public EdgeType getEdgeType(H edge)
120 {
121 if (containsEdge(edge))
122 return EdgeType.UNDIRECTED;
123 else
124 return null;
125 }
126
127 public boolean containsVertex(V vertex) {
128 return vertices.keySet().contains(vertex);
129 }
130
131 public boolean containsEdge(H edge) {
132 return edges.keySet().contains(edge);
133 }
134
135 public Collection<H> getEdges()
136 {
137 return edges.keySet();
138 }
139
140 public Collection<V> getVertices()
141 {
142 return vertices.keySet();
143 }
144
145 public int getEdgeCount()
146 {
147 return edges.size();
148 }
149
150 public int getVertexCount()
151 {
152 return vertices.size();
153 }
154
155 public Collection<V> getNeighbors(V vertex)
156 {
157 if (!containsVertex(vertex))
158 return null;
159
160 Set<V> neighbors = new HashSet<V>();
161 for (H hyperedge : vertices.get(vertex))
162 {
163 neighbors.addAll(edges.get(hyperedge));
164 }
165 return neighbors;
166 }
167
168 public Collection<H> getIncidentEdges(V vertex)
169 {
170 return vertices.get(vertex);
171 }
172
173 public Collection<V> getIncidentVertices(H edge)
174 {
175 return edges.get(edge);
176 }
177
178 public H findEdge(V v1, V v2)
179 {
180 if (!containsVertex(v1) || !containsVertex(v2))
181 return null;
182
183 for (H h : getIncidentEdges(v1))
184 {
185 if (isIncident(v2, h))
186 return h;
187 }
188 return null;
189 }
190
191 public Collection<H> findEdgeSet(V v1, V v2)
192 {
193 if (!containsVertex(v1) || !containsVertex(v2))
194 return null;
195
196 Collection<H> edges = new ArrayList<H>();
197 for (H h : getIncidentEdges(v1))
198 {
199 if (isIncident(v2, h))
200 edges.add(h);
201 }
202 return Collections.unmodifiableCollection(edges);
203 }
204
205 public boolean addVertex(V vertex)
206 {
207 if(vertex == null)
208 throw new IllegalArgumentException("cannot add a null vertex");
209 if (containsVertex(vertex))
210 return false;
211 vertices.put(vertex, new HashSet<H>());
212 return true;
213 }
214
215 public boolean removeVertex(V vertex)
216 {
217 if (!containsVertex(vertex))
218 return false;
219 for (H hyperedge : vertices.get(vertex))
220 {
221 edges.get(hyperedge).remove(vertex);
222 }
223 vertices.remove(vertex);
224 return true;
225 }
226
227 public boolean removeEdge(H hyperedge)
228 {
229 if (!containsEdge(hyperedge))
230 return false;
231 for (V vertex : edges.get(hyperedge))
232 {
233 vertices.get(vertex).remove(hyperedge);
234 }
235 edges.remove(hyperedge);
236 return true;
237 }
238
239 public boolean isNeighbor(V v1, V v2)
240 {
241 if (!containsVertex(v1) || !containsVertex(v2))
242 return false;
243
244 if (vertices.get(v2).isEmpty())
245 return false;
246 for (H hyperedge : vertices.get(v1))
247 {
248 if (edges.get(hyperedge).contains(v2))
249 return true;
250 }
251 return false;
252 }
253
254 public boolean isIncident(V vertex, H edge)
255 {
256 if (!containsVertex(vertex) || !containsEdge(edge))
257 return false;
258
259 return vertices.get(vertex).contains(edge);
260 }
261
262 public int degree(V vertex)
263 {
264 if (!containsVertex(vertex))
265 return 0;
266
267 return vertices.get(vertex).size();
268 }
269
270 public int getNeighborCount(V vertex)
271 {
272 if (!containsVertex(vertex))
273 return 0;
274
275 return getNeighbors(vertex).size();
276 }
277
278 public int getIncidentCount(H edge)
279 {
280 if (!containsEdge(edge))
281 return 0;
282
283 return edges.get(edge).size();
284 }
285
286 public int getEdgeCount(EdgeType edge_type)
287 {
288 if (edge_type == EdgeType.UNDIRECTED)
289 return edges.size();
290 return 0;
291 }
292
293 public Collection<H> getEdges(EdgeType edge_type)
294 {
295 if (edge_type == EdgeType.UNDIRECTED)
296 return edges.keySet();
297 return null;
298 }
299
300 public EdgeType getDefaultEdgeType()
301 {
302 return EdgeType.UNDIRECTED;
303 }
304
305 public Collection<H> getInEdges(V vertex)
306 {
307 return getIncidentEdges(vertex);
308 }
309
310 public Collection<H> getOutEdges(V vertex)
311 {
312 return getIncidentEdges(vertex);
313 }
314
315 public int inDegree(V vertex)
316 {
317 return degree(vertex);
318 }
319
320 public int outDegree(V vertex)
321 {
322 return degree(vertex);
323 }
324
325 public V getDest(H directed_edge)
326 {
327 return null;
328 }
329
330 public V getSource(H directed_edge)
331 {
332 return null;
333 }
334
335 public Collection<V> getPredecessors(V vertex)
336 {
337 return getNeighbors(vertex);
338 }
339
340 public Collection<V> getSuccessors(V vertex)
341 {
342 return getNeighbors(vertex);
343 }
344 }