En este artículo vamos a ver una rápida introducción a la estimación de tamaño, esfuerzo, tiempos total, costos y optimización (compresión) de schedule utilizando simulaciones mediante el método de Monte Carlo.
Aclaración: lo de avanzado es según quien lo lea.
Idea
La idea detrás de esta alternativa de estimación es aprovechar toda la información disponible y utilizarla para ejecutar miles y miles de proyectos virtuales (simulados) idénticos al nuestro para conocer cual es el esfuerzo medio requerido, tiempo medio de ejecución del schedule planteado y la dispersión que presenta. Luego, es posible también plantear distintas combinaciones de ejecución de tareas, simularlas y obtener así el schedule más comprimido, el que presenta menor dispersión, o de ser posible, el más comprimido y que a su vez presenta la menor dispersión (no siempre es posible).
Fundamento
"Caper Jones identifies three major root causes for large software project delays and disasters: inaccurate estimation, inaccurate status reporting, and inaccurate historical data." [Why Flawed Software Projects Are Not Cancelled in Time]. Y seguro que es así, si partimos del hecho de que la estimación es sobre lo que se basa la planificación y el control del proyecto y el presupuesto, queda claro que un error aquí es un error caro
En cualquier proyecto, la estimación del tamaño (y del esfuerzo luego) es justamente eso: una "estimación". Y por lo tanto se trata de un proceso estocástico en el cual, la salida no es solo un número sino que además viene acompañado de un grado de confianza sobre ese valor.
Cuando alguien presenta una estimación rara vez da a conocer el grado de confianza que tiene sobre ella, ya sea porque es muy bajo, o porque no se conoce, o porque no se sabe calcular, o porque no se sabe aprovechar o simplemente porque parece complicado de administrar. Evidentemente si la duración de cada tarea de un proyecto se observa como una posible nube probabilística, en el sentido de que no se conoce con exactitud cual será su esfuerzo/duración real, la confección del schedule, su control, la determinación del camino crítico y la asignación de tareas parece complicarse un poco. No obstante, aunque existen herramientas para solucionar este problema (véase: PERT), estos son más complejos que la alternativa recursiva y de fuerza bruta que vamos a tratar y además no dicen nada sobre cual es distribución de probabilidades de la duración del proyecto, ni su dispersión por lo que no es sencillo obtener un intervalo de confianza sobre la duración de nuestro proyecto. Por el contrario, simulando el mismo proyecto una y otra vez hasta haberlo hecho algunas miles de veces nos permite obtener las estadísticas de cuanto tamaño/esfuerzo/costos insumieron esos proyectos. Es como revisar los datos históricos sobre proyectos virtuales.
La obtención del esfuerzo está en función del tamaño estimado y, la función de conversión es determinística. Ya sea que se utilicen datos históricos de la empresa, de la industria o métodos como COCOMO, todo se resume a una conversión directa. Pero si aceptamos que el tamaño estimado es solo eso, un valor perteneciente a un espacio probabilístico, y que la función de conversión también tiene cierto error, entonces aceptaremos que tratarlos como datos estadísticos tiene sentido. No estoy solo en este punto ni en ningún otro; el Software Productivity Center Inc. recomienda estimar rangos y menciona explícitamente que la conversión size-effort tiene cierto margen de error.
Mejoras
No más buffers. Por lo general, y según lo visto en el punto anterior, cuando se le solicita a un desarrollador (tester o lo que fuese) una estimación sobre una tarea a realizar, lo que se espera es lisa y llanamente un número fijo y certero desprovisto de cualquier indicio de 'probabilidad'. Aún gente que respeto mucho y que sabe muchísimo del tema, y que entienden a la perfección la diferencia entre estimado/real y esfuerzo/duración, no se sienten cómodos con la idea de tener que considerar a las probabilidades sus estimaciones y menos aún en un schedule por lo que prefieren implementar el concepto de 'buffer' o 'gap' para incrementar las posibilidades de éxito de entrega a tiempo. ¿Pero, de cuanto debe ser ese buffer? ¿Como lo calculan? La realidad nos dice que no se hace nada muy científico :). O es un porcentaje del tiempo de la tarea, o se acuerda con el desarrollador según sus habilidades para negociar, o se le suma un número de horas basado en los dos últimos dígitos del número ganador sorteado por la lotería nacional.
La simulación hace a las asignaciones de tareas más justas y mejor justificadas puesto que otro inconveniente de esta práctica es que, además de ser totalmente arbitraria la asignación de tiempos y solo basarse en aspectos tan subjetivos, como el "a esta tarea deberíamos darle un poquitín más", logra que algunas personas se encuentren muy sobrecargadas mientras que otras se aburren y optan por escribir largas entradas en sus blogs referentes a simulación de proyectos :). Es claro, si a todas las tareas se les da un margen un tanto caprichoso (casi aleatorio) entonces habrá algún desarrollador que terminará todas sus tareas sin necesidad de consumir todo su margen y estará escribiendo un post (si no tiene chat) mientras que otro ya se habrá consumido todo su tiempo más su buffer y todavía seguirá sin poder entregar su trabajo (amén de las malas caras del jefe, el overwork y los dibujos en el timesheet para no cargarle más horas a esa tarea a la vez que intenta que no parezca que estuvo desocupado. Dios! pobre tipo.). Pero una cosa es segura, si al que le sobró tiempo no se le permite disfrutar de su tiempo "ganado" entonces la próxima vez consumirá todo su tiempo disponible y oh! casualidad, lo terminará el último día!
Con una simulación, no hacen falta buffer ya que están considerados dentro del esfuerzo total del proyecto. Otra alternativa es manejar dos milestones: uno interno y uno para el cliente. Uno podría tranquilamente calcular cual es el plazo necesario para tener una certeza de entrega a tiempo del 85% y cual es el que nos garantiza un 70% de entrega a tiempo y manejarnos internamente con el primer milestone mientras que nos comprometemos con el cliente para la otra fecha. Como siempre el proyecto se irá atrasando y el gap entre las dos fechas se irá reduciendo a modo de termómetro.
Sencillez, flexibilidad y economicidad. La verdad es que por más que el juicio experto sea un método demasiado 'intuitivo', además que se requiere la existencia de un experto en proyectos similares, es uno de los métodos más utilizados. Ya sea en su forma más pura, o como complemento de otros métodos o como parámetro de entrada en alguna tool de estimación parametrizable, esta técnica sobrevive gracias a su sencillez, flexibilidad y economicidad. Pero aquellas empresas que no poseen un historial de proyectos, muchas veces acuden a una estimación direct-to-effort utilizando el juicio experto el cual no aporta más que un único dato: la estimación pelada, sin un grado de certeza o riesgo.
Con el método que veremos ahora es posible aunque más no sea, introducir en las consideraciones mayor información proveniente del experto como cual estima que sería el tiempo mínimo, el más probable y el tiempo máximo de duración de una tarea, y de esta manera realizar simulaciones teniendo en cuenta que la tarea en cuestión posee una distribución de probabilidades triangular (este fue solo un ejemplo. Según los datos que tengamos podremos utilizar la distribución más conveniente).
Por otro lado, si este no fuera el caso y sí se contara con información histórica, podría alimentarse el modelo con esos datos y simular la ejecución del proyecto para estudiar alternativas de schedule, simular riesgos o realizar análisis de sensibilidad sobre las tareas del proyecto.
Análisis de sensibilidad. Al contar con un modelo que puede ser simulado, es posible realizar un análisis de sensibilidad para conocer como se verá afectado el proyecto ante variaciones en el tamaño/esfuerzo de las tareas de modo de focalizar la atención sobre las tareas que tienen mayor potencial de hacer fracasar el proyecto en términos de tiempos mientras que se libera el control innecesario sobre las tareas que tienen un bajo poder de impacto.
Por ejemplo, del análisis de sensibilidad del schedule más conveniente del proyecto de ejemplo, surge que hay que presarle especial atención a las tareas test_contacts_report y test_contacts_search (tareas de testing de dos features del módulo de contactos) que como se imaginarán están en el camino crítico.
Considerar los riesgos. En todo proyecto existen riesgos que deben ser controlados. En la mayoría de las veces esto se gestiona utilizando una planilla Excel como herramienta en la que a cada riesgo identificado se le asigna, entre otras cosas, una probabilidad de ocurrencia y el impacto que tendría su ocurrencia sobre el proyecto. Por más que los riesgos se "gestiones", estos no desaparecerán del todo y su ocurrencia seguirá afectando al proyecto de alguna manera consumiendo esfuerzo indefectiblemente y esa relación (riesgo->esfuerzo) puede introducirse en la simulación de manera que, en alguna de las corridas del proyecto el riesgo se producirá, consumirá el esfuerzo en cuestión y ese esfuerzo formará parte de las estadísticas finales. Los riesgos convendría asociarlos a las tareas en lugar de hacerlo con el proyecto completo porque la ocurrencia de un riesgo no afectará al proyecto de igual manera si retrasa a una tarea que se encuentra en el camino crítico que si lo retrasa a una tarea que no lo está.
Mayor entendimiento de los posibles escenarios. Como ya dijimos, el que cada una de nuestras certezas tenga ahora un grado (medida de la certeza) parece complicar la administración haciéndola demasiado parecida a la realidad. Pero esto es muy bueno porque presenta una enorme cantidad de información contra-intuitiva que nunca se nos hubiera ocurrido (o al menos eso me pasó a mi). Luego de simular varios schedules con las mismas tareas uno puede encontrarse con que existen schedules que arrojan menores tiempos en promedio pero con mayor desviación estándar mientras que otros tienen peores plazos pero con mucho menor desviación estandár. La elección dependerá de nuestra simpatía o aversión por los riesgos o a otras necesidades. Otro efecto (demoledor) de simular nuestros proyectos es que por más que ajustemos todo y elijamos valores para tiempos de entrega y esfuerzo que nos garanticen un 90% de certeza de cumplir con el cliente y el presupuesto, cuando simulamos con un gran número de iteraciones vemos que: el 10% de las veces nuestro proyecto fracasa!!!! Parece una obviedad y lo es pero no deja de hacerme pensar. Cae al caso recomendarles el libro "¿Existe la suerte?: Engañados por el azar" de Nassim Nicholas Taleb que podríamos resumir así: "si nunca ha fracasado ninguno de tus proyectos es solo porque no has participado en suficientes" la pura estadística lo demuestra.

El camino crítico puede no ser el camino crítico. Si bien duración no es igual a esfuerzo, cuando solo se cuenta con un único desarrollador que trabaja exactamente 8 horas y que está abocado a una única tarea, entonces en ese caso particular el esfuerzo y la duración son lo mismo (quiten los fines de semana, vacaciones y cualquier otra cosa que hagan que esto no se válido). En ese caso, si planteamos que esfuerzo y duración son lo mismo, y acordamos que el esfuerzo no es un valor obtenido de forma determinística, entonces la duración de las tareas variará. En el ejemplo de abajo ilustro esa situación en la que existen tres tareas y dos desarrolladores, dev1 tiene asignada dos tareas secuenciales cuya duración media son de 4,6 hs. y 4,85 hs respectivamente mientras que dev2 tiene asignada una única tarea cuya duración media estimada es de 10 hs. Si no fuese porque en este ejemplo hemos establecido que esfuerzo y duración son equivalentes, el camino crítico estaría dado por la tarea nro. 3 pero en este caso particular el tiempo máximo de la ejecución en serie de las tareas 1 y 2 es mayor al tiempo mínimo de ejecución de la tarea 3 por lo que aquí no tenemos un camino crítico definido.
Conocer el coeficiente de amortiguamiento. Ante un retraso, si no es posible re planificar la entrega, existen dos posibilidades: asignar más recursos a una tarea (este es todo un tema aparte) o que la gente haga overwork. Estos dos factores hacen las veces de amortiguadores del proyecto. Ahora, la asignación de más gente a una tarea no siempre es buena idea y tiene un límite, de igual manera, la jornada laboral de los ingenieros no puede alargarse hasta el infinito. Por lo que estos amortiguadores tienen una limitada capacidad de absorber las oscilaciones de un proyecto. Simulando estas situaciones con datos históricos de los timesheets es posible conocer cual es la capacidad que tienen los ingenieros de salvarnos.
Una herramienta
Para realizar cualquier tipo de simulaciones con el método de Monte Carlo nada mejor que MS Excel sin duda. Ahora, además de esto existen muchos add ins comerciales que pueden adquirirse en la web, pero para quienes quieran experimentar con un sencillo y muy útil add-in les recomiendo SimuAr es un "emailware" . Con esta herramienta he desarrollado el ejemplo.
Para simular proyectos en serio les recomiendo Slim y Construx Estimate.
El ejemplo
Por razones de sencillez del modelo voy a realizar una estimación direct-to-effort, es decir, no estimaremos el tamaño y vamos a hacer de cuenta que esfuerzo y duración de la tarea es lo mismo. En otras palabras, vamos a estimar como lo haría un albañil.
En este ejemplo existen solo tres etapas: Análisis de requerimientos a cargo del líder técnico, codificación y test unitario a cargo de tres desarrolladores y testing a cargo de un solo tester. Se desarrollarán 4 módulos de un CRM: Contacts, Activities, Cases y Opportunities. Todos utilizan una distribución triangular cuyos parámetros han sido proporcionados por nuestro experto virtual (no tengo un experto cerca en este momento). Se plantan dos schedules ultrasencillos para simular, el primero consiste en "Etapas secuenciales y codificación en paralelo (salvo Contacts y Activities que pertenecen al mismo desarrollador)" mientras que el segundo consiste en "Modulós en paralelo c/lider técnico en el camino crítico", esto significa que debemos esperar a que el TL ponga las specs de un módulo en baseline antes de poder comenzar con la codificación.
Los schedules se simulan con la siguientes fórmulas:
| secuenciales y codificación en paralelo |
=s_reqana+MAX(s_cu_contacts+s_cu_activities;s_cu_cases;s_cu_opp)+s_test_contacts |
| Modulos en paralelo c/lider técnico en el camino critico |
=MAX(reqana_contacts+s_cu_contacts+s_test_contacts+s_cu_activities+reqana_activities;SUM(I3:I5)+s_cu_cases;SUM(I3:I6)+s_cu_opp)+vsalida() |
Esto es porque la duración total de las tareas secuenciales es igual a la suma de sus duraciones mientras que la duración de las tareas paralelas es igual al tiempo de duración de la que insume mayor tiempo.
Para bajar el archivo de ejemplo y correrlo hay que instalar previamente el addin SimuAr.
Continuará...
Lucas Ontivero