1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package edu.uci.ics.jung.graph;
24
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.apache.commons.collections15.Factory;
34
35 import edu.uci.ics.jung.graph.util.EdgeType;
36 import edu.uci.ics.jung.graph.util.Pair;
37
38
39
40
41
42 @SuppressWarnings("serial")
43 public class UndirectedSparseMultigraph<V,E>
44 extends AbstractTypedGraph<V,E>
45 implements UndirectedGraph<V,E>, MultiGraph<V,E>
46 {
47
48
49
50
51
52 public static <V,E> Factory<UndirectedGraph<V,E>> getFactory() {
53 return new Factory<UndirectedGraph<V,E>> () {
54
55 public UndirectedGraph<V,E> create() {
56 return new UndirectedSparseMultigraph<V,E>();
57 }
58 };
59 }
60
61 protected Map<V, Set<E>> vertices;
62 protected Map<E, Pair<V>> edges;
63
64
65
66
67 public UndirectedSparseMultigraph() {
68 super(EdgeType.UNDIRECTED);
69 vertices = new HashMap<V, Set<E>>();
70 edges = new HashMap<E, Pair<V>>();
71 }
72
73 public Collection<E> getEdges() {
74 return Collections.unmodifiableCollection(edges.keySet());
75 }
76
77 public Collection<V> getVertices() {
78 return Collections.unmodifiableCollection(vertices.keySet());
79 }
80
81 public boolean containsVertex(V vertex) {
82 return vertices.keySet().contains(vertex);
83 }
84
85 public boolean containsEdge(E edge) {
86 return edges.keySet().contains(edge);
87 }
88
89 protected Collection<E> getIncident_internal(V vertex)
90 {
91 return vertices.get(vertex);
92 }
93
94 public boolean addVertex(V vertex) {
95 if(vertex == null) {
96 throw new IllegalArgumentException("vertex may not be null");
97 }
98 if (!containsVertex(vertex))
99 {
100 vertices.put(vertex, new HashSet<E>());
101 return true;
102 } else {
103 return false;
104 }
105 }
106
107 public boolean removeVertex(V vertex) {
108 if (!containsVertex(vertex))
109 return false;
110
111 for (E edge : new ArrayList<E>(getIncident_internal(vertex)))
112 removeEdge(edge);
113
114 vertices.remove(vertex);
115 return true;
116 }
117
118 @Override
119 public boolean addEdge(E edge, V v1, V v2, EdgeType edgeType) {
120 return addEdge(edge, new Pair<V>(v1, v2), edgeType);
121 }
122
123 @Override
124 public boolean addEdge(E edge, Pair<? extends V> endpoints, EdgeType edge_type)
125 {
126 validateEdgeType(edge_type);
127
128 Pair<V> new_endpoints = getValidatedEndpoints(edge, endpoints);
129 if (new_endpoints == null)
130 return false;
131
132 V v1 = endpoints.getFirst();
133 V v2 = endpoints.getSecond();
134
135 edges.put(edge, new_endpoints);
136
137 if (!containsVertex(v1))
138 this.addVertex(v1);
139
140 if (!containsVertex(v2))
141 this.addVertex(v2);
142
143 vertices.get(v1).add(edge);
144 vertices.get(v2).add(edge);
145
146 return true;
147 }
148
149 public boolean removeEdge(E edge) {
150 if (!containsEdge(edge))
151 return false;
152
153 Pair<V> endpoints = getEndpoints(edge);
154 V v1 = endpoints.getFirst();
155 V v2 = endpoints.getSecond();
156
157
158 vertices.get(v1).remove(edge);
159 vertices.get(v2).remove(edge);
160
161 edges.remove(edge);
162 return true;
163 }
164
165 public Collection<E> getInEdges(V vertex) {
166 return this.getIncidentEdges(vertex);
167 }
168
169 public Collection<E> getOutEdges(V vertex) {
170 return this.getIncidentEdges(vertex);
171 }
172
173 public Collection<V> getPredecessors(V vertex) {
174 return this.getNeighbors(vertex);
175 }
176
177 public Collection<V> getSuccessors(V vertex) {
178 return this.getNeighbors(vertex);
179 }
180
181 public Collection<V> getNeighbors(V vertex) {
182 if (!containsVertex(vertex))
183 return null;
184
185 Set<V> neighbors = new HashSet<V>();
186 for (E edge : getIncident_internal(vertex))
187 {
188 Pair<V> endpoints = this.getEndpoints(edge);
189 V e_a = endpoints.getFirst();
190 V e_b = endpoints.getSecond();
191 if (vertex.equals(e_a))
192 neighbors.add(e_b);
193 else
194 neighbors.add(e_a);
195 }
196
197 return Collections.unmodifiableCollection(neighbors);
198 }
199
200 public Collection<E> getIncidentEdges(V vertex) {
201 if (!containsVertex(vertex))
202 return null;
203
204 return Collections.unmodifiableCollection(getIncident_internal(vertex));
205 }
206
207 @Override
208 public E findEdge(V v1, V v2) {
209 if (!containsVertex(v1) || !containsVertex(v2))
210 return null;
211 for (E edge : getIncident_internal(v1)) {
212 Pair<V> endpoints = this.getEndpoints(edge);
213 V e_a = endpoints.getFirst();
214 V e_b = endpoints.getSecond();
215 if ((v1.equals(e_a) && v2.equals(e_b)) || (v1.equals(e_b) && v2.equals(e_a)))
216 return edge;
217 }
218 return null;
219 }
220
221 public Pair<V> getEndpoints(E edge) {
222 return edges.get(edge);
223 }
224
225 public V getDest(E directed_edge) {
226 return null;
227 }
228
229 public V getSource(E directed_edge) {
230 return null;
231 }
232
233 public boolean isDest(V vertex, E edge) {
234 return false;
235 }
236
237 public boolean isSource(V vertex, E edge) {
238 return false;
239 }
240
241 public int getEdgeCount() {
242 return edges.size();
243 }
244
245 public int getVertexCount() {
246 return vertices.size();
247 }
248
249 }