Skip to content

[Feature Request]: Add PERT (Program Evaluation and Review Technique) support with optimistic, pessimistic, and most-likely duration inputs #80

Description

@prince-pokharna

Summary

The library is named networkdiagram and the README explicitly mentions CPM/PERT in its title and description. However, the current implementation only supports CPM (Critical Path Method) with deterministic single-point durations. PERT — which uses three-point estimates (optimistic, most likely, pessimistic) to model uncertainty — is entirely unimplemented.

This is a significant gap for a library that presents itself as both CPM and PERT capable.

Problem

  • CriticalPathMethod is the only class available. There is no PERTNetwork class.
  • PERT duration formula t_e = (O + 4M + P) / 6 and variance σ² = ((P - O) / 6)² are not implemented anywhere.
  • Users expecting PERT functionality from the library description will find it missing with no error message — just absent functionality.
  • The visualization does not support displaying uncertainty ranges or variance on the network graph.

Impact

  • The library misleads users with its CPM/PERT branding.
  • Project managers and students using this for probabilistic scheduling have no tool support.
  • Opportunity cost: PERT support would make this library significantly more useful for real-world project management scenarios.

Proposed Solution

I would like to implement a PERTNetwork class inside networkdiagram/:

class PERTActivity:
    def __init__(self, name: str, optimistic: float, most_likely: float, pessimistic: float, predecessors: list[str]):
        self.name = name
        self.optimistic = optimistic
        self.most_likely = most_likely
        self.pessimistic = pessimistic
        self.predecessors = predecessors
        self.expected_duration = (optimistic + 4 * most_likely + pessimistic) / 6
        self.variance = ((pessimistic - optimistic) / 6) ** 2

class PERTNetwork:
    def __init__(self):
        self.activities: dict[str, PERTActivity] = {}

    def add_activity(self, name, optimistic, most_likely, pessimistic, predecessors):
        self.activities[name] = PERTActivity(name, optimistic, most_likely, pessimistic, predecessors)

    def calculate_project_variance(self, critical_path: list[str]) -> float:
        return sum(self.activities[a].variance for a in critical_path if a in self.activities)

    def calculate_probability(self, target_duration: float, critical_path_duration: float, project_variance: float) -> float:
        import math
        from scipy import stats
        z = (target_duration - critical_path_duration) / math.sqrt(project_variance)
        return stats.norm.cdf(z)

I will also add PERT examples to the README and update the visualization to optionally display variance ranges on critical path nodes. Please assign this to me.

Labels: enhancement, feature, math, help wanted, GSSoC 2026

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions