Simulación de Eventos Discretos · Tema 10

Demoras

Esperas con duración desconocida —la fila antes de la caja— que no se programan sino que se sufren y se miden.

01 · Punto de partida

La espera no avisa cuándo termina

C7 llegó a las 8 y empezó a las 10: esperó 2. A las 8 nadie podía decirle “esperarás 2”: dependía de los que estaban antes y de cuánto tardaran. La atención, en cambio, al empezar a las 10 sí sabía que terminaría a las 13.

Esa es la frontera de este tema: la actividad nace con su fin agendado; la demora nace sin hora de salida. La demora no se programa: se entra en una lista y se sale cuando el sistema lo permite. Solo al salir se sabe cuánto duró.

  • Al empezar, ¿ya sé cuándo termina?
  • ¿Ocupa un recurso o solo un lugar en la lista?
  • ¿Su fin lo agenda un reloj o lo dispara una condición?
  • ¿Cómo la mido si no la programé?

02 · Definición

Condicionadas e incondicionadas

⏳

Condicionada

Espera hasta que algo pase: “hasta que se libere una caja”. Típica de colas. Nadie agenda su fin.

◷

Incondicionada

Retraso con duración sorteada al entrar: “viaje de 2 días”, “secado de 1 hora”. Sí agenda su fin, pero sin recurso.

∑

Medible

Ambas se miden al salir: espera, máxima, promedio, por clase. La demora es la materia prima de Wq.

Actividad frente a los dos tipos de demora.
ConceptoFin al empezarOcupa recursoImplementación
ActividadConocido: inicio + SSíAgendar fin en el FEL
Demora condicionadaDesconocido: “cuando se libere”NoLista + reintento tras cada fin
Demora incondicionadaSorteado: inicio + DNoAgendar fin sin tomar recurso

03 · Mecánica

Cómo vive una demora condicionada

entra a la lista con su hora→cada fin reintenta→sale y se mide Wq
  1. 1
    Entrar con hora.

    La llegada sin lugar hace cola.append({id, llegada: t}). La hora es el pasaporte para medir después.

  2. 2
    Reintentar tras cada fin.

    Cada salida libera un lugar e intenta if cola: siguiente = popleft(); Wq = ahora − llegada. Sin este reintento la cola duerme para siempre.

  3. 3
    Medir al salir.

    Acumular espera_total += Wq, máx y conteo por clase. La demora solo existe como número al salir.

Lista de condicionadas
La cola misma: guarda quién espera y desde cuándo. Una demora sin lista pierde su hora de entrada.
Evento que la termina
Siempre es otro evento (un fin que libera). La demora no tiene evento propio: “cabalga” sobre los fines ajenos.
Abandono
La demora puede terminar por cansancio en vez de por servicio: el que se va tras esperar T. Requiere paciencia como atributo.
Wq vs. W
Wq = demora en cola; W = Wq + S = vida en sistema. El cliente sufre W; el dimensionador ataca Wq.

Actividad

Se programa

“Terminás a las 13”: el FEL guarda el futuro y el recurso se reserva. Exacta y previsible.

Demora condicionada

Se sufre y se mide

“Salís cuando haya lugar”: nadie lo agenda, se espera en lista y al salir se anota cuánto fue.

04 · Ejemplos

Dónde duele la espera

Demoras típicas y qué condición las termina.
SistemaDemora condicionadaTermina cuando…
BancoFila antes de cajaSe libera una caja
WebBuffer de requestsUn worker queda libre
ImpresoraSpoolTermina el trabajo anterior
SemáforoAutos en rojoCambia a verde (condición externa)

05 · Representación en Python

Lista + reintento + medición

La demora son tres líneas repartidas: entrar con hora, reintentar al liberar, medir al salir. Nada va al FEL con hora de “fin de espera”.

Python en tu navegador. El primer bloque sufre la demora; el segundo la mide por clase. Cambiá llegadas y mirá Wq.

from collections import deque
cola = deque([{"id": "C5", "llegada": 4.0}, {"id": "C6", "llegada": 6.0}])
# A las 10 se libera la caja: reintento (no había fin agendado para la espera)
reloj = 10.0
e = cola.popleft()
wq = reloj - e["llegada"]  # recién ahora se sabe: 6.0
print(e["id"], "esperó", wq)
# Demora incondicionada (retraso): sí agenda fin, sin recurso
import heapq
fel = []
heapq.heappush(fel, (8.0 + 2.0, "fin_retraso", {"id": "P3"}))  # viaje de 2
print("fin programado:", fel[0][0], "| ocupa recurso: no")

06 · Exploración

Laboratorio: quién espera y cuánto

Llega uno cada A, atención S, c cajas. Cada barra es una entidad en orden de atención: el tramo naranja es su demora (Wq) y la línea punteada marca la media. Subí c de 1 a 2 y mirá cómo las barras se aplastan: la capacidad compra espera.

EXPERIMENTO 10

Demoras a la vista

Wq = inicio − llegada · nadie la agenda

Los resultados numéricos aparecen debajo.
Espera media Wq0
Espera máxima0
El que más esperó—
Con espera cero0

Mueve c para comprar espera.

Barras naranjas: Wq individual en orden de atención. Punteada blanca: media. Los que entran directo tienen barra cero (no sufrieron demora).

Preguntas para explorar

  1. Con c=1, A=2, S=3, ¿cuánto vale la media? ¿Quién espera más?
  2. Subí a c=2: ¿cuántos quedan con espera cero? ¿Qué le pasa a la máxima?
  3. Con A=4, S=2 y c=1, ¿hay demoras? ¿Qué significa Wq=0 para todos?
Ver respuestas sugeridas
  1. Media de varios pasos con máximo en los últimos (efecto avalancha: cada uno espera lo acumulado). El último es el que más sufre.
  2. Casi todos en cero y la máxima se desploma: dos cajas absorben el ritmo. La demora es elástica a la capacidad.
  3. Cero demoras: cada llegada encuentra caja libre. El sistema está sobredimensionado (o el período es flojo): Wq=0 es espera nula, no error.

07 · Comprensión

Confusiones frecuentes

«La espera se agenda como una actividad»

Agendar “fin de espera a las 10” supone saber lo incognoscible. La espera sale por reintento tras un fin real, no por reloj.

«Wq cero es un bug»

Wq=0 significa “entró directo”: éxito del dimensionamiento, no dato perdido. Hay que contarlo en la media.

«La demora ocupa recurso»

La demora ocupa lugar en la lista, no caja ni worker. Quien ocupa es la actividad posterior. Mezclarlos duplica la ocupación.

«Con promediar alcanza»

La media esconde al último que esperó el triple. Máximo y distribución (quién, cuánto) deciden niveles de servicio.

08 · Práctica guiada

Ejercicios con Python

Ejercicio 1: medir al salir

C6 llegó en 6 y empieza en 13. ¿Cuánto esperó?

llegada, inicio = 6.0, 13.0
print("Wq:", inicio - llegada)  # 7.0: demora medida, no programada
Ver solución razonada

7.0. A las 6 nadie lo sabía; a las 13 queda registrado. Así nace cada dato de espera del simulador.

Ejercicio 2: reintento que despierta

Al liberar con 2 en cola, ¿a quién despierto y con qué Wq si el reloj marca 10?

from collections import deque
cola = deque([{"id": "C5", "llegada": 4.0}, {"id": "C6", "llegada": 6.0}])
reloj = 10.0
e = cola.popleft()  # reintento tras el fin
print(e["id"], "Wq =", reloj - e["llegada"])
Ver solución

C5 con Wq=6.0; C6 sigue esperando (su Wq aún no existe). Cada fin despierta de a uno en FIFO.

Ejercicio 3: media con ceros incluidos

Esperas [0, 0, 2, 5]: ¿media honesta vs. media “solo los que esperaron”?

Ver una posible respuesta
wqs = [0, 0, 2, 5]
print("honesta:", sum(wqs) / len(wqs))  # 1.75
solo = [w for w in wqs if w > 0]
print("solo esperan:", sum(solo) / len(solo))  # 3.5: infla el problema

La honesta incluye ceros (1.75); la otra los esconde (3.5). Para dimensionar se usa la honesta; para consolar al que esperó, la otra.

09 · Síntesis

Ideas para recordar

  • Demora = intervalo con fin desconocido; termina por condición, no por reloj.
  • Condicionada (cola → hasta liberarse) vs. incondicionada (retraso sorteado sin recurso).
  • En Python: lista con hora + reintento tras cada fin + Wq = inicio − llegada al salir.
  • Nunca agendes fines de espera condicionada en el FEL.
  • Wq=0 cuenta: entrar directo es el éxito a promediar, no un dato roto.

En el próximo tema veremos el reloj de simulación: el tiempo virtual que ordena todos estos eventos.