Simulación de Eventos Discretos · Tema 01

Sistemas dinámicos discretos

Qué significa que un sistema solo cambie en instantes de eventos, cómo se ve su trayectoria escalonada y cómo representarlo en Python antes de simularlo por eventos.

01 · Punto de partida

Entre evento y evento, nada cambia

Pensá en la fila de un banco a las 10 de la mañana: hay 4 personas esperando. Si nadie llega y nadie termina de ser atendido durante los próximos 2 minutos, ¿cuántas personas hay? Exactamente 4. El número no “fluye”: salta de 4 a 5 cuando llega alguien, y de 5 a 4 cuando alguien termina.

Esa es la idea central de todo el curso: hay sistemas donde el estado se queda congelado entre eventos y solo cambia en instantes contables. Simularlos no exige integrar segundo a segundo: alcanza con saltar de evento en evento.

  • ¿En qué instantes puede cambiar el sistema y en cuáles es imposible que cambie?
  • ¿Qué variable resume la situación (el estado) y qué hechos la modifican (los eventos)?
  • ¿La trayectoria es una curva suave o una escalera con saltos?
  • ¿Qué nos ahorramos si solo calculamos en los instantes de salto?

02 · Definición

Dinámico, discreto y sistema: las tres palabras

Cada palabra aporta una condición. Si falta una, ya hablamos de otro tipo de modelo:

◈

Sistema

Componentes + relaciones + frontera. Ejemplo: clientes, fila y cajero en una sucursal de 9 a 13 h.

◔

Dinámico

Cambia en el tiempo. Hay una historia s(t): no alcanza una foto, necesitamos la película.

◧

Discreto

Cambia por saltos en instantes contables. Entre tk y tk+1, s(t) es constante.

Formalmente: existe una secuencia de instantes t₀ < t₁ < t₂ < … tal que el estado s(t) no cambia dentro de cada intervalo, y en cada tk ocurre un evento ek que lo transforma: sk+1 = f(sk, ek). Esa función f es la regla de transición que programaremos.

Cuatro familias de sistemas según cómo cambia el estado.
FamiliaCómo cambiaEjemploSe simula con
EstáticoNo cambia en el horizonte estudiadoCosto de un presupuesto hoyUna fórmula
Dinámico continuoCambia a cada instante (curva suave)Nivel de un tanque con canilla abiertaEcuaciones diferenciales / pasos finos
Dinámico discretoSolo cambia en eventos (escalera)Personas en una fila, stock por lotesCalendario de eventos (este curso)
HíbridoMezcla saltos y flujo continuoHeladera con termostato que corta y arrancaEventos + integración entre eventos

03 · El corazón visual

La trayectoria escalonada

Dibujemos el número de personas en el banco N(t) durante 6 minutos. Empieza en 2. En t=1 llega una (→3), en t=2 no pasa nada (sigue 3), en t=3 termina una atención (→2), en t=4 llegan dos juntas (→4):

Estado sk→Ocurre evento e→Nuevo estado sk+1

Entre eventos la línea es horizontal (nada cambia); en el evento hay un salto vertical (cambio instantáneo). Esa escalera es la firma visual de lo discreto. Si ves una curva inclinada suave, estás ante un continuo; si ves mesetas y saltos, ante un discreto.

Estado s(t)
Lo mínimo que hay que saber para continuar la historia: cuántos hay en cola, si el servidor está ocupado, cuánto stock queda. (Tema 4)
Evento e
Hecho instantáneo que puede cambiar el estado: llegada, fin de servicio, falla, reposición. No dura: ocurre. (Tema 3)
Reloj t
Tiempo virtual de la simulación. En sistemas discretos salta al próximo evento, no avanza segundo a segundo. (Temas 11–12)
Transición f
Regla “si pasa e estando en s, voy a s′”. Es el if central de tu simulador. (Temas 16–18)

Cambio continuo

Fluye siempre

El tanque con canilla abierta sube un poquito en cada décima de segundo. Para simularlo hay que cortar el tiempo en rodajas finas y acumular.

Cambio discreto

Salta a veces

La fila solo cambia cuando alguien llega o se va. Entre esos instantes el simulador puede “dormir” y despertar en el próximo evento: es exacto y rapidísimo.

04 · Ejemplos

Cinco discretos que un programador reconoce

El mismo patrón estado + eventos aparece en dominios muy distintos. Si sabés detectar el estado y los eventos, ya sabés qué simular:

Estado y eventos típicos de sistemas dinámicos discretos.
SistemaEstado s(t)Eventos que lo cambian
Fila de bancoN en sistema, cajero libre/ocupadoLlegada, fin de atención
Servidor webRequests en cola, workers ocupadosArribo HTTP, fin de procesamiento, timeout
Inventario por lotesStock actualVenta, reposición, vencimiento
Semáforo + cruceAutos esperando, luz actualLlegada de auto, cambio de luz, cruce
Caja de supermercadoLongitud de cada filaLlegada, cambio de fila, fin de cobro
  1. 1
    Fila de banco.

    Estado: 4 en sistema. Evento llegada → 5. Evento fin de servicio → 4. Entre eventos, 4 es 4.

  2. 2
    Servidor web.

    Estado: 12 requests encolados, 3 workers ocupados. Evento arribo suma uno; evento fin libera un worker.

  3. 3
    Inventario.

    Estado: 20 unidades. No baja de a gotas: salta a 19 con cada venta y a 50 con cada reposición.

  4. 4
    Semáforo.

    Estado: luz en verde + 6 autos. Evento cambio a rojo congela la salida; evento llegada suma cola.

  5. 5
    Soporte técnico.

    Estado: tickets abiertos por prioridad. Evento nuevo ticket, resolución, escalamiento.

05 · Representación en Python

Un discreto es un estado más una lista de saltos

En Python, un sistema dinámico discreto se representa con dos cosas: una variable de estado y una regla de transición que solo se aplica cuando ocurre un evento. Todavía no hay calendario automático: enumeramos los eventos a mano para entender la mecánica.

Python en tu navegador. Los bloques de esta página se ejecutan localmente con Pyodide, sin instalar nada. La primera ejecución tarda unos segundos; las siguientes son inmediatas. Podés editar el código y volver a ejecutarlo.

# Estado: personas en el sistema. Eventos: +1 llegada, -1 salida.
estado = 2
eventos = ["llegada", "nada", "salida", "llegada", "llegada"]
historia = [estado]

for e in eventos:
    if e == "llegada":
        estado = estado + 1
    elif e == "salida":
        estado = max(0, estado - 1)
    # si e == "nada", el estado no cambia: esa es la discretitud
    historia.append(estado)

print(historia)  # [2, 3, 3, 2, 3, 4]

Consejo: cambiá un "nada" por "llegada" y observá que solo ese instante genera un salto; el resto de la historia queda igual.

Con tiempo explícito: la escalera

El paso siguiente es anotar cuándo ocurre cada evento. Cada evento es una tupla (tiempo, tipo) y la historia guarda (tiempo, estado). Entre tiempos listados, el estado se supone constante:

estado = 2
eventos = [(1, "llegada"), (2, "nada"), (3, "salida"), (4, "llegada")]
historia = [(0, estado)]

for t, e in eventos:
    if e == "llegada":
        estado = estado + 1
    elif e == "salida":
        estado = max(0, estado - 1)
    historia.append((t, estado))

print(historia)
# [(0, 2), (1, 3), (2, 3), (3, 2), (4, 3)]
# Leélo así: de t=1 a t=2 vale 3, de t=2 a t=3 sigue valiendo 3.

06 · Exploración

Laboratorio: la escalera discreta

Este sistema solo puede cambiar en instantes enteros t = 0…12. En cada instante puede haber una llegada (cada A pasos), una salida (cada S pasos, si hay alguien) o nada. Movete los controles y comprobá que la curva nunca se inclina: o es horizontal, o salta.

EXPERIMENTO 01

Estado N(t): mesetas y saltos

N(t+1) = N(t) + llegada − salida

Los resultados numéricos aparecen debajo.
Estado inicial2
Eventos que cambiaron el estado0
Estado final N(12)0
Máximo alcanzado0

Mueve los controles para generar una historia.

La línea lima avanza en horizontal (nada cambia) y salta en vertical (evento). Los puntos verdes son llegadas, los naranjas son salidas efectivas. Si llegada y salida coinciden, el estado no cambia.

Preguntas para explorar

  1. Igualá llegada y servicio (cada 2 pasos). ¿La escalera sube, baja o queda acotada? ¿Por qué no es idéntica a cero?
  2. Poné llegadas cada 1 y servicio cada 4 con N(0)=0. ¿Cuánto vale el máximo en 12 pasos? ¿Hay alguna diagonal inclinada?
  3. Poné servicio más rápido que llegadas (ej. llega cada 4, sirve cada 1). ¿Qué le pasa a la cola? ¿Puede ser negativa?
Ver respuestas sugeridas
  1. Queda acotada oscilando: en los instantes múltiplos de 2 hay llegada y salida a la vez y se compensan (salvo cuando N=0, donde la salida se pierde). La escalera nunca se inclina.
  2. Llegan 12 y salen 3 → N(12)=9, máximo 9. No hay diagonales: cada tramo es horizontal y cada cambio es un salto de ±1.
  3. La cola se vacía y se queda en 0: la regla max(0, …) impide negativos. Las salidas con sistema vacío son eventos que no cambian el estado.

07 · Comprensión

Confusiones frecuentes

«Discreto significa pasos iguales de tiempo»

No. Discreto significa cambios en instantes contables, que pueden ser irregulares (t=1.2, t=1.7, t=5.0). Los pasos iguales son solo una forma cómoda de empezar; la simulación por eventos usa tiempos arbitrarios.

«Entre eventos hay que seguir calculando»

No hace falta: por definición el estado no cambia. Calcular en esos huecos es desperdiciar CPU. El simulador “salta” al próximo evento y retoma allí.

«Si el programa usa floats, el sistema es continuo»

El tipo de dato no define la familia. Una fila con tiempos de llegada 1.37 y 2.91 sigue siendo discreta porque el estado solo salta en esos instantes.

«Discreto es una versión груба (burda, grosera, aproximada) de lo continuo»

A veces sí se discretiza un continuo como aproximación, pero aquí lo discreto es exacto: la fila realmente tiene 4 o 5 personas, nunca 4.37.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: leer una escalera

Ejecutá esta historia con tiempos y decí en qué intervalos el estado vale 3. Después cambiá un evento y observá el efecto local.

historia = [(0, 2), (1, 3), (2, 3), (3, 2), (4, 3)]
for (t0, s0), (t1, s1) in zip(historia[:-1], historia[1:]):
    print(f"de t={t0} a t={t1}: vale {s0}")
Ver solución razonada

Vale 3 de t=1 a t=2 y de t=3 a t=4 (en t=2 sigue valiendo 3 porque el evento fue "nada"). Cada línea horizontal es un intervalo donde el simulador podría no hacer nada.

Ejercicio 2: contar solo lo que cambia

Sin ejecutar primero: con estado inicial 1 y eventos ["llegada", "salida", "salida", "salida"], ¿cuál es la historia? ¿Cuántos eventos cambian realmente el estado?

estado = 1
historia = [estado]
for e in ["llegada", "salida", "salida", "salida"]:
    if e == "llegada":
        estado += 1
    else:
        estado = max(0, estado - 1)
    historia.append(estado)
print(historia)
Ver solución

Historia [1, 2, 1, 0, 0]. Los tres primeros eventos cambian el estado; la última salida con sistema vacío ocurre pero no cambia nada (de 0 a 0). Distinguir “ocurrir” de “cambiar” es clave para las estadísticas del Tema 20.

Ejercicio 3: detectar el primer vaciado

Escribí una función que, dada una lista de eventos con tiempo, devuelva el primer instante en que el sistema queda en 0 (o None si nunca se vacía).

Ver una posible respuesta
def primer_vaciado(estado_inicial, eventos):
    estado = estado_inicial
    for t, e in eventos:
        if e == "llegada":
            estado += 1
        elif e == "salida":
            estado = max(0, estado - 1)
        if estado == 0:
            return t
    return None

evs = [(1, "llegada"), (2, "salida"), (3, "salida"), (4, "salida")]
print(primer_vaciado(1, evs))  # 3

Con estado 1: en t=1 sube a 2, en t=2 baja a 1, en t=3 baja a 0 → responde 3. El evento de t=4 ya encuentra el sistema vacío.

09 · Síntesis

Ideas para recordar

  • Dinámico = cambia en el tiempo; discreto = cambia por saltos en instantes contables.
  • El estado s(t) es constante entre eventos; la historia es una escalera de mesetas y saltos.
  • Todo discreto se describe con estado + eventos + regla de transición s′ = f(s, e).
  • En Python: variable de estado, lista de (tiempo, tipo) y un bucle que solo calcula en eventos.
  • Entre eventos el simulador puede saltar: esa es la eficiencia de la simulación por eventos.

En el próximo tema veremos la simulación orientada a eventos: cómo automatizar esos saltos con reloj, calendario y lista de eventos futuros.