Skip to content

Commit 6e63e4e

Browse files
committed
Init project sources
1 parent f81ac3d commit 6e63e4e

File tree

14 files changed

+2370
-0
lines changed

14 files changed

+2370
-0
lines changed

src/graphs/firstversion/Graph.java

Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
package graphs.firstversion;
2+
3+
import java.util.HashMap;
4+
import java.util.LinkedList;
5+
import java.util.ListIterator;
6+
import java.util.Map;
7+
import java.util.NoSuchElementException;
8+
9+
/**
10+
* Class implementing a graph data structure
11+
*
12+
* @param <V> type of elements used as identifier for graph vertexes
13+
*/
14+
public class Graph<V> {
15+
16+
private final HashMap<V, LinkedList<Edge>> adjs;
17+
private final boolean oriented;
18+
19+
/**
20+
* Constructor for an empty graph
21+
*
22+
* @param oriented boolean value specifying the graph orientation:
23+
* true if oriented, false if not
24+
*/
25+
public Graph(boolean oriented) {
26+
this.adjs = new HashMap();
27+
this.oriented = oriented;
28+
}
29+
30+
/**
31+
* Method that adds a vertex to graph
32+
*
33+
* @param vertexName the label of the vertex to add
34+
*/
35+
public void addVertex(V vertexName) {
36+
adjs.putIfAbsent(vertexName, new LinkedList());
37+
}
38+
39+
/**
40+
* Method adding a connection between two vertexes already present in the graph
41+
*
42+
* @param src the label of the connection starting vertex
43+
* @param dest the label of the connection ending vertex
44+
* @param weight the cost of the connection
45+
* @throws NoSuchElementException if one of the two vertexes doesn't exist in the graph
46+
*/
47+
public void addEdge(V src, V dest, double weight) {
48+
if (!containsVertex(src)) {
49+
throw new NoSuchElementException("Vertex " + src.toString() + " not found while creating edge");
50+
}
51+
if (!containsVertex(dest)) {
52+
throw new NoSuchElementException("Vertex " + dest.toString() + " not found while creating edge");
53+
}
54+
if (!containsEdge(src, dest)) {
55+
adjs.get(src).add(new Edge(dest, weight));
56+
if (!oriented) {
57+
adjs.get(dest).add(new Edge(src, weight));
58+
}
59+
}
60+
}
61+
62+
/**
63+
* Method that adds a connection between two vertexes; if they don't exist they are created
64+
*
65+
* @param src the label of the connection starting vertex
66+
* @param dest the label of the connection ending vertex
67+
* @param weight the cost of the connection
68+
*/
69+
public void addEdgeForced(V src, V dest, double weight) {
70+
addVertex(src);
71+
addVertex(dest);
72+
if (!containsEdge(src, dest)) {
73+
adjs.get(src).add(new Edge(dest, weight));
74+
if (!oriented) {
75+
adjs.get(dest).add(new Edge(src, weight));
76+
}
77+
}
78+
}
79+
80+
/**
81+
* Method that removes a vertex and all its references from the graph
82+
*
83+
* @param vertexName the label of the vertex to remove
84+
* @throws NoSuchElementException if the vertex to be removed is not contained in the graph
85+
*/
86+
public void removeVertex(V vertexName) {
87+
if (!containsVertex(vertexName)) {
88+
throw new NoSuchElementException("Vertex " + vertexName.toString() + " not found while removing it");
89+
}
90+
adjs.remove(vertexName);
91+
for (LinkedList<Edge> link : adjs.values()) {
92+
ListIterator<Edge> i = link.listIterator();
93+
while (i.hasNext()) {
94+
Edge e = i.next();
95+
if (e.getDestination() == vertexName) {
96+
i.remove();
97+
}
98+
}
99+
}
100+
}
101+
102+
/**
103+
* Method that removes a connection between two vertexes
104+
*
105+
* @param src the label of the connection starting vertex
106+
* @param dest the label of the connection ending vertex
107+
* @throws NoSuchElementException if one of the two vertexes isn't contained in the graph
108+
* or the edge does not exist
109+
*/
110+
public void removeEdge(V src, V dest) {
111+
if (!containsVertex(src)) {
112+
throw new NoSuchElementException("Edge can't be removed because vertex " + src.toString() + " doesn't exist");
113+
}
114+
if (!containsVertex(dest)) {
115+
throw new NoSuchElementException("Edge can't be removed because vertex " + dest.toString() + " doesn't exist");
116+
}
117+
if (!containsEdge(src, dest)) {
118+
throw new NoSuchElementException("Edge to be removed doesn't exist");
119+
}
120+
121+
ListIterator<Edge> i = adjs.get(src).listIterator();
122+
while (i.hasNext()) {
123+
Edge e = i.next();
124+
if (e.dest == dest) {
125+
i.remove();
126+
}
127+
}
128+
129+
if (!oriented) {
130+
i = adjs.get(dest).listIterator();
131+
while (i.hasNext()) {
132+
Edge e = i.next();
133+
if (e.dest == src) {
134+
i.remove();
135+
}
136+
}
137+
}
138+
139+
}
140+
141+
/**
142+
* Method returning all vertexes contained in the graph
143+
*
144+
* @return a list of all graph vertexes
145+
*/
146+
public LinkedList<V> getAllVertex() {
147+
return new LinkedList(adjs.keySet());
148+
}
149+
150+
/**
151+
* Method returning all connections of a given vertex on the graph
152+
*
153+
* @param vertex the label of the vertex
154+
* @return a list of all connections related to the vertex, passed as param
155+
*/
156+
public LinkedList<V> getVertexAdjs(V vertex) {
157+
LinkedList<V> out = new LinkedList();
158+
for (Edge e : adjs.get(vertex)) {
159+
out.add(e.dest);
160+
}
161+
return out;
162+
}
163+
164+
/**
165+
* Method telling if a certain edge, specified by its vertexes, is contained in the graph
166+
*
167+
* @param src the label of the connection starting vertex
168+
* @param dest the label of the connection ending ertex
169+
* @return true if the calculated edge is contained in the graph, false if not
170+
* @throws NoSuchElementException when the edge does not exist because one (or both) specified
171+
* vertex (vertexes) is (are) not in the graph
172+
*/
173+
public boolean containsEdge(V src, V dest) {
174+
if (!containsVertex(src)) {
175+
throw new NoSuchElementException("Edge not found because vertex " + src.toString() + " doesn't exist");
176+
}
177+
if (!containsVertex(dest)) {
178+
throw new NoSuchElementException("Edge not found because vertex " + dest.toString() + " doesn't exist");
179+
}
180+
for (Edge e : adjs.get(src)) {
181+
if (e.dest == dest) {
182+
return true;
183+
}
184+
}
185+
return false;
186+
}
187+
188+
/**
189+
* Method returning the weight of an edge, specified by its vertexes
190+
*
191+
* @param src the label of the connection starting vertex
192+
* @param dest the label of the connection ending vertex
193+
* @return a double value for the edge weight
194+
* @throws NoSuchElementException when the edge does not exist because one (or both) specified
195+
* vertex (vertexes) is (are) not in the graph
196+
*/
197+
public Double getEdgeWeight(V src, V dest) {
198+
if (!containsVertex(src)) {
199+
throw new NoSuchElementException("Edge not found because vertex " + src.toString() + " doesn't exist");
200+
}
201+
if (!containsVertex(dest)) {
202+
throw new NoSuchElementException("Edge not found because vertex " + dest.toString() + " doesn't exist");
203+
}
204+
LinkedList<Edge> srcEdges = adjs.get(src);
205+
for (Edge e : srcEdges) {
206+
if (dest == e.dest)
207+
return e.weight;
208+
}
209+
throw new NoSuchElementException("Edge doesn't exist");
210+
}
211+
212+
/**
213+
* Method returning the number of vertexes contained in the graph
214+
*
215+
* @return an integer value of the vertexes count
216+
*/
217+
public int vertexCount() {
218+
return adjs.size();
219+
}
220+
221+
/**
222+
* Method returning the number of connections contained in the graph
223+
*
224+
* @return an integer value counting the number of connections in the graph
225+
*/
226+
public int edgeCount() {
227+
int count = 0;
228+
for (LinkedList<Edge> link : adjs.values()) {
229+
count += link.size();
230+
}
231+
return oriented ? count : count / 2;
232+
}
233+
234+
/**
235+
* Method that calculates the total cost of every single connection contained in the graph
236+
*
237+
* @return a double value counting the cost of the whole graph
238+
*/
239+
public double weight() {
240+
double weight = 0;
241+
for (LinkedList<Edge> link : adjs.values()) {
242+
for (Edge e : link) {
243+
weight += e.weight;
244+
}
245+
}
246+
return oriented ? weight : weight / 2;
247+
}
248+
249+
/**
250+
* Method checking if the graph is empty or not (meaning it doesn't contain a single vertex)
251+
*
252+
* @return true if the graph is empty, false if not
253+
*/
254+
public boolean isEmpty() {
255+
return adjs.isEmpty();
256+
}
257+
258+
/**
259+
* Method telling if the graph is oriented or not
260+
*
261+
* @return true of it is oriented, false if it's not
262+
*/
263+
public boolean isOriented() {
264+
return oriented;
265+
}
266+
267+
/**
268+
* Method checking if a given vertex is contained in the graph
269+
*
270+
* @param vertexName the label of the vertex to find
271+
* @return true if the specified vertex has been found in the graph, false if it has not
272+
*/
273+
public boolean containsVertex(V vertexName) {
274+
return adjs.containsKey(vertexName);
275+
}
276+
277+
/**
278+
* Method returning a stringified representation of the graph structure
279+
*
280+
* @return a string representing the graph structure
281+
*/
282+
@Override
283+
public String toString() {
284+
String out = "";
285+
out += oriented ? "Oriented Graph" : "Not Oriented Graph";
286+
out += "\n";
287+
out += "Vertex count: " + this.vertexCount() + "\n";
288+
out += "Edge count: " + this.edgeCount() + "\n";
289+
out += "Total weight: " + this.weight() + "\n";
290+
out += "Vertex list: [ ";
291+
for (V v : adjs.keySet()) {
292+
out += v.toString() + ", ";
293+
}
294+
if (this.vertexCount() > 0) {
295+
out = out.substring(0, out.length() - 2);
296+
}
297+
out += " ]\n";
298+
out += "Adjacencies: {\n";
299+
for (Map.Entry<V, LinkedList<Edge>> entry : adjs.entrySet()) {
300+
out += "\t" + entry.getKey().toString() + ": [ ";
301+
LinkedList<Edge> dest = entry.getValue();
302+
for (Edge e : dest) {
303+
out += e.toString() + ", ";
304+
}
305+
if (dest.size() > 0) {
306+
out = out.substring(0, out.length() - 2);
307+
}
308+
out += " ]\n";
309+
}
310+
out += "}";
311+
return out;
312+
}
313+
314+
/**
315+
* Inner class representing a single connection/edge in the graph
316+
*/
317+
protected class Edge {
318+
319+
private final V dest;
320+
private final double weight;
321+
322+
/**
323+
* Constructor for a graph edge object passing the destination vertex
324+
* and the edge weight
325+
*
326+
* @param destination the label of the connection ending vertex
327+
* @param weight a double value for the edge weight
328+
*/
329+
public Edge(V destination, double weight) {
330+
this.dest = destination;
331+
this.weight = weight;
332+
}
333+
334+
/**
335+
* Auxilary method getting the edge destination vertex label
336+
*
337+
* @return the egde destination vertex label
338+
*/
339+
public V getDestination() {
340+
return dest;
341+
}
342+
343+
/**
344+
* Auxilary method getting the edge weight
345+
*
346+
* @return a double value of the edge weight
347+
*/
348+
public double getWeight() {
349+
return weight;
350+
}
351+
352+
/**
353+
* Auxilary method telling if an object, passed as param, is equal to the current edge object
354+
*
355+
* @param o the object that needs to be compared with the current edge object
356+
* @return true if the edge object and the passed object are equal, false if they are not
357+
*/
358+
@Override
359+
public boolean equals(Object o) {
360+
if(o == this)
361+
return true;
362+
if(!(o.getClass() == getClass()))
363+
return false;
364+
Edge otherEdge = (Edge)o;
365+
return this.dest == otherEdge.dest && this.weight == otherEdge.weight;
366+
}
367+
368+
/**
369+
* Method returning a stringified representation of the current edge object
370+
* specifiying the destination vertex label and the required weight
371+
*
372+
* @return a string representing the current edge object
373+
*/
374+
@Override
375+
public String toString() {
376+
return "<to " + dest.toString() + " in " + weight + ">";
377+
}
378+
379+
}
380+
381+
}

0 commit comments

Comments
 (0)