El algoritmo A* (A-star) se utiliza principalmente para la búsqueda de rutas y el recorrido de grafos. Es famoso por su eficiencia a la hora de determinar la ruta más corta. Campos como la inteligencia artificial, la robótica y el desarrollo de juegos dependen de este algoritmo.
La fortaleza clave del algoritmo A* radica en su exploración sistemática de un gráfico o cuadrícula. A partir de un nodo inicial, busca eficientemente la ruta óptima hacia el nodo objetivo. Esta eficiencia se logra combinando la naturaleza integral del algoritmo de Dijkstra y el enfoque heurístico de Greedy Best-First Search.
La función de costo única del algoritmo A* lo distingue. Al considerar tanto el costo real de llegar a un nodo como una heurística estimada del costo restante, prioriza de manera inteligente los caminos más prometedores. Esta doble consideración agiliza la búsqueda, haciéndola muy precisa y valiosa.
En el siguiente artículo, profundizaremos en ejemplos detallados del algoritmo A* en acción, mostrando su eficacia y versatilidad.
Al mantener un tono formal y utilizar oraciones cortas y concisas, esta versión transmite los puntos clave sobre el algoritmo A* manteniendo un enfoque profesional y técnico.
Descripción general
- Describe el uso principal de A* en la búsqueda de rutas y el recorrido de gráficos.
- Explique los componentes de la función de costos: g(n)g(n)g(n), h(n)h(n)h(n) y f(n)f(n)f(n).
- Identificar y diferenciar entre heurísticas de Manhattan, Euclidiana y Diagonal.
- Implemente el algoritmo A* en Python para la búsqueda de rutas basada en cuadrículas.
- Reconocer las aplicaciones de A* en IA, robótica y desarrollo de juegos.
¿Cómo funciona el algoritmo A*?
El algoritmo A* utiliza una combinación de distancias reales y heurísticas para determinar el mejor camino. Aquí están los componentes principales:
- g(n) : El costo de la ruta desde el nodo inicial hasta el nodo actual nnn.
- h(n) : una función heurística que estima el costo desde el nodo nnn hasta el objetivo.
- f(n) : El costo total estimado de la ruta a través del nodo nnn (f(n)=g(n)+h(n)f(n) = g(n) + h(n)f(n)=g (n)+h(n)).
Algoritmo A*: Guía paso a paso
Inicialización
- Cree una lista abierta para rastrear nodos para su evaluación.
- Hacer una lista cerrada de los nodos que han sido evaluados.
- Agregue el nodo de inicio a la lista abierta, marcando el comienzo de su camino.
Bucle principal
- Continúe hasta que la lista abierta esté vacía o se alcance el objetivo:
- Seleccione el nodo con el valor f(x) más bajo, lo que indica la ruta más prometedora.
- Mueva el nodo seleccionado de la lista abierta a la lista cerrada.
- Examine cada vecino del nodo seleccionado para determinar los próximos pasos.
Evaluación de vecinos
- Para cada vecino:
- Si es el objetivo, reconstruye el camino y devuélvelo como solución.
- Omita a los vecinos que ya estén en la lista cerrada, ya que han sido evaluados.
- Si un vecino no está en la lista abierta:
- Súmalo y calcula sus valores g(x), h(x) y f(x).
- Para los vecinos que ya están en la lista abierta:
- Compruebe si la nueva ruta es más eficiente (valor g(x) más bajo).
- Si es así, actualice los valores de g(x), h(x) y f(x) y establezca el nodo actual como su padre.
Heurística en A*
La heurística se utiliza para estimar la distancia desde el nodo actual hasta el objetivo. Las heurísticas comunes incluyen:
- Distancia Manhattan: Se utiliza cuando los movimientos están restringidos a direcciones horizontales y verticales.

Distancia Euclidiana: Se utiliza cuando los movimientos pueden ser en cualquier dirección.

Distancia Diagonal: Se utiliza cuando los movimientos pueden ser en ocho direcciones posibles (como un rey en el ajedrez).

Implementación del algoritmo A* en Python
Ahora, veamos cómo implementar el algoritmo A* en Python. Definiremos un mapa simple basado en una cuadrícula donde 0 representa celdas transitables y 1 representa obstáculos.
Código:
import heapq
import math
class Node:
def __init__(self, position, parent=None):
self.position = position
self.parent = parent
self.g = 0 # Distance from start node
self.h = 0 # Heuristic to goal
self.f = 0 # Total cost
def __eq__(self, other):
return self.position == other.position
def __lt__(self, other):
return self.f < other.f
def __repr__(self):
return f"({self.position}, f: {self.f})"
def heuristic(a, b):
return math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2)
def astar(maze, start, end):
open_list = []
closed_list = set()
start_node = Node(start)
end_node = Node(end)
heapq.heappush(open_list, start_node)
while open_list:
current_node = heapq.heappop(open_list)
closed_list.add(current_node.position)
if current_node == end_node:
path = []
while current_node:
path.append(current_node.position)
current_node = current_node.parent
return path[::-1]
for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]:
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) - 1) or node_position[1] < 0:
continue
if maze[node_position[0]][node_position[1]] != 0:
continue
new_node = Node(node_position, current_node)
if new_node.position in closed_list:
continue
new_node.g = current_node.g + 1
new_node.h = heuristic(new_node.position, end_node.position)
new_node.f = new_node.g + new_node.h
if add_to_open(open_list, new_node):
heapq.heappush(open_list, new_node)
return None
def add_to_open(open_list, neighbor):
for node in open_list:
if neighbor == node and neighbor.g > node.g:
return False
return True
maze = [
[0, 1, 0, 0, 0, 0, 0],
[0, 1, 0, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0, 0]
]
start = (0, 0)
end = (4, 6)
path = astar(maze, start, end)
print(path)
Producción: [(0, 0), (1, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (3, 6), ( 4, 6)]

Explicación del resultado
Esta ruta representa la secuencia de pasos desde el punto inicial (0, 0) hasta el punto final (4, 6). Aquí hay una explicación detallada paso a paso del recorrido:
- Comienza en (0, 0): esta es la posición inicial en la esquina superior izquierda del laberinto.
- Mover a (1, 0): Bajar un paso a la primera fila.
- Mover a (2, 1): Mueve un paso hacia abajo y un paso hacia la derecha, evitando el obstáculo en (1, 1).
- Mover a (2, 2): Mover un paso a la derecha.
- Mover a (2, 3): Mover un paso a la derecha.
- Mover a (2, 4): Mover un paso a la derecha.
- Mover a (2, 5): Mover un paso a la derecha.
- Mover a (3, 6): Muévete en diagonal hacia abajo a la derecha, saltando los obstáculos y llegando a la penúltima columna de la tercera fila.
Mover a (4, 6): Bajar un paso para alcanzar la posición objetivo.
Conclusión
Esta guía proporciona una descripción general completa de la funcionalidad del algoritmo A* junto con la implementación del código.
El algoritmo A* es una herramienta valiosa que simplifica problemas complejos y ofrece un enfoque estratégico y eficiente para encontrar soluciones óptimas. Espero que este artículo le resulte útil para comprender este algoritmo de Python.