Python 项目进度管理的关键路径的确定

系列文章目录



前言

        本站内其实有许多讲如何找关键路径的,但是我看了下几篇博客,感觉都写得好难好难,有点难以理解,比如下面是某篇博客所描述的确定关键路径的算法:

         看完后是一脸懵逼的状态。那么是否有我们工程人方便理解的算法呢,那必然是有的,详见下文。


一、算法的确定

        根据我们考建造师的学习内容,大家都知道:可以依靠总时差来确定关键路径。即关键路径上的活动的总时差是为0的。因此我们的算法就可以简单的归纳为以下四步:

1、求该项目中所有活动的最早开始时间

2、求该项目中所有活动的最晚开始时间

3、求该项目中所有活动的总时差

4、依次遍历该项目中所有活动的总时差(或最早开始时间是否等于最晚开始时间),如果总时差等于0,那么就把当前活动添加到关键路径列表中。

二、模型的建立

        首先我们确定一个研究模型,方便我们检验算法是否满足要求。这里我选择RCPLIB数据集下文件名为“mv1.rcp”的文件中的数据做参考,为了方便我们直观地理解模型,我将这个文件中的数据整理成如下字典的形式。

{
    1:{"successors":[2, 3, 4, 5],"predecessors":[],"duration":0},
    2:{"successors":[6],"predecessors":[1],"duration":2},
    3:{"successors":[10],"predecessors":[1],"duration":4},
    4:{"successors":[9],"predecessors":[1],"duration":6},
    5:{"successors":[11],"predecessors":[1],"duration":9},
    6:{"successors":[7],"predecessors":[2],"duration":8},
    7:{"successors":[8, 11],"predecessors":[6],"duration":10},
    8:{"successors":[12],"predecessors":[7],"duration":4},
    9:{"successors":[12],"predecessors":[4],"duration":3},
    10:{"successors":[12],"predecessors":[3],"duration":5},
    11:{"successors":[12],"predecessors":[5, 7],"duration":1},
    12:{"successors":[],"predecessors":[8, 9, 10, 11],"duration":0}
}

        其中,“2:{"successors":[6],"predecessors":[1],"duration":2}”代表该项目中活动序号为2的活动的紧后活动为活动6,活动序号为2的活动的紧前活动为活动1,活动序号为2的活动的工期为2。以此类推。

        这里我简单地手画一个AoN图方便我们理解:

        请大家谅解,实在懒得找画图工具画了哈哈哈哈哈

三、代码的实现

        算法很清晰,故而咱们代码也很清晰,就三个函数:calculate_early_start_time(),calculate_late_start_time(),find_critical_path()。顾名思义,即找最早开始时间的函数,找最晚开始时间的函数,和找寻关键路径的函数。代码如下:

def calculate_early_start_time(project):
    """
    计算各个活动的最早开始时间(Early Start Time),返回一个字典。
    """
    early_start_time = {1: 0}
    for i in range(2, len(project)+1):
        predecessors = project[i]["predecessors"]
        max_time = max([early_start_time[p] + project[p]["duration"] for p in predecessors])
        early_start_time[i] = max_time
    return early_start_time

def calculate_late_start_time(project, early_start_time):
    """
    计算各个活动的最晚开始时间(Late Start Time),返回一个字典。
    """
    late_start_time = {}
    max_time = max(early_start_time.values())
    late_start_time[12] = max_time
    for i in range(len(project)-1, 0, -1):
        successors = project[i]["successors"]
        min_time = min([late_start_time[s] - project[i]["duration"] for s in successors])
        late_start_time[i] = min_time
    return late_start_time

def find_critical_path(project):
    """
    找到项目的关键路径,返回关键路径上的活动序号列表。
    """
    early_start_time = calculate_early_start_time(project)
    late_start_time = calculate_late_start_time(project, early_start_time)
    critical_path = []
    for i in range(1, len(project)+1):
        if early_start_time[i] == late_start_time[i]:
            critical_path.append(i)
    return critical_path

# 项目为
project = {
    1:{"successors":[2, 3, 4, 5],"predecessors":[],"duration":0},
    2:{"successors":[6],"predecessors":[1],"duration":2},
    3:{"successors":[10],"predecessors":[1],"duration":4},
    4:{"successors":[9],"predecessors":[1],"duration":6},
    5:{"successors":[11],"predecessors":[1],"duration":9},
    6:{"successors":[7],"predecessors":[2],"duration":8},
    7:{"successors":[8, 11],"predecessors":[6],"duration":10},
    8:{"successors":[12],"predecessors":[7],"duration":4},
    9:{"successors":[12],"predecessors":[4],"duration":3},
    10:{"successors":[12],"predecessors":[3],"duration":5},
    11:{"successors":[12],"predecessors":[5, 7],"duration":1},
    12:{"successors":[],"predecessors":[8, 9, 10, 11],"duration":0}
}

critical_path = find_critical_path(project)
print(critical_path)  # 输出 [1, 2, 6, 7, 8, 12]

 

总结

        就是一个对项目管理内容的基本的代码的实现。此外,我们也可以根据关键路径上的活动的工期和算出这个项目的最短工期。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伊江痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值