Phantom Float and the Resource Critical Path

In a prior article, we explored how to develop a resource-feasible schedule, one in which resources are not over allocated.  The process for leveling is straight forward and the use of various leveling heuristics guarantees that scheduling software like MS Project can find a solution quickly, even though the result might not be optimal.   However, resource-constrained scheduling (RCS) has a troublesome side-effect:  phantom float.  Further, the length of the leveled schedule may be driven not by one or more logical critical paths, but by one or more resource critical paths (RCP’s).  These resource critical paths are a byproduct of the leveling, as well.   We will take a look at both of these phenomena in this article.   

We will continue to use the exercise that we leveled in the prior article.  However, instead of using the Standard leveling order in MS Project, we will use the ID only leveling rule, for variety.   Figure 1 shows the Leveling Options dialog.  In order to simplify the exercise, we continue to avoid task preemption and the adjustment of initial assignment units.  Figure 2 shows the MS Project 2016 leveled schedule.  It is 26 days in length.  As we found in the first article, the MS Project solution is not a non-delay schedule.  A manual, hand-leveled schedule using only the ID rule is presented in Figure 3.  It is 26 days in length, also.  But, through inspection of the hand-leveled schedule, we see that task d was assigned on day 1, which means that resource r was not left idle at that time, as it was in the MS Project leveling.


Figure 1 MSP ID Only Leveling Options Dialog

Figure 1.  MS Project ID Only Leveling Options dialog


Figure 2 MSP ID Only

Figure 2. MS Project ID Only Leveling Solution


Figure 3 Manual ID Only

Figure 3. Manual Hand-Leveled ID Only Solution


There is nothing wrong with the MS Project leveling.  Both schedules are resource-feasible.  The manual, hand-leveled solution used the ID only heuristic, but ensured that tasks were scheduled whenever a resource was available.  This difference, as noted in the prior article, is likely the result of the algorithm and set of heuristics that MS Project uses.  We do not know what these are, but they compel MS Project to find a different, viable solution.  We will compare and contrast these two schedules.  But, before we do, let’s define phantom float.


Phantom Float

Total Slack and Free Slack fields are shown in Figures 2 and 3.  In Figure 3, we see that the critical path tasks x, y and z have no Total Slack and no Free Slack.  The non-critical tasks have float to varying extents.  However, in a leveled schedule, total float calculations may be incorrect since resource constraints are not considered in Critical Path Method (CPM) calculations.  Resource-constrained float takes both logic and resource constraints into account.  Phantom float is the difference between CPM total float and resource-constrained total float.  This means that some non-critical tasks may not have as much float as MS Project calculates.  This can lead to misunderstandings, at best, and unanticipated schedule blockage and costly penalties, at worst.

There is a simple test for phantom float.  For any non-critical task in a resource leveled schedule, delay its start date up to the stated number of total float days. Alternatively, increase the task’s duration up to the stated number of total float days. If a resource over allocation occurs or the project duration is extended, phantom float exists for that task.  For example, in Figure 3, if we delay task b by one day, it creates an over allocation on day 7 against task x.  Clearly, task b does not have 20 days of float, it has none.  We cannot delay task b without affecting task x.  Both use resource q.  Task x is resource dependent upon b.  Likewise, tasks c, d, and f have no float.  Task a has no float, since delaying a would delay c, which we now know has no float.  Task e does have 5 days of float.  Note that Leveling Delay is present in these leveled schedules and that such lag is taken into consideration when calculating the critical path and float.


Resource Paths and Resource Constraints

In this particular exercise, it is easy to see resource paths since there is only one resource of each type and each resource can only be assigned to one task at a time.  In Figure 2, resource p works on tasks a, f and z, in that order.  This means that task a must finish before f can start; and f must finish before z can start.  We can construct a resource path for p as <a,f,z> for q as <b,x,e>, and for r as <c,d,y>.  This gives us a set of resource constraints AR = {<a-f>,<f-z>,<b-x>,<x-e>,<c-d>,<d-y>} for this particular schedule.  The set of resource constraints for the schedule in Figure 3 is different, AR = {<a-f>,<f-z>,<b-e>,<e-x>,< d-c>,<c-y>}, since the set of resource paths in Figure 3 is different from the set of resource paths in Figure 2.  In Figure 3, the resource path for p is <a,f,z>, for q is <b,e,x>, and for r is <d,c,y>.

Resource constraints are derived from the order in which the tasks were scheduled during leveling.  Prior to leveling, we know that resource q will work on tasks b, e and x, for example.  We do not know in which order those tasks will be scheduled during leveling.  We start with a disjunctive set of unordered relationships for tasks associated with resource q, {(b,e) v (b,x) v (e,x)}.  We know that two of these relationships must hold, but we don’t know which ones.  Once we level the schedule, we know which two of the three pairs were utilized and we can glean the ordering of the task pairs.  For the schedule in Figure 2, the set of ordered resource constraints for q is {<b,x>,<x,e>}.  But, in Figure 3, the set is {<b,e>,<e,x>}.

There is a caveat.  In this simple example, there is only one unit of each resource type and a resource cannot work on more than one task at a time.  However, when there are multiple units of a resource type, there can be multiple ways to interpret how an individual resource unit “flows” from one task to another.  For one particular unit resource of a certain type, there could be multiple ways in which that resource is assigned to tasks throughout the schedule, resulting in multiple, different resource paths for that particular resource.  This could lead to a different set of resource constraints evolving for a particular resource-feasible schedule, and hence, this could lead to a different set of paths and float calculations for that schedule.  For any particular resource-feasible schedule, there could be multiple, different sets of resource constraints that explain how resources could be assigned during leveling.  This ambiguity is one reason the RCS problem is hard to solve, especially when trying to identify resource critical paths and correct float calculations.


Resolving Phantom Float

CPM scheduling is based on calculating path lengths over an acyclic digraph G = (N, A), consisting of the set of nodes N and the set of logical dependencies A.  If we incorporate resource dependencies, the digraph becomes G = ( N, A  AR ), with transitive (redundant) dependencies removed.  According to Bowers (1995; 2000), adding resource constraints to the network logic rectifies phantom float and allows the identification of Resource Critical Paths (RCP’s).  So, for the schedules above, if we add the shared set of logical constraints, A = {<a-c>,<d-e>,<d-f>,<x-y>,<y-z>}, and either set of resource constraints, AR defined above, we will able to use CPM to compute correct floats and to identify resource critical paths.


MS Project Implementation

How might we implement this in MS Project?  MS Project does not have the capability to differentiate between logic and resource dependencies.  Further, we know that resource constraints are ephemeral.  Whereas logical constraints are permanent, resource constraints might change as a schedule is executed. Resource leveling is an ongoing process during project execution and tracking; it is not a one-time planning process.  Resource constraints are dependent upon the order in which tasks were leveled.   We clearly see that the set of resource constraints are different between the two leveled schedules in Figures 2 and 3, and this will lead to different resource-critical paths and float calculations.

Ben Howard (2014), in his MPUG article “Hard and Soft Dependencies,” shares macros that insert and delete soft dependencies.  This is a way to define and use resource dependencies without altering the underlying logical dependencies in the schedule.  Using the MS Project ID Only schedule from Figure 2, Figure 4 shows the insertion of resource constraints.  Whereas Ben Howard’s original macros used Unique Predecessor ID’s, this implementation used Unique Successor ID’s.  When the Add Resource Constraint macro is invoked from the ribbon, it adds resource constraint successors to the Successor field.  The Remove Resource Constraint macro removes the resource constraints from the Successor field.


Figure 4 MSP ID Only with Macros

Figure 4.  Macro insertion of resource constraints into the MS Project ID only leveled schedule


Resource Critical Paths

Figure 5 shows the MS Project leveling (from Figure 2) and Figure 6 shows the manual hand-leveled solution (from Figure 3), with the respective set of resource constraints added to the set of logical constraints for each schedule.  Float calculations are correct and the resource critical paths identified.  Both schedules share the set of logical constraints, A = {<a-c>,<d-e>,<d-f>,<x-y>,<y-z>}.  But, the schedule in Figure 5 adds this set of resource constraints, AR = {<a-f>,<f-z>,<b-x>,<x-e>,<c-d>,<d-y>} and the schedule in Figure 6 adds a different set of constraints, AR = {<a-f>,<f-z>,<b-e>,<e-x>,< d-c>,<c-y>}, as explained above.


Figure 5 MSP ID Only with RCs

Figure 5.  MS Project ID only leveling with resource constraints added


Figure 6 Manual ID Only with RCs

Figure 6. Manual hand-leveled ID only leveling with resource constraints added


In Figures 2 and 3, path <x,y,z> is critical, although the path has a different vector of start times in each schedule.  The set of paths through both of these schedules, {<a,c>,<b>,<d,e>,<d,f>, and <x,y,z>},  is determined by the set of logical constraints.  However, in Figure 5, with resource constraints added, the set of paths through the network is {<a,d,c,e>,<a,d,c,f,z>,<a,c,d,y,z>,<b,x,e>,<b,x,y,z>}.  Paths <a,d,c,f,z> and <a,c,d,y,z> are critical .  Note that task x is not critical in this schedule.  In Figure 6, the set of paths is {<a,c,y,z>,<a,f,z>,<d,f,z>,<b,e,x,y,z>,<d,e,y,z>,<d,e,x,y,z>}.  Paths <b,e,x,y,z> and <d,e,x,y,z> are critical.  In Figures 5 and 6, the critical paths are resource critical paths.

In the schedules with resource constraints, there is no Leveling Delay (lag).  Note that in the Figures 2 and 3, Leveling Delay masked the resource critical paths and made the critical path appear to be discontinuous, even though it is not. Lag is part of the critical path calculation.  In the schedules with resource constraints, Figures 5 and 6, the resource critical paths are simply the critical paths and no lag is involved.



Once a set of resource constraints for a leveled schedule has been determined, it is easy to add the set of resource constraints to the set of logical constraints and compute a schedule using critical path method (CPM).  This schedule will have correct float calculations and resource critical paths can be identified.   We removed phantom float errors by incorporating resource constraints into the network logic.  This enables us to clearly see which tasks are both time- and resource-critical.  Further, we showed how macros can be used in MS Project to add or remove resource constraints from the network logic.

However, we considered an extremely simple example. There was only one unit of each resource type and a resource could not work on more than one task at a time.  As mentioned in the caveat above, whenever you have more than one unit of any resource type, there is a possibility that multiple, different sets of resource constraints exist that would explain a particular resource-feasible schedule.  This would yield different sets of resource paths for the same schedule, and possibly a different resource critical path, or paths.  This ambiguity makes it difficult to resolve phantom float and to identify RCP’s in a definitive way for some schedules.



Bowers, J. A. 1995. “Criticality in Resource Constrained Networks.” Journal of Operations Research Society, 46(1): 80-91.

Bowers, J. A. 2000. “Multiple Schedules and Measures of Resource Constrained Float.” Journal of Operations Research Society, 51(7): 855-862.

Howard, Ben.  2014. “Hard and Soft Dependencies.”  Microsoft Project Users’ Group (MPUG).  (retrieved 18 January 2018)


© Nicklas, Inc. and, 2018.  All rights reserved.  Unauthorized use and/or duplication of this material without express and written permission from this site’s author and/or owner is strictly prohibited.