/****************************************************
* CS2510 Fall 2011
* Lecture #28
* JavaDocs, JUnit
****************************************************/
import java.util.*;
import tester.*;
/**
* The Graph class which contains Edge links between Vertices
* @author mattea
*
*/
class Graph {
HashMap> g;
/**
* Creates an empty graph
*/
Graph() {
g = new HashMap>();
}
/**
* Add an edge to this graph, adding vertices as necessary
* @param v1 - Source Vertex
* @param v2 - Dest Vertex
*/
void addEdge(Vertex v1, Vertex v2) {
if (! g.containsKey(v1)) {
g.put(v1, new ArrayList());
}
if (! g.containsKey(v2)) {
g.put(v2, new ArrayList());
}
Edge e = new Edge(v1,v2);
if (! g.get(v1).contains(e)) {
g.get(v1).add(new Edge(v1,v2));
}
}
/**
* Returns the edges for this vertex
* @param v - The vertex to search for
* @return All edges out of v
*/
ArrayList getEdges(Vertex v) {
if (!g.containsKey(v)) {
throw new NoEdgeException("No such vertex " + v.name);
}
return g.get(v);
}
}
/**
* A RuntimeException for the inability to find edges
* @author mattea
*
*/
class NoEdgeException extends RuntimeException {
/**
* @param e - The Error message
*/
NoEdgeException(String e) {
super(e);
}
}
/**
* Our representation of a vertex for a graph
* @author mattea
*
*/
class Vertex {
String name;
/**
* @param name - The name of this Vertex
*/
Vertex(String name) {
this.name = name;
}
// Our int representation of a vertex: a number plus the int of the name
public int hashCode() {
return name.hashCode() + 6458;
}
// Are two vertices equal?
public boolean equals(Object o) {
if( o.getClass() == Vertex.class) {
Vertex tmp = (Vertex) o;
return this.name == tmp.name;
} else {
return false;
}
}
}
//
/**
* Our representation of a graph edge between two vertices
* @author mattea
*
*/
class Edge {
Vertex s;
Vertex d;
/**
* The Edge Constructor for 2 Vertex arguments
* @param s - Source vertex
* @param d - Destination Vertex
*/
Edge(Vertex s, Vertex d) {
this.s = s;
this.d = d;
}
// Are two Edges equal?
public boolean equals(Object o) {
if( o.getClass() == Edge.class) {
Edge tmp = (Edge) o;
return this.s.equals(tmp.s) && this.d.equals(tmp.d);
} else {
return false;
}
}
}
/**
* Breadth First Search Traversal of our Graph
* @author mattea
*
*/
class BFS {
Graph g;
/**
* The BFS Constructor for a Graph
* @param g - The Graph to Traverse
*/
BFS(Graph g) {
this.g = g;
}
/**
* Can we get from s to e in g?
* @param s - Start
* @param e - End
* @return true if a path exists, false otherwise
*/
boolean fromTo(Vertex s, Vertex e) {
LinkedList next = new LinkedList();
next.add(s);
while(!next.isEmpty()) {
Vertex curr = next.remove();
if (curr.equals(e)) {
return true;
}
for(Edge edge : g.getEdges(curr)) {
next.add(edge.d);
}
}
return false;
}
}
/**
* Depth First Search Traversal of our Graph
* @author mattea
*
*/
class DFS {
Graph g;
/**
* The DFS Constructor for a Graph
* @param g - The Graph to Traverse
*/
DFS(Graph g) {
this.g = g;
}
/**
* Can we get from s to e in g?
* @param s - Start
* @param e - End
* @return true if a path exists, false otherwise
*/
boolean fromTo(Vertex s, Vertex e) {
LinkedList next = new LinkedList();
next.push(s);
while(!next.isEmpty()) {
Vertex curr = next.pop();
if (curr.equals(e)) {
return true;
}
for(Edge edge : g.getEdges(curr)) {
next.add(edge.d);
}
}
return false;
}
}
/**
* Test class for our Graph, BFS and DFS
* @author mattea
*/
class LectureExamples {
/**
* Test our Graph and BFS/DFS Traversals
* @param t - Tester
*/
void testSearch(Tester t) {
Graph g = new Graph();
Vertex va = new Vertex("a");
Vertex vb = new Vertex("b");
Vertex vc = new Vertex("c");
Vertex vd = new Vertex("d");
Vertex ve = new Vertex("e");
Vertex vf = new Vertex("f");
Vertex vg = new Vertex("g");
Vertex vnone = new Vertex("none");
g.addEdge(va, vb);
g.addEdge(va, vc);
g.addEdge(vb, vd);
g.addEdge(vc, vd);
g.addEdge(vc, ve);
g.addEdge(ve, vf);
g.addEdge(vg, vf);
t.checkExpect(g.g.containsKey(va),true);
t.checkExpect(g.g.containsKey(vg),true);
t.checkExpect(g.g.containsKey(vnone),false);
BFS bfs = new BFS(g);
DFS dfs = new DFS(g);
t.checkExpect(bfs.fromTo(va, vf), true);
t.checkExpect(dfs.fromTo(va, vf), true);
t.checkExpect(bfs.fromTo(vb, vf), false);
t.checkExpect(dfs.fromTo(vb, vf), false);
t.checkExpect(bfs.fromTo(vf, vg), false);
t.checkExpect(dfs.fromTo(vf, vg), false);
t.checkExpect(g.getEdges(vg).get(0).d,new Vertex("f"));
t.checkExpect(g.getEdges(vg).get(0),new Edge(new Vertex("g"),new Vertex("f")));
}
/**
* Example of using an array
* @param t - Tester
*/
void testArray(Tester t) {
String s = "a b c d e f";
String sa[] = s.split(" ");
System.out.println("First element: " + sa[0]);
System.out.println("Length of sa: " + sa.length);
}
}