Due: Thu, Nov 21, by 11:59pm
|
Due: Mon, Nov 25, by 11:59pm |
Graph
is a collection of Vertices
connected by Edges
. It is a generalization of the Tree
data structure from the previous assignments.
The focus is on the following algorithms and data structures:
assertEquals
. Instead each @Test
method will look like a mini-main
method and you will inspect the console to see if the output is correct.
[ To test individual components you can comment //@Test
]
Here is an example:
@Test public void test_bfs() { Graph graph = new Graph("undirected.txt"); String[] labelsList = { "a", ... }; for ( ... ) { System.out.println("Source: ?"); GraphAlgos.bfs(graph, ?); } } |
@Test public void test_dijkstra() { Graph graph = new Graph("directed.txt"); String[] labelsList = { "a", ... }; for ( ... ) { System.out.println("Source: ?"); GraphAlgos.dijkstra(graph, ?); } } |
@Test public void test_dfs() { Graph graph = new Graph("directed.txt"); String[] labelsList = { "a", ... }; for ( ... ) { System.out.println("Source: ?"); GraphAlgos.dfs(graph, ?); } } |
default
(i.e. non-private) as in the previous Node
classes:
Each vertex will have the following data members:
Vertex(String theLabel)
- creates a blank vertex with the given text and integer labelstoString()
- returns a string representation of this vertex in the following format:
MyLabel:MyDist:MyParentLabel i.e. Hanover:15:NewOxford
Edge
is described by its source and target vertices, and by its weight.
The interface for the Edge
class is:
Egde(Vertex theSource, Vertex theTarget, double theWeight)
Vertex getSource()
Vertex getTarget()
double getWeight()
Graph
should use the adjacency list representation based on a HashMap
with (key,value)=(?,?)
.
The graph data members:
edge map
- associates a vertex label with a list of edgesvertex map
- associates a vertex label with a vertexedge map
)Graph
class:
Graph(String filename)
Reads a graph from the file with the given
filename (see Scanner API).
Make sure to use the appropriate constructor to open the file. If Eclipse does not suggest adding try/catch , you are using the wrong Scanner constructor.
Methods .next() and .nextDouble() will read a single string and a single double, respectively. Method hasNext() will determine when to stop.
The files are formatted as follows:
source target weight src/, bin/ ):
|
||
Graph()
This constructor is not required, but you might use it initially if you are not sure whether you can read from a file.
This is just a sequence of
addEgde calls for each line in the file you want to test.
public Graph() { // any intialization // for BFS load "undirected.txt" // addEdge("a", "b", 2); // addEdge("a", "f", 7); // addEdge("a", "g", 3); // addEdge("a", "b", 2); ... USE ONLY ONE OR THE OTHER // for Dijkstra/DFS load "directed.txt" // addEdge("a", "b", 4); // addEdge("a", "f", 2); // addEdge("b", "c", 3); .... } |
||
void addEdge(String sourceLabel, String targetLabel, double weight)
Adds an edge with the given weight from the vertex with the given source label to the vertex with the given target label.
Make sure duplicate vertices are not created. In other words, if called multiple times with
sourceLabel or targetLabel "Gettysburg" it should always use the same Vertex object for "Gettysburg" .
|
||
Vertex getVertex(String label)
Returns a
Vertex object for the given label.
It should ensure that vertices are constructed/setup properly.
|
||
List<Edge> getAdjacent(Vertex source)
Returns an unmodifiable list of the edges that have the given vertex as their
source .
[ Initially ignore the unmodifiable part. Later see the relevant method in the Collections API. ]
|
||
Collection<Vertex> getVertices()
Returns an unmodifiable collection of the vertices in the
graph .
[ Initially ignore the unmodifiable part. Later see the relevant method in the Collections API. ]
|
GraphAlgos
and implement the Breadth-First Search and Depth-First Search graph traversal algorithms by adding the following methods:
static void __method__(Graph graph)
A useful helper method...
|
static void bfs(Graph graph, String sourceLabel)
Performs Breadth-First Search (pseudocode) on the given
graph starting at the given source vertex. This is essentially Level Order with vertex marking; see Figure 4.3 in [ALG].
The vertices are displayed on one line separated by a space in the order they are finished in the format:
a:0:* b:1:a f:1:a g:1:a c:2:b e:2:f i:2:f h:2:g d:3:cBFS results on undirected.txt for each vertex as source
|
static void dfs(Graph graph, String sourceLabel)
Performs Depth-First Search on the given
graph starting at the given source vertex. See Figures 3.5 and 3.3 in [ALG].
This method simply calls the next method after carrying out any preliminary steps (if necessary).
The vertices are displayed on one line separated by a space in the order they are finished in the format:
a:0:* b:1:a c:2:b d:3:c e:4:d f:1:aDFS results on directed.txt for each vertex as source |
static void dfs(Graph graph, Vertex curr)
Uses recursion to perform Depth First Search on the given
graph starting at the given vertex curr . See Figures 3.5 and 3.3 in [ALG].
Depth-First Search is a generalization of the Preorder Traversal of BSTree : in each case first "process" the circle and then "process" all arrows for that circle.
The major difference between "peorder traversal" for BSTree and Graph is that in the case of Graph the vertices/nodes need to be marked and the other bookkeeping fields need to be updated (marking is needed to ignore traversing a vertex again after it has been traversed/marked by someone else).
For simplicity, "processing vertex" for Graph will simply print the string representation of the vertex.
|
GraphAlgos
.
static void dijkstra(Graph graph, String sourceLabel)
Computes the shortest paths from the given
source vertex to all the other vertices in the given graph using Dijkstra's algorithm (pseudocode).
You will need to create VertexComparator .
As soon as a vertex is finished:
PQ .
|
static void printPathLoop(Vertex startVertex, Vertex destVertex)
Uses a loop to print the path (in reverse) from the given destination vertex to the given starting vertex.
[ During the execution of Dijkstra's Algorithm the source will always be given as the starting vertex when this method is called. ]
The path is printed in the following format:
F <--5-- D <--2-- G <--6-- C <--4-- A (total length 17) A is the original source and F is the destination, and the path is printed in reverse (this makes the problem simpler).
Note: The individual numbers are edge lengths, not cumulative distances.
This method will be tested indirectly by testing Dijkstra's algorithm.
|
static void printPathRec(Vertex startVertex, Vertex destVertex)
Same as method
printPath but uses recursion (does not include the total length). Unlike the previous method, this one shows the path from the startVertex to the given destVertex , i.e. not in reverse.
A --4--> C --6--> G --2--> D --5--> F A is the source and F is the destination, and the path is printed correctly. This makes the problem harder (but total distance is not printed).
Note: The individual numbers are edge lengths, not cumulative distances.
This method will be tested indirectly by testing Dijkstra's algorithm.
|
GraphExplorer
that has only a single main
method:
main
run the various algorithms with hardcoded input files and source verticesmain
to use its command-line arguments from the String[]
parameter:
GraphExplorer
at least one time before the next step. It is enough to print a simple message in the main
method. Without this step there won't be a Launch Configuration
.In Step 4 choose
GraphExplorer
under Launch Configuration
and Browse
to the project's main folder (Graph/
) and save the jar under the name gbcsmaps.jar
.
cd path/to/project/Graph (go to correct project folder) java -jar gbcsmaps.jar -bfs undirected.txt c (runs BFS starting at c) java -jar gbcsmaps.jar -dfs directed.txt d (runs DFS starting at d) java -jar gbcsmaps.jar -dijkstra tube.txt CHARING_CROSS (runs Dijkstra starting at Charing Cross)
java
with the full path
which varies based on your installation. Try the following:
but replace javaw with java
if path is too long, hover over it with the mouse