package id.ac.itats.skripsi.shortestpath.engine; import id.ac.itats.skripsi.shortestpath.model.Edge; import id.ac.itats.skripsi.shortestpath.model.Graph; import id.ac.itats.skripsi.shortestpath.model.Vertex; import id.ac.itats.skripsi.util.ProgressReporter; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.PriorityQueue; public class AStar2 { private double tLat; private double tLon; private Graph graph; private ProgressReporter reporter; public AStar2(Graph graph, ProgressReporter reporter) { this.graph = graph; this.reporter = reporter; } public List<Vertex> computePaths(Vertex source, Vertex target) { int process = 0; reporter.finish(false); if (!graph.hasClearTree) { graph.clearTree(); } reporter.process(process); tLat = Double.valueOf(target.lat); tLon = Double.valueOf(target.lon); PriorityQueue<Vertex> openList = new PriorityQueue<Vertex>(5, Vertex.CompareF); source.minDistance = 0.; source.minF = source.minDistance + calcHeuristic(source); openList.add(source); while (!openList.isEmpty()) { reporter.process(process++); Vertex current = openList.poll(); current.onClosedList = true; if (current.equals(target)) { reporter.report("Shortest path finish...!"); reporter.finish(true); return reconstructPath(current); } // currentNeighborhood for (Edge e : current.adjacencies) { Vertex neighbor = e.target; boolean neighborIsBetter; if (neighbor.onClosedList) { continue; } if (!neighbor.isObstacle) { double tentativeG = current.minDistance + e.weight; if (!neighbor.onOpenList) { openList.add(neighbor); neighbor.onOpenList = true; neighborIsBetter = true; } else if (tentativeG < current.minDistance) { neighborIsBetter = true; } else { neighborIsBetter = false; } if (neighborIsBetter) { neighbor.previous = current; neighbor.minDistance = tentativeG; neighbor.minF = neighbor.minDistance + calcHeuristic(neighbor); } } } } reporter.report("path not found!"); reporter.finish(true); return null; } private List<Vertex> reconstructPath(Vertex target) { List<Vertex> path = new ArrayList<Vertex>(); for (Vertex vertex = target; vertex != null; vertex = vertex.previous) path.add(vertex); Collections.reverse(path); graph.hasClearTree = false; return path; } private double calcHeuristic(Vertex current) { double x = Double.valueOf(current.lat) - tLat; double y = Double.valueOf(current.lon) - tLon; return Math.sqrt(x * x + y * y); } }