---
title: ""
date: "`r Sys.Date()`"
output:
  rmdformats::readthedown:
    highlight: kate
---

```{r setup, include=FALSE}
## Global options
knitr::opts_chunk$set(cache = TRUE)
```


# Simulación de proyectos 

## Consideraciones principales
Si bien es altamente conocida la historia del desarrollo de las dos técnicas de gestión de proyectos, clasicos de la **Investigación de Operaciones** y sus orígenes en el Desembarco del Dia D y la construccuíon del Submarino Nuclear Polaris, es poco lo que en térnimos de algoritmos se ha avanzado en este terreno.

El algoritmo que utiliza *Microsoft Project* (CPM) está basado en código escrito en Fortran que fue desarrollado por IBM entre 1959 a 1962. En rigor esta técnica no es en si una simulación. Por el contrario es una técnias en la que el problema del proyecto se modela en forma determinística. Vale decir cada tarea tiene una duracuíón fija.

Resulta dificil de ver pero PERT es en sí misma una técnica que al recurrir a entradas estocáticas (duraciones de tarea que tienen una media y un desvio estandard) no nos otorcan una fecha de finalización fija, sino que nos entregan un promedio y un desvío estandar, al que le podemos aplicar medición de riesgo.

En este caso de estudio analizaremos una biblioteca de R-Cran en la que nos limitaremos a conocer los aspectos relativos a la duración en tiempo del proyecto, prescindiendo de los costos y los recursos a efectos de entender como funciona la parte medular de esta simulación. Existen parámetros complementarios y bibliotecas anexas que realizan este trabajo que omitiremos y que además tienen poderosas herramientas de optimización multi-objetivo.



# Técnicas Pert & CPM

Hay dos enfoques en la gestión de proyectos para presentar proyectos multifuncionales en un gráfico:

1. Notación de actividad en el arco (AoA), donde cada flecha (arista) significa una actividad. Los nodos determinan el inicio o el final de una o más actividades.

2. Notación de actividad en el nodo (AoN), en la que el nodo denota una actividad. Las flechas representan las relaciones entre la actividad dada y las actividades inmediatamente anteriores e inmediatamente posteriores.

La versión actual del paquete que mostramos utiliza la notación AoA.



# El método del Camino Crítico CPM

En el CPM (Critical Path Method) asumimos que la duración de cada actividad es exactamente conocida (determinista).
Tomemos la notación AoA. La actividad comienza en el nodo número i y termina en el nodo número j. Todo el proyecto comienza y termina en un nodo par de nodos. Veamos la figura de abajo.  Los momentos de Comienzo y Fin difieren porque las actividades pueden ocurrir en paralelo y en serie dentro de un proyecto. Además, las actividades variarán en duración.

![Momento de Inicio y Finalización](fig-000.png)

## Nomenclatura

$t_i⁰$  - hora de inicio más temprana posible de la tarea i;

$t_i¹$  - hora de inicio más tardía posible de la tarea i;

$t_j⁰$  - el tiempo de finalización más temprano posible de la tarea j;

$t_j¹$  - última hora posible de finalización de la tarea j.


El momento de completar todo el proyecto se denomina término directivo. El análisis de CPM se puede dividir en las siguientes etapas:

1. Establecer los tiempos más tempranos para las tareas.
2. Establecer los últimos tiempos para las tareas.
3. Determinación de holguras para actividades.
4. Elaboración del cronograma del proyecto.
5. Determinación de la ruta crítica del proyecto.

Además, podemos hacer un diagrama de Gantt y gráficos ASAP (lo antes posible) y ALAP (lo más tarde posible).

La preparación de un cronograma del proyecto consiste en determinar todos los tiempos posibles de inicio y finalización de las actividades. Además, calculamos un tiempo flotante total (holgura total) para cada actividad. Durante este tiempo, la actividad se puede retrasar sin retrasar la finalización de todo el proyecto.

## Abreviaturas


$ES_{ij}$ = $t_i⁰$ - momento de inicio más temprano posible de la actividad $(i, j)$;

$LF_{ij}$ = $t_i^1$ - último momento de finalización permitido para la actividad $(i, j)$;

$LS_{ij} = LF_{ij} − t_{ij}$  - último momento de inicio permitido para la actividad $(i, j)$;

$EF_{ij} = ES_{ij} + t_{ij}$ - el tiempo de terminación más temprano posible de la actividad $(i, j)$;

$TS_{ij}  = LF_{ij} − ES{ij} − t_{ij}$   - holgura total de tiempo (total float) para la actividad $(i, j)$ . Una reserva de tiempo que se puede utilizar para realizar una actividad determinada sin afectar el tiempo de finalización del proyecto.
$FS_{ij} = t_j⁰ - t_i⁰ - t{ij}$   - holgura libre de tiempo (free float) para la actividad $(i, j)$ . Cantidad máxima de tiempo por que una actividad se puede retrasar sin retrasar la hora de inicio más temprana posible de cualquier siguiente
actividad.


$CS_{ij} = t_j¹- t_i¹-t_{ij}  - holgura condicional de tiempo para la actividad $(i, j)$ . Cantidad máxima de tiempo por que una actividad se puede retrasar sin retrasar y sin afectar las holguras de tiempo de las actividades que preceden la actividad (incluida en el mismo camino).
Suponemos que el término directivo ($DT$) es igual al tiempo más temprano del evento final ($DT = t_n^0$) entonces, las holguras para actividades críticas igual a cero. Extensión de la duración de cualquier actividad crítica por tiempo $\tau$ 
unidades pospondrá el tiempo de finalización de todo el proyecto por $\tau$ unidades.

Si asumimos que $DT > t_n^0$ entonces la extensión de la duración de cualquier actividad crítica por $\tau$ unidades de tiempo será posponer el tiempo de finalización de todo el proyecto en $\tau − (DT − t_0^n )$ unidades para $\tau > (DT − t_0^n)$.

Los retrasos más pequeños no afectan la duración de todo el proyecto.


# Ejemplo de análisis CPM con biblioteca critpath

## Nota:
Debes cargar la biblioteca con el comando correspondoente antes de poder invocara

    install.packages("cripath")
    
Esta biblioteca depende de otras tres, llamadas **DiagrameR**, **rshape2**  , y **ggplot2**    

```{r}
library(critpath)
```

Esta bibbilioteca tiene varios datasets de prueba (proyectos)

```{r}
data(package="critpath")
```

Usemos el proyecto *cpmexample1* para ver como es la red

```{r}
cpmexample1
```
Podemos realizar el siguiente análisis del proyecto

- grafo de conexiones entre actividades
- encontrar momento de inicio y fin de todas las actividades
- encontrar los cuellos de botella (actividades críticas)
- poner actividades criticas en el grafo
- hacer un gráfico de Gantt
- hacer los gráficos ASAP y ALAP

Por lo general, sabemos cómo se ve el gráfico antes de resolver el problema de gestión de proyectos, pero
supongamos que por el momento no lo hacemos. Con la ayuda de la función **plot_graphAOA()** crearemos un
gráfico basado en los datos de la Tabla 1. La función toma dos argumentos: marco de datos con... bueno,
datos y si las duraciones son deterministas.
El marco de datos debe tener la misma estructura que en la Tabla 1. El orden de las columnas es importante,
no sus nombres. Las dos primeras columnas contienen los números de los nodos inicial y final. El
la siguiente columna contiene los nombres de las actividades y la última hora de su duración. todo el paquete
Las funciones que usan el marco de datos como argumento deben mantener esta estructura.

## Grafo del proyecto

```{r}
plot_graphAOA(cpmexample1)
```

## Resolución del grafo

Los siguientes dos elementos de la lista anterior son realizados por la función **solve_pathAOA()**. Crea el
cronograma del proyecto y requiere dos argumentos: marco de datos preparado de acuerdo con el esquema
descrito anteriormente y un argumento lógico que indica qué tipo de duración (determinista o estocástica)
Estamos tratando con.



```{r}
x <- solve_pathAOA(cpmexample1, deterministic = TRUE)
x
```



Una vez que se completan los cálculos, se muestra un mensaje con el término de la directiva. el resultado de la
La función **solve_pathAOA()** se guarda en la lista x . Sus elementos individuales varían ligeramente dependiendo del tipo de
método utilizado. 
Para el CPM, estos serán:

1. Un gráfico guardado creado con un paquete DiagrammeR.
2. El cronograma del proyecto.
3. Tiempo de finalización del proyecto.
4. Lista de actividades críticas.
5. Una tabla con valores flotantes libres y flotantes condicionales.

Los operadores **"[** devuelven los objetos tipo lista. En cambio el operador **"[["** permite el acceso a un ítem específico.

## Listado de tareas críticas
Scehduling

```{r}
x[2]
```


## Término directivo

```{r}
x[3]
```
## Actividades críticas

```{r}
x[4]
```
## Tiempo libre flotante y valor flotante

```{r}
x[5]
```

El primer elemento de la lista $x$ es utilizado por otras funciones del paquete. Los Asteriscos en la última columna de
el cronograma indica qué actividades son críticas.
Ahora, dibujemos un gráfico con las actividades críticas marcadas. Usaremos la función **plot_graphAOA()** otra vez pero con otro argumento. Será una lista creada después de resolver el problema. Esto requiere la uso del argumento pasado sea **"solved"***.

```{r}
plot_graphAOA(solved = x)
```

## Gráfica de Gantt

El siguiente elemento del análisis de CPM será el diagrama de Gantt. La función **plot_gantt()** requiere la
Los paquetes ggplot2 y reshape2 se instalarán primero. También toma la lista elaborada por el **solve_pathAOA()** como argumento obligatorio. El argumento opcional **bar_size** determina el
espesor de la barra de la actividad dibujada. El valor predeterminado es 10 y, si corresponde, este argumento debe
no ser proporcionado.

```{r}
plot_gantt(x)
```


## Gráfica ASAP

Las actividades se muestran en el orden en que fueron ingresadas. Los críticos están marcados con CR y
los no críticos con NC. Además, se han agregado holguras mayores que cero para no críticos
actividades.
Según el gráfico de Gantt, podemos trazar dos gráficos más. El primero es el gráfico ASAP que muestra
efectos de iniciar la actividad lo antes posible y terminarla lo antes posible. Se puede lograr con
la función **plot_asap()**.


```{r}
plot_asap(x)
```

## Gráfica ALAP

Por otro lado, la gráfica ALAP muestra los efectos de iniciar la actividad lo más tarde posible y terminarla lo más tarde posible QUE sea posible. Se puede lograr con la función **plot_alap()**.

```{r}
plot_alap(x)
```




# El método PERT


La abreviatura **PERT** significa *Técnica de Evaluación y Revisión de Programas*. Este método se basa
en los siguientes supuestos:

Se supone que las duraciones de las actividades tienen distribución Beta con valores esperados $E(t_{ij} )$ y desviaciones estándar $D(t_{ij} )$ .

Las siguientes restricciones se aplican a la distribución de la duración de la actividad, es decir, sobre la densidad función $\mathscr{F}(t_{ij} )$ :

- La duración de la actividad está dentro del rango $\langle t_{ij}â , t_{ij}^b \rangle$.Suponemos que la probabilidad
de la realización de la actividad $(a)$ en tiempos  menores que t_{ij}â o mayores de t_{ij}b unidades es cero;


- Los parámetros de la función **Beta** aseguran que la distribución de probabilidad de la la duración de la actividad es asimétrica a la derecha.

Los expertos estiman la duración de las actividades individuales. Como resultado, obtenemos:

- $t_{ij}â$ duración optimista de la actividad $(a)$;

- $t_{ij}^b$  duración pesimista de la actividad $(a)$;

- $t_{ij}^m$ la duración más probable de la actividad (a).

El análisis de tiempo PERT comienza con la fase introductoria, que consiste en estimar el tiempo esperado
Variación de valor y duración para cada actividad.

## Duración prevista de la actividad (a):


$$ m_{ij}= \frac{t_{ij}â + 4*t_{ij}^m + t_{ij}^b }{6} $$

## Varianza de la duración de la actividad (a)

$$ S_{ij}² = \left(  \frac{t_{ij}^b - t_{ij}^a }{6}  \right)   $$


Los cálculos en el problema estocástico son análogos al determinista (CPM) excepto que
ahora use las duraciones esperadas en lugar de las duraciones fijas.
El enfoque PERT clásico utiliza el teorema del límite central. Este teorema establece que la suma
(diferencia) de un gran número de variables aleatorias independientes con la misma distribución tiene un
distribución asintóticamente normal.
La probabilidad de cumplir con el término de directiva esperado () igual a la fecha más temprana en que ocurrió el
última actividad $(t_n⁰ )$ es 50%.
En el método PERT, se supone que debe seleccionarse de tal manera que su probabilidad sea
estar entre 30% y 60%:

$$ 0.3 \le P(t_n < DT) \le 0.6 $$


Un cronograma con menos del 30% de posibilidades de realización se denomina cronograma del tomador de riesgos, y el que con más del 60 % de probabilidad se llama cronograma conservador .


## Ejemplo de análisis con la biblioteca critpath

Usaremos un dato diferente que en CPM. Estos datos están disponibles en un conjunto denominado **pertexample1** que vimos antes. Nos deja que supongamos que la duración de las actividades es aleatoria y se describe con tres valores numéricos como en
Tabla 2.

```{r}
y <- pertexample1
y
```

Estamos interesados en los siguientes tipos de análisis:

- determinar las horas de inicio y finalización de cada actividad,
- identificar los cuellos de botella del proyecto (actividades críticas),
- colocando actividades críticas en el gráfico,
- hacer un diagrama de Gantt,
- elaboración de gráficos ASAP y ALAP,
- indicación de los términos de las directivas para los horarios del tomador de riesgos y del conservador.

La duración es una variable aleatoria, por lo que cambiaremos el argumento determinista a FALSO.

```{r}
y <- solve_pathAOA(pertexample1, deterministic = FALSE)
```
El resultado nos indica 31 días +/- 1.5 dias

Después de resolver el problema, aparece un mensaje que da los parámetros de la distribución normal de un
variable aleatoria que describe la duración del proyecto.
A continuación mostramos los elementos de la lista que almacenan la solución. Contiene un elemento más que el
lista creada para el método CPM. La columna Tiempo contiene la duración esperada de la actividad.


## Scheduling 2

```{r}
y[2]
```


## Términación directiva esperada.

```{r}
y[3]
```

## Devios estandard de la finalización

```{r}
y[4]
```

## Actividades críticas

```{r}
y[5]
```

## tiempo flotante condicional y valores flotantes

```{r}
y[6]
```

## Gráficos ASAP y ALAP

```{r}
plot_graphAOA(solved = y)
```


Gant

```{r}
plot_gantt(y)
```


Gantt ASAP

```{r}
plot_asap(y)
```

Gantt ALAP

```{r}
plot_alap(y)
```


## Riesgo implícito en el proyecto

La posibilidad de comparar varios proyectos nos permitirá 

Para fijar plazos correspondientes a los horarios del arriesgado y del asegurador, utilizaremos el Función **PERT_newtime()**.


```{r}
PERT_newtime(new_prob = 0.3, y)
```

```{r}
PERT_newtime(new_prob = 0.6, y)
```


La función **PERT_newprob()** responde a la pregunta sobre la probabilidad de completar el proyecto
para un término directivo dado. Por ejemplo, la probabilidad de que el proyecto termine después de 30 días



```{r}
PERT_newprob(new_DT = 30, y)
```

Además, la función **plot_norm()** dibuja un gráfico de la distribución normal de una variable aleatoria describiendo el tiempo de término directivo esperado.


```{r}
plot_norm(y)
```

Las líneas verticales adicionales indican los horarios del tomador de riesgos y el conservador.

##Notas adicionales finales

1. La versión actual del paquete (0.1.1) admite problemas con actividades en arcos.

2. Los gráficos son dibujados por la función **render_graph()** del paquete DiagrammeR usando el Algoritmo de Fruchterman-Reingold. Es garantizar, entre otros, que no se crucen los bordes.

Pero esto no siempre es posible. Además, ejecuciones posteriores de esta función para el mismo problema puede producir (y a menudo lo hace) un gráfico que se coloca en el plano de una manera ligeramente diferente cada uno tiempo.

3. El primer objeto de la lista pertenece a la clase **dgr_graph** compatible con DiagrammeR paquete. Es posible realizar las operaciones descritas en el manual de este paquete.


