将 DAG 分离成层序拓扑排序子图的森林
separate a DAG into a forest of level-ordered topological sorted subgraphs
我有一个 DAG,其中一条边表示两个节点之间的依赖关系,一个节点表示要在机器上执行的任务。有多台机器。对于每个(任务,机器)对,都有一个估计的运行时间。
现在,我想将这个 DAG 分成一个森林,以便森林中的每个子图代表自己一个“完整”的 DAG,并由拓扑级有序排序表示。 “完整”是指从任何根节点开始的子图具有它在原始 DAG 中的所有路径。
我得到一个无序的 List<Task> tasks
,其中 Task
是一个 class,代表 DAG 中的任务节点。每个任务都有一个包含其所有父项的列表和一个包含其所有子项的列表。
我会如何天真地去做:遍历所有节点 v,做一个 dfs 以获得以 v 为根的子图,在每次迭代中检查是否可以合并两个子图,因为它们有一个共同的父节点。
可以更快地完成吗?
使用遍历子链接和父链接的 depth-first 搜索将图表分成组件。然后你可以对每个组件进行拓扑排序。两种算法都是O(N+E)(对于N个节点和E条边);这可能是 O(N²),但对于依赖数量通常很少的典型依赖图,它可能更接近 O(N)。
我有一个 DAG,其中一条边表示两个节点之间的依赖关系,一个节点表示要在机器上执行的任务。有多台机器。对于每个(任务,机器)对,都有一个估计的运行时间。
现在,我想将这个 DAG 分成一个森林,以便森林中的每个子图代表自己一个“完整”的 DAG,并由拓扑级有序排序表示。 “完整”是指从任何根节点开始的子图具有它在原始 DAG 中的所有路径。
我得到一个无序的 List<Task> tasks
,其中 Task
是一个 class,代表 DAG 中的任务节点。每个任务都有一个包含其所有父项的列表和一个包含其所有子项的列表。
我会如何天真地去做:遍历所有节点 v,做一个 dfs 以获得以 v 为根的子图,在每次迭代中检查是否可以合并两个子图,因为它们有一个共同的父节点。
可以更快地完成吗?
使用遍历子链接和父链接的 depth-first 搜索将图表分成组件。然后你可以对每个组件进行拓扑排序。两种算法都是O(N+E)(对于N个节点和E条边);这可能是 O(N²),但对于依赖数量通常很少的典型依赖图,它可能更接近 O(N)。