1 /*
2 * Created on Oct 17, 2005
3 *
4 * Copyright (c) 2005, The JUNG Authors
5 *
6 * All rights reserved.
7 *
8 * This software is open-source under the BSD license; see either
9 * "license.txt" or
10 * https://github.com/jrtom/jung/blob/master/LICENSE for a description.
11 */
12 package edu.uci.ics.jung.graph;
13
14 import java.util.Collection;
15
16 import edu.uci.ics.jung.graph.util.EdgeType;
17
18 /**
19 * A hypergraph, consisting of a set of vertices of type <code>V</code>
20 * and a set of hyperedges of type <code>E</code> which connect the vertices.
21 * This is the base interface for all JUNG graph types.
22 * <P>
23 * This interface permits, but does not enforce, any of the following
24 * common variations of graphs:
25 * <ul>
26 * <li>hyperedges (edges which connect a set of vertices of any size)
27 * <li>edges (these have have exactly two endpoints, which may or may not be distinct)
28 * <li>self-loops (edges which connect exactly one vertex)
29 * <li>directed and undirected edges
30 * <li>vertices and edges with attributes (for example, weighted edges)
31 * <li>vertices and edges with different constraints or properties (for example, bipartite
32 * or multimodal graphs)
33 * <li>parallel edges (multiple edges which connect a single set of vertices)
34 * <li>internal representations as matrices or as adjacency lists or adjacency maps
35 * </ul>
36 * Extensions or implementations of this interface
37 * may enforce or disallow any or all of these variations.
38 * <p><b>Notes</b>:
39 * <ul>
40 * <li> The collections returned by <code>Hypergraph</code> instances
41 * should be treated in general as if read-only. While they are not contractually
42 * guaranteed (or required) to be immutable,
43 * this interface does not define the outcome if they are mutated.
44 * Mutations should be done via <code>{add,remove}{Edge,Vertex}</code>, or
45 * in the constructor.
46 * <li>
47 * </ul>
48 *
49 * @author Joshua O'Madadhain
50 */
51 public interface Hypergraph<V, E>
52 {
53 /**
54 * Returns a view of all edges in this graph. In general, this
55 * obeys the <code>Collection</code> contract, and therefore makes no guarantees
56 * about the ordering of the vertices within the set.
57 * @return a <code>Collection</code> view of all edges in this graph
58 */
59 Collection<E> getEdges();
60
61 /**
62 * Returns a view of all vertices in this graph. In general, this
63 * obeys the <code>Collection</code> contract, and therefore makes no guarantees
64 * about the ordering of the vertices within the set.
65 * @return a <code>Collection</code> view of all vertices in this graph
66 */
67 Collection<V> getVertices();
68
69 /**
70 * Returns true if this graph's vertex collection contains <code>vertex</code>.
71 * Equivalent to <code>getVertices().contains(vertex)</code>.
72 * @param vertex the vertex whose presence is being queried
73 * @return true iff this graph contains a vertex <code>vertex</code>
74 */
75 boolean containsVertex(V vertex);
76
77 /**
78 * Returns true if this graph's edge collection contains <code>edge</code>.
79 * Equivalent to <code>getEdges().contains(edge)</code>.
80 * @param edge the edge whose presence is being queried
81 * @return true iff this graph contains an edge <code>edge</code>
82 */
83 boolean containsEdge(E edge);
84
85 /**
86 * Returns the number of edges in this graph.
87 * @return the number of edges in this graph
88 */
89 int getEdgeCount();
90
91 /**
92 * Returns the number of vertices in this graph.
93 * @return the number of vertices in this graph
94 */
95 int getVertexCount();
96
97 /**
98 * Returns the collection of vertices which are connected to <code>vertex</code>
99 * via any edges in this graph.
100 * If <code>vertex</code> is connected to itself with a self-loop, then
101 * it will be included in the collection returned.
102 *
103 * @param vertex the vertex whose neighbors are to be returned
104 * @return the collection of vertices which are connected to <code>vertex</code>,
105 * or <code>null</code> if <code>vertex</code> is not present
106 */
107 Collection<V> getNeighbors(V vertex);
108
109 /**
110 * Returns the collection of edges in this graph which are connected to <code>vertex</code>.
111 *
112 * @param vertex the vertex whose incident edges are to be returned
113 * @return the collection of edges which are connected to <code>vertex</code>,
114 * or <code>null</code> if <code>vertex</code> is not present
115 */
116 Collection<E> getIncidentEdges(V vertex);
117
118 /**
119 * Returns the collection of vertices in this graph which are connected to <code>edge</code>.
120 * Note that for some graph types there are guarantees about the size of this collection
121 * (i.e., some graphs contain edges that have exactly two endpoints, which may or may
122 * not be distinct). Implementations for those graph types may provide alternate methods
123 * that provide more convenient access to the vertices.
124 *
125 * @param edge the edge whose incident vertices are to be returned
126 * @return the collection of vertices which are connected to <code>edge</code>,
127 * or <code>null</code> if <code>edge</code> is not present
128 */
129 Collection<V> getIncidentVertices(E edge);
130
131 /**
132 * Returns an edge that connects this vertex to <code>v</code>.
133 * If this edge is not uniquely
134 * defined (that is, if the graph contains more than one edge connecting
135 * <code>v1</code> to <code>v2</code>), any of these edges
136 * may be returned. <code>findEdgeSet(v1, v2)</code> may be
137 * used to return all such edges.
138 * Returns null if either of the following is true:
139 * <ul>
140 * <li><code>v2</code> is not connected to <code>v1</code>
141 * <li>either <code>v1</code> or <code>v2</code> are not present in this graph
142 * </ul>
143 * <p><b>Note</b>: for purposes of this method, <code>v1</code> is only considered to be connected to
144 * <code>v2</code> via a given <i>directed</i> edge <code>e</code> if
145 * <code>v1 == e.getSource() && v2 == e.getDest()</code> evaluates to <code>true</code>.
146 * (<code>v1</code> and <code>v2</code> are connected by an undirected edge <code>u</code> if
147 * <code>u</code> is incident to both <code>v1</code> and <code>v2</code>.)
148 *
149 * @param v1 the first endpoint of the returned edge
150 * @param v2 the second endpoint of the returned edge
151 * @return an edge that connects <code>v1</code> to <code>v2</code>,
152 * or <code>null</code> if no such edge exists (or either vertex is not present)
153 * @see Hypergraph#findEdgeSet(Object, Object)
154 */
155 E findEdge(V v1, V v2);
156
157 /**
158 * Returns all edges that connects this vertex to <code>v</code>.
159 * If this edge is not uniquely
160 * defined (that is, if the graph contains more than one edge connecting
161 * <code>v1</code> to <code>v2</code>), any of these edges
162 * may be returned. <code>findEdgeSet(v1, v2)</code> may be
163 * used to return all such edges.
164 * Returns null if <code>v2</code> is not connected to <code>v1</code>.
165 * <br>Returns an empty collection if either <code>v1</code> or <code>v2</code>
166 * are not present in this graph.
167 *
168 * <p><b>Note</b>: for purposes of this method, <code>v1</code> is only considered to be connected to
169 * <code>v2</code> via a given <i>directed</i> edge <code>d</code> if
170 * <code>v1 == d.getSource() && v2 == d.getDest()</code> evaluates to <code>true</code>.
171 * (<code>v1</code> and <code>v2</code> are connected by an undirected edge <code>u</code> if
172 * <code>u</code> is incident to both <code>v1</code> and <code>v2</code>.)
173 *
174 * @param v1 the first endpoint of the returned edge set
175 * @param v2 the second endpoint of the returned edge set
176 * @return a collection containing all edges that connect <code>v1</code> to <code>v2</code>,
177 * or <code>null</code> if either vertex is not present
178 * @see Hypergraph#findEdge(Object, Object)
179 */
180 Collection<E> findEdgeSet(V v1, V v2);
181
182 /**
183 * Adds <code>vertex</code> to this graph.
184 * Fails if <code>vertex</code> is null or already in the graph.
185 *
186 * @param vertex the vertex to add
187 * @return <code>true</code> if the add is successful, and <code>false</code> otherwise
188 * @throws IllegalArgumentException if <code>vertex</code> is <code>null</code>
189 */
190 boolean addVertex(V vertex);
191
192 /**
193 * Adds <code>edge</code> to this graph.
194 * Fails under the following circumstances:
195 * <ul>
196 * <li><code>edge</code> is already an element of the graph
197 * <li>either <code>edge</code> or <code>vertices</code> is <code>null</code>
198 * <li><code>vertices</code> has the wrong number of vertices for the graph type
199 * <li><code>vertices</code> are already connected by another edge in this graph,
200 * and this graph does not accept parallel edges
201 * </ul>
202 *
203 * @param edge the edge to add
204 * @param vertices the vertices to which the edge will be connected
205 * @return <code>true</code> if the add is successful, and <code>false</code> otherwise
206 * @throws IllegalArgumentException if <code>edge</code> or <code>vertices</code> is null,
207 * or if a different vertex set in this graph is already connected by <code>edge</code>,
208 * or if <code>vertices</code> are not a legal vertex set for <code>edge</code>
209 */
210 boolean addEdge(E edge, Collection<? extends V> vertices);
211
212 /**
213 * Adds <code>edge</code> to this graph with type <code>edge_type</code>.
214 * Fails under the following circumstances:
215 * <ul>
216 * <li><code>edge</code> is already an element of the graph
217 * <li>either <code>edge</code> or <code>vertices</code> is <code>null</code>
218 * <li><code>vertices</code> has the wrong number of vertices for the graph type
219 * <li><code>vertices</code> are already connected by another edge in this graph,
220 * and this graph does not accept parallel edges
221 * <li><code>edge_type</code> is not legal for this graph
222 * </ul>
223 *
224 * @param edge edge to add to this graph
225 * @param vertices vertices which are to be connected by this edge
226 * @param edge_type type of edge to add
227 * @return <code>true</code> if the add is successful, and <code>false</code> otherwise
228 * @throws IllegalArgumentException if <code>edge</code> or <code>vertices</code> is null,
229 * or if a different vertex set in this graph is already connected by <code>edge</code>,
230 * or if <code>vertices</code> are not a legal vertex set for <code>edge</code>
231 */
232 boolean addEdge(E edge, Collection<? extends V> vertices, EdgeType
233 edge_type);
234
235 /**
236 * Removes <code>vertex</code> from this graph.
237 * As a side effect, removes any edges <code>e</code> incident to <code>vertex</code> if the
238 * removal of <code>vertex</code> would cause <code>e</code> to be incident to an illegal
239 * number of vertices. (Thus, for example, incident hyperedges are not removed, but
240 * incident edges--which must be connected to a vertex at both endpoints--are removed.)
241 *
242 * <p>Fails under the following circumstances:
243 * <ul>
244 * <li><code>vertex</code> is not an element of this graph
245 * <li><code>vertex</code> is <code>null</code>
246 * </ul>
247 *
248 * @param vertex the vertex to remove
249 * @return <code>true</code> if the removal is successful, <code>false</code> otherwise
250 */
251 boolean removeVertex(V vertex);
252
253 /**
254 * Removes <code>edge</code> from this graph.
255 * Fails if <code>edge</code> is null, or is otherwise not an element of this graph.
256 *
257 * @param edge the edge to remove
258 * @return <code>true</code> if the removal is successful, <code>false</code> otherwise
259 */
260 boolean removeEdge(E edge);
261
262
263 /**
264 * Returns <code>true</code> if <code>v1</code> and <code>v2</code> share an incident edge.
265 * Equivalent to <code>getNeighbors(v1).contains(v2)</code>.
266 *
267 * @param v1 the first vertex to test
268 * @param v2 the second vertex to test
269 * @return <code>true</code> if <code>v1</code> and <code>v2</code> share an incident edge
270 */
271 boolean isNeighbor(V v1, V v2);
272
273 /**
274 * Returns <code>true</code> if <code>vertex</code> and <code>edge</code>
275 * are incident to each other.
276 * Equivalent to <code>getIncidentEdges(vertex).contains(edge)</code> and to
277 * <code>getIncidentVertices(edge).contains(vertex)</code>.
278 * @param vertex vertex to test
279 * @param edge edge to test
280 * @return <code>true</code> if <code>vertex</code> and <code>edge</code>
281 * are incident to each other
282 */
283 boolean isIncident(V vertex, E edge);
284
285 /**
286 * Returns the number of edges incident to <code>vertex</code>.
287 * Special cases of interest:
288 * <ul>
289 * <li> Incident self-loops are counted once.
290 * <li> If there is only one edge that connects this vertex to
291 * each of its neighbors (and vice versa), then the value returned
292 * will also be equal to the number of neighbors that this vertex has
293 * (that is, the output of <code>getNeighborCount</code>).
294 * <li> If the graph is directed, then the value returned will be
295 * the sum of this vertex's indegree (the number of edges whose
296 * destination is this vertex) and its outdegree (the number
297 * of edges whose source is this vertex), minus the number of
298 * incident self-loops (to avoid double-counting).
299 * </ul>
300 * <p>Equivalent to <code>getIncidentEdges(vertex).size()</code>.
301 *
302 * @param vertex the vertex whose degree is to be returned
303 * @return the degree of this node
304 * @see Hypergraph#getNeighborCount(Object)
305 */
306 int degree(V vertex);
307
308 /**
309 * Returns the number of vertices that are adjacent to <code>vertex</code>
310 * (that is, the number of vertices that are incident to edges in <code>vertex</code>'s
311 * incident edge set).
312 *
313 * <p>Equivalent to <code>getNeighbors(vertex).size()</code>.
314 * @param vertex the vertex whose neighbor count is to be returned
315 * @return the number of neighboring vertices
316 */
317 int getNeighborCount(V vertex);
318
319 /**
320 * Returns the number of vertices that are incident to <code>edge</code>.
321 * For hyperedges, this can be any nonnegative integer; for edges this
322 * must be 2 (or 1 if self-loops are permitted).
323 *
324 * <p>Equivalent to <code>getIncidentVertices(edge).size()</code>.
325 * @param edge the edge whose incident vertex count is to be returned
326 * @return the number of vertices that are incident to <code>edge</code>.
327 */
328 int getIncidentCount(E edge);
329
330 /**
331 * Returns the edge type of <code>edge</code> in this graph.
332 * @param edge the edge whose type is to be returned
333 * @return the <code>EdgeType</code> of <code>edge</code>, or <code>null</code> if <code>edge</code> has no defined type
334 */
335 EdgeType getEdgeType(E edge);
336
337 /**
338 * Returns the default edge type for this graph.
339 *
340 * @return the default edge type for this graph
341 */
342 EdgeType getDefaultEdgeType();
343
344 /**
345 * Returns the collection of edges in this graph which are of type <code>edge_type</code>.
346 * @param edge_type the type of edges to be returned
347 * @return the collection of edges which are of type <code>edge_type</code>, or
348 * <code>null</code> if the graph does not accept edges of this type
349 * @see EdgeType
350 */
351 Collection<E> getEdges(EdgeType edge_type);
352
353 /**
354 * Returns the number of edges of type <code>edge_type</code> in this graph.
355 * @param edge_type the type of edge for which the count is to be returned
356 * @return the number of edges of type <code>edge_type</code> in this graph
357 */
358 int getEdgeCount(EdgeType edge_type);
359
360 /**
361 * Returns a <code>Collection</code> view of the incoming edges incident to <code>vertex</code>
362 * in this graph.
363 * @param vertex the vertex whose incoming edges are to be returned
364 * @return a <code>Collection</code> view of the incoming edges incident
365 * to <code>vertex</code> in this graph
366 */
367 Collection<E> getInEdges(V vertex);
368
369 /**
370 * Returns a <code>Collection</code> view of the outgoing edges incident to <code>vertex</code>
371 * in this graph.
372 * @param vertex the vertex whose outgoing edges are to be returned
373 * @return a <code>Collection</code> view of the outgoing edges incident
374 * to <code>vertex</code> in this graph
375 */
376 Collection<E> getOutEdges(V vertex);
377
378 /**
379 * Returns the number of incoming edges incident to <code>vertex</code>.
380 * Equivalent to <code>getInEdges(vertex).size()</code>.
381 * @param vertex the vertex whose indegree is to be calculated
382 * @return the number of incoming edges incident to <code>vertex</code>
383 */
384 int inDegree(V vertex);
385
386 /**
387 * Returns the number of outgoing edges incident to <code>vertex</code>.
388 * Equivalent to <code>getOutEdges(vertex).size()</code>.
389 * @param vertex the vertex whose outdegree is to be calculated
390 * @return the number of outgoing edges incident to <code>vertex</code>
391 */
392 int outDegree(V vertex);
393
394 /**
395 * If <code>directed_edge</code> is a directed edge in this graph, returns the source;
396 * otherwise returns <code>null</code>.
397 * The source of a directed edge <code>d</code> is defined to be the vertex for which
398 * <code>d</code> is an outgoing edge.
399 * <code>directed_edge</code> is guaranteed to be a directed edge if
400 * its <code>EdgeType</code> is <code>DIRECTED</code>.
401 * @param directed_edge the edge whose source is to be returned
402 * @return the source of <code>directed_edge</code> if it is a directed edge in this graph, or <code>null</code> otherwise
403 */
404 V getSource(E directed_edge);
405
406 /**
407 * If <code>directed_edge</code> is a directed edge in this graph, returns the destination;
408 * otherwise returns <code>null</code>.
409 * The destination of a directed edge <code>d</code> is defined to be the vertex
410 * incident to <code>d</code> for which
411 * <code>d</code> is an incoming edge.
412 * <code>directed_edge</code> is guaranteed to be a directed edge if
413 * its <code>EdgeType</code> is <code>DIRECTED</code>.
414 * @param directed_edge the edge whose destination is to be returned
415 * @return the destination of <code>directed_edge</code> if it is a directed edge in this graph, or <code>null</code> otherwise
416 */
417 V getDest(E directed_edge);
418
419 /**
420 * Returns a <code>Collection</code> view of the predecessors of <code>vertex</code>
421 * in this graph. A predecessor of <code>vertex</code> is defined as a vertex <code>v</code>
422 * which is connected to
423 * <code>vertex</code> by an edge <code>e</code>, where <code>e</code> is an outgoing edge of
424 * <code>v</code> and an incoming edge of <code>vertex</code>.
425 * @param vertex the vertex whose predecessors are to be returned
426 * @return a <code>Collection</code> view of the predecessors of
427 * <code>vertex</code> in this graph
428 */
429 Collection<V> getPredecessors(V vertex);
430
431 /**
432 * Returns a <code>Collection</code> view of the successors of <code>vertex</code>
433 * in this graph. A successor of <code>vertex</code> is defined as a vertex <code>v</code>
434 * which is connected to
435 * <code>vertex</code> by an edge <code>e</code>, where <code>e</code> is an incoming edge of
436 * <code>v</code> and an outgoing edge of <code>vertex</code>.
437 * @param vertex the vertex whose predecessors are to be returned
438 * @return a <code>Collection</code> view of the successors of
439 * <code>vertex</code> in this graph
440 */
441 Collection<V> getSuccessors(V vertex);
442 }