En el artículo sobre el promedio dejé una promesa pendiente: mostrar la simulación de Montecarlo funcionando sobre un caso real de gestión, con código completo. Este es ese artículo.
El punto de partida es una escena universal. El gerente pregunta: “¿Cuándo terminamos?”. El jefe de proyecto responde: “15 de marzo”. Y desde ese momento, el 15 de marzo deja de ser una estimación y se convierte en un compromiso: se promete al cliente, se agenda la inauguración, se calcula la multa.
El problema no es que la fecha esté “mal calculada”. El problema es que una fecha única es el formato equivocado para la respuesta. El término de un proyecto depende de docenas de duraciones inciertas encadenadas; la respuesta honesta no es una fecha, es una distribución de fechas con probabilidades. Y “15 de marzo” suele ser un percentil optimista de esa distribución: el futuro que solo ocurre si casi nada sale mal.
Por qué sumar duraciones “probables” da un plazo improbable
La intuición falla por tres razones que se acumulan. Conviene separarlas desde ya, porque no pesan lo mismo.
Lo “probable” no es el promedio. Cuando el jefe de terreno dice “normalmente 4 semanas”, te está dando el valor más frecuente, no el promedio. En una tarea que puede atrasarse mucho más de lo que puede adelantarse, esos dos números no coinciden: si todo calza son 3 semanas y lo normal son 4, pero las veces que se complica son 7, esas veces empujan el promedio por encima de 4,5. Nadie mintió. Pero cada tarea esconde unos días, y el cronograma los suma todos hacia el mismo lado.
Los atrasos se propagan, los adelantos no.
- Si la tarea A termina 5 días tarde, la B empieza 5 días tarde.
- Si la A termina 5 días antes… la B rara vez empieza antes: la cuadrilla no está, el material llega en la fecha comprometida, el permiso sale cuando sale.
Las convergencias eligen a la peor. Cuando tres cadenas de tareas deben terminar para que empiece la cuarta, la fecha de inicio la fija la peor de las tres, no la promedio.
Intuición (La tiranía del máximo)
Si tres actividades predecesoras tienen cada una 80% de probabilidad de terminar a tiempo, la actividad que depende de las tres tiene 0.8³ ≈ 51% de empezar a tiempo. El cronograma determinista trata ese 51% como si fuera un hecho. Multiplica esa erosión por cada nodo de convergencia del Gantt y entenderás por qué “todo venía bien” hasta que dejó de venir.
La simulación completa
Montecarlo resuelve esto por fuerza bruta honesta: en vez de calcular el futuro, simula diez mil futuros posibles y cuenta resultados. Para cada tarea necesitas tres estimaciones en vez de una: optimista, probable y pesimista. Son las mismas que tu jefe de terreno ya sabe (“si todo calza, 3 semanas; normalmente 4; si se complica el clima, 7”).
import numpy as np
rng = np.random.default_rng(42)N = 10_000 # futuros simulados
# Cronograma: (optimista, probable, pesimista) en días# La distribución triangular es imperfecta pero honesta con pocos datostareas = { 'excavacion': (15, 20, 35), 'fundaciones': (25, 30, 50), 'estructura': (60, 75, 110), 'techumbre': (15, 20, 30), 'instalaciones': (40, 50, 80), 'terminaciones': (35, 45, 75), 'recepcion': (10, 20, 60), # la cola larga de la burocracia}
def dur(nombre): o, m, p = tareas[nombre] return rng.triangular(o, m, p, N)
# Lógica de precedencia (aquí está el modelo real del proyecto):# excavación → fundaciones → estructura → techumbre# instalaciones parte con la estructura al 50%# terminaciones exigen techumbre E instalaciones listas ← convergenciafin_excav = dur('excavacion')fin_fund = fin_excav + dur('fundaciones')d_estructura = dur('estructura')fin_estr = fin_fund + d_estructurafin_techo = fin_estr + dur('techumbre')fin_inst = fin_fund + d_estructura * 0.5 + dur('instalaciones')fin_term = np.maximum(fin_techo, fin_inst) + dur('terminaciones')fin_total = fin_term + dur('recepcion')
# El plan "oficial": la ruta crítica calculada con las duraciones probablesm = {k: v[1] for k, v in tareas.items()}plan = (m['excavacion'] + m['fundaciones'] + max(m['estructura'] + m['techumbre'], m['estructura'] * 0.5 + m['instalaciones']) + m['terminaciones'] + m['recepcion'])
# La respuesta: no una fecha, una distribuciónprint(f"Plazo 'oficial' (ruta con duraciones probables): {plan:.0f} días")print(f"Probabilidad de cumplirlo: {(fin_total <= plan).mean():.1%}")for pct in [50, 80, 95]: print(f"P{pct}: {np.percentile(fin_total, pct):.0f} días")Plazo 'oficial' (ruta con duraciones probables): 210 díasProbabilidad de cumplirlo: 1.8%P50: 245 díasP80: 261 díasP95: 277 díasDetente en la segunda línea del resultado. El plazo que el cronograma oficial declara como “el plan”, construido con la duración más probable de cada tarea, tiene menos de un 2% de probabilidad de cumplirse. Y el modelo no tiene ni una catástrofe adentro: no hay terremoto, no hay quiebra del subcontratista, solo rangos razonables de terreno. El P50 real queda 35 días más allá del plan.
Distribución del plazo total (10.000 futuros simulados)
El plan oficial de 210 días queda en la cola izquierda: casi ningún futuro simulado lo cumple.
De dónde salen los 35 días
Vale la pena desarmar esa brecha, porque la respuesta no es la que uno esperaría. Aislando cada mecanismo en el mismo modelo:
| Mecanismo | Días que agrega | Cómo se aísla |
|---|---|---|
| Lo probable no es el promedio | 33 | Rehacer el plan con la duración promedio de cada tarea en vez de la probable: da 243 días, sin simular nada. |
| La convergencia de techumbre e instalaciones | 2 | Diferencia entre ese plan y el promedio de los 10.000 futuros simulados: 245 días. |
| Los adelantos que no se aprovechan | 1 más | Agregar la regla de que ninguna tarea parte antes de su fecha agendada. El script de arriba no la trae, por eso no suma en los 35: con ella, la probabilidad de cumplir baja de 1,8% a 0,8%. |
Casi todo el efecto es el primero, el más aburrido. La convergencia pesa poco en este cronograma porque la ruta de la techumbre fija el término en 7 de cada 10 futuros: las instalaciones rara vez son las que llegan tarde. En un proyecto con varios frentes parejos que convergen (varias torres, especialidades en paralelo que tienen que cerrar juntas) ese segundo mecanismo pesa mucho más.
La lección práctica es incómoda por lo simple: el plan construido con duraciones probables es optimista antes de que la incertidumbre interactúe siquiera, y eso se corrige en una planilla. En cada fila, en vez de usar la columna del medio, promedia las tres estimaciones. Este plan pasa de 210 a 243 días y de un 2% a casi un 50% de probabilidad. La simulación no la necesitas para eso: la necesitas para lo que viene después.
Nota (¿Esto no es PERT?)
En parte. PERT, de fines de los años 50, ya pedía las mismas tres estimaciones y corregía la duración probable con un promedio ponderado. Lo que no hace es mirar más de una ruta: calcula la incertidumbre de la ruta crítica y trata a las demás como si no pudieran llegar tarde, así que subestima justo el efecto de las convergencias. Y no responde las preguntas que importan en una negociación: qué pasa si acelero esto, dónde está el riesgo, cuánto me cuesta en multas. Para eso sirve simular.
Cómo se usa esto en una negociación real
La distribución convierte tres conversaciones imposibles en conversaciones con números:
-
El compromiso con el cliente. En vez de prometer el P20 y pagar multas, o el P95 y perder la licitación por conservador, eliges el percentil según el costo real de fallar: multa alta → comprométete al P80–P90 y explica por qué; multa simbólica → P60 y precio más competitivo. El percentil de compromiso es una decisión comercial, no técnica, y hoy la está tomando por defecto (y mal) quien arma el Gantt.
Cuando el plazo no lo eliges tú porque viene fijado en las bases, la distribución sirve igual: te dice cuánto vas a pagar en multas en promedio, y ese es un costo que va en la oferta como cualquier otro. Con el script de arriba es una línea:
np.maximum(fin_total - plazo_bases, 0).mean() * multa_diaria.Y comprometerte al P80 con el cliente no significa darle el P80 a la obra. Igual que con el presupuesto, la meta interna sigue siendo el plan exigente. La diferencia entre ambos es tu colchón, y lo administra la gerencia, no terreno.
-
El precio de acelerar. ¿Vale la pena poner un segundo subcontratista de instalaciones? Baja sus tres duraciones un 20% en el modelo y corre de nuevo: el P80 se mueve menos de 2 días, porque en 7 de cada 10 futuros el término lo fija la techumbre. La misma aceleración en estructura lo mueve 14. Acabas de ahorrarte una aceleración inútil y de encontrar la útil.
-
Dónde vive el riesgo. Corre la simulación congelando una tarea a la vez en su valor probable y mira cuál reduce más la varianza del total. Esa es la tarea que merece tu mejor subcontratista y tu plan B. En mi ejemplo es la recepción, la tarea con menos “obra” y más cola: congelarla quita un tercio de la varianza, más que congelar la estructura, que es la tarea más larga del proyecto. Y atacarla no cuesta turnos extra. Si bajas su pesimista de 60 a 35 días (ingresando los antecedentes antes, sin esperar el último certificado para partir el trámite), el P80 se adelanta 11 días, no muy lejos de los 14 que da acelerar la estructura.
Advertencia (La basura entra elegante)
La simulación es tan honesta como sus insumos. Si el jefe de terreno da rangos complacientes (“optimista 20, pesimista 22”), Montecarlo devolverá certeza falsa con decimales. Dos defensas: usa tus duraciones históricas reales para calibrar los pesimistas (¿cuánto demoró de verdad la recepción en las últimas 5 obras? Ese dato ya lo tienes), y desconfía de todo rango donde el pesimista no supere al optimista en al menos un 50%. La incertidumbre real de terreno es fea; si el modelo se ve bonito, está mintiendo.
Y un supuesto que conviene declarar: el modelo trata cada tarea como independiente. En terreno no lo son. El invierno lluvioso o el subcontratista débil atrasan varias tareas a la vez, y eso engorda la cola. Tu P95 real es peor que el simulado, no mejor.
Empezar sin permiso
No necesitas modelar las 400 líneas del Gantt. Toma las 10–15 macro-actividades que definen el proyecto, pide los tres valores para cada una (media hora de conversación con terreno), y corre el script de arriba. La primera vez que muestres “el plan oficial tiene un 2% de probabilidad” en un comité, la conversación sobre plazos de tu empresa no vuelve a ser la misma.
Y si esta semana no vas a correr Python, haz al menos la versión de planilla: promedia las tres estimaciones de cada fila en vez de usar la del medio. No te da percentiles ni te dice dónde está el riesgo, pero te saca del plan que casi nunca se cumple y te pone a discutir el número correcto.
Y esa es la verdadera tesis de esta serie: el promedio, la fecha única, el número redondo, son tecnologías de comunicación cómodas que destruyen información de riesgo. Recuperar esa información no requiere un doctorado: requiere 40 líneas de Python y la voluntad de escuchar la respuesta.
Resumen (TL;DR)
Una fecha única de término es el percentil optimista de una distribución que nadie calculó. La mayor parte del sesgo sale de sumar duraciones “probables”, que en tareas con cola larga quedan bajo el promedio (en el ejemplo, 33 de los 35 días), y eso se corrige en una planilla. Encima se suman las convergencias y los adelantos que no se aprovechan. Montecarlo con tres estimaciones por macro-tarea (40 líneas de Python) te da la distribución completa: el percentil al que te comprometes es una decisión comercial según el costo de fallar, las multas esperadas van en la oferta, y la simulación te dice qué aceleración vale la pena pagar y dónde vive realmente el riesgo del plazo.