01 · Punto de partida
Entre el “empieza” y el “termina” hay trabajo
La llegada de C7 (t=8) y su salida (t=13) son dos eventos instantáneos. Pero entre ambos pasaron 5 unidades donde ocurrieron dos cosas distintas: esperó 2 (demora, Tema 10) y la atendieron 3 (actividad, este tema).
La diferencia importa: la atención tiene duración conocida al empezar (3 minutos de trámite) y ocupa un recurso (la caja). La espera, en cambio, dura “lo que toque” y no ocupa a nadie. Confundirlas es el origen de simuladores que liberan la caja antes de tiempo.
- ¿Cuánto dura y cuándo se sabe esa duración?
- ¿Qué recurso queda reservado mientras dura?
- ¿Qué dos eventos la abren y la cierran?
- ¿Puede interrumpirse o es ininterrumpible?
02 · Definición
Inicio, duración y fin: el triplete inseparable
Inicio
Evento (a veces condicionado) que la dispara: “C7 empieza en caja 1 a las 10”. Allí se sortea o se fija S.
Duración
Tiempo que ocupa: fijo (3 min de trámite) o aleatorio (exponencial, normal…). Se conoce al iniciar, no antes.
Fin
Evento incondicionado agendado en inicio + S. Libera el recurso y encadena lo siguiente.
Programar una actividad es siempre la misma frase: “al iniciar en t con duración S, agendá el fin en t+S”. Todo lo demás (sorteos, prioridades, fallas) adorna esa frase.
| Concepto | Duración al iniciar | Ocupa recurso | Ejemplo |
|---|---|---|---|
| Actividad | Conocida (fija o sorteada) | Sí (caja, worker) | Atención de 3 min |
| Demora | Desconocida (depende del sistema) | No (se espera) | Espera en fila |
| Evento | Cero (instante) | No (marca el borde) | Inicio / fin de atención |
03 · Variantes
Fijas, aleatorias e interrumpibles
- 1Duración fija.
Trámite estándar, lavado de 5 min, viaje programado. Predecible y fácil de validar a mano.
- 2Duración aleatoria.
Atención que varía por cliente: se sortea al iniciar (exponencial en M/M/1, Tema 31). La actividad sigue siendo actividad: al iniciar ya se sabe cuánto durará esta vez.
- 3Ininterrumpible vs. preemptiva.
Normal: una vez que empieza termina. Preemptiva: un VIP puede pausarla (urgencias, CPU). La pausa genera eventos extra de suspensión y reanudación.
- Actividad con recurso
- La típica: atención, mecanizado, procesamiento. Reserva caja/worker/máquina en [inicio, fin).
- Actividad sin recurso (retraso)
- Viaje, secado, incubación: dura S pero no bloquea capacidad. Se agenda igual, sin tomar recurso.
- Solapamiento
- Con c>1, varias actividades corren en paralelo. El Gantt del laboratorio lo muestra: barras encimadas en el tiempo.
- Ocio
- Horizonte sin actividad (recurso libre y cola vacía). No es espera: nadie lo sufre, pero cuesta utilización.
Actividad
“Sé cuándo termino”
Al empezar se agenda el fin. El sistema puede contar con esa hora para planificar.
Demora
“Termino cuando me atienden”
Nadie agenda su fin; termina cuando el recurso se libera. Se mide, no se programa.
04 · Ejemplos
La misma forma en todos lados
| Sistema | Actividad | Recurso que reserva | Duración |
|---|---|---|---|
| Banco | Atender | Caja | 3 min (fija aquí) |
| Web | Procesar request | Worker | Aleatoria (exponencial) |
| Fábrica | Mecanizar pieza | Máquina A | Según pieza (atributo) |
| Logística | Viajar depósito→cliente | Camión (o nadie, si es retraso) | Distancia / velocidad |
05 · Representación en Python
Agendar el fin al iniciar
La actividad son dos líneas: fijar fin = inicio + S y meterlo al FEL con heappush. Si S es aleatoria, se sortea en el inicio con random.expovariate.
Python en tu navegador. El primer bloque agenda el fin; el segundo sortea S al iniciar. Cambiá S y re-ejecutá.
import heapq
fel = []
inicio, S = 10.0, 3.0
fin = inicio + S # la actividad reserva [10, 13)
heapq.heappush(fel, (fin, "salida", {"caja": 1}))
print("agendado:", fel[0])
print("recurso ocupado en [10, 13): sí")
import random
random.seed(7)
mu = 1 / 3 # servicio medio 3 -> tasa 1/3
for i in range(3):
S = random.expovariate(mu) # se sortea AL INICIAR
inicio = 10.0 + i
print(f"actividad {i}: S={S:.2f} fin={inicio + S:.2f}")
06 · Exploración
Laboratorio: Gantt de actividades
Llega uno cada A, cada atención dura S, con c cajas en paralelo. Cada fila es una entidad: el tramo fino gris es su espera (demora) y la barra gruesa lima su actividad (reserva [inicio, fin)). La línea blanca es Tp: lo de la izquierda ya pasó, lo de la derecha es futuro agendado.
Barras que reservan recursos
fin = inicio + S · gris = espera · lima = actividad
Mueve c para ver solapamiento.
Eje horizontal: tiempo 0–12. Lima gruesa: actividad que reserva caja. Gris fina: espera previa. Con c=2 las limas pueden encimarse; con c=1 nunca.
Preguntas para explorar
- Con c=1, A=2, S=3, ¿las barras lima se enciman alguna vez? ¿Y las grises qué dicen?
- Subí a c=2: ¿qué le pasa a las grises (esperas)? ¿Y al solape de limas?
- En Tp=7, ¿cuántas actividades están en curso y cuántas completadas?
Ver respuestas sugeridas
- Con una caja nunca: es el invariante físico. Las grises crecen porque cada llegada espera a que termine la anterior.
- Las grises se achican o desaparecen y las limas se solapan: dos cajas trabajan en paralelo. Capacidad compra espera.
- Depende de A y S, pero con el ejemplo hay 1 en curso y 2 completadas: el laboratorio las cuenta con la línea Tp.
07 · Comprensión
Confusiones frecuentes
«La espera es una actividad»
La espera es demora: duración desconocida y sin recurso. La actividad dura S conocido y reserva capacidad. Tratar la espera como actividad agenda fines fantasmas.
«La duración se sortea al terminar»
Se sortea al iniciar y se agenda el fin. Sortear al final rompe reproducibilidad y permite “actividades” que cambian de duración a mitad de camino.
«Con c=1 no hay paralelismo, así que da igual»
Con c=1 las actividades no se solapan, pero las esperas sí se acumulan. El Gantt lo muestra: limas en fila, grises creciendo.
«Toda actividad ocupa recurso»
La mayoría sí, pero viajes y secados son retrasos sin recurso: se agendan igual sin tomar nada. No reserves caja para un camión en ruta.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: agendar el fin
Si C7 empieza en 10 con S=3, ¿cuándo termina y qué intervalo reserva?
inicio, S = 10.0, 3.0
fin = inicio + S
print("fin:", fin, "| reserva: [%s, %s)" % (inicio, fin))
Ver solución razonada
Fin 13.0, reserva [10, 13). En 13.0 exacto la caja ya está libre para el siguiente: intervalos semiabiertos evitan doble conteo.
Ejercicio 2: solape imposible con c=1
Dos actividades [10,13) y [12,15) con una caja: ¿se solapan? ¿Qué debería pasar con la segunda?
a = (10.0, 13.0)
b = (12.0, 15.0)
solapan = a[0] < b[1] and b[0] < a[1]
print("¿solapan?", solapan, "-> con c=1 la 2ª debe esperar a 13.0")
Ver solución
Sí se solapan en [12,13), imposible con c=1. La segunda debió iniciar en 13: su espera es 1.0 y su fin real 16.0.
Ejercicio 3: sortear al iniciar
Sorteá 3 duraciones exponenciales de media 3 y agendá sus fines desde inicios 10, 11, 12.
Ver una posible respuesta
import random
random.seed(1)
inicios = [10.0, 11.0, 12.0]
for t in inicios:
S = random.expovariate(1 / 3)
print(f"inicio {t} S={S:.2f} fin={t + S:.2f}")
Cada fin nace del inicio + su S sorteado allí. Cambiá la semilla y verás otras duraciones, pero siempre fijadas al iniciar.
09 · Síntesis
Ideas para recordar
- Actividad = inicio + duración S + fin agendado en inicio+S, reservando recurso.
- S se fija (o sortea) al iniciar y viaja con la entidad; nunca al terminar.
- Con c=1 las actividades no se solapan; con c>1 sí: el Gantt lo prueba.
- En Python:
fin = inicio + S+heappush(fel, (fin,…)). - Actividad (programable) ≠ demora (medible): no agendes fines de esperas.
En el próximo tema veremos las demoras: esperas con duración desconocida que se miden en vez de programarse.