Simulación de Eventos Discretos · Tema 18

Procesamiento de eventos

Qué hace cada rutina al recibir su evento — actualizar estado, medir área y esperas, reintentar la cola y agendar futuro.

01 · Punto de partida

Recibir no es solo cambiar un número

Cuando la rutina principal entrega “llegada en t=4”, la rutina de llegada hace cuatro trabajos en orden: cobra el tiempo pasado (área += N·(t − t_prev)), cambia el estado (N+1), mide si corresponde y agenda futuro (próxima llegada + eventual salida). Si cambia el orden —medir antes de cobrar el área, agendar antes de actualizar— las estadísticas mienten aunque N termine bien.

Procesar es ejecutar esa coreografía sin saltarse pasos. Este tema la escribe para llegada y salida, los dos verbos del 90% de las colas.

  • ¿Qué se cobra del intervalo desde el evento anterior?
  • ¿Cómo cambia N y la ocupación?
  • ¿Qué espera se registra y qué futuro se agenda?
  • ¿Qué condicionado se reintenta tras el cambio?

02 · Definición

La coreografía de cinco pasos

▦

Cobrar área

área += N_prev·(t − t_prev) antes de tocar N: integra personas×tiempo para L media. (Tema 20)

⇄

Actualizar

Llegada: N+1 y (ocupar o encolar). Salida: N−1 y (reintentar o liberar). Invariantes intactos.

✚

Medir y agendar

Registrar Wq al salir de la cola; agendar próxima llegada / próxima salida. El futuro no se olvida.

al_llegar→al_salir→reintentar inicio
Rutinas de 1 caja FIFO, paso a paso.
RutinaHaceAgenda
al_llegar(t)Área; N+1; si libre ocupa e inicia, si no encola con su horaPróxima llegada; salida si ocupó
al_salir(t)Área; N−1; atendidos+1; si hay cola saca al 1º, mide Wq e iniciaSalida del siguiente (o libera)

03 · Detalles que salvan corridas

  1. 1
    El área se cobra antes.

    El intervalo [t_prev, t) perteneció al N viejo. Cobrar después lo asigna al N nuevo y sesga L. Es el error silencioso más común.

  2. 2
    La espera nace al salir de la cola.

    Wq = ahora − llegada_desencolada en la salida, no en la llegada. En la llegada la espera aún no existe.

  3. 3
    Todo fin reintenta.

    Cada salida intenta if cola: iniciar siguiente. Sin reintento la cola duerme aunque haya lugar.

Área N·Δt
Personas×tiempo acumulado: dividido por T da L media. Se cobra en cada evento con el N previo.
t_prev
Reloj del evento anterior. Sin guardarlo no hay área: el intervalo se pierde.
Reintento (inicio condicionado)
Tras cada cambio que libera capacidad, intentar arrancar al siguiente. No va al FEL: es if.
Orden salidas-primero
En empates, procesar la salida antes: libera justo para la llegada simultánea y evita rechazos fantasmas.

Rutina sana

Orden fijo, cinco pasos

Área primero, invariantes al final con assert. Cada evento deja estado, stats y futuro consistentes.

Rutina apurada

Solo N y agenda

Sin área ni Wq: N termina bien pero L y esperas son cero. El informe sale “gratis” y falso.

04 · Ejemplo con números

Dos eventos, todas las cuentas

Estado previo: t_prev=2, N=1. Llega en t=4 con caja ocupada y S=3:

Procesar “llegada en 4” paso a paso.
PasoCuentaResultado
Área1 × (4−2) = 2área = 2 (el intervalo tuvo 1 persona)
EstadoN = 1+1 = 2, a cola con hora 4N=2, cola=[4]
MedidaNada aún (su Wq nacerá al salir)espera_total intacta
AgendaPróxima llegada (6); sin salida (no inició)FEL += llegada 6

05 · Representación en Python

Dos funciones con área y espera

El esqueleto completo de 1 caja: área antes de todo, cola con horas, Wq al desencolar. El t_prev viaja en lista mutable para las closures.

Python en tu navegador. Ejecuta la traza 2→4→5: mirá área y espera nacer en el orden correcto. Cambiá S y re-ejecutá.

N, ocupado, cola = 0, 0, []
area, t_prev = 0.0, [0.0]
espera_total, atendidos = [0.0], [0]

def cobrar(t):
    global area
    area += N * (t - t_prev[0])
    t_prev[0] = t

def al_llegar(t, S, fel_proxima=None):
    cobrar(t)
    global N, ocupado
    N += 1
    if not ocupado:
        ocupado = 1
        print(t, "llega y ocupa; agenda salida en", t + S)
    else:
        cola.append(t)
        print(t, "llega y espera; cola:", cola)

def al_salir(t, S):
    cobrar(t)
    global N, ocupado
    N -= 1
    atendidos[0] += 1
    if cola:
        llegada = cola.pop(0)
        espera_total[0] += t - llegada
        print(t, "sale; entra el de", llegada, "Wq =", round(t - llegada, 1))
    else:
        ocupado = 0
        print(t, "sale y libera")

al_llegar(2.0, 3.0)
al_llegar(4.0, 3.0)
al_salir(5.0, 3.0)
print("área:", area, "| espera_total:", espera_total[0])

06 · Exploración

Laboratorio: cobrar el área vuelta por vuelta

Sistema A/S en 1 caja hasta T=12. Mové paso k: el sombreado lima es el área acumulada N·Δt hasta ese evento (la materia de L media), y la ficha narra qué cobró, cómo cambió N y qué agendó. Comprobá que el área se cobra con el N viejo.

EXPERIMENTO 18

Área, estado y agenda en cada vuelta

área += N_prev·(t − t_prev) antes de actualizar

Los resultados numéricos aparecen debajo.
Paso / total0 / 0
Reloj0
Área hasta aquí0
Espera total0

Mueve k para cobrar.

Sombreado: personas×tiempo acumulado. Blanca: reloj actual. La ficha detalla ΔN, cobro y agenda de la vuelta.

Preguntas para explorar

  1. En la llegada 4 (con N_prev=1 desde t=2), ¿cuánto área cobra? ¿Con qué N?
  2. En la salida 5, ¿qué Wq registra? ¿De quién?
  3. Si cobraras el área después de actualizar, ¿el área de [2,4) usaría N=1 o N=2?
Ver respuestas sugeridas
  1. 1×(4−2)=2 con el N viejo (1). El intervalo perteneció a 1 persona, no a 2.
  2. Wq del que esperaba desde la llegada sin lugar (si lo hay); si la caja estaba libre al llegar, Wq=0 del que sale.
  3. Usaría 2 (nuevo) e inflaría el área: el sesgo se acumula en cada evento y L sale alta.

07 · Comprensión

Confusiones frecuentes

«El área se cobra después, da igual»

No da igual: el intervalo pasado pertenece al N previo. Cobrar después asigna el N nuevo al pasado y sesga L hacia arriba.

«Wq se mide en la llegada»

En la llegada la espera no existe aún. Nace al salir de la cola (en la salida que libera). Medirla antes es adivinar.

«El que llega a la cola agenda su salida»

Solo agenda salida quien inicia servicio. El encolado espera su turno para tener fin; agendarle salida duplica fines.

«Sin reintento la cola se vacía sola»

La cola no se mueve sola: cada fin debe intentar el siguiente. Sin reintento hay lugar libre con gente esperando.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: cobrar antes

Con N=1 en [2,4), ¿área correcta vs. cobrada después (N=2)?

print("correcta:", 1 * (4 - 2))  # 2
print("tardía:", 2 * (4 - 2))  # 4: infla al doble
Ver solución razonada

2 vs. 4: cobrar tarde duplica ese tramo. En corridas largas el sesgo se vuelve L inventada.

Ejercicio 2: Wq del desencolado

Cola [4, 6], salida en 8 que libera: ¿quién sale de la cola y con qué Wq?

cola = [4.0, 6.0]
llegada = cola.pop(0)
print("sale de la cola el de", llegada, "Wq =", 8.0 - llegada)
Ver solución

El de 4.0 con Wq=4.0; el de 6.0 sigue (su Wq nacerá después). FIFO puro.

Ejercicio 3: agenda del que inicia

Solo quien inicia agenda salida. Codificá ambas ramas.

Ver una posible respuesta
ocupado, S, reloj = 0, 3.0, 4.0
if not ocupado:
    ocupado = 1
    print("inicia: agenda salida en", reloj + S)
else:
    print("encola: no agenda nada")

Encolar no agenda; iniciar sí. Así nunca hay fines duplicados ni fantasmas.

09 · Síntesis

Ideas para recordar

  • Orden sagrado: área (con N viejo) → estado → medida → reintento → agenda.
  • Llegada agenda próxima llegada siempre; salida solo si inicia.
  • Wq nace al desencolar en la salida: ahora − llegada.
  • Cada fin reintenta la cola: sin reintento hay ocio con espera.
  • Área acumulada / T = L media: la base del Tema 20.

En el próximo tema cerraremos el ciclo con la finalización de una simulación: cuándo parar y cómo cerrar.