有依赖关系的任务安排--拓扑排序

假设某个软件工程项目包含n个功能模块。给定每个模块所需要的处理时间为 ti (1≤i≤n) 以及模块之间的依赖关系,比如模块5耗时0.3小时,且必须在模块1和3完成后方可开始处理。模块之间没有循环依赖关系。
(1)若只能顺序处理这些模块,请设计算法给出一种可行的处理顺序来完成该软件工程项目。
(2)若同一时间可以并行处理任意多的模块,请设计算法求出完成该项目的最短时间。

(1)拓扑排序,将任务之间的依赖关系构成一个有向无环图,然后通过拓扑排序获取可行的处理顺序。

算法实现(Python):

def toposort(graph):
    in_degrees = dict((u,0) for u in graph)   #初始化所有顶点入度为0
    vertex_num = len(in_degrees)
    for u in graph:
        for v in graph[u]:
            in_degrees[v] += 1       #计算每个顶点的入度
    Q = [u for u in in_degrees if in_degrees[u] == 0]   # 筛选入度为0的顶点
    Seq = []
    while Q:
        u = Q.pop()       #默认从最后一个删除
        Seq.append(u)
        for v in graph[u]:
            in_degrees[v] -= 1       #移除其所有指向
            if in_degrees[v] == 0:
                Q.append(v)          #再次筛选入度为0的顶点
    if len(Seq) == vertex_num:       
        return Seq
    else:
        print("there's a circle.")

(2)在拓扑排序的基础上添加前置条件,每个任务的最早完成时间为其最晚前置任务完成时间与自身完成任务需要时间之和,因此可以在拓扑排序的过程中动态更新节点任务完成的最早时间,最后节点中值最大的为所有任务最早完成时间。

算法实现(Python):

def toposort(graph):
    in_degrees = dict((u,0) for u in graph)   #初始化所有顶点入度为0
    vertex_num = len(in_degrees)
    time = dict((u,0) for u in graph)
    res = dict((u,0) for u in graph)
    for u in graph:
        time[u] = graph[u][0]
        res[u] = graph[u][0]
        for v in graph[u][1]:
            in_degrees[v] += 1       #计算每个顶点的入度
    Q = [u for u in in_degrees if in_degrees[u] == 0]   # 筛选入度为0的顶点
    Seq = []
    while Q:
        u = Q.pop()       #默认从最后一个删除
        Seq.append(u)
        for v in graph[u][1]:
            in_degrees[v] -= 1       #移除其所有指向
            if in_degrees[v] == 0:
                Q.append(v)          #再次筛选入度为0的顶点
            res[v] = max(res[v],res[u]+time[v])  #更新任务的完成时间
    print(time)
    if len(Seq) == vertex_num:       
        return max(res[u] for u in res)
    else:
        return -1

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值