diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e1d71a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +target +bin +classes diff --git a/src/main/java/assembly/Graph.java b/src/main/java/assembly/Graph.java index 1702487..2b5fb8a 100644 --- a/src/main/java/assembly/Graph.java +++ b/src/main/java/assembly/Graph.java @@ -6,59 +6,60 @@ /** * @author dev - * * @param */ public class Graph { - /** - * ArrayList to hold edges for random access - */ - private ArrayList> edges; + /** + * ArrayList to hold edges for random access + */ + private ArrayList> edges; - public Graph() { - edges = new ArrayList>(); - } + public Graph() { + edges = new ArrayList>(); + } - /** - * @param vertex - * @return - boolean - * - * Add Edge to the List - */ - public boolean addEdge(Edge vertex) { - if (edges.contains(vertex)) - return false; - edges.add(vertex); - return true; - } + /** + * @param vertex + * @return - boolean Add Edge to the List + */ + public boolean addEdge(Edge vertex) { + if (edges.contains(vertex)) + return false; + edges.add(vertex); + return true; + } - public boolean contains(Edge vertex) { - return edges.contains(vertex); - } + public boolean contains(Edge vertex) { + return edges.contains(vertex); + } - public Edge get(int index) { - return edges.get(index); - } + public Edge get(int index) { + return edges.get(index); + } - /** - * @return : number of Edges in Graph - */ - public int count() { - return edges.size(); - } + /** + * @return : number of Edges in Graph + */ + public int count() { + return edges.size(); + } - /** - * Checks if two graphs are equal. Store all of Edges of larger Graph & Graphs are equal only if - * temp is unchanged * - */ - public boolean equals(Graph other) { + /** + * Checks if two graphs are equal. Store all of Edges of larger Graph & Graphs are equal only if temp is unchanged * + */ + public boolean equals(Graph other) { - if (other.edges.size() != edges.size()) - return false; + if (other.edges.size() != edges.size()) + return false; - ArrayList> temp = new ArrayList>(other.edges); + ArrayList> temp = new ArrayList>(other.edges); - return temp.retainAll(edges); - } + return temp.retainAll(edges); + } + + public void reset() { + for (int i = 0; i < count(); i++) + get(i).setDistance(Integer.MAX_VALUE); + } } diff --git a/src/main/java/graph/Edge.java b/src/main/java/graph/Edge.java index 1c42cad..206e41b 100644 --- a/src/main/java/graph/Edge.java +++ b/src/main/java/graph/Edge.java @@ -1,112 +1,48 @@ package graph; -import java.util.Collections; -import java.util.Iterator; import java.util.LinkedList; - - /** * @author dev - * * @param - * - * Base class for creating an edge.Stores the number of edges,an Element - used in - * weighted graphs and game theory in-case of incoming gains,this is a provision for the - * change in fuel prices or new routes. It has individual edge identifier,weight and pointers - * for reference to other edges. + * Base class for creating an edge.Stores the number of edges,an Element - used in weighted graphs and game theory + * in-case of incoming gains,this is a provision for the change in fuel prices or new routes. It has individual edge + * identifier,weight and pointers for reference to other edges. */ public class Edge { - - private static int ID = 0; - - private E element; - - private int id; - - private int weight; - - private LinkedList> pointers; - - public Edge() { - this(null, Integer.MAX_VALUE); - } - - public Edge(E elem, int distance) { - this.element = elem; - id = ID++; - pointers = new LinkedList>(); - this.weight = distance; - } - - public int getId() { - return id; - } - - public E getElem() { - return element; - } - - public void setElem(E elem) { - this.element = elem; - } - - public int getDistance() { - return weight; - } - - public void setDistance(int dist) { - weight = dist; - } - - // add a connection - public void connectTo(Edge other) { - Link c = new Link(this, other); - - // check for duplicates - if (!pointers.contains(c)) - pointers.add(c); - - // reference Connector in other Edge as well - LinkedList> conn = other.getConnections(); - if (!conn.contains(c)) - conn.add(c); - } - - public void connectTo(Edge other, int distance) { - Link c = new Link(this, other, distance); - if (!pointers.contains(c)) - pointers.add(c); - } - - public LinkedList> getConnections() { - return pointers; - } - - public void sortConnections() { - Collections.sort(pointers); - } - - public Iterator> iterator() { - return pointers.iterator(); - } - - // one Edge is equal to another if the two elems are equal to each other - // and they have the same Connections - public boolean equals(Edge other) { - - if (other.pointers.size() != pointers.size()) - return false; - - LinkedList> temp = new LinkedList>(pointers); - - // edges are order agnostic - // if the elements are equal and the Lists are equal, regardless of order - // then the Edges are equal - return element.equals(other.getElem()) && temp.retainAll(other.pointers); - } - - public String toString() { - return this.element.toString(); - } + private static int ID = 0; + private E element; + private int id; + private int weight; + private LinkedList> pointers; + + public Edge(E elem, int distance) { + this.element = elem; + id = ID++; + pointers = new LinkedList>(); + this.weight = distance; + } + + public int getDistance() { + return weight; + } + + public void setDistance(int dist) { + weight = dist; + } + + public void connectTo(Edge other, int distance) { + Link c = new Link(this, other, distance); + if (!pointers.contains(c)) + pointers.add(c); + } + + public LinkedList> getConnections() { + return pointers; + } + + @Override + public String toString() { + return this.element.toString(); + } } diff --git a/src/main/java/graph/Link.java b/src/main/java/graph/Link.java index 25ba277..ad16aa1 100644 --- a/src/main/java/graph/Link.java +++ b/src/main/java/graph/Link.java @@ -1,54 +1,37 @@ package graph; public class Link implements Comparable> { - - private Edge source, sink; - private int distance; - - /* - * constructor- creates a Link object to Connect two Nodes together with a standard distance of 0 - * , it is assumed That distance is either weighted through the Edges or otherwise is irrelevant - */ - public Link(Edge source, Edge sink) { - this(source, sink, 0); - } - - public Link(Edge source, Edge sink, int distance) { - this.source = source; - this.sink = sink; - this.distance = distance; - } - - public Edge getSource() { - return source; - } - - public Edge getSink() { - return sink; - } - - public int getDistance() { - return distance; - } - - public void setDistance(int distance) { - this.distance = distance; - } - - /* - * Two connectors are equal if the two Edges are equal and the distance is equal - */ - public boolean equals(Link other) { - return source.equals(other.getSource()) && sink.equals(other.getSink()) - && distance == other.getDistance(); - } - - @Override - public String toString() { - return "Link [source=" + source + ", sink=" + sink + ", distance=" + distance + "]"; - } - - public int compareTo(Link other) { - return this.distance - other.distance; - } + private Edge source, sink; + private int distance; + + public Link(Edge source, Edge sink, int distance) { + this.source = source; + this.sink = sink; + this.distance = distance; + } + + public Edge getSource() { + return source; + } + + public Edge getSink() { + return sink; + } + + public int getDistance() { + return distance; + } + + public void setDistance(int distance) { + this.distance = distance; + } + + @Override + public String toString() { + return "Link [source=" + source + ", sink=" + sink + ", distance=" + distance + "]"; + } + + public int compareTo(Link other) { + return this.distance - other.distance; + } } diff --git a/src/main/java/greedy/Dijkstra.java b/src/main/java/greedy/Dijkstra.java index dd7a8e7..4cb3ba3 100644 --- a/src/main/java/greedy/Dijkstra.java +++ b/src/main/java/greedy/Dijkstra.java @@ -4,7 +4,6 @@ import graph.Link; import java.util.Comparator; -import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; @@ -14,203 +13,116 @@ /** * @author dev - * - * @param : The type to store in the Graph - */ -/** - * @author dev - * * @param + * : The type to store in the Graph */ public class Dijkstra { - - private Graph graph; - - private PriorityQueue> heap; - - Map, Edge> learnedPath; - String path; - Boolean isPathValid; - Integer distance; - - private static final int INITIAL_CAPACITY = 10; - - - /** - * @param graph: The Graph to traverse - * - * Constructor - initializes each Node's distance to infinity,used for initial comparison - * */ - - public Dijkstra(Graph graph) { - this.graph = graph; - learnedPath = new LinkedHashMap, Edge>(); - resetGraph(); - setIsPathValid(false); - distance = new Integer(0); - - heap = new PriorityQueue>(INITIAL_CAPACITY, new Comparator>() { - public int compare(Link source, Link sink) { - return (source.getDistance() + source.getSource().getDistance()) - - (sink.getDistance() + sink.getSource().getDistance()); - } - }); - } - - public void resetGraph() { - for (int i = 0; i < this.graph.count(); i++) { - this.graph.get(i).setDistance(Integer.MAX_VALUE); - this.graph.get(i); - } - } - - /** - * @param start - * @param end - * @return - shortest distance from source to destination - * - * Starting point is the start vertex.Initial distance is 0. PriorityQueue is used to - * determine which Edge to visit next. Nodes are evaluated in a breadth-first search, and - * pushed onto the PriorityQueue. The PriorityQueue is then polled and the process is - * repeated until the PriorityQueue is empty. This method also keeps a track of the vertex - * being set and its parent from the source to destination.A linkedHashMap is used to - * maintain a combination of - */ - public int heapPath(Edge start, Edge end) { - start.setDistance(0); - - Edge evaluate = start; - - do { - LinkedList> links = evaluate.getConnections(); - Iterator> iterate = links.iterator(); - - while (iterate.hasNext()) { - Link conn = iterate.next(); - heap.add(conn); - } - - Link temp = null; - if (!heap.isEmpty()) { - while (learnedPath.containsKey((temp = heap.peek()).getSource()) - && learnedPath.containsKey((temp = heap.peek()).getSink())) { - temp = heap.poll(); - } - - temp = heap.poll(); - - } else { - break; - } - - evaluate = temp.getSink(); - - int distance = evaluate.getDistance(); - int newDist = temp.getSource().getDistance() + temp.getDistance(); - - if (newDist < distance) { - evaluate.setDistance(newDist); - if (!learnedPath.containsKey(temp.getSink())) { - learnedPath.put(temp.getSink(), temp.getSource()); - } else { - break; - } - } - - } while (!heap.isEmpty()); - - return end.getDistance(); - } - - /** - * @param start - * @param end - * @return path- shortest path from source to destination input - source edge,destination edge - * This is an orchestration method that invokes the method that calculates the shortest - * distance - heapPath and also invokes the method to plot the path.- plotPath .Returns - * the shortest path from source to destination. - */ - - public String getPath(Edge start, Edge end) { - distance = heapPath(start, end); - path = plotPath(start, end, graph.count()); - return path; - } - - /** - * @param start - * @param end - * @param length - * @return - shortest path from source to destination is it is a valid path,"Sink unreachable" - * otherwise. - * - * This method iterates over the learnedPath , from sink to source to capture the shortest - * path.Map is of the form ,the method goes from the - * destination,picking up its parent and using the parent as the next vertex.A path - * reversal is used at the end. - */ - - public String plotPath(Edge start, Edge end, int length) { - - StringBuffer sb = new StringBuffer(); - Edge sink = end; - int i = 0; - - while (learnedPath.get(end) != start && i++ < length) { - sb.append(learnedPath.get(end)); - end = learnedPath.get(end); - } - - if (learnedPath.get(end) == start && learnedPath.get(start) != end) { - setIsPathValid(true); - - sb.reverse(); - - sb.insert(0, start); - sb.append(sink); - return sb.toString(); - } else { - sb = new StringBuffer(); - return sb.append("Sink Unreachable").toString(); - } - - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public Graph getGraph() { - return graph; - } - - public void setGraph(Graph graph) { - this.graph = graph; - } - - public PriorityQueue> getHeap() { - return heap; - } - - public void setHeap(PriorityQueue> heap) { - this.heap = heap; - } - - public Map, Edge> getLearnedPath() { - return learnedPath; - } - - - public Boolean getIsPathValid() { - return isPathValid; - } - - public void setIsPathValid(Boolean isPathValid) { - this.isPathValid = isPathValid; - } - + private static final int INITIAL_CAPACITY = 10; + public Graph graph; + private PriorityQueue> heap; + private Map, Edge> learnedPath = new LinkedHashMap, Edge>(); + + /** + * @param graph + * : The Graph to traverse Constructor - initializes each Node's distance to infinity,used for initial comparison + */ + + public Dijkstra(Graph graph) { + graph.reset(); + this.graph = graph; + heap = new PriorityQueue>(INITIAL_CAPACITY, new Comparator>() { + public int compare(Link source, Link sink) { + return source.getDistance() + source.getSource().getDistance() + - (sink.getDistance() + sink.getSource().getDistance()); + } + }); + } + + /** + * @param start + * @param end + * @return - shortest distance from source to destination Starting point is the start vertex.Initial distance is 0. + * PriorityQueue is used to determine which Edge to visit next. Nodes are evaluated in a breadth-first search, and + * pushed onto the PriorityQueue. The PriorityQueue is then polled and the process is repeated until the PriorityQueue + * is empty. This method also keeps a track of the vertex being set and its parent from the source to destination.A + * linkedHashMap is used to maintain a combination of + */ + public int heapPath(Edge start, Edge end) { + start.setDistance(0); + + Edge evaluate = start; + + do { + LinkedList> links = evaluate.getConnections(); + + for (Link link : links) + heap.add(link); + + Link temp = null; + if (heap.isEmpty()) + break; + while (learnedPath.containsKey((temp = heap.peek()).getSource()) + && learnedPath.containsKey((temp = heap.peek()).getSink())) + temp = heap.poll(); + + temp = heap.poll(); + + evaluate = temp.getSink(); + + int distance = evaluate.getDistance(); + int newDist = temp.getSource().getDistance() + temp.getDistance(); + + if (newDist < distance) { + evaluate.setDistance(newDist); + if (learnedPath.containsKey(temp.getSink())) + break; + learnedPath.put(temp.getSink(), temp.getSource()); + } + + } while (!heap.isEmpty()); + + return end.getDistance(); + } + + /** + * @param start + * @param end + * @return path- shortest path from source to destination input - source edge,destination edge This is an orchestration method + * that invokes the method that calculates the shortest distance - heapPath and also invokes the method to plot the + * path.- plotPath .Returns the shortest path from source to destination. + */ + + public String getPath(Edge start, Edge end) { + heapPath(start, end); + return plotPath(start, end, graph.count()); + } + + /** + * @param start + * @param end + * @param length + * @return - shortest path from source to destination is it is a valid path,"Sink unreachable" otherwise. This method iterates + * over the learnedPath , from sink to source to capture the shortest path.Map is of the form ,the + * method goes from the destination,picking up its parent and using the parent as the next vertex.A path reversal is + * used at the end. + */ + + public String plotPath(Edge start, Edge end, int length) { + StringBuffer sb = new StringBuffer(); + Edge sink = end; + int i = 0; + + while (learnedPath.get(end) != start && i++ < length) { + sb.append(learnedPath.get(end)); + end = learnedPath.get(end); + } + + if (learnedPath.get(end) == start && learnedPath.get(start) != end) { + sb.reverse(); + sb.insert(0, start); + sb.append(sink); + return sb.toString(); + } + return "Sink Unreachable"; + } } diff --git a/src/test/java/greedy/TestShortestPath.java b/src/test/java/greedy/TestShortestPath.java index 93c8505..e09fe5c 100644 --- a/src/test/java/greedy/TestShortestPath.java +++ b/src/test/java/greedy/TestShortestPath.java @@ -8,73 +8,71 @@ import assembly.Graph; - public class TestShortestPath { - Edge i, j, k, l, m, n, x; - Graph list; - Dijkstra test; - - @Before - public void assembleGraph() { - list = new Graph(); - i = new Edge(1, 0); - j = new Edge(2, 0); - k = new Edge(3, 0); - l = new Edge(4, 0); - m = new Edge(5, 0); - n = new Edge(6, 0); - x = new Edge(7, 0); - - list.addEdge(i); - list.addEdge(j); - list.addEdge(k); - list.addEdge(l); - list.addEdge(m); - list.addEdge(n); - list.addEdge(x); - - i.connectTo(j, 7); - i.connectTo(k, 9); - i.connectTo(n, 14); - i.connectTo(x, 200); - - k.connectTo(j, 11); - k.connectTo(n, 2); - k.connectTo(l, 11); - - j.connectTo(k, 10); - j.connectTo(l, 15); - - l.connectTo(j, 11); - l.connectTo(m, 6); - - n.connectTo(m, 9); - - m.connectTo(i, 9); - - test = new Dijkstra(list); - } - - @Test - public void testDistance() { - Dijkstra test = new Dijkstra(list); - Assert.assertEquals(20, test.heapPath(i, l)); - } - - @Test - public void testIncorrectDistance() { - Assert.assertNotEquals(22, test.heapPath(i, l)); - } - - @Test - public void testPath() { - Assert.assertEquals("134", test.getPath(i, l)); - } - - @Test - public void testUnreachablePath() { - Assert.assertEquals("Sink Unreachable", test.getPath(m, l).trim()); - } + Edge i, j, k, l, m, n, x; + Graph list; + Dijkstra test; + + @Before + public void assembleGraph() { + list = new Graph(); + i = new Edge(1, 0); + j = new Edge(2, 0); + k = new Edge(3, 0); + l = new Edge(4, 0); + m = new Edge(5, 0); + n = new Edge(6, 0); + x = new Edge(7, 0); + + list.addEdge(i); + list.addEdge(j); + list.addEdge(k); + list.addEdge(l); + list.addEdge(m); + list.addEdge(n); + list.addEdge(x); + + i.connectTo(j, 7); + i.connectTo(k, 9); + i.connectTo(n, 14); + i.connectTo(x, 200); + + k.connectTo(j, 11); + k.connectTo(n, 2); + k.connectTo(l, 11); + + j.connectTo(k, 10); + j.connectTo(l, 15); + + l.connectTo(j, 11); + l.connectTo(m, 6); + + n.connectTo(m, 9); + + m.connectTo(i, 9); + + test = new Dijkstra(list); + } + + @Test + public void testDistance() { + Assert.assertEquals(20, test.heapPath(i, l)); + } + + @Test + public void testIncorrectDistance() { + Assert.assertNotEquals(22, test.heapPath(i, l)); + } + + @Test + public void testPath() { + Assert.assertEquals("134", test.getPath(i, l)); + } + + @Test + public void testUnreachablePath() { + Assert.assertEquals("Sink Unreachable", test.getPath(m, l).trim()); + } } diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF deleted file mode 100644 index db473f0..0000000 --- a/target/classes/META-INF/MANIFEST.MF +++ /dev/null @@ -1,5 +0,0 @@ -Manifest-Version: 1.0 -Built-By: dev -Build-Jdk: 1.7.0_60 -Created-By: Maven Integration for Eclipse - diff --git a/target/classes/META-INF/maven/shortest-path/shortest-path/pom.properties b/target/classes/META-INF/maven/shortest-path/shortest-path/pom.properties deleted file mode 100644 index 041b4e0..0000000 --- a/target/classes/META-INF/maven/shortest-path/shortest-path/pom.properties +++ /dev/null @@ -1,7 +0,0 @@ -#Generated by Maven Integration for Eclipse -#Mon Jul 21 19:28:50 IST 2014 -version=0.0.1-SNAPSHOT -groupId=shortest-path -m2e.projectName=shortest-path -m2e.projectLocation=/home/dev/workspace/shortest-path -artifactId=shortest-path diff --git a/target/classes/META-INF/maven/shortest-path/shortest-path/pom.xml b/target/classes/META-INF/maven/shortest-path/shortest-path/pom.xml deleted file mode 100644 index 67560fd..0000000 --- a/target/classes/META-INF/maven/shortest-path/shortest-path/pom.xml +++ /dev/null @@ -1,15 +0,0 @@ - - 4.0.0 - shortest-path - shortest-path - 0.0.1-SNAPSHOT - Finds the shortest path between two locations - - - junit - junit - 4.11 - test - - - \ No newline at end of file diff --git a/target/classes/assembly/Graph.class b/target/classes/assembly/Graph.class deleted file mode 100644 index 2e522e4..0000000 Binary files a/target/classes/assembly/Graph.class and /dev/null differ diff --git a/target/classes/graph/Edge.class b/target/classes/graph/Edge.class deleted file mode 100644 index 3e6e9cd..0000000 Binary files a/target/classes/graph/Edge.class and /dev/null differ diff --git a/target/classes/graph/Link.class b/target/classes/graph/Link.class deleted file mode 100644 index 8c8cd95..0000000 Binary files a/target/classes/graph/Link.class and /dev/null differ diff --git a/target/classes/greedy/Dijkstra$1.class b/target/classes/greedy/Dijkstra$1.class deleted file mode 100644 index f645b33..0000000 Binary files a/target/classes/greedy/Dijkstra$1.class and /dev/null differ diff --git a/target/classes/greedy/Dijkstra.class b/target/classes/greedy/Dijkstra.class deleted file mode 100644 index 08f4c3f..0000000 Binary files a/target/classes/greedy/Dijkstra.class and /dev/null differ diff --git a/target/test-classes/greedy/TestShortestPath.class b/target/test-classes/greedy/TestShortestPath.class deleted file mode 100644 index 01d50e0..0000000 Binary files a/target/test-classes/greedy/TestShortestPath.class and /dev/null differ