01 · Punto de partida
Entrar es quedarse para siempre
Ruina o éxito, resuelto o caído para siempre: hay estados de los que no se sale. Una vez adentro, la historia se congela. Son los absorbentes.
Con dos absorbentes rivales (0 pierde, 4 gana), la pregunta es cuál captura según dónde se empieza.
- ¿Qué fila es [0,…,1,…,0] con el 1 en la diagonal?
- ¿Cuántos absorbentes hay: uno o rivales?
- ¿Con qué chance captura cada uno desde i?
- ¿Cuánto tarda la captura?
02 · Definición
¿Qué es absorbente?
Una sola condición, tres lecturas:
Fila unitaria
pᵢᵢ = 1 y resto 0. El sorteo desde i siempre da i.
Lazo único
En el diagrama: solo su rulo. Sin flechas de salida.
Rivales
Con varios, cada uno captura con su chance uᵢ (suman 1).
En la ruina 0–4 con moneda pareja, desde 2 gana el 4 con 50 %; desde 1, con 25 %; desde 3, con 75 %: la cercanía manda.
| Inicio i | P(gana) | P(pierde) |
|---|---|---|
| 1 | 0,25 | 0,75 |
| 2 | 0,50 | 0,50 |
| 3 | 0,75 | 0,25 |
03 · Anatomía
Trampa, rivales y tiempo
Cuatro ideas para operar con absorbentes:
- Detección
- Fila unitaria en P o nodo con solo su lazo. Se lee sin simular.
- Captura segura
- En finitas con absorción segura, desde lo transitorio se absorbe con chance 1 en algún absorbente.
- Reparto uᵢ
- Con rivales, cada inicio i tiene su vector de captura. Suma 1 entre absorbentes.
- Tiempo medio
- Pasos hasta la captura desde i. Crece lejos de las trampas. (Tema 37)
Un absorbente
Destino único
Todo termina ahí. Solo importa cuándo (tiempo de absorción).
Rivales
Final disputado
Importa cuál y cuándo: chances uᵢ y tiempos por inicio.
04 · Ejemplos
Trampas de manual
Todo final sin retorno:
- 1Ruina / éxito.
0 pierde y 4 gana: rivales clásicos del laboratorio.
- 2Resuelto.
Ticket cerrado: no se reabre (en el modelo).
- 3Muerte / alta.
Egresos que terminan el episodio.
- 4Abandono.
Cliente perdido: no vuelve en el horizonte.
- 5Casi-trampa.
Caído con reparación 0,01: parece absorbente en corto, no en largo.
05 · Representación en Python
Detectar filas unitarias
En Python, absorbente se detecta por fila (1,0 en la diagonal) y se simula frenando al llegar: la historia termina en la captura.
Python en tu navegador. Estos bloques se ejecutan localmente con Pyodide, sin instalar nada. Cambiá el inicio y mirá el reparto.
P = [[1.0, 0.0, 0.0, 0.0, 0.0],
[0.5, 0.0, 0.5, 0.0, 0.0],
[0.0, 0.5, 0.0, 0.5, 0.0],
[0.0, 0.0, 0.5, 0.0, 0.5],
[0.0, 0.0, 0.0, 0.0, 1.0]]
print("absorbentes:", [i for i, f in enumerate(P) if f[i] == 1.0 and sum(f) == 1.0])
Salen 0 y 4: rivales en los extremos. Los interiores 1–3 son transitorios.
Simular hasta la captura
El bucle frena en absorbente y reporta cuál capturó:
import random
P = [[1.0, 0.0, 0.0, 0.0, 0.0],
[0.5, 0.0, 0.5, 0.0, 0.0],
[0.0, 0.5, 0.0, 0.5, 0.0],
[0.0, 0.0, 0.5, 0.0, 0.5],
[0.0, 0.0, 0.0, 0.0, 1.0]]
def capturar(x0=2, semilla=7):
random.seed(semilla)
x = x0
while x not in (0, 4):
u, ac = random.random(), 0.0
for j, p in enumerate(P[x]):
ac += p
if u < ac:
x = j
break
return x
print([capturar(semilla=s) for s in range(10)])
06 · Exploración
Laboratorio: dos trampas rivales
Ruina 0–4 pareja desde inicio i elegible. La curva verde es P(ya en 4) y la roja P(ya en 0) hasta N; la gris, aún jugando. Movete el inicio: cerca del 4, gana el 4; cerca del 0, el 0.
Captura rival por inicio
0 pierde · 4 gana · P(gana|i) = i/4
Desde 2, gana el 50 % (teoría i/4).
200 réplicas por inicio. Con N grande, la gris se vacía y verde + roja suman 100 % en proporción i/4.
Preguntas para explorar
- Desde 1, ¿gana cerca de 25 %? ¿Y desde 3 cerca de 75 %?
- En N = 5 desde 2, ¿ya se repartió o aún juegan muchas?
- ¿La suma verde + roja + gris da 100 % siempre? ¿Por qué?
Ver respuestas sugeridas
- Sí: i/4 con moneda pareja. La cercanía manda lineal.
- Aún juegan ~30 %: la captura tarda. N = 80 casi liquida.
- Sí: son tres destinos excluyentes (gana, pierde, sigue).
07 · Comprensión
Confusiones frecuentes
«pᵢᵢ = 0,99 ya absorbe»
No: se escapa 1 % por visita y con visitas infinitas se escapa seguro. Absorbente es 1,0 exacto.
«Absorbente = recurrente cualquiera»
Es el caso extremo (solo). Los ciclos recurrentes no atrapan: siguen moviéndose.
«Con un absorbente no hay nada que estimar»
Sí: el tiempo hasta la captura y (con rivales) el reparto uᵢ por inicio.
«La captura es rápida»
Puede tardar cientos de pasos lejos de la trampa. Absorción segura ≠ pronta.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: detectar trampas
Detectá absorbentes en esta P 4×4 con dos rivales.
P = [[1.0, 0, 0, 0],
[0.2, 0.5, 0.3, 0],
[0, 0.4, 0.4, 0.2],
[0, 0, 0, 1.0]]
print([i for i, f in enumerate(P) if f[i] == 1.0 and sum(f) == 1.0])
Ver solución razonada
[0, 3]: rivales en extremos. 1 y 2 son transitorios que se reparten.
Ejercicio 2: reparto i/4
Sin ejecutar primero: desde 3 con moneda pareja, ¿P(gana)? Comprobalo con 3000 réplicas.
import random
def capturar(x0):
x = x0
while x not in (0, 4):
x += 1 if random.random() < 0.5 else -1
return x
random.seed(4)
print(sum(capturar(3) == 4 for _ in range(3000)) / 3000)
Ver solución
≈ 0,75 = 3/4. La teoría i/4 se verifica.
Ejercicio 3: tiempo hasta la trampa
Medí pasos medios hasta absorber desde 2. ¿Ronda 4? (Teoría de ruina: i·(4−i) = 4.)
Ver una posible respuesta
import random
def tiempo(x0=2):
x, n = x0, 0
while x not in (0, 4):
x += 1 if random.random() < 0.5 else -1
n += 1
return n
random.seed(6)
print(sum(tiempo() for _ in range(3000)) / 3000)
Sí: ≈ 4 pasos. Lejos de la trampa tarda más (máximo en el centro).
09 · Síntesis
Ideas para recordar
- Absorbente: pᵢᵢ = 1 (fila unitaria, solo su lazo).
- Es recurrente solo; lo demás hacia él es transitorio.
- Con rivales, el inicio reparte la captura (uᵢ).
- En Python: detectar filas + frenar al absorber.
- Medir reparto y tiempo, no solo destino.
En el próximo tema generalizaremos: cadenas absorbentes con varios transitorios.