nathanwailes

A* algorithm

Apr 14th, 2024 (edited)
861
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.96 KB | None | 0 0
  1. """
  2. The A* (A-star) algorithm is an efficient pathfinding and graph traversal algorithm. It finds the shortest path from the start node to a goal node by using a heuristic to estimate the cost from the current node to the goal, thus prioritizing paths that appear to be leading closer to the goal.
  3.  
  4. Below is a concise example of the A* algorithm in Python. This implementation assumes you have a graph where nodes are connected by weighted edges and you have a heuristic function that estimates the cost from any node to the goal node. We'll use a simple heuristic function: the Euclidean distance (for a grid-based graph), or you can adjust it according to your specific use case.
  5.  
  6. There are two concepts used to determine the best path from a start node to a goal node: weight and heuristic. Let's clarify each of these:
  7. - Weight is a measure of the effort, distance, or resource consumption required to move between nodes directly connected in the graph. It is a concrete measure based on the actual layout and characteristics of the graph.
  8. - The heuristic function is used to estimate the cost from a given node to the goal node, providing an informed guess about the remaining distance or cost. The heuristic function does not reflect the actual shortest path cost between two nodes, but rather provides an optimistic estimate, which guides the A* algorithm in its search for the shortest path.
  9.  
  10. - The total cost of a path through a given node is evaluated as f(n) = g(n) + h(n), where g(n) is the actual cost from the start node to node n (accumulated weights), and h(n) is the heuristic estimate from node n to the goal.
  11. - The algorithm maintains a priority queue (or a heap in this code) that sorts nodes based on their f(n) values, meaning nodes with lower estimated total costs are explored first.
  12.  
  13. Nathan's notes: This is basically just like a BFS except using a heap to order the vertices to be explored by their estimated total cost.
  14.  
  15. Mnemonic summary: A* algorithm is just like Dijkstra's algorithm, the only difference is that A* tries to look for a better path by using a heuristic function, which gives priority to nodes that are supposed to be better than others while Dijkstra's just explores all possible ways.
  16. """
  17. import heapq
  18. from random import randint
  19.  
  20. class Node:
  21.     def __init__(self, name, x, y, neighbors=None):
  22.         self.name = name
  23.         self.x, self.y = x, y
  24.         self.neighbors = neighbors if neighbors else {}  # dict to Node: weight
  25.  
  26. def astar(start, goal, heuristic):
  27.     # Heap of (estimated_total_cost, cost_to_start, node, path)
  28.     open_heap = [(heuristic(start, goal), 0, start, [start.name])]
  29.     while open_heap:
  30.         current_est, current_cost, current_node, path = heapq.heappop(open_heap)
  31.         if current_node == goal:
  32.             return path  # Goal reached, return the path
  33.         for neighbor, weight in current_node.neighbors.items():
  34.             new_cost = current_cost + weight
  35.             estimated_total_cost = new_cost + heuristic(neighbor, goal)
  36.             heapq.heappush(open_heap, (estimated_total_cost, new_cost, neighbor, path + [neighbor.name]))
  37.     return None  # No path found
  38.  
  39. def heuristic(node, goal):
  40.     """Example heuristic: Euclidean distance."""
  41.     return ((node.x - goal.x) ** 2 + (node.y - goal.y) ** 2) ** 0.5
  42.  
  43. # Example usage
  44. # Creating a simple graph (with dummy heuristic values as placeholders)
  45. node_a = Node('A', randint(0, 10), randint(0, 10))
  46. node_b = Node('B', randint(0, 10), randint(0, 10))
  47. node_c = Node('C', randint(0, 10), randint(0, 10))
  48. node_d = Node('D', randint(0, 10), randint(0, 10))
  49. node_e = Node('E', randint(0, 10), randint(0, 10))
  50.  
  51. # Cost from each node to its neighbor (e.g. the speed of travel on a particular segment of road)
  52. node_a.neighbors = {node_b: 1.0, node_c: 3.0}
  53. node_b.neighbors = {node_d: 1.0}
  54. node_c.neighbors = {node_d: 1.0, node_e: 5.0}
  55. node_d.neighbors = {node_e: 1.0}
  56.  
  57. # Find path from A to E
  58. path = astar(node_a, node_e, heuristic)
  59. print("Path from A to E:", path)
Advertisement
Add Comment
Please, Sign In to add comment