package gps; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Queue; import java.util.Stack; // trois algorithmes : DFS, BFS, Dijkstra public class FindPath { public static Iterable<Edge> runDijkstra(Vertex source, Vertex target) { HashSet<Vertex> visited = new HashSet<Vertex>(); HashMap<Vertex, Edge> path = new HashMap<Vertex, Edge>(); path.put(source, null); HashMap<Vertex, Double> distance = new HashMap<Vertex, Double>(); distance.put(source, 0.); PriorityQueue<VertexDist> pq = new PriorityQueue<VertexDist>(); pq.add(new VertexDist(source, 0.)); while (!pq.isEmpty()) { VertexDist n = pq.poll(); if (visited.contains(n.v)) continue; visited.add(n.v); for (Edge e : Graph.successors(n.v)) { double d = n.d + e.length(); if (!distance.containsKey(e.dst) || d < distance.get(e.dst)) { distance.put(e.dst, d); pq.add(new VertexDist(e.dst, d)); path.put(e.dst, e); } } } return buildPath(source, target, path); } public static Iterable<Edge> runBFS(Vertex source, Vertex target) { Queue<Vertex> queue = new LinkedList<Vertex>(); HashMap<Vertex, Edge> visited = new HashMap<Vertex, Edge>(); queue.add(source); visited.put(source, null); while (!queue.isEmpty()) { Vertex v = queue.poll(); if (v.equals(target)) break; for (Edge e : Graph.successors(v)) if (!visited.containsKey(e.dst)) { visited.put(e.dst, e); queue.add(e.dst); } } return buildPath(source, target, visited); } public static Iterable<Edge> runDFS(Vertex source, Vertex target) { Stack<Vertex> stack = new Stack<Vertex>(); HashMap<Vertex, Edge> visited = new HashMap<Vertex, Edge>(); visited.put(source, null); stack.add(source); while (!stack.isEmpty()) { Vertex v = stack.pop(); if (v.equals(target)) break; for (Edge e : Graph.successors(v)) if (!visited.containsKey(e.dst)) { visited.put(e.dst, e); stack.add(e.dst); } } return buildPath(source, target, visited); } static Iterable<Edge> buildPath(Vertex source, Vertex target, HashMap<Vertex, Edge> visited) { LinkedList<Edge> p = new LinkedList<Edge>(); while (visited.containsKey(target) && !target.equals(source)) { Edge e = visited.get(target); p.addFirst(e); target = e.src; } return p; } static void printPath(Iterable<Edge> path) { if (path == null) return; double dist = 0.; int size = 0; for (Edge e : path) { dist += e.length(); size++; // System.out.println(e); if (e.name != null) System.out.printf(" %s (%.2f km)\n", e.name, e.length()); } System.out.println(size + " arcs"); System.out.printf("distance totale = %.2f km\n", dist); } }