Operadores de Bellman, visualmente¶
8 minutos de lectura · 14 abril 2026
La ecuación de Bellman tiene fama de árida. Aparece en reinforcement learning, en optimización dinámica, en finanzas, y cada disciplina la presenta con su propia notación incomprensible.
Lo que la ecuación dice es trivial: el valor de estar en un sitio es el premio inmediato más el valor descontado de estar en el sitio siguiente.
Y aun así, cuando uno la ve por primera vez en forma de operador T, pierde cualquier intuición. Voy a intentar devolverla.
La idea, sin matemáticas¶
Imagínate un laberinto con celdas. Cada celda tiene un valor: cuánto premio esperas obtener si empiezas ahí y juegas óptimamente.
Para calcular ese valor, hay un proceso iterativo:
- Empiezas adivinando. Todas las celdas valen cero. Es una adivinanza terrible, pero da igual.
- Mejoras la adivinanza mirando a los vecinos: "el valor de esta celda es el premio que recibo aquí + el mejor valor de la celda a la que me podría mover".
- Repites hasta que los valores dejan de cambiar.
Ese proceso de "mejorar la adivinanza" es exactamente el operador de Bellman. Aplicarlo una vez. Otra. Otra. Hasta converger.
Lo geométrico¶
Pensar el operador como una función T(v) → v' te lleva a este dibujo mental:
- Tienes un espacio donde cada punto es una posible función de valor (todas las celdas asignadas a un número).
Tmueve puntos a otros puntos en ese espacio.- Hay un punto fijo único
v*que satisfaceT(v*) = v*. Ese punto fijo es la solución óptima. - Cada aplicación de
Tte acerca al punto fijo en un factorγ(el descuento), constante.
Esto último es lo que se llama contracción. Y es lo que garantiza que el proceso iterativo converge: cada paso reduce la distancia al óptimo al menos en γ.
Visualízalo como una espiral hacia un centro. No te acercas igual de rápido todo el rato, pero te acercas siempre.
Por qué importa para tu código¶
Si has implementado value iteration en un agente de RL, esto es lo que estás haciendo:
def value_iteration(estados, transiciones, premio, gamma=0.95, tol=1e-6):
V = {s: 0.0 for s in estados}
while True:
V_nuevo = {}
for s in estados:
V_nuevo[s] = max(
premio(s, a) + gamma * sum(p * V[s_] for s_, p in transiciones(s, a))
for a in acciones(s)
)
if max(abs(V_nuevo[s] - V[s]) for s in estados) < tol:
return V_nuevo
V = V_nuevo
El V_nuevo = T(V) ese es el operador. El bucle es la contracción.
Tres cosas se entienden mejor con la imagen geométrica:
- Por qué siempre converge. Estás en un espacio métrico completo y
Tes contracción. Banach garantiza el punto fijo. No hay misticismo. - Por qué
γcercano a 1 converge despacio. El factor de contracción esγ. Siγ = 0.99, cada paso reduce la distancia un 1%. Cien pasos para reducir un 63%. - Por qué cambiar la política no rompe el método. Si en lugar de
maxhacessum_a π(a|s) * (...), el operador resultante también es contracción. Eso es el operador de Bellman para una política fija. Mismo dibujo, otro punto fijo.
El truco que pocas veces te cuentan¶
El operador tiene dos formas distintas que conviene no confundir:
T*(operador óptimo): usamaxsobre acciones. Su punto fijo esV*, la función de valor óptima.T^π(operador de evaluación): usa la políticaπfija. Su punto fijo esV^π, el valor de seguir esa política.
Métodos como policy iteration alternan: evalúan con T^π hasta converger (calculan V^π para una π fija), y luego mejoran la política mirando ese V^π. Es dos puntos fijos anidados en lugar de uno.
Saber esto cambia cómo lees cualquier paper de RL. Casi todos los algoritmos son una variación sobre cuándo aplicar qué operador y qué aproximar con redes.
Próxima entrada
El siguiente paso natural es Q-learning, donde el operador deja de mover funciones de valor y empieza a mover funciones de acción-valor. Mismo principio, otra superficie. En la próxima.
¿Comentarios o correcciones? info@encodigo.es.