将“并行性”引入任务调度问题

时间:2019-10-01 12:08:30

标签: algorithm graph

qoutes中的并行性,因为我实际上并不是在指并行编程(线程/分叉等)

当前正在处理依赖图问题,其中给出了DAG(有向无环图),其中每个顶点表示必须完成的任务,以及从一个顶点 v 到另一个顶点 u 表示必须先完成 v ,然后才能完成 u 。每个任务需要一定的时间才能完成。

示例: dependency graph

(这只是一个例子,程序应该能够解决任何DAG问题)

使用拓扑排序,如果一次完成一项任务,我发现有多个命令可以完成所有任务。但是,我有兴趣介绍一下可以同时启动和/或处理多个任务的想法。我假设“人力”是无限的,这意味着可以同时处理任意数量的任务。我想找到一种在最快的时间内完成项目中所有任务的方法。

我的task(vertex)类具有以下变量(Java):

class Task{
    int id, time;
    String name;
    List<Task> outEdges;
    List<Task> inEdges;
    boolean isFinished;
    Task(int id, String name, int time){
        this.id = id;
        this.name = name;
        this.time = time;
        isFinished = false;
        outEdges = new ArrayList<Task>();
        inEdges = new ArrayList<Task>();
//Tasks and edges between them are generated while reading from a file.
    }
      ...
}

(以及获取/操作它们的方法) 该图本身由一系列任务表示。

我可以使用哪种概念/算法来做到这一点?

3 个答案:

答案 0 :(得分:1)

假设您的意思是,如果图形中从vu处有一个弧,则必须先完成v,然后才能启动u

当您将该图视为项目优先级图时,这只是找到最短的项目完成时间。给定节点j(任务)的活动时间为dj >= 0,让sj表示其开始时间。

然后,以下线性程序解决了您的问题

Minimize  sN [i.e., minimize the starting time of the last activity]
such that sj >= si + di , forall (i,j) in graph [i.e., ensure starting time of jth activity is after completion of ith activity if j follows i in the precedence graph]
such that all si's >= 0 [i.e., all starting times are nonnegative. Without these constraints, problem is unbounded.]

为方便起见,1N在项目的开头和结尾分别是虚拟活动,活动时间为0。 1在图中的所有其他节点之前。 N位于图中所有其他节点的后方。

答案 1 :(得分:0)

这可能取决于特定图形的结构。

如果仅需要到达一个最终节点,则可以使用诸如depth first search之类的算法来提供事件序列。一旦可用,就无法进行并行化,因为存在严格的序列依赖性。

如果需要到达多个节点(并且图形可以在合理的时间内遍历),则可以使用诸如breadth first search之类的算法来提供所需的序列。然后,说您要到达n个不同的顶点。可以通过到达所需顶点所共有的路径部分来定义新的语义图(我们称其为g2)。这意味着,新图中的每个边都将由朝向这些顶点的公共部分的串联组成。对于g2,可以并行启动所有边缘。

免责声明:以上不是经过严格验证的算法,仅是一种实现思路。

答案 2 :(得分:0)

我假设您还指定了K个“工人”(处理器)来完成任务。即,最多可以同时处理K个任务。显然,完成所有任务所需的时间将取决于K。

此问题称为优先约束调度。

如果辅助程序K的数量大于或等于任务N的数量,则Tryer概述的解决方案是正确的:依赖项DAG中最重路径的权重将为您提供所需的时间。 (最重的路径有时称为关键路径,可以使用特定的最短路径算法在线性时间内进行计算。)

如果K = 1,正如您已经注意到的,您只需要遵循拓扑顺序即可,所需时间将是任务时间的总和。

不幸的是,在1 list调度算法来获得近似最佳的解决方案。列表调度的思想非常简单。在算法的每个步骤中,您都要遍历所有K个工作者。对于它们中的任何一个,您可以分配一个未分配的任务,该任务可用并且依赖关系已经得到满足。然后,将该任务标记为已分配,然后继续。在所有工作人员忙碌或无法分配其他任务后,您可以等待一些任务完成,然后像以前一样恢复算法。

可以严格证明,列表调度算法将完成最后一个任务的时间T'最多为T * + P,其中T *为最佳时间,P为关键路径的权重。因此,如果关键路径上的任务占总数的一小部分,则该算法将运行良好。