01 · Punto de partida
Simular es decidir bajo incertidumbre
Un modelo determinístico da siempre la misma respuesta con los mismos datos: si la demanda es 10 por día, en 12 días vende 120. Pero la realidad no es así: un día vende 7, otro 13, otro 9. Un modelo que ignora esa variación promete una precisión falsa.
La incertidumbre es la diferencia entre lo que el modelo supone y lo que puede pasar. En simulación la tratamos de frente: la modelamos con probabilidad, la alimentamos con datos y la medimos con réplicas. Este curso es aplicado: usamos la base de Probabilidad y Estadística de Matemática para Programadores para tomar mejores decisiones con código.
- ¿Qué parte del resultado es predecible y qué parte es azar?
- ¿Cuánto puede variar la respuesta si repetimos el experimento?
- ¿Qué decisión sigue siendo buena aunque el azar juegue en contra?
- ¿Cuántas réplicas necesito para confiar en el promedio?
02 · Definición
¿Qué es incertidumbre en un modelo?
Es la falta de certeza sobre el valor exacto que tomará una variable del modelo. No es un error de programación: es una propiedad del fenómeno. La clasificamos por su origen:
Entradas inciertas
Llegadas de clientes, demanda diaria, tiempos entre fallas. Sabemos el promedio, no el valor de mañana.
Parámetros inciertos
Tasas estimadas con pocos datos: el tiempo medio de atención es 4,2 min ± 0,8. El parámetro también varía.
Modelo incierto
Supuestos simplificadores: suponemos llegadas uniformes cuando en realidad hay picos. El modelo mismo es aproximado.
La probabilidad pone número a esa incertidumbre y la estadística la estima desde datos. En los próximos temas veremos eventos, variables aleatorias y distribuciones; aquí nos basta la intuición: si repetís, varía.
| Problema | Versión determinística | Versión con incertidumbre |
|---|---|---|
| Inventario | Demanda 10/día, vende 120 en 12 días | Demanda 6 a 14/día, vende entre 90 y 150 |
| Cola de banco | Llega 1 cada 5 min exactos | Llega cada 2 a 9 min, la espera varía |
| Servidor | 100 pedidos/hora fijos | 60 a 160/hora, a veces se satura |
| Proyecto | Cada tarea dura 3 días | Cada tarea dura 1 a 6 días, el fin se mueve |
03 · Dónde aparece
Lugares típicos del azar en una simulación
Cuando programes un simulador, el azar entra casi siempre por las mismas puertas. Reconocerlas te dice qué distribución elegir más adelante (temas 17 a 24):
Lo más frecuente
Entradas y tiempos
Cuánto llega, cuándo llega y cuánto tarda: demanda, llegadas, servicios, traslados. Es la fuente número uno de variabilidad.
Lo más costoso
Fallas y decisiones
Roturas, errores, clics, compras, abandonos: eventos sí/no o conteos que cambian el escenario por completo.
- Variabilidad
- Diferencias naturales entre repeticiones: dos días nunca venden exactamente igual.
- Riesgo
- Probabilidad de un resultado malo: quiebre de stock, espera mayor a 10 min, pérdida.
- Réplica
- Una ejecución completa del simulador con valores aleatorios distintos. El promedio de muchas réplicas estima lo esperado.
- Escenario
- Una configuración fija (stock inicial, personal, precios) evaluada con muchas réplicas.
04 · Ejemplos
Casos que un programador simula con incertidumbre
El patrón es siempre el mismo: regla fija + azar → resultado variable → decisión con margen:
- 1Inventario.
Compro 120 unidades. Demanda 6 a 14/día. ¿Cuál es la probabilidad de quiebre en 12 días?
- 2Cola de atención.
2 cajeros. Llegadas aleatorias. ¿Espera promedio y peor espera del día?
- 3Servidor web.
Pedidos por minuto variables. ¿Probabilidad de latencia mayor a 2 s?
- 4Entregas.
Tiempo de viaje 20 a 50 min. ¿A qué hora prometer la entrega con 95 % de cumplimiento?
- 5Juego.
Daño 8 a 12 por golpe. ¿Cuántos turnos para derrotar a un enemigo de 50 puntos?
05 · Representación en Python
Fijo frente a aleatorio, en código
En Python, lo determinístico es una cuenta; lo aleatorio es un muestreo con el módulo random. Todavía no elegimos distribuciones formales (temas 17 a 24): usamos uniform para expresar «no sé el valor exacto, pero sé el rango».
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.
# Determinístico: siempre 120
demanda_fija = 10
print("Fijo:", demanda_fija * 12)
# Con incertidumbre: 12 días entre 6 y 14
import random
random.seed(7)
dias = [random.uniform(6, 14) for _ in range(12)]
print("Días:", [round(d, 1) for d in dias])
print("Total aleatorio:", round(sum(dias), 1))
Consejo: ejecutá varias veces cambiando la semilla (seed 7 por otro número) y observá que el total cambia: esa es la variabilidad entre ejecuciones (tema 40).
De una cuenta a una réplica
Una réplica es una función que devuelve un resultado distinto cada vez. El promedio de muchas réplicas estima el valor esperado (tema 13):
import random
def una_replica(dias=12):
return sum(random.uniform(6, 14) for _ in range(dias))
random.seed(1)
replicas = [una_replica() for _ in range(5)]
print([round(r, 1) for r in replicas])
print("Promedio de 5 réplicas:", round(sum(replicas) / len(replicas), 1))
06 · Exploración
Laboratorio: stock fijo vs stock con azar
Un negocio empieza con un stock inicial y enfrenta una demanda diaria de base ± variabilidad. La línea blanca es el cálculo determinístico (siempre vende la base). Las 3 líneas de colores son 3 réplicas aleatorias con demanda uniforme. Movete los controles y observá cuándo el promedio engaña.
Inventario bajo incertidumbre
stock(t+1) = stock(t) − U(base−var, base+var)
Con variabilidad 0, todas las líneas coinciden: no hay incertidumbre.
Cada línea muestra el stock día a día durante 12 días. Si la variabilidad es 0, las 4 líneas coinciden. Al aumentarla, las réplicas se separan: el promedio se parece al cálculo fijo, pero el riesgo de quiebre aparece.
Preguntas para explorar
- Poné variabilidad en 0. ¿Qué pasa con el rango? ¿Por qué?
- Subí la variabilidad a 8 con base 10. ¿El promedio final cambia mucho? ¿Y el rango?
- ¿Qué escenario es más riesgoso: base 8 con variabilidad 6, o base 10 con variabilidad 0? ¿Por qué el promedio solo no alcanza?
Ver respuestas sugeridas
- El rango es 0: sin azar todas las réplicas son idénticas al cálculo determinístico.
- El promedio final se mantiene cerca del determinístico (Ley de los Grandes Números, tema 15), pero el rango crece: algunas réplicas quiebran y otras sobran.
- El primero: aunque vende menos en promedio, su dispersión genera quiebres. El promedio oculta el riesgo; hacen falta varianza (tema 14) y réplicas (tema 41).
07 · Comprensión
Confusiones frecuentes
«Si uso el promedio, ya contemplé la incertidumbre»
No: el promedio resume el centro, pero no el riesgo. Hacen falta dispersión, histogramas y probabilidad de falla.
«Aleatorio significa sin reglas»
No: aleatorio significa gobernado por una distribución. La regla existe (rango, promedio, forma), lo que varía es el valor puntual.
«Con una corrida alcanza»
Una corrida es una anécdota. La conclusión sale del conjunto de réplicas: promedio, rango y error (temas 40 a 42).
«Más variabilidad siempre es mala»
Depende de la decisión: a veces conviene un escenario con más promedio aunque varíe más, si el riesgo se puede absorber con stock o capacidad.
08 · Práctica guiada
Ejercicios con Python
Ejercicio 1: medir la variación
Generá 10 totales de 12 días con demanda uniforme entre 6 y 14. Calculá el mínimo, el máximo y el rango. Ejecutalo dos veces con distinta semilla.
import random
def total_12(semilla):
random.seed(semilla)
return sum(random.uniform(6, 14) for _ in range(12))
totales = [total_12(s) for s in range(10)]
print("Mín:", round(min(totales), 1))
print("Máx:", round(max(totales), 1))
print("Rango:", round(max(totales) - min(totales), 1))
Ver solución razonada
El rango típico ronda 15 a 30 unidades: con la misma regla (6 a 14) el total de 12 días varía mucho. Esa es la incertidumbre que el cálculo fijo 120 oculta.
Ejercicio 2: probabilidad de quiebre
Con stock 120 y 12 días de demanda uniforme 6 a 14, estimá por réplicas la probabilidad de terminar con stock negativo (quiebre). Usá 1000 réplicas.
import random
random.seed(2)
def hay_quiebre(stock=120, dias=12):
for _ in range(dias):
stock -= random.uniform(6, 14)
if stock < 0:
return True
return False
N = 1000
quiebres = sum(hay_quiebre() for _ in range(N))
print("Quiebres:", quiebres, "de", N)
print("Prob. estimada:", round(quiebres / N, 3))
Ver solución
La probabilidad ronda 0,5: con stock igual al promedio esperado (120), la mitad de las veces el azar juega a favor y la mitad en contra. Para bajar el riesgo hay que sobrestockear o aceptar el quiebre.
Ejercicio 3: el promedio se estabiliza
Calculá el promedio acumulado de réplicas con N = 10, 100 y 1000. Observá cómo se acerca a 120 (12 × 10). Es un adelanto de la Ley de los Grandes Números.
Ver una posible respuesta
import random
random.seed(3)
def una_replica():
return sum(random.uniform(6, 14) for _ in range(12))
for N in [10, 100, 1000]:
prom = sum(una_replica() for _ in range(N)) / N
print(N, "réplicas →", round(prom, 2))
Con 10 réplicas el promedio salta (115 a 125); con 1000 se pega a 120. Más réplicas, menos error: la idea central de los temas 15, 41 y 42.
09 · Síntesis
Ideas para recordar
- La incertidumbre no es un error: es parte del fenómeno y debe modelarse.
- Un cálculo determinístico da un punto; una simulación da una distribución de resultados.
- Las fuentes típicas son entradas, parámetros y supuestos del modelo.
- En Python, el azar se expresa muestreando:
random.uniformes el primer paso antes de las distribuciones formales. - Una réplica no decide: deciden el promedio, el rango y la probabilidad de falla sobre muchas réplicas.
En el próximo tema distinguiremos fenómenos determinísticos y aleatorios: cuándo alcanza una fórmula fija y cuándo hay que simular con azar.