criticalpath - R Package Implementation of Critical Path Method

Rubens Jose Rosa, Marcos dos Santos, Thiago Marques

2021-01-22

library(criticalpath)

Introduction

Critical Path Method

criticalpath package is an object oriented implementation of the Critical Path Method (CPM) in R with R6 library. CPM is a method used to estimate the minimum project duration and determine the amount of scheduling flexibility on the logical network paths within the schedule model. The flexibility is in terms of early start, early finish, late start, late finish, total float and free float. Beside, it permits to quantify the complexity of network diagram through the analysis of topological indicators. Finally, it permits to change the activities duration to perform what-if scenario analysis.

With this package, you can calculate the following CPM parameters:

The aim of this package is to apply critical path method, for the researcher to make experiments with CPM parameters.

How to create a schedule

You have the following alternatives to create a schedule:

  1. Create an empty schedule and add activities to i.
  2. Create an empty schedule, add activities and relations to it.
  3. Create an empty schedule and add activities at the same time that add relations to it.
  4. Create an schedule from activities data frame and relations data frame.

Lets discuss each one.

Add activities to a schedule

Usage:

Parameters:

# Activities added one by one
schedule <- Schedule$new()
schedule$add_activity(1, "Task 1", 5)
schedule$add_activity(2, "Task 2", 6)
schedule$add_activity(3, "Task 3", 8)
schedule$add_activity(4, "Task 4", 6)
schedule$add_activity(5, "Task 5", 9)
schedule$add_activity(6, "Task 6", 3)
schedule$add_activity(7, "Task 7", 4)
schedule$duration
#> [1] 9
schedule$activities
#>   id   name duration milestone critical ES EF LS LF total_float free_float
#> 1  1 Task 1        5     FALSE    FALSE  0  5  4  9           4          4
#> 2  2 Task 2        6     FALSE    FALSE  0  6  3  9           3          3
#> 3  3 Task 3        8     FALSE    FALSE  0  8  1  9           1          1
#> 4  4 Task 4        6     FALSE    FALSE  0  6  3  9           3          3
#> 5  5 Task 5        9     FALSE     TRUE  0  9  0  9           0          0
#> 6  6 Task 6        3     FALSE    FALSE  0  3  6  9           6          6
#> 7  7 Task 7        4     FALSE    FALSE  0  4  5  9           5          5
#>   progr_level regr_level topo_float
#> 1           1          1          0
#> 2           1          1          0
#> 3           1          1          0
#> 4           1          1          0
#> 5           1          1          0
#> 6           1          1          0
#> 7           1          1          0

# Activities add once for all
activities <- data.frame(
  id        = 1:17,
  name      = paste("a", as.character(1:17), sep=""),
  duration  = c(1,2,2,4,3,3,3,2,1,1,2,1,1,1,1,2,1)
)
schedule <- Schedule$new()
schedule$add_activities(activities)
schedule$duration
#> [1] 4
schedule$activities
#>    id name duration milestone critical ES EF LS LF total_float free_float
#> 1   1   a1        1     FALSE    FALSE  0  1  3  4           3          3
#> 2   2   a2        2     FALSE    FALSE  0  2  2  4           2          2
#> 3   3   a3        2     FALSE    FALSE  0  2  2  4           2          2
#> 4   4   a4        4     FALSE     TRUE  0  4  0  4           0          0
#> 5   5   a5        3     FALSE    FALSE  0  3  1  4           1          1
#> 6   6   a6        3     FALSE    FALSE  0  3  1  4           1          1
#> 7   7   a7        3     FALSE    FALSE  0  3  1  4           1          1
#> 8   8   a8        2     FALSE    FALSE  0  2  2  4           2          2
#> 9   9   a9        1     FALSE    FALSE  0  1  3  4           3          3
#> 10 10  a10        1     FALSE    FALSE  0  1  3  4           3          3
#> 11 11  a11        2     FALSE    FALSE  0  2  2  4           2          2
#> 12 12  a12        1     FALSE    FALSE  0  1  3  4           3          3
#> 13 13  a13        1     FALSE    FALSE  0  1  3  4           3          3
#> 14 14  a14        1     FALSE    FALSE  0  1  3  4           3          3
#> 15 15  a15        1     FALSE    FALSE  0  1  3  4           3          3
#> 16 16  a16        2     FALSE    FALSE  0  2  2  4           2          2
#> 17 17  a17        1     FALSE    FALSE  0  1  3  4           3          3
#>    progr_level regr_level topo_float
#> 1            1          1          0
#> 2            1          1          0
#> 3            1          1          0
#> 4            1          1          0
#> 5            1          1          0
#> 6            1          1          0
#> 7            1          1          0
#> 8            1          1          0
#> 9            1          1          0
#> 10           1          1          0
#> 11           1          1          0
#> 12           1          1          0
#> 13           1          1          0
#> 14           1          1          0
#> 15           1          1          0
#> 16           1          1          0
#> 17           1          1          0

Add relations to a schedule

Usage

Parameters:

# First, create an empty schedule
schedule <- Schedule$new()
schedule$title <- "Project 3: Old Carriage House Renovation"
schedule$reference <-
  "VANHOUCKE, Mario. Integrated project management and control:
  first comes the theory, then the practice. Gent: Springer, 2014, p. 11"

# Second, add activities to it
schedule$add_activity(1, "a1" , 2)
schedule$add_activity(2, "a2" , 2)
schedule$add_activity(3, "a3" , 4)
schedule$add_activity(4, "a4" , 3)
schedule$add_activity(5, "a5" , 4)
schedule$add_activity(6, "a6" , 1)
schedule$add_activity(7, "a7" , 1)
schedule$add_activity(8, "a8" , 1)
schedule$add_activity(9, "a9" , 1)
schedule$add_activity(10, "a10", 1)
schedule$add_activity(11, "a11", 3)
schedule$add_activity(12, "a12", 2)
schedule$add_activity(13, "a13", 1)
schedule$add_activity(14, "a14", 1)
schedule$add_activity(15, "a15", 2)
schedule$add_activity(16, "a16", 1)
schedule$add_activity(17, "a17", 1)

# Finaly, add relations to it
schedule$add_relation( 1, 2)
schedule$add_relation( 2, 3)
schedule$add_relation( 3, 4)
schedule$add_relation( 4, 5)
schedule$add_relation( 5, 6)
schedule$add_relation( 6, 7)
schedule$add_relation( 6, 8)
schedule$add_relation( 6, 9)
schedule$add_relation( 7, 10)
schedule$add_relation( 8, 10)
schedule$add_relation( 9, 10)
schedule$add_relation( 10, 11)
schedule$add_relation( 10, 13)
schedule$add_relation( 11, 12)
schedule$add_relation( 12, 15)
schedule$add_relation( 13, 14)
schedule$add_relation( 14, 15)
schedule$add_relation( 15, 16)
schedule$add_relation( 16, 17)
schedule$duration
#> [1] 27
schedule$activities
#>    id name duration milestone critical ES EF LS LF total_float free_float
#> 1   1   a1        2     FALSE     TRUE  0  2  0  2           0          0
#> 2   2   a2        2     FALSE     TRUE  2  4  2  4           0          0
#> 3   3   a3        4     FALSE     TRUE  4  8  4  8           0          0
#> 4   4   a4        3     FALSE     TRUE  8 11  8 11           0          0
#> 5   5   a5        4     FALSE     TRUE 11 15 11 15           0          0
#> 6   6   a6        1     FALSE     TRUE 15 16 15 16           0          0
#> 7   7   a7        1     FALSE     TRUE 16 17 16 17           0          0
#> 8   8   a8        1     FALSE     TRUE 16 17 16 17           0          0
#> 9   9   a9        1     FALSE     TRUE 16 17 16 17           0          0
#> 10 10  a10        1     FALSE     TRUE 17 18 17 18           0          0
#> 11 11  a11        3     FALSE     TRUE 18 21 18 21           0          0
#> 12 12  a12        2     FALSE     TRUE 21 23 21 23           0          0
#> 13 13  a13        1     FALSE    FALSE 18 19 21 22           3          0
#> 14 14  a14        1     FALSE    FALSE 19 20 22 23           3          3
#> 15 15  a15        2     FALSE     TRUE 23 25 23 25           0          0
#> 16 16  a16        1     FALSE     TRUE 25 26 25 26           0          0
#> 17 17  a17        1     FALSE     TRUE 26 27 26 27           0          0
#>    progr_level regr_level topo_float
#> 1            1          1          0
#> 2            2          2          0
#> 3            3          3          0
#> 4            4          4          0
#> 5            5          5          0
#> 6            6          6          0
#> 7            7          7          0
#> 8            7          7          0
#> 9            7          7          0
#> 10           8          8          0
#> 11           9          9          0
#> 12          10         10          0
#> 13           9          9          0
#> 14          10         10          0
#> 15          11         11          0
#> 16          12         12          0
#> 17          13         13          0
schedule$relations
#>    from to type lag critical ord i_from i_to
#> 1     1  2   FS   0     TRUE   1      1    2
#> 2     2  3   FS   0     TRUE   2      2    3
#> 3     3  4   FS   0     TRUE   3      3    4
#> 4     4  5   FS   0     TRUE   4      4    5
#> 5     5  6   FS   0     TRUE   5      5    6
#> 6     6  7   FS   0     TRUE   6      6    7
#> 7     6  8   FS   0     TRUE   7      6    8
#> 8     6  9   FS   0     TRUE   8      6    9
#> 9     7 10   FS   0     TRUE   9      7   10
#> 10    8 10   FS   0     TRUE  10      8   10
#> 11    9 10   FS   0     TRUE  11      9   10
#> 12   10 11   FS   0     TRUE  12     10   11
#> 13   10 13   FS   0    FALSE  13     10   13
#> 14   11 12   FS   0     TRUE  14     11   12
#> 15   13 14   FS   0    FALSE  16     13   14
#> 16   12 15   FS   0     TRUE  15     12   15
#> 17   14 15   FS   0    FALSE  17     14   15
#> 18   15 16   FS   0     TRUE  18     15   16
#> 19   16 17   FS   0     TRUE  19     16   17

Add activities and relations together to an schedule

Add an activity to a schedule in the same time that adds relations.

Usage

Parameters:

# Create a schedule
schedule <- Schedule$new()
schedule$title <- "Fictitious Project Example"
schedule$reference <- "VANHOUCKE, Mario. Measuring time:
  improving project performance using earned value management.
  Gent: Springer, 2009, p. 18"

# Add activities and relations to it.
schedule$add_act_rel(  1, "a1" , 0, c(2,3,4))
schedule$add_act_rel(  2, "a2" , 4, c(5))
schedule$add_act_rel(  3, "a3" , 9, c(10))
schedule$add_act_rel(  4, "a4" , 1, c(6))
schedule$add_act_rel(  5, "a5" , 4, c(9))
schedule$add_act_rel(  6, "a6" , 5, c(7))
schedule$add_act_rel(  7, "a7" , 1, c(8,11))
schedule$add_act_rel(  8, "a8" , 7, c(12))
schedule$add_act_rel(  9, "a9" , 8, c(12))
schedule$add_act_rel( 10, "a10", 3, c(12))
schedule$add_act_rel( 11, "a11", 3, c(12))
schedule$add_act_rel( 12, "a12", 0)
schedule$duration
#> [1] 16
schedule$activities
#>    id name duration milestone critical ES EF LS LF total_float free_float
#> 1   1   a1        0      TRUE     TRUE  0  0  0  0           0          0
#> 2   2   a2        4     FALSE     TRUE  0  4  0  4           0          0
#> 3   3   a3        9     FALSE    FALSE  0  9  4 13           4          0
#> 4   4   a4        1     FALSE    FALSE  0  1  2  3           2          0
#> 5   5   a5        4     FALSE     TRUE  4  8  4  8           0          0
#> 6   6   a6        5     FALSE    FALSE  1  6  3  8           2          0
#> 7   7   a7        1     FALSE    FALSE  6  7  8  9           2          0
#> 8   8   a8        7     FALSE    FALSE  7 14  9 16           2          2
#> 9   9   a9        8     FALSE     TRUE  8 16  8 16           0          0
#> 10 10  a10        3     FALSE    FALSE  9 12 13 16           4          4
#> 11 11  a11        3     FALSE    FALSE  7 10 13 16           6          6
#> 12 12  a12        0      TRUE     TRUE 16 16 16 16           0          0
#>    progr_level regr_level topo_float
#> 1            1          1          0
#> 2            2          3          1
#> 3            2          4          2
#> 4            2          2          0
#> 5            3          4          1
#> 6            3          3          0
#> 7            4          4          0
#> 8            5          5          0
#> 9            4          5          1
#> 10           3          5          2
#> 11           5          5          0
#> 12           6          6          0
schedule$relations
#>    from to type lag critical ord i_from i_to
#> 1     1  2   FS   0     TRUE   1      1    2
#> 2     1  3   FS   0    FALSE   2      1    3
#> 3     1  4   FS   0    FALSE   3      1    4
#> 4     2  5   FS   0     TRUE   4      2    5
#> 5     3 10   FS   0    FALSE   9      3   10
#> 6     4  6   FS   0    FALSE   5      4    6
#> 7     5  9   FS   0     TRUE   8      5    9
#> 8    10 12   FS   0    FALSE  13     10   12
#> 9     6  7   FS   0    FALSE   6      6    7
#> 10    9 12   FS   0     TRUE  12      9   12
#> 11    7  8   FS   0    FALSE   7      7    8
#> 12    7 11   FS   0    FALSE  10      7   11
#> 13    8 12   FS   0    FALSE  11      8   12
#> 14   11 12   FS   0    FALSE  14     11   12

Create a schedule object from data frames

Make a schedule with activities and relations between activities. The method Schedule$new(activities, relations) creates an schedule object from two data frames, one containing activities lists and the other the precedence relations between activities. After creation, it is applied the Critical Path Method (CPM).

It is possible to create a empty schedule, without any activity or relation with the constructor Schedule$new(). After that, it is possible to add activity with add_activity and relation with add_relation methods.

Parameters:


# An empty schedule.
schedule <- Schedule$new()
schedule$duration
#> [1] 0
schedule$activities
#>  [1] id          name        duration    milestone   critical    ES         
#>  [7] EF          LS          LF          total_float free_float 
#> <0 rows> (or 0-length row.names)
schedule$relations
#> [1] from     to       type     lag      critical ord      i_from   i_to    
#> <0 rows> (or 0-length row.names)

# A schedule with activities and relations.
activities <- data.frame(
  id        = 1:17,
  name      = paste("a", as.character(1:17), sep=""),
  duration  = c(1,2,2,4,3,3,3,2,1,1,2,1,1,1,1,2,1)
)

relations <- data.frame(
  from = c(1, 1, 2, 2, 2, 3, 3, 3,  3,  4,  5,  6,
           7,  8,  9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15),
  to   = c(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 11, 11,
           12, 13, 14, 15, 16, 17, 16, 17, 16, 17, 16, 17, 16, 17)
)
schedule <- Schedule$new(activities, relations)
schedule$title <- "Project 1: Cost Information System"
schedule$reference <- "VANHOUCKE, Mario.
Integrated project management and control:
  first comes the theory, then the practice.
  Gent: Springer, 2014, p. 6"
schedule$duration
#> [1] 11
schedule$activities
#>    id name duration milestone critical ES EF LS LF total_float free_float
#> 1   1   a1        1     FALSE     TRUE  0  1  0  1           0          0
#> 2   2   a2        2     FALSE     TRUE  1  3  1  3           0          0
#> 3   3   a3        2     FALSE    FALSE  1  3  3  5           2          0
#> 4   4   a4        4     FALSE     TRUE  3  7  3  7           0          0
#> 5   5   a5        3     FALSE    FALSE  3  6  4  7           1          1
#> 6   6   a6        3     FALSE    FALSE  3  6  4  7           1          1
#> 7   7   a7        3     FALSE    FALSE  3  6  5  8           2          0
#> 8   8   a8        2     FALSE    FALSE  3  5  6  8           3          0
#> 9   9   a9        1     FALSE    FALSE  3  4  7  8           4          0
#> 10 10  a10        1     FALSE    FALSE  3  4  7  8           4          0
#> 11 11  a11        2     FALSE     TRUE  7  9  7  9           0          0
#> 12 12  a12        1     FALSE    FALSE  6  7  8  9           2          2
#> 13 13  a13        1     FALSE    FALSE  5  6  8  9           3          3
#> 14 14  a14        1     FALSE    FALSE  4  5  8  9           4          4
#> 15 15  a15        1     FALSE    FALSE  4  5  8  9           4          4
#> 16 16  a16        2     FALSE     TRUE  9 11  9 11           0          0
#> 17 17  a17        1     FALSE    FALSE  9 10 10 11           1          1
#>    progr_level regr_level topo_float
#> 1            1          1          0
#> 2            2          2          0
#> 3            2          2          0
#> 4            3          3          0
#> 5            3          3          0
#> 6            3          3          0
#> 7            3          3          0
#> 8            3          3          0
#> 9            3          3          0
#> 10           3          3          0
#> 11           4          4          0
#> 12           4          4          0
#> 13           4          4          0
#> 14           4          4          0
#> 15           4          4          0
#> 16           5          5          0
#> 17           5          5          0
schedule$relations
#>    from to type lag critical ord i_from i_to
#> 1     1  2   FS   0     TRUE   1      1    2
#> 2     1  3   FS   0    FALSE   2      1    3
#> 3     2  4   FS   0     TRUE   3      2    4
#> 4     2  5   FS   0    FALSE   4      2    5
#> 5     2  6   FS   0    FALSE   5      2    6
#> 6     3  7   FS   0    FALSE   6      3    7
#> 7     3  8   FS   0    FALSE   7      3    8
#> 8     3  9   FS   0    FALSE   8      3    9
#> 9     3 10   FS   0    FALSE   9      3   10
#> 10    4 11   FS   0     TRUE  10      4   11
#> 11    5 11   FS   0    FALSE  11      5   11
#> 12    6 11   FS   0    FALSE  12      6   11
#> 13    7 12   FS   0    FALSE  13      7   12
#> 14    8 13   FS   0    FALSE  14      8   13
#> 15    9 14   FS   0    FALSE  15      9   14
#> 16   10 15   FS   0    FALSE  16     10   15
#> 17   11 16   FS   0     TRUE  17     11   16
#> 18   11 17   FS   0    FALSE  18     11   17
#> 19   12 16   FS   0    FALSE  19     12   16
#> 20   12 17   FS   0    FALSE  20     12   17
#> 21   13 16   FS   0    FALSE  21     13   16
#> 22   13 17   FS   0    FALSE  22     13   17
#> 23   14 16   FS   0    FALSE  23     14   16
#> 24   14 17   FS   0    FALSE  24     14   17
#> 25   15 16   FS   0    FALSE  25     15   16
#> 26   15 17   FS   0    FALSE  26     15   17

How to get schedule information

Title, Reference and Schedule Duration

After a schedule is created, it is possible access several type of information:

# Create a schedule
schedule <- Schedule$new()
schedule$title <- "Fictitious Project Example"
schedule$reference <- "VANHOUCKE, Mario. Measuring time:
  improving project performance using earned value management.
  Gent: Springer, 2009, p. 18"

# Add activities and relations to it.
schedule$add_act_rel(  1, "a1" , 0, c(2,3,4))
schedule$add_act_rel(  2, "a2" , 4, c(5))
schedule$add_act_rel(  3, "a3" , 9, c(10))
schedule$add_act_rel(  4, "a4" , 1, c(6))
schedule$add_act_rel(  5, "a5" , 4, c(9))
schedule$add_act_rel(  6, "a6" , 5, c(7))
schedule$add_act_rel(  7, "a7" , 1, c(8,11))
schedule$add_act_rel(  8, "a8" , 7, c(12))
schedule$add_act_rel(  9, "a9" , 8, c(12))
schedule$add_act_rel( 10, "a10", 3, c(12))
schedule$add_act_rel( 11, "a11", 3, c(12))
schedule$add_act_rel( 12, "a12", 0)
schedule$title
#> [1] "Fictitious Project Example"
schedule$reference
#> [1] "VANHOUCKE, Mario. Measuring time:\n  improving project performance using earned value management.\n  Gent: Springer, 2009, p. 18"
schedule$duration
#> [1] 16

How to get activities properties

Activity Properties

There several methods about activities that you can use to get information about them. After you add activities to a schedule, you may want to know how much activities has in a schedule or when each activity is planned to start or to finish. In this section, we will explain how you can find these information.

# Create a schedule
schedule <- Schedule$new()
schedule$title <- "Fictitious Project Example"
schedule$reference <- "VANHOUCKE, Mario. Measuring time:
  improving project performance using earned value management.
  Gent: Springer, 2009, p. 18"

schedule$has_any_activity  # FALSE
#> [1] FALSE
schedule$nr_activities     # 0
#> [1] 0

# Add activities and relations to it.
schedule$add_act_rel(  1, "a1" , 0, c(2,3,4))
schedule$add_act_rel(  2, "a2" , 4, c(5))
schedule$add_act_rel(  3, "a3" , 9, c(10))
schedule$add_act_rel(  4, "a4" , 1, c(6))
schedule$add_act_rel(  5, "a5" , 4, c(9))
schedule$add_act_rel(  6, "a6" , 5, c(7))
schedule$add_act_rel(  7, "a7" , 1, c(8,11))
schedule$add_act_rel(  8, "a8" , 7, c(12))
schedule$add_act_rel(  9, "a9" , 8, c(12))
schedule$add_act_rel( 10, "a10", 3, c(12))
schedule$add_act_rel( 11, "a11", 3, c(12))
schedule$add_act_rel( 12, "a12", 0)

schedule$has_any_activity  # TRUE
#> [1] TRUE
schedule$nr_activities     # 12
#> [1] 12

schedule$get_activity(10)
#>    id name duration milestone critical ES EF LS LF total_float free_float
#> 10 10  a10        3     FALSE    FALSE  9 12 13 16           4          4
#>    progr_level regr_level topo_float
#> 10           3          5          2
schedule$activities
#>    id name duration milestone critical ES EF LS LF total_float free_float
#> 1   1   a1        0      TRUE     TRUE  0  0  0  0           0          0
#> 2   2   a2        4     FALSE     TRUE  0  4  0  4           0          0
#> 3   3   a3        9     FALSE    FALSE  0  9  4 13           4          0
#> 4   4   a4        1     FALSE    FALSE  0  1  2  3           2          0
#> 5   5   a5        4     FALSE     TRUE  4  8  4  8           0          0
#> 6   6   a6        5     FALSE    FALSE  1  6  3  8           2          0
#> 7   7   a7        1     FALSE    FALSE  6  7  8  9           2          0
#> 8   8   a8        7     FALSE    FALSE  7 14  9 16           2          2
#> 9   9   a9        8     FALSE     TRUE  8 16  8 16           0          0
#> 10 10  a10        3     FALSE    FALSE  9 12 13 16           4          4
#> 11 11  a11        3     FALSE    FALSE  7 10 13 16           6          6
#> 12 12  a12        0      TRUE     TRUE 16 16 16 16           0          0
#>    progr_level regr_level topo_float
#> 1            1          1          0
#> 2            2          3          1
#> 3            2          4          2
#> 4            2          2          0
#> 5            3          4          1
#> 6            3          3          0
#> 7            4          4          0
#> 8            5          5          0
#> 9            4          5          1
#> 10           3          5          2
#> 11           5          5          0
#> 12           6          6          0

Gantt Matrix

Create a matrix that represents a Gantt chart, a matrix where “1” indicate that an activity is planned to be in execution.

In this matrix, the rows represents activities, Whereas the columns represents the activity execution period. So, the number of columns is equal to project duration.

activities <- data.frame(
  id        = c( 1,   2,   3,   4 ),
  name      = c("A", "B", "C", "D"),
  duration  = c( 2,   3,   1,   2 )
)
relations <- data.frame(
  from = c(1, 2, 4, 4),
  to   = c(3, 3, 1, 2)
)
schedule <- Schedule$new(activities, relations)
schedule$title <- "A project"
schedule$reference <- "From criticalpath"
gantt <- schedule$gantt_matrix()
gantt
#>   1 2 3 4 5 6
#> 1 0 0 1 1 0 0
#> 2 0 0 1 1 1 0
#> 3 0 0 0 0 0 1
#> 4 1 1 0 0 0 0
#> attr(,"class")
#> [1] "Gantt"  "matrix" "array"
# What is the effort by time period?
colSums(gantt) # 1 1 2 2 1 1
#> 1 2 3 4 5 6 
#> 1 1 2 2 1 1
# What is the duration by activities?
rowSums(gantt) # 2 3 1 2
#> 1 2 3 4 
#> 2 3 1 2
# what is the S curve
cumsum(colSums(gantt))
#> 1 2 3 4 5 6 
#> 1 2 4 6 7 8
plot(cumsum(colSums(gantt)), type="l", lwd=3)

xyw <- schedule$xy_gantt_matrix()
xyw
#>      [,1] [,2] [,3]
#> [1,]    2    1    1
#> [2,]    3    1    1
#> [3,]    2    2    1
#> [4,]    3    2    1
#> [5,]    4    2    1
#> [6,]    5    3    1
#> [7,]    0    4    1
#> [8,]    1    4    1
plot(xyw[, 1:2])

How to change activities duration

Change Activities Duration

Change activities duration and calculate critical path. This way is faster than creating a new schedule with new durations. new_durations A vector with new activities’ duration.

Attention: The vector duration must be ordered by activity id.

activities <- data.frame(
  id        = 1:17,
  name      = paste("a", as.character(1:17), sep=""),
  duration  = c(1,1,3,2, 2,2,2,1, 4,5,3,3, 4,5,1,5,2)
)

relations <- data.frame(
  from = c(1, 2, 3, 3, 4, 5, 6, 7, 8,  8,  8,
    8,  8,  9, 10, 11, 12, 13, 13, 14, 14, 15, 15),
  to   = c(2, 3, 4, 6, 5, 8, 7, 8, 9, 10, 11,
   12, 13, 14, 14, 14, 14, 14, 15, 16, 17, 16, 17)
)

schedule <- Schedule$new(activities, relations)
schedule$title <- "Project 2: Patient Transport System"
schedule$reference <-
  "VANHOUCKE, Mario. Integrated project management and control:
  first comes the theory, then the practice. Gent: Springer, 2014, p. 9"
#Project duration
schedule$duration # 25
#> [1] 25
#Activities duration
schedule$activities$duration
#>  [1] 1 1 3 2 2 2 2 1 4 5 3 3 4 5 1 5 2

new_durations <- c(1,2,5, 4,3, 2,1, 5, 3,5,5,3,4, 2,1, 2,4)
schedule$change_durations(new_durations)

#Project duration
schedule$duration # 31
#> [1] 31
#Activities duration
schedule$activities$duration
#>  [1] 1 2 5 4 3 2 1 5 3 5 5 3 4 2 1 2 4

How to get relations properties

Relation Properties

There several methods about relations that you can use to get information about them. After you add activities and relations to a schedule, you may want to know how much relations has in a schedule or which relations belong to critical path. In this section, we will explain how you can find these information.

# Create a schedule
schedule <- Schedule$new()
schedule$title <- "Fictitious Project Example"
schedule$reference <- "VANHOUCKE, Mario. Measuring time:
  improving project performance using earned value management.
  Gent: Springer, 2009, p. 18"

schedule$has_any_relation  # FALSE
#> [1] FALSE
schedule$nr_relations      # 0
#> [1] 0

# Add activities and relations to it.
schedule$add_act_rel(  1, "a1" , 0, c(2,3,4))
schedule$add_act_rel(  2, "a2" , 4, c(5))
schedule$add_act_rel(  3, "a3" , 9, c(10))
schedule$add_act_rel(  4, "a4" , 1, c(6))
schedule$add_act_rel(  5, "a5" , 4, c(9))
schedule$add_act_rel(  6, "a6" , 5, c(7))
schedule$add_act_rel(  7, "a7" , 1, c(8,11))
schedule$add_act_rel(  8, "a8" , 7, c(12))
schedule$add_act_rel(  9, "a9" , 8, c(12))
schedule$add_act_rel( 10, "a10", 3, c(12))
schedule$add_act_rel( 11, "a11", 3, c(12))
schedule$add_act_rel( 12, "a12", 0)

schedule$has_any_relation  # TRUE
#> [1] TRUE
schedule$nr_relations      # 14
#> [1] 14

schedule$relations
#>    from to type lag critical ord i_from i_to
#> 1     1  2   FS   0     TRUE   1      1    2
#> 2     1  3   FS   0    FALSE   2      1    3
#> 3     1  4   FS   0    FALSE   3      1    4
#> 4     2  5   FS   0     TRUE   4      2    5
#> 5     3 10   FS   0    FALSE   9      3   10
#> 6     4  6   FS   0    FALSE   5      4    6
#> 7     5  9   FS   0     TRUE   8      5    9
#> 8    10 12   FS   0    FALSE  13     10   12
#> 9     6  7   FS   0    FALSE   6      6    7
#> 10    9 12   FS   0     TRUE  12      9   12
#> 11    7  8   FS   0    FALSE   7      7    8
#> 12    7 11   FS   0    FALSE  10      7   11
#> 13    8 12   FS   0    FALSE  11      8   12
#> 14   11 12   FS   0    FALSE  14     11   12

Successors and Predecessors

A schedule is structured by activities and each activity has zero, one or more successors and predecessors. Besides, a relation may be redundant.

# Create a schedule
schedule <- Schedule$new()
schedule$title <- "Fictitious Project Example"
schedule$reference <- "VANHOUCKE, Mario. Measuring time:
  improving project performance using earned value management.
  Gent: Springer, 2009, p. 18"

# Add activities and relations to it.
schedule$add_act_rel(  2, "a2" , 4, c(5, 12))
schedule$add_act_rel(  3, "a3" , 9, c(10))
schedule$add_act_rel(  4, "a4" , 1, c(6))
schedule$add_act_rel(  5, "a5" , 4, c(9))
schedule$add_act_rel(  6, "a6" , 5, c(7))
schedule$add_act_rel(  7, "a7" , 1, c(8,11))
schedule$add_act_rel(  8, "a8" , 7, c(12))
schedule$add_act_rel(  9, "a9" , 8, c(12))
schedule$add_act_rel( 10, "a10", 3, c(12))
schedule$add_act_rel( 11, "a11", 3, c(12))
schedule$add_act_rel( 12, "a12", 0)

schedule$all_successors(2) # 5, 9, 12
#> [1]  5  9 12
schedule$all_successors(7) # 8, 11, 12
#> [1]  8 11 12
schedule$all_successors(10) # 12
#> [1] 12

schedule$all_predecessors(2) # nothing
#> numeric(0)
schedule$all_predecessors(7) # 6, 4
#> [1] 6 4
schedule$all_predecessors(10) # 3
#> [1] 3

schedule$is_redundant(2, 5)  #FALSE
#> [1] FALSE
schedule$is_redundant(2, 12) #TRUE
#> [1] TRUE

How to get topological properties

Topological Indicators

Shows information about network structure. It may be of four type:

SP Serial or Parallel: It shows the closeness of a network to a serial or parallel graph. As the network becomes serial, the SP increase, until one, when the network totally serial. - Usage: Schedule$topoi_sp()

AD Activity Distribution: Measures the distribution of the activities over the levels. If AD is approximately equal zero, each level has same numbers of activities. Otherwise, if AD is equal one, the quantity of each level is not uniformly distributed. - Usage: Schedule$topoi_ad()

LA Length of Arcs: Measures the presence of long arcs based on the difference between the progressive level of the end activity and the start node of each relation. If LA is approximately equal zero, the progressive level between activities are as far as possible. Otherwise, if LA is equal one, the relation distance are one. - Usage: Schedule$topoi_la()

TF Topological Float Indicator: Measures the topological float of each activity. If TF = 0, there is no float between activities. If TF = 1, there is float between activities and they be shift without affecting other activities. - Usage: Schedule$topoi_tf()

# Create a schedule
schedule <- Schedule$new()
schedule$title <- "Fictitious Project Example"
schedule$reference <- "VANHOUCKE, Mario. Measuring time:
  improving project performance using earned value management.
  Gent: Springer, 2009, p. 18"

# Add activities and relations to it.
schedule$add_act_rel(  1, "a1" , 0, c(2,3,4))
schedule$add_act_rel(  2, "a2" , 4, c(5))
schedule$add_act_rel(  3, "a3" , 9, c(10))
schedule$add_act_rel(  4, "a4" , 1, c(6))
schedule$add_act_rel(  5, "a5" , 4, c(9))
schedule$add_act_rel(  6, "a6" , 5, c(7))
schedule$add_act_rel(  7, "a7" , 1, c(8,11))
schedule$add_act_rel(  8, "a8" , 7, c(12))
schedule$add_act_rel(  9, "a9" , 8, c(12))
schedule$add_act_rel( 10, "a10", 3, c(12))
schedule$add_act_rel( 11, "a11", 3, c(12))
schedule$add_act_rel( 12, "a12", 0)

schedule$topoi_sp()
#> [1] 0.4545455
schedule$topoi_ad()
#> [1] 0.4
schedule$topoi_la()
#> [1] 0.07692308
schedule$topoi_tf()
#> [1] 0.2333333

References

Csardi, G. & Nepusz, T. (2005). The Igraph Software Package for Complex Network Research. InterJournal. Complex Systems. 1695.

Project Management Institute (2017) A Guide to the Project Management Body of Knowledge (PMBOK Guide). Sixth Edition.

Project Management Institute (2017) PMI Lexicon of Project Management Terms: Version 3.2.

Vanhoucke, M. (2009) Measuring Time: Improving Project Performance Using Earned Value Management. Springer-Verlag US.

Vanhoucke, M. (2013) Project Management with Dynamic Scheduling: Baseline Scheduling, Risk Analysis and Project Control. Springer-Verlag Berlin Heidelberg.

Vanhoucke, M. (2014) Integrated Project Management and Control: First Comes the Theory, then the Practice. Springer International Publishing Switzerland.