# 🎯 A* (A-Star) Algorithm `#pathfinding` `#graph-search` `#algorithms` `#heuristic-search` `#optimization` <div style="background-color: #4A90E2; color: white; padding: 25px; border-radius: 10px; margin: 30px 0; font-size: 18px;"> <h1 style="color: white; font-size: 24px;">🎯 Quick Overview</h1> A* is an informed search algorithm that combines Dijkstra's algorithm with heuristic estimation. It guarantees the shortest path while being more efficient than exhaustive searches by using heuristic functions to guide the search towards the goal. </div> ## 📊 Visual Understanding of A* ### Basic A* Search Pattern ```mermaid graph TD S((Start)) -->|f=0| A((A)) S -->|f=2| B((B)) A -->|f=3| C((C)) B -->|f=4| D((D)) C -->|f=5| G((Goal)) D -->|f=6| G style S fill:#4CAF50 style G fill:#FF5722 style C fill:#2196F3 style A fill:#2196F3 ``` ![image](https://hackmd.io/_uploads/HkxTCIPg1x.png) ![image](https://hackmd.io/_uploads/SJQeyDvlke.png) ## 📚 Introduction to A* A* (pronounced "A-star") is one of the most popular and widely-used pathfinding algorithms, developed by Peter Hart, Nils Nilsson, and Bertram Raphael in 1968. It combines the benefits of both Dijkstra's algorithm and greedy best-first search. ### Core Principles - **Best-First Search**: Always expands the most promising node - **Heuristic Guidance**: Uses estimated cost to goal - **Optimality**: Guarantees shortest path with admissible heuristics - **Completeness**: Will always find a solution if one exists <div style="background-color: #4A90E2; color: white; padding: 25px; border-radius: 10px; margin: 30px 0;"> <h2>🔑 Fundamental Components</h2> 1. **Cost Function f(n)** ``` f(n) = g(n) + h(n) ``` - g(n): Actual cost from start to node n - h(n): Estimated cost from n to goal - f(n): Total estimated path cost 2. **Data Structures** - Open List: Priority queue of nodes to explore - Closed List: Set of already explored nodes - Parent Map: Tracks optimal path 3. **Heuristic Function** - Manhattan Distance (Grid) - Euclidean Distance (Continuous) - Diagonal Distance (8-connected grid) </div> ## 💻 Implementation <div style="background-color: #040720; padding: 25px; border-radius: 10px; border-left: 5px solid #228be6;"> ```python class Node: def __init__(self, position, g=float('inf'), h=0): self.position = position self.g = g # Cost from start to node self.h = h # Estimated cost to goal self.f = g + h # Total estimated cost self.parent = None class AStar: def __init__(self, grid): self.grid = grid self.open_list = [] self.closed_set = set() def manhattan_distance(self, p1, p2): return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]) def get_neighbors(self, node): neighbors = [] for dx, dy in [(0,1), (1,0), (0,-1), (-1,0)]: new_pos = (node.position[0] + dx, node.position[1] + dy) if self.is_valid(new_pos): neighbors.append(new_pos) return neighbors def find_path(self, start, goal): start_node = Node(start, g=0, h=self.manhattan_distance(start, goal)) heapq.heappush(self.open_list, (start_node.f, start_node)) while self.open_list: current_f, current_node = heapq.heappop(self.open_list) if current_node.position == goal: return self.reconstruct_path(current_node) self.closed_set.add(current_node.position) for neighbor_pos in self.get_neighbors(current_node): if neighbor_pos in self.closed_set: continue tentative_g = current_node.g + 1 neighbor = Node( neighbor_pos, g=tentative_g, h=self.manhattan_distance(neighbor_pos, goal) ) if self.is_better_path(neighbor): neighbor.parent = current_node heapq.heappush(self.open_list, (neighbor.f, neighbor)) return None ``` </div> ## 🔬 Advanced Features ### 1. Heuristic Functions ```python def euclidean_distance(p1, p2): return ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)**0.5 def diagonal_distance(p1, p2): dx = abs(p1[0] - p2[0]) dy = abs(p1[1] - p2[1]) return max(dx, dy) + (math.sqrt(2) - 1) * min(dx, dy) ``` ### 2. Optimizations - **Tie-Breaking**: Prefer paths towards goal - **Binary Heap**: Efficient priority queue - **Hash Table**: Fast node lookup ## ⚖️ Pros and Cons <div style="background-color: #040720; padding: 25px; border-radius: 10px; margin: 20px 0;"> <h3>✅ Advantages</h3> 1. **Optimality** - Guaranteed shortest path - Optimal with admissible heuristics - Complete algorithm 2. **Efficiency** - More efficient than Dijkstra - Explores fewer nodes - Guided search direction 3. **Flexibility** - Works with any graph structure - Customizable heuristics - Handles different movement costs </div> <div style="background-color: #29465B; padding: 25px; border-radius: 10px; margin: 20px 0;"> <h3>❌ Disadvantages</h3> 1. **Memory Usage** - Stores all nodes in memory - Can be memory-intensive - Scales with search space 2. **Heuristic Dependency** - Performance relies on good heuristic - Poor heuristics reduce efficiency - Must be admissible for optimality 3. **Processing Overhead** - Priority queue operations - Path reconstruction cost - Heuristic calculations </div> [Would you like me to continue with the remaining sections (Applications, Comparison, etc.)?]