COMP 410, Fall 2012 Graph Data Structure Graph Algorithms: Dijkstra’s, Topological Sort Due: Tues. Nov. 27 11:59 pm Do this: Implement a graph data structure and then program the following 1) An algorithm to produce a topological sort of the graph (DAG) 2) Dijkstra’s algorithm for shortest paths (undirected weighted graph) For now use your own data file(s) in the format given below to test your code. I will supply a data file for you to test on that will be the one we use for grading. In a week or so I will give you the file. Topological sort Make the algorithm the efficient version we discussed in class (and in your book). You will need the graph structure and you will also need the “box” structure (i.e., a stack or queue). Program your own graph class(es); you may use stacks and/or queues from the Java class library. Make sure your code correctly identifies a graph that has a cycle (and therefore has no topological sort). Input: For this algorithm you will interpret the graph input data file as defining a directed acyclic graph (DAG) and you will be ignoring the weights on the edges. You will also be ignoring the “start node” that is the last line of the file. Output: a topological sort, meaning a sequence of all the nodes in the graph (use their text names). Dijkstra’s Algorithm For this algorithm the graph input data is interpreted as an undirected graph. You will need your own classes implementing the graph data structure, as well as a min-priority queue to make the algorithm run efficiently. You may use the priority queue class that is in the Java class library. Input: For this algorithm, the weights on the edges are used (of course), as well as the “start node” on the last line of the input file. Output: A table showing the shortest path from the start node to every other node. Show a path as a sequence of node text names starting with the start node. Show the cost for each path. Programming the Graph data structure You are to implement a graph object that is stored internally as an adjacency-list. One implementation should work for both algorithms above (meaning one graph class can do both directed and undirected graphs). The algorithms you ultimately program will work on directed graphs and undirected graphs, so make sure your data structure design will handle both (it most likely will without major internal differences). You may assume that the vertices of your graph are given as ASCII strings, and that all edge-weights are positive integers. The specifications of the graph are to be read from an input file by your program. This file has the following format: u1 v1 w1 u2 v2 w2 ... um vm wm -1 source Each 3-tuple denotes an edge, which is specified by its source-vertex, its destination-vertex, and its weight (example: raleigh chapel_hill 30). For an undirected graph, each line has no direction (no “to” or “from”), just that an edge exists between the 2 nodes. The description of the graph is terminated by a “flag”, the integer -1. A string follows this flag; this string is the name of the source vertex for the Dijkstra shortest-path algorithm. That is, you are to determine and print out the shortest path from this source vertex to every other vertex in the graph. Example: Raleigh Durham 14 Durham Hillsborough 9 Chapel_hill Graham 25 Chapel_hill Carrboro 1 Carboro Cary 32 Cary Raleigh 3 Pittsboro Cary 17 Pittsboro Sanford 15 Sanford Los_angeles 3012 -1 Pittsboro Some suggestions: 1. It may be helpful to read the input twice: the first time to determine all the vertex names, and the second time to read in the edges. 2. Consider storing the vertex-names in a sorted array, or hashmap, or something similar; that way, translating from these names to the numbers used to represent the vertices internally is more efficient. This hashmap would supplement the adjacency list structure that represents the basic nodes and arcs of the graph (nodes in a list, each node with a list of edges attached to it). If you need to get a single node, you can hash it in constant time rather than search a list of all nodes in linear time.