In my recent “Is MS Project’s Leveling Optimal?” article, I covered the fact that MS Project may not produce optimally leveled schedules in terms of schedule length. The analysis showed us how well Project’s leveling performs relative to established optima. In a comment on that article, Eric Uyttewaal suggested it would be informative to explore the performance of specific leveling options within Project like task splitting and adjusting individual resource assignments. There are many options. Which one should we choose? Is one better than another?
Data and Method
The following analysis looks at the 480 schedules of the j30 sample in PSPLIB. Details of the factorial sample design can be found in the articles on the PSPLIB site. Each schedule in the sample has 30 tasks plus a start and a finish milestone. Task durations range randomly between 1 and 10 days. There are four resource types whose maximum units vary randomly with four levels of resource strength (the ratio of peak usage to capacity) and whose assignment to tasks varies randomly with four levels of resource factor (number of different resource types assigned to a task). There are three levels of network complexity, as measured by the ratio of tasks to task dependencies.
The analysis was automated using the Python programming language and the Microsoft Component Object Model (COM). The analysis was duplicated using VBA macros within the MS Project Professional 2019 client. The following VBA code snippet is an example of how leveling can be invoked within a macro:
Automatic := False, _
DelayInSlack := False, _
PeriodBasis := pjDay, _
AutoClearLeveling := True, _
LevelEntireProject := True, _
Order := pjLevelStandard, _
LevelingCanSplit := False, _
LevelIndividualAssignments := False
All := True
Several leveling options remained constant throughout the analysis. These options were: leveling done manually, leveling done outside of available slack (that is, leveling could extend the project duration), schedules leveled on a day by day basis, prior leveling data cleared before leveling, and leveling of the entire schedule.
Each schedule in the sample was leveled in eight ways as listed in the following table. The list represents combinations of three parameters: leveling order (standard and ID only), task splitting (enabled and disabled), and adjustment of individual resource assignments (enabled and disabled).
For each, the leveled schedule length was recorded for each leveling treatment, along with the unleveled schedule length. In VBA, schedule duration in days was computed as follows:
ActiveProject.Duration / 480
This takes into account that duration is stored internally as minutes in Project. The leveled schedule lengths were scaled relative to the unleveled schedule length.
The boxplots in the following figure show that standard leveling order in conjunction with task splitting and adjustment of individual resource assignments yields the best result in terms of minimizing leveled schedule length. The distribution of leveled schedule lengths for each leveling treatment has a lower bound of the unleveled schedule length (some schedules don’t need to be leveled or can be leveled within available slack). It also shows that the distributions are positively skewed.
Trade-off between Scheduling Complexity and Leveled Schedule Length
In order to minimize leveled schedule length, you might be wondering if we should use the standard leveling order in conjunction with task splitting and individual resource adjustment? There is a trade-off in schedule complexity that some project managers may not be willing to take on. The schedule complexity introduced by this type of leveling may be more onerous than accepting a longer, but less complicated, leveling method. Let’s look at the j306_2 schedule from the j30 sample.
Table 2 shows the schedule lengths for all eight leveling treatments of the j306_2 schedule. Figure 2 shows that schedule, after it has been leveled using the standard leveling order with splitting and adjustment enabled (stdsa). The leveled schedule length happens to equal the unleveled schedule length. The difference is that the unleveled schedule is not resource feasible. The 50-day leveling involves some tasks being delayed, some split, some with adjusted resource assignments, and some with all three.
Let’s look at how two tasks in the schedule were leveled. Figures 3a and 3b show the resource usage associated with Task 3 prior to and after leveling. Two of the three resource assignments were split, increasing the task duration to 13 days, not including the 7 days of total inactivity. While this leveling is perfectly feasible, as a project manager, imagine trying to manage who is working on that task on a daily basis, especially as resources leave and join the task at several different times.
If we look at the leveling of Task 30, we see that it was initially delayed by two days since Task 13 had to complete in order to free resources for Task 30. Once the task started, one resource type had its assignment split and the other had its assignment delayed, and then split. While this is feasible, it is more complicated than simply delaying the entire task without preemption and assignment adjustment.
From these two examples, we see that using the standard leveling order, in conjunction with task splitting and resource assignment adjustment, tends to complicate the schedule. So, there is a trade-off. Do we want to take on the additional scheduling complexity in order to achieve a decrease in leveled schedule length?
How Would You Explain the Leveling to your Stakeholders?
For project management students, resource leveling is one of the harder concepts to grasp. In my “Scheduling Schemes and Heuristics for Leveling” article, simple leveling without task splitting (preemption) and resource adjustment is explained. Leveling involves delaying tasks until logical constraints have been satisfied and sufficient resources are available to execute the task.
If task splitting is considered on a day by day basis, all tasks are broken up into series of one-day tasks linked together with finish-to-start task relationships. Then, all of the smaller tasks are leveled. After leveling, consecutive task segments are consolidated.
If adjusting individual resource assignments is considered, the task-oriented Gantt chart is converted into a resource Gantt chart, with each row representing a resource’s assignment to a task. That set of “tasks” is leveled and the result is converted back to a task-oriented Gantt chart.
If task splitting and resource adjustment are considered together, students’ eyes glaze over and then their heads explode into an expanse of intractability. Poof!
The methods described above are hypothetical. Without technical documentation, we do not know exactly how MS Project computes its leveling. However, the more options we choose, the more difficult it is to trace how the schedule was leveled. And hence, the harder it is to explain to others.
As mentioned in the article on optimality, it is difficult to generalize the findings in this study. First, the range of network complexity in the sample is limited and may not be fully representative. Further, the parameters that governed how schedules in the sample were created need to be validated against those of schedules we encounter in the field.
Second, without intimate knowledge of the MS Project leveling algorithms, it is not possible to explain why the differences between leveling treatments exist. As users, we do not know how a leveling was computed. Explaining differences would be conjecture. Certainly, technical documentation describing how the MS Project leveling algorithms work would be helpful.
What do you think?
How do you deal with the complexity of resource leveling? How have you used MS Project’s various leveling options? Is there one set of options you prefer to another? Have you ever had to explain how a schedule was leveled?
Please share your experience and insight by contributing a comment below.