Start from the start node. Pick the node with lowest distance and update distance to its neighbors. Break out early to find min distance to end node only.
graph: s 4 e 1 1 a 1 b order of nodes: s, a, b, e path: s, e (d = 3) graph: 1 a 9 s 2 b 7 e order of nodes: s, a, b, e path: s, b, e (d = 9)
graph: nodes node: id neighbors // O(vlogv + e) dijkstra(g, start, end): dist = new map() dist[start.id] = 0 previous = new map() unvisited = new min-heap(capacity: g.nodes.count(), x => x.dist[x.n.id]) for n in g.nodes: unvisited.insert({n, dist}) while !unvisited.isempty(): n = unvisited.delete() //break early to find min distance to end only if n == end: break for neighbor in n.neighbors: //no need to update dist if neighbor is visited if !unvisited.has(neighbor.id): continue distneighbor = n.distance-to(neighbor) + dist[n.id] if dist[neighbor.id] == null || distneighbor < dist[neighbor.id]: dist[neighbor.id] = distneighbor previous[neighbor.id] = n if previous[end.id] == null: return null //no path path = new stack() path.push(end.id) n = end while n.id != start.id: n = previous[n.id] path.push(n) return tuple(dist[end.id], path))
For A*, don't update the neighbor's distance if not within limit. If no path exists within limit then n's distance will be null (infinity).
// O(vlogv + e) a-star(g, start, end, limit): dist = new map() dist[start.id] = 0 previous = new map() unvisited = new min-heap(capacity: g.nodes.count(), x => x.dist[x.n.id]) for n in g.nodes: unvisited.insert({n, dist}) while !unvisited.isempty(): n = unvisited.delete() //no path exists within limit if dist[n.id] == null: break //break early to find min distance to end only if n == end: break for neighbor in n.neighbors: //no need to update dist if neighbor is visited if !unvisited.has(neighbor.id): continue distneighbor = n.distance-to(neighbor) + dist[n.id] if (dist[neighbor.id] == null || distneighbor < dist[neighbor.id]) && distneighbor <= limit: dist[neighbor.id] = distneighbor previous[neighbor.id] = n if previous[end.id] == null: return null //no path path = new stack() path.push(end.id) n = end while n.id != start.id: n = previous[n.id] path.push(n) return tuple(dist[end.id], path))[Hat tip to SM]
No comments:
Post a Comment