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.
}
...
}
(以及获取/操作它们的方法) 该图本身由一系列任务表示。
我可以使用哪种概念/算法来做到这一点?
答案 0 :(得分:1)
假设您的意思是,如果图形中从v
到u
处有一个弧,则必须先完成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.]
为方便起见,1
和N
在项目的开头和结尾分别是虚拟活动,活动时间为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
可以严格证明,列表调度算法将完成最后一个任务的时间T'最多为T * + P,其中T *为最佳时间,P为关键路径的权重。因此,如果关键路径上的任务占总数的一小部分,则该算法将运行良好。