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.
| Concepto | Fin al empezar | Ocupa recurso | Implementación |
|---|---|---|---|
| Actividad | Conocido: inicio + S | Sí | Agendar fin en el FEL |
| Demora condicionada | Desconocido: “cuando se libere” | No | Lista + reintento tras cada fin |
| Demora incondicionada | Sorteado: inicio + D | No | Agendar fin sin tomar recurso |
03 · Mecánica
Cómo vive una demora condicionada
- 1Entrar con hora.
La llegada sin lugar hace
cola.append({id, llegada: t}). La hora es el pasaporte para medir después. - 2Reintentar 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. - 3Medir al salir.
Acumular
espera_total += Wq,máxy 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
| Sistema | Demora condicionada | Termina cuando… |
|---|---|---|
| Banco | Fila antes de caja | Se libera una caja |
| Web | Buffer de requests | Un worker queda libre |
| Impresora | Spool | Termina el trabajo anterior |
| Semáforo | Autos en rojo | Cambia 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.
Demoras a la vista
Wq = inicio − llegada · nadie la agenda
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
- Con c=1, A=2, S=3, ¿cuánto vale la media? ¿Quién espera más?
- Subí a c=2: ¿cuántos quedan con espera cero? ¿Qué le pasa a la máxima?
- Con A=4, S=2 y c=1, ¿hay demoras? ¿Qué significa Wq=0 para todos?
Ver respuestas sugeridas
- 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.
- Casi todos en cero y la máxima se desploma: dos cajas absorben el ritmo. La demora es elástica a la capacidad.
- 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 − llegadaal 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.