!pip install gymnasium
import gymnasium as gym
import numpy as np
import random
# ============================================================
# CREAR EL ENTORNO
# ============================================================
# is_slippery=True hace que el hielo sea resbaladizo,
# por lo que el agente no siempre se moverá exactamente
# hacia donde desea.
env = gym.make("FrozenLake-v1", is_slippery=True)
# Obtener el número de estados y acciones disponibles
n_estados = env.observation_space.n
n_acciones = env.action_space.n
print("Número de estados:", n_estados)
print("Número de acciones:", n_acciones)
# La tabla Q almacenará el valor esperado de realizar
# una acción en un estado determinado.
# Inicialmente todos los valores son cero.
Q = np.zeros((n_estados, n_acciones))
# ============================================================
# DEFINIR HIPERPARÁMETROS
# ============================================================
# Tasa de aprendizaje
# Determina cuánto aprende el agente en cada experiencia.
alpha = 0.8
# Factor de descuento
# Indica qué tan importantes son las recompensas futuras.
gamma = 0.95
# Probabilidad inicial de explorar acciones aleatorias.
epsilon = 1.0
# Valor mínimo permitido para epsilon.
epsilon_min = 0.01
# Reducción gradual de la exploración.
epsilon_decay = 0.995
# Número de episodios de entrenamiento.
episodios = 5000
# Máximo de pasos permitidos por episodio.
max_pasos = 100
# Lista para guardar las recompensas obtenidas.
recompensas = []
# ============================================================
# ENTRENAMIENTO DEL AGENTE
# ============================================================
for episodio in range(episodios):
# Reiniciar el entorno al inicio de cada episodio.
estado, _ = env.reset()
recompensa_total = 0
# Ejecutar el episodio.
for paso in range(max_pasos):
# ----------------------------------------------------
# POLÍTICA EPSILON-GREEDY
# ----------------------------------------------------
# Con cierta probabilidad explora una acción aleatoria.
# De lo contrario utiliza la mejor acción conocida.
# ----------------------------------------------------
if random.uniform(0, 1) < epsilon:
accion = env.action_space.sample()
else:
accion = np.argmax(Q[estado])
# Ejecutar la acción seleccionada.
nuevo_estado, recompensa, terminado, truncado, _ = env.step(accion)
# ----------------------------------------------------
# ACTUALIZAR LA TABLA Q
#
# Fórmula de Q-Learning:
#
# Q(s,a) = Q(s,a) +
# alpha * [recompensa +
# gamma * max(Q(s')) - Q(s,a)]
# ----------------------------------------------------
Q[estado, accion] = Q[estado, accion] + alpha * (
recompensa
+ gamma * np.max(Q[nuevo_estado])
- Q[estado, accion]
)
# Actualizar el estado actual.
estado = nuevo_estado
# Acumular recompensa.
recompensa_total += recompensa
# Finalizar si llegó a la meta o cayó en un agujero.
if terminado or truncado:
break
# Reducir poco a poco la exploración.
epsilon = max(epsilon_min, epsilon * epsilon_decay)
# Guardar la recompensa obtenida.
recompensas.append(recompensa_total)
print("\nEntrenamiento finalizado.")
# ============================================================
# MOSTRAR LA TABLA Q APRENDIDA
# ============================================================
print("\nTabla Q aprendida:\n")
print(Q)
# ============================================================
# EVALUACIÓN DEL AGENTE
# ============================================================
# Durante la evaluación el agente ya no explora,
# únicamente utiliza la mejor acción aprendida.
exitos = 0
pruebas = 100
for episodio in range(pruebas):
estado, _ = env.reset()
for paso in range(max_pasos):
# Elegir siempre la acción con mayor valor Q.
accion = np.argmax(Q[estado])
estado, recompensa, terminado, truncado, _ = env.step(accion)
if terminado or truncado:
# Si la recompensa es 1 significa que llegó a la meta.
if recompensa == 1:
exitos += 1
break
print("\n==============================")
print("RESULTADOS DE LA EVALUACIÓN")
print("==============================")
print(f"Episodios exitosos: {exitos} de {pruebas}")
print(f"Porcentaje de éxito: {(exitos/pruebas)*100:.2f}%")