package DirectedGraphJava; import java.util.HashSet; import java.util.HashMap; import java.util.Iterator; import java.util.Queue; import java.util.Set; import java.util.LinkedList; import java.util.ArrayList; import java.util.Collections; public class DirectedGraph implements IDirectedGraph { private HashSet _vertices = new HashSet(); private HashMap> _inbounds = new HashMap>(); private HashMap> _outbounds = new HashMap>(); private HashMap,Integer> _edges = new HashMap,Integer>(); public DirectedGraph() { //nothing to do } public DirectedGraph reindex(){ HashMap oldToNew = new HashMap(); int i = 0; for (Integer vertex : _vertices) { oldToNew.put(vertex,i); i++; } DirectedGraph newGraph = new DirectedGraph(); for (Integer vertex : _vertices) { newGraph.addVertex(oldToNew.get(vertex)); } for (Pair edge : _edges.keySet()) { newGraph.addEdge(oldToNew.get(edge.first),oldToNew.get(edge.second),_edges.get(edge)); } return newGraph; } public Integer numVertices() { return _vertices.size(); } public Integer numEdges() { return _edges.size(); } public Iterator vertices() { return _vertices.iterator(); } public Iterator,Integer>> edges() { HashSet,Integer>> keyValues = new HashSet,Integer>>(); for (Pair key : this._edges.keySet()) { Pair,Integer> keyValuePair = new Pair,Integer>(key,this._edges.get(key)); keyValues.add(keyValuePair); } return keyValues.iterator(); } public boolean isEdge(Integer v1, Integer v2) { if(!_vertices.contains(v1) || !_vertices.contains(v2)) { throw new IllegalArgumentException("Vertex does not exist"); } return _edges.containsKey(new Pair(v1,v2)); } public int inDegree(Integer v) { if(!_vertices.contains(v)) { throw new IllegalArgumentException("Vertex does not exist"); } return _inbounds.get(v).size(); } public int outDegree(Integer v) { if(!_vertices.contains(v)) { throw new IllegalArgumentException("Vertex does not exist"); } return _outbounds.get(v).size(); } public Iterator inbounds(Integer v) { if(!_vertices.contains(v)) { throw new IllegalArgumentException("Vertex does not exist"); } return _inbounds.get(v).iterator(); } public Iterator outbounds(Integer v) { if(!_vertices.contains(v)) { throw new IllegalArgumentException("Vertex does not exist"); } return _outbounds.get(v).iterator(); } public Integer weight(Integer v1, Integer v2) { if(!_vertices.contains(v1) || !_vertices.contains(v2)) { throw new IllegalArgumentException("Vertex does not exist"); } if(!_edges.containsKey(new Pair(v1,v2))) { throw new IllegalArgumentException("Edge does not exist"); } return _edges.get(new Pair(v1,v2)); } public void weight(Integer v1, Integer v2, Integer w) { if(!_vertices.contains(v1) || !_vertices.contains(v2)) { throw new IllegalArgumentException("Vertex does not exist"); } if(!_edges.containsKey(new Pair(v1,v2))) { throw new IllegalArgumentException("Edge does not exist"); } _edges.put(new Pair(v1,v2),w); } public void addVertex(Integer v) { if(_vertices.contains(v)) { throw new IllegalArgumentException("Vertex already exists"); } _vertices.add(v); _inbounds.put(v,new HashSet()); _outbounds.put(v,new HashSet()); } public void removeVertex(Integer v) { if(!_vertices.contains(v)) { throw new IllegalArgumentException("Vertex does not exist"); } _vertices.remove(v); for (Integer vertex : _inbounds.get(v)) { _outbounds.get(vertex).remove(v); _edges.remove(new Pair(vertex,v)); } for (Integer vertex : _outbounds.get(v)) { _inbounds.get(vertex).remove(v); _edges.remove(new Pair(v,vertex)); } _inbounds.remove(v); _outbounds.remove(v); } public void addEdge(Integer v1, Integer v2, Integer w) { if(!_vertices.contains(v1) || !_vertices.contains(v2)) { throw new IllegalArgumentException("Vertex does not exist"); } if(_edges.containsKey(new Pair(v1,v2))) { throw new IllegalArgumentException("Edge already exists"); } _edges.put(new Pair(v1,v2),w); _inbounds.get(v2).add(v1); _outbounds.get(v1).add(v2); } public void removeEdge(Integer v1, Integer v2) { if(!_vertices.contains(v1) || !_vertices.contains(v2)) { throw new IllegalArgumentException("Vertex does not exist"); } if(!_edges.containsKey(new Pair(v1,v2))) { throw new IllegalArgumentException("Edge does not exist"); } _edges.remove(new Pair(v1,v2)); _inbounds.get(v2).remove(v1); _outbounds.get(v1).remove(v2); } public HashMap> shortestPath(Integer v){ //Initializations Queue queue = new LinkedList(); HashMap> map = new HashMap>(); Set visited = new HashSet(); for(Iterator vertex = this._vertices.iterator();vertex.hasNext();){ map.put(vertex.next(),new Pair(null,-1)); } //Add the first vertex to the queue, the visited set, and the map of distances and parents with a distance of 0 map.put(v,new Pair(null,0)); queue.add(v); map.put(v,new Pair(null,0)); visited.add(v); //BFS to find the shortest path while(!queue.isEmpty()){ Integer current = queue.poll(); //Get the next vertex //For each neighbor of the current vertex for(Integer neighbor : _outbounds.get(current)){ //If the neighbor has not been visited, add it to the queue, the visited set, and the map of distances and parents with a distance of 1 more than the current vertex if(!visited.contains(neighbor)){ queue.add(neighbor); visited.add(neighbor); map.put(neighbor,new Pair(current,map.get(current).second+1)); } } } return map; } public HashMap> shortestPath(Integer v,Integer u){ //Initializations Queue queue = new LinkedList(); HashMap> map = new HashMap>(); Set visited = new HashSet(); for(Iterator vertex = this._vertices.iterator();vertex.hasNext();){ map.put(vertex.next(),new Pair(null,-1)); } //Add the first vertex to the queue, the visited set, and the map of distances and parents with a distance of 0 map.put(v,new Pair(null,0)); queue.add(v); map.put(v,new Pair(null,0)); visited.add(v); //BFS to find the shortest path while(!queue.isEmpty()){ Integer current = queue.poll(); //Get the next vertex //For each neighbor of the current vertex for(Integer neighbor : _outbounds.get(current)){ //If the neighbor has not been visited yet add it to the queue, visited set, and map. if(!visited.contains(neighbor)){ queue.add(neighbor); visited.add(neighbor); //Add the neighbor to the map with the current vertex as its parent and a distance of the current vertex's distance + 1 map.put(neighbor,new Pair(current,map.get(current).second+1)); //If the neighbor is the destination vertex return the map if(neighbor == u) return map; } } } return map; } public ArrayList path(Integer v1,Integer v2){ //Get the shortest path from v1 to v2 HashMap> map = shortestPath(v1); ArrayList path = new ArrayList(); //If there is no path return an empty arraylist if(map.get(v2).second == -1) return path; path.add(v2); //Add each vertex in the path to the arraylist starting from the destination vertex while(map.containsKey(v2)){ path.add(map.get(v2).first); v2 = map.get(v2).first; } //Remove the first element of the arraylist which is null and reverse the arraylist path.remove(path.size()-1); Collections.reverse(path); return path; } }