/** * Find the path from start to goal using breadth first search * * @param start The starting location * @param goal The goal location * @param nodeSearched A hook for visualization. See assignment instructions for how to use it. * @return The list of intersections that form the shortest (unweighted) path from start to goal * (including both start and goal). */ public List<GeographicPoint> bfs( GeographicPoint start, GeographicPoint goal, Consumer<GeographicPoint> nodeSearched) { // TODO: Implement this method in WEEK 2 // Hook for visualization. See writeup. // nodeSearched.accept(next.getLocation()); Queue<GeographicPoint> queue = new LinkedList<GeographicPoint>(); Set<GeographicPoint> visited = new HashSet<GeographicPoint>(); Map<GeographicPoint, GeographicPoint> parentMap = new HashMap<GeographicPoint, GeographicPoint>(); queue.add(start); visited.add(start); while (!queue.isEmpty()) { GeographicPoint curr = queue.poll(); nodeSearched.accept(curr); if (curr.equals(goal)) { // reaches the goal return RetrievePath(parentMap, start, goal); // retrieve the path } MapVertex node = Vertices.get(curr); // the MapVertex associated with the location curr Set<MapEdge> edges = node.getEdges(); // the edges connected to the node for (MapEdge edge : edges) { MapVertex next = edge.getEnd(); // neighbor of the location curr GeographicPoint nextLoc = next.getLocation(); if (!visited.contains(nextLoc)) { visited.add(nextLoc); parentMap.put(nextLoc, curr); // set curr as the parent of next in tha path map queue.add(nextLoc); } } } /////// if the goal is not achievable return null; }
@Override public boolean equals(Object obj) { Intersection i = (Intersection) obj; if (i.getLocation().getX() == location.getX() && i.getLocation().getY() == location.getY()) { return true; } return false; }
private List<GeographicPoint> RetrievePath( Map<GeographicPoint, GeographicPoint> parentMap, GeographicPoint start, GeographicPoint goal) { List<GeographicPoint> path = new ArrayList<GeographicPoint>(); GeographicPoint curr = goal; while (!curr.equals(start)) { path.add(0, curr); curr = parentMap.get(curr); } path.add(0, curr); return path; }
/** * Find the path from start to goal using breadth first search * * @param start The starting location * @param goal The goal location * @param nodeSearched A hook for visualization. See assignment instructions for how to use it. * @return The list of intersections that form the shortest (unweighted) path from start to goal * (including both start and goal). */ public List<GeographicPoint> bfs( GeographicPoint start, GeographicPoint goal, Consumer<GeographicPoint> nodeSearched) { // TODO: Implement this method in WEEK 2 Set<GeographicPoint> visited = new HashSet<GeographicPoint>(); Queue<GeographicPoint> searchQueue = new LinkedBlockingQueue<GeographicPoint>(); Map<GeographicPoint, GeographicPoint> parentMap = new HashMap<GeographicPoint, GeographicPoint>(); LinkedList<GeographicPoint> result = new LinkedList<GeographicPoint>(); if (null == start || null == goal) throw new IllegalArgumentException(); searchQueue.add(start); visited.add(start); GeographicPoint curr = null; while (!searchQueue.isEmpty()) { curr = searchQueue.remove(); nodeSearched.accept(curr); if (curr.equals(goal)) break; for (GeographicPoint neighbor : getUnvisitedNeighbors(curr, visited)) { visited.add(neighbor); searchQueue.add(neighbor); parentMap.put(neighbor, curr); } } if (curr == null || !curr.equals(goal)) return null; for (GeographicPoint node = goal; node != null; node = parentMap.get(node)) { result.push(node); } return result; // Hook for visualization. See writeup. // nodeSearched.accept(next.getLocation()); }
/** * Compare the user's result with the right answer. * * @param i The graph number * @param result The user's graph * @param corr The correct answer * @param start The point to start from * @param end The point to end at */ public void judge( int i, MapGraph result, CorrectAnswer corr, GeographicPoint start, GeographicPoint end) { // Correct if paths are same length and have the same elements feedback += appendFeedback( i, "Running Dijkstra's algorithm from (" + start.getX() + ", " + start.getY() + ") to (" + end.getX() + ", " + end.getY() + ")"); List<GeographicPoint> path = result.dijkstra(start, end); if (path == null) { if (corr.path == null) { feedback += "PASSED."; correct++; } else { feedback += "FAILED. Your implementation returned null; expected \n" + printPath(corr.path) + "."; } } else if (path.size() != corr.path.size() || !corr.path.containsAll(path)) { feedback += "FAILED. Expected: \n" + printPath(corr.path) + "Got: \n" + printPath(path); if (path.size() != corr.path.size()) { feedback += "Your result has size " + path.size() + "; expected " + corr.path.size() + "."; } else { feedback += "Correct size, but incorrect path."; } } else { feedback += "PASSED."; correct++; } }
/** * Find the path from start to goal using A-Star search * * @param start The starting location * @param goal The goal location * @param nodeSearched A hook for visualization. See assignment instructions for how to use it. * @return The list of intersections that form the shortest path from start to goal (including * both start and goal). */ public List<GeographicPoint> aStarSearch( GeographicPoint start, GeographicPoint goal, Consumer<GeographicPoint> nodeSearched) { // Initialize priority queue PriorityQueue<MapNode> pq = new PriorityQueue<MapNode>(); // Initialize priority queue // Initialize HashSet HashSet<MapNode> visited = new HashSet<MapNode>(); HashMap<MapNode, MapNode> parent = new HashMap<MapNode, MapNode>(); // Initialize parent HashMap // Initialize values to infinity MapNode startNode = vertices.get(start); initializeNodes(startNode, vertices); // Initialize estimated distance double heuristicDistance = start.distance(goal); // Enqueue start node pq.add(startNode); // Count int aStarCount = 0; // while queue is not empty while (pq.isEmpty() == false) { // dequeue current node from the front of the queue // MapNode dqNode = pq.remove(); MapNode dqNode = pq.poll(); aStarCount++; // Hook for visualization. nodeSearched.accept(dqNode.getCoordinates()); // if curr is not visited if (visited.contains(dqNode) == false) { // add curr to the visited set visited.add(dqNode); // for each of the current node's neighbors not in the visited set for (MapEdge e : dqNode.getEdges()) { MapNode n = vertices.get(e.end); if (visited.contains(n) == false) { // calculate the distance from the start node to the current node, // to each neighboring node // double g = dqNode.getWeight() + e.getDistance(); double g = dqNode.getWeight() + dqNode.getCoordinates().distance(n.getCoordinates()); // calculate the estimated distance from the neighboring node to // the goal double h = n.getCoordinates().distance(goal); // set the weight of the neighboring node n.setWeight(g + h); // set the current node as it's neighboring nodes' parent parent.put(n, dqNode); // If neighbor is the goal, return! if (vertices.get(n.getCoordinates()) == vertices.get(goal)) { List<GeographicPoint> listCoordinates = new ArrayList<GeographicPoint>(); // Build a list using the path found from the start node to the goal node. listCoordinates = buildPath(n, parent); // Print out the visited nodes printPathOfCoordinates(listCoordinates); System.out.println("a star count: " + aStarCount); return listCoordinates; } // if the original heuristic distance is less than or equal // to the new heuristic distance, add the node to the // priority queue. if (heuristicDistance <= n.getWeight()) { pq.offer(n); } } } } // if } // while return null; }
public GeographicPoint getLocation() { return new GeographicPoint(location.getX(), location.getY()); }