【发布时间】:2021-04-30 17:12:08
【问题描述】:
我有一个任务类,它在执行之前依赖于其他任务。我想对可以并行化的任务进行分组并对其进行排序。我决定它可以首先表示为 DAG 并尝试使用 JGrapht。 首先,我遍历任务的输入列表以获取所有任务及其依赖项并将它们收集到一个列表中。 然后对于每个任务,我在图中创建一个顶点。
DirectedAcyclicGraph<Task, DefaultEdge> d = new DirectedAcyclicGraph<>(DefaultEdge.class);
Set<Task> all = collectAllTasks(tasks);
all.forEach(d::addVertex);
然后我尝试使用相同的列表在节点之间创建边。
all.forEach(task -> {
Set<TaskName> predecessors = task.getPredecessors();
predecessors.forEach(name -> {
Task predecessor = taskService.getTaskByName(name);
d.addEdge(predecessor, task);
});
});
然后我正在尝试对任务进行分组
private Set<Set<TaskId>> groupTasks(DirectedAcyclicGraph<TaskId, DefaultEdge> dag) {
Set<Set<TaskId>> groups = new LinkedHashSet<>();
Iterator<TaskId> iterator = new TopologicalOrderIterator<>(dag);
iterator.forEachRemaining(taskId -> {
//source?
if (dag.incomingEdgesOf(taskId).isEmpty()) {
if (groups.isEmpty()) {
Set<TaskId> set = new HashSet<>();
set.add(taskId);
groups.add(set);
} else {
groups.iterator().next().add(taskId);
}
}
Set<TaskId> tasks = new HashSet<>(Graphs.successorListOf(dag, taskId));
//sink?
if (tasks.isEmpty()) {
return;
}
groups.add(featuresGroup);
});
return groups;
}
所以结果是有序和分组的任务,例如图形
结果将是A, B, {C, D}, E.
但是,当B 也是E 的前身时,它完全打破了这个例子
我怎样才能像以前一样为图形实现A, B, {C, D}, E 的顺序?
有没有我可以查看的特定算法或如何以更好的方式实现它?谢谢。
【问题讨论】:
-
和这个stackoverflow.com/questions/67265652/…很像,请看一下
-
考虑使标题更具描述性。类似于:“使用拓扑排序在有向无环依赖图中对并发处理进行分组任务”。这样,其他用户更容易找到您的问题。
标签: java algorithm graph jgrapht