|
|
@@ -2,7 +2,7 @@ import math |
|
|
|
from typing import Callable |
|
|
|
import re |
|
|
|
from graph import Graph, AdjacencyListGraph, AdjacencyMatrixGraph, NodeColor, Vertex |
|
|
|
|
|
|
|
import heapq |
|
|
|
|
|
|
|
def a_star(self, start_name: str, end_name: str, heuristic: Callable[[Vertex], float]): |
|
|
|
color_map = {} # maps vertices to their color |
|
|
@@ -15,6 +15,8 @@ def a_star(self, start_name: str, end_name: str, heuristic: Callable[[Vertex], f |
|
|
|
return math.inf |
|
|
|
return distance_map[vertex] + heuristic(vertex) |
|
|
|
|
|
|
|
Vertex.__lt__ = lambda self, other: cost(self) < cost(other) |
|
|
|
|
|
|
|
# Initialize the maps |
|
|
|
for vertex in self.all_vertices(): |
|
|
|
color_map[vertex] = NodeColor.WHITE |
|
|
@@ -27,12 +29,15 @@ def a_star(self, start_name: str, end_name: str, heuristic: Callable[[Vertex], f |
|
|
|
distance_map[start_node] = 0 |
|
|
|
|
|
|
|
# Initialize the queue with the start vertex |
|
|
|
queue = [start_node] |
|
|
|
queue = [] # Use a list instead of a deque, because we need to sort it with |
|
|
|
heapq.heappush(queue, start_node) |
|
|
|
|
|
|
|
# Process the queue |
|
|
|
while len(queue) > 0: |
|
|
|
queue.sort(key=cost) |
|
|
|
vertex = queue.pop(0) |
|
|
|
vertex = heapq.heappop(queue) |
|
|
|
if color_map[vertex] == NodeColor.BLACK: |
|
|
|
# Skip already processed vertices (possibly with a higher cost) |
|
|
|
continue |
|
|
|
if vertex.value == end_name: |
|
|
|
# Return the distance and predecessor maps |
|
|
|
return distance_map, predecessor_map |
|
|
@@ -44,8 +49,8 @@ def a_star(self, start_name: str, end_name: str, heuristic: Callable[[Vertex], f |
|
|
|
continue |
|
|
|
predecessor_map[dest] = vertex |
|
|
|
distance_map[dest] = distance_map[vertex] + weight |
|
|
|
heapq.heappush(queue, dest) |
|
|
|
if color_map[dest] == NodeColor.WHITE: |
|
|
|
queue.append(dest) |
|
|
|
color_map[dest] = NodeColor.GRAY |
|
|
|
color_map[vertex] = NodeColor.BLACK |
|
|
|
|