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
19 import edu.uci.ics.jung.graph.util.EdgeType;
20 import edu.uci.ics.jung.graph.util.Pair;
21
22
23
24
25
26
27
28 @SuppressWarnings("serial")
29 public abstract class AbstractGraph<V, E> implements Graph<V,E>, Serializable
30 {
31 public boolean addEdge(E edge, Collection<? extends V> vertices)
32 {
33 return addEdge(edge, vertices, this.getDefaultEdgeType());
34 }
35
36 @SuppressWarnings("unchecked")
37 public boolean addEdge(E edge, Collection<? extends V> vertices, EdgeType edgeType) {
38 if (vertices == null)
39 throw new IllegalArgumentException("'vertices' parameter must not be null");
40 if (vertices.size() == 2)
41 return addEdge(edge,
42 vertices instanceof Pair ? (Pair<V>)vertices : new Pair<V>(vertices),
43 edgeType);
44 else if (vertices.size() == 1)
45 {
46 V vertex = vertices.iterator().next();
47 return addEdge(edge, new Pair<V>(vertex, vertex), edgeType);
48 }
49 else
50 throw new IllegalArgumentException("Graph objects connect 1 or 2 vertices; vertices arg has " + vertices.size());
51 }
52
53 public boolean addEdge(E e, V v1, V v2)
54 {
55 return addEdge(e, v1, v2, this.getDefaultEdgeType());
56 }
57
58 public boolean addEdge(E e, V v1, V v2, EdgeType edge_type)
59 {
60 return addEdge(e, new Pair<V>(v1, v2), edge_type);
61 }
62
63
64
65
66
67
68
69
70
71 public boolean addEdge(E edge, Pair<? extends V> endpoints)
72 {
73 return addEdge(edge, endpoints, this.getDefaultEdgeType());
74 }
75
76
77
78
79
80
81
82
83
84
85 public abstract boolean addEdge(E edge, Pair<? extends V> endpoints, EdgeType edgeType);
86
87 protected Pair<V> getValidatedEndpoints(E edge, Pair<? extends V> endpoints)
88 {
89 if (edge == null)
90 throw new IllegalArgumentException("input edge may not be null");
91
92 if (endpoints == null)
93 throw new IllegalArgumentException("endpoints may not be null");
94
95 Pair<V> new_endpoints = new Pair<V>(endpoints.getFirst(), endpoints.getSecond());
96 if (containsEdge(edge))
97 {
98 Pair<V> existing_endpoints = getEndpoints(edge);
99 if (!existing_endpoints.equals(new_endpoints)) {
100 throw new IllegalArgumentException("edge " + edge +
101 " already exists in this graph with endpoints " + existing_endpoints +
102 " and cannot be added with endpoints " + endpoints);
103 } else {
104 return null;
105 }
106 }
107 return new_endpoints;
108 }
109
110 public int inDegree(V vertex)
111 {
112 return this.getInEdges(vertex).size();
113 }
114
115 public int outDegree(V vertex)
116 {
117 return this.getOutEdges(vertex).size();
118 }
119
120 public boolean isPredecessor(V v1, V v2)
121 {
122 return this.getPredecessors(v1).contains(v2);
123 }
124
125 public boolean isSuccessor(V v1, V v2)
126 {
127 return this.getSuccessors(v1).contains(v2);
128 }
129
130 public int getPredecessorCount(V vertex)
131 {
132 return this.getPredecessors(vertex).size();
133 }
134
135 public int getSuccessorCount(V vertex)
136 {
137 return this.getSuccessors(vertex).size();
138 }
139
140 public boolean isNeighbor(V v1, V v2)
141 {
142 if (!containsVertex(v1) || !containsVertex(v2))
143 throw new IllegalArgumentException("At least one of these not in this graph: " + v1 + ", " + v2);
144 return this.getNeighbors(v1).contains(v2);
145 }
146
147 public boolean isIncident(V vertex, E edge)
148 {
149 if (!containsVertex(vertex) || !containsEdge(edge))
150 throw new IllegalArgumentException("At least one of these not in this graph: " + vertex + ", " + edge);
151 return this.getIncidentEdges(vertex).contains(edge);
152 }
153
154 public int getNeighborCount(V vertex)
155 {
156 if (!containsVertex(vertex))
157 throw new IllegalArgumentException(vertex + " is not a vertex in this graph");
158 return this.getNeighbors(vertex).size();
159 }
160
161 public int degree(V vertex)
162 {
163 if (!containsVertex(vertex))
164 throw new IllegalArgumentException(vertex + " is not a vertex in this graph");
165 return this.getIncidentEdges(vertex).size();
166 }
167
168 public int getIncidentCount(E edge)
169 {
170 Pair<V> incident = this.getEndpoints(edge);
171 if (incident == null)
172 return 0;
173 if (incident.getFirst() == incident.getSecond())
174 return 1;
175 else
176 return 2;
177 }
178
179 public V getOpposite(V vertex, E edge)
180 {
181 Pair<V> incident = this.getEndpoints(edge);
182 V first = incident.getFirst();
183 V second = incident.getSecond();
184 if (vertex.equals(first))
185 return second;
186 else if (vertex.equals(second))
187 return first;
188 else
189 throw new IllegalArgumentException(vertex + " is not incident to " + edge + " in this graph");
190 }
191
192 public E findEdge(V v1, V v2)
193 {
194 for (E e : getOutEdges(v1))
195 {
196 if (getOpposite(v1, e).equals(v2))
197 return e;
198 }
199 return null;
200 }
201
202 public Collection<E> findEdgeSet(V v1, V v2)
203 {
204 if (!getVertices().contains(v1))
205 throw new IllegalArgumentException(v1 + " is not an element of this graph");
206
207 if (!getVertices().contains(v2))
208 throw new IllegalArgumentException(v2 + " is not an element of this graph");
209
210 Collection<E> edges = new ArrayList<E>();
211 for (E e : getOutEdges(v1))
212 {
213 if (getOpposite(v1, e).equals(v2))
214 edges.add(e);
215 }
216 return Collections.unmodifiableCollection(edges);
217 }
218
219 public Collection<V> getIncidentVertices(E edge)
220 {
221 Pair<V> endpoints = this.getEndpoints(edge);
222 Collection<V> incident = new ArrayList<V>();
223 incident.add(endpoints.getFirst());
224 incident.add(endpoints.getSecond());
225
226 return Collections.unmodifiableCollection(incident);
227 }
228
229 @Override
230 public String toString() {
231 StringBuffer sb = new StringBuffer("Vertices:");
232 for(V v : getVertices()) {
233 sb.append(v+",");
234 }
235 sb.setLength(sb.length()-1);
236 sb.append("\nEdges:");
237 for(E e : getEdges()) {
238 Pair<V> ep = getEndpoints(e);
239 sb.append(e+"["+ep.getFirst()+","+ep.getSecond()+"] ");
240 }
241 return sb.toString();
242 }
243
244 }