01 · Punto de partida
La prueba de la pausa
Imaginá que simulás el banco y a las 10:07 tenés que apagar la computadora. Anotás algo en un papel para seguir mañana exactamente donde quedaste. ¿Qué anotás?
Si anotás “hay 4 personas”, ¿alcanza? Mañana no sabrás si el cajero está atendiendo a una (y termina a las 10:09) o si está libre. Si anotás “hay 4, cajero ocupado, termina 10:09, próxima llegada 10:11”, sí podés continuar: cada evento futuro tiene todo lo que necesita.
Ese papel es el estado: lo mínimo que, junto al reloj y al FEL, permite retomar la historia sin adivinar.
- Si pauso ahora, ¿qué necesito para seguir sin preguntarle a nadie?
- ¿Qué dato, si lo borro, me deja sin saber qué hacer ante el próximo evento?
- ¿Qué dato puedo recalcular y por lo tanto no necesito guardar?
- ¿Mi estado cabe en 3 variables o necesito 30?
02 · Definición
Mínimo y suficiente, las dos condiciones
Un conjunto de variables es estado si pasa dos tests:
Suficiente
Con ese dato + reloj + FEL puedo procesar cualquier evento futuro sin información extra. Si dudo ante una salida (“¿a quién atiendo?”), falta algo.
Mínimo
Nada sobra: cada variable que puedo derivar de las otras se va. en_cola sobra si guardo N y ocupado, porque cola = N − ocupado.
Constante a trozos
En sistemas discretos el estado solo cambia en eventos. Entre eventos es una meseta: por eso pausar y reanudar es exacto.
Ejemplo mínimo del banco con 1 caja: s = (N, ocupado) donde N = personas en sistema y ocupado = 0/1. Con eso: llegada → N+1 y si estaba libre se ocupa; salida → N−1 y si queda N=0 se libera. Nada más hace falta para decidir.
| Sistema | Estado mínimo s | Derivado (no guardar) | Por qué alcanza |
|---|---|---|---|
| Banco, 1 caja | N, ocupado (0/1) | En cola = N − ocupado | Decide llegadas y salidas |
| Servidor, c workers | En cola, ocupados (0…c) | Libres = c − ocupados | Asigna arribos al worker libre |
| Inventario | Stock, pedido en curso (sí/no) | Faltantes acumulados (estadística) | Decide vender, pedir, recibir |
| Taller 2 máquinas | Cola A, estado A, cola B, estado B | Total en sistema (suma) | Cada máquina decide por separado |
03 · Cómo elegirlo
El test de las tres preguntas
Ante cada variable candidata, preguntate:
- 1¿La necesito para procesar el próximo evento?
“Servidor ocupado” sí: sin eso no sé si una llegada espera o se atiende. “Color de las sillas” no.
- 2¿La puedo derivar de otras?
Si guardo N y ocupado, la cola sale sola. Guardarla duplica y arriesga inconsistencia (N=5 pero cola=7).
- 3¿Cambia solo en eventos?
Si cambia sola con el tiempo (ej. “temperatura que se enfría”), o no es discreto puro o falta un evento que lo actualice. En discretos puros, todo cambio tiene su evento.
- Variable de estado
- Parte del mínimo suficiente: N, ocupado, stock. Vive en
sy la modifican las rutinas. - Variable complementaria
- Se deriva del estado: en cola, libres, utilización instantánea. Se calcula, no se guarda.
- Parámetro
- No cambia en la corrida: nº de cajas, tasa de llegada, capacidad. Configura, no es estado.
- Estadística acumulada
- Espera total, máximos, atendidos. Crece monótonamente para medir, no para decidir. (Tema 20)
Estado sano
Pequeño y consistente
2–4 variables, sin redundancia, siempre válidas (N ≥ 0, ocupados ≤ c). Pausar es copiar 3 números.
Estado enfermo
Grande y contradictorio
Guarda N, cola y total por separado y un día dicen cosas distintas. Cada evento debe actualizar 5 lugares y olvida uno.
04 · Ejemplos
Cuatro estados que ya sabés leer
- 1Banco 1 caja: s=(2, ocupado).
Llegada con libre → (3, ocupado). Salida con N=1 → (0, libre). Cola = N − ocupado siempre.
- 2Servidor 3 workers: s=(cola=4, ocupados=3).
Arribo → cola=5 (nadie libre). Fin → ocupados sigue 3 pero cola=4 (el siguiente toma el worker).
- 3Inventario: s=(stock=6, pedido=no).
Venta de 2 → (4, no). Si cruza el punto de pedido → (4, sí) y se agenda arribo de reposición.
- 4Urgencias con prioridad: s=(cola_alta=1, cola_baja=3, médicos_ocupados=2).
Sin separar por prioridad el estado no sabe a quién atender: la granularidad la pide la decisión.
05 · Representación en Python
El estado es un dict; la transición es pura
Guardá el estado en un diccionario (o dataclass) y escribí transiciones como funciones que reciben (estado, evento) y devuelven el nuevo estado. Así podés hacer snapshot con copy() y probar “¿qué pasaría si…?” sin romper nada.
Python en tu navegador. El primer bloque define el estado mínimo y sus transiciones; el segundo hace snapshot, pausa y reanuda. Editá N y re-ejecutá.
estado = {"N": 2, "ocupado": 1} # mínimo suficiente (1 caja)
def al_llegar(s):
s = dict(s)
s["N"] += 1
s["ocupado"] = 1
return s
def al_salir(s):
s = dict(s)
s["N"] = max(0, s["N"] - 1)
if s["N"] == 0:
s["ocupado"] = 0
return s
print(al_llegar(estado)) # {'N': 3, 'ocupado': 1}
print(al_salir({"N": 1, "ocupado": 1})) # {'N': 0, 'ocupado': 0}
# Snapshot: pausar en t=6 y reanudar mañana es copiar el dict + reloj
reloj = 6
snapshot = (reloj, dict({"N": 3, "ocupado": 1}))
print("pausa:", snapshot)
# Mañana: restauro y sigo
reloj2, estado2 = snapshot[0], dict(snapshot[1])
estado2 = {"N": estado2["N"] + 1, "ocupado": 1} # llega uno en t=7
print("reanudo en", reloj2, "-> tras llegada:", estado2)
print("en cola:", estado2["N"] - estado2["ocupado"], "(derivado, no guardado)")
06 · Exploración
Laboratorio: pausar y reanudar sin perder nada
Elegí llegadas (A), servicio (S) y N(0). La curva muestra N(t) y la barra inferior si el servidor está ocupado. Movete el control pausa en Tp: la ficha muestra el snapshot mínimo para reanudar (N, ocupado, reloj, próximos del FEL). Comprobá que con esos 5 datos alcanza.
El papel para continuar mañana
snapshot(Tp) = (reloj, N, ocupado, próx. llegada, próx. salida)
Mueve la pausa para inspeccionar el estado.
Escalera lima: N(t). Banda inferior verde: servidor ocupado; gris: libre. Línea blanca vertical: instante de pausa Tp. Con N, ocupado, reloj y los dos próximos alcanza para seguir.
Preguntas para explorar
- Con A=2, S=3, N(0)=2 y Tp=6, ¿cuánto valen N, ocupado y en cola? ¿Necesitás algo más para seguir?
- Buscá un Tp donde N=0. ¿Qué vale ocupado? ¿Y la próxima salida?
- Si agregaras “en cola” al estado guardado, ¿qué riesgo aparece? Provocá un ejemplo inconsistente.
Ver respuestas sugeridas
- N=3, ocupado=1, en cola=2 (derivado). Más reloj=6, próxima llegada 8 y próxima salida 9: con esos 5 datos reanudás exacto.
- Ocupado=0 y “próxima salida: —”. Sin nadie en servicio no hay salida futura: el FEL solo trae llegadas. Guardar una salida fantasma rompería la causalidad.
- Podrías guardar N=3 con cola=5 (imposible, pues cola ≤ N). Con una sola fuente (N y ocupado) ese error no existe: la cola se calcula.
07 · Comprensión
Confusiones frecuentes
«El estado es todo lo que sé del sistema»
No: es lo mínimo suficiente. Parámetros (nº de cajas), derivados (en cola) y estadísticas (espera total) no son estado aunque los conozcas.
«El FEL es parte del estado»
El FEL acompaña al estado para reanudar, pero conceptualmente es futuro anunciado, no situación actual. Mezclarlos complica las transiciones.
«Más variables = modelo más fiel»
Más variables = más lugares para olvidar actualizar. La fidelidad la da elegir bien las mínimas, no acumular.
«El estado cambia solo»
En discretos puros, si algo cambió sin evento, tu diseño está incompleto: falta el evento que lo explica o el sistema no es discreto.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: detectar redundancia
Este “estado” guarda de más. ¿Qué sobra y cómo lo derivás?
s = {"N": 4, "ocupado": 1, "en_cola": 3}
print("derivado:", s["N"] - s["ocupado"], "| guardado:", s["en_cola"]) # ¿coinciden?
Ver solución razonada
Sobra en_cola: vale N − ocupado = 3. Guardarlo invita a que un día valga 5 con N=4. Estado sano: {"N": 4, "ocupado": 1} + función cola(s).
Ejercicio 2: transición completa
Sin ejecutar primero: con {"N": 0, "ocupado": 0}, ¿qué dejan una llegada y luego una salida?
def llegar(s):
return {"N": s["N"] + 1, "ocupado": 1}
def salir(s):
n = max(0, s["N"] - 1)
return {"N": n, "ocupado": 0 if n == 0 else 1}
s0 = {"N": 0, "ocupado": 0}
print(salir(llegar(s0)))
Ver solución
{"N": 0, "ocupado": 0}: la llegada ocupa (N=1) y la salida vacía y libera. El sistema vuelve al reposo exacto.
Ejercicio 3: snapshot que sí reanuda
Guardá reloj + estado en una tupla, modificá una copia y mostrá que el original no se contaminó.
Ver una posible respuesta
reloj, estado = 6, {"N": 3, "ocupado": 1}
foto = (reloj, dict(estado)) # snapshot
copia = dict(foto[1])
copia["N"] += 1 # experimento "¿y si llega uno?"
print("foto intacta:", foto)
print("copia:", copia)
La foto sigue (6, N=3) y la copia prueba el escenario. Así se implementan réplicas y “qué pasaría si” sin corromper la corrida.
09 · Síntesis
Ideas para recordar
- Estado = mínimo y suficiente para continuar solo con reloj + FEL (test de la pausa).
- Banco 1 caja:
(N, ocupado); lo demás (en cola, libres) se deriva. - Parámetros configuran, estadísticas miden: ninguno es estado.
- En Python: dict pequeño + transiciones puras +
dict(s)para snapshot. - Todo cambio de estado tiene su evento; si cambia solo, falta modelar.
En el próximo tema conoceremos las entidades: quiénes circulan por el sistema y qué las distingue.