106 lines
4.5 KiB
Java
106 lines
4.5 KiB
Java
import java.util.*;
|
|
// const data = [
|
|
// { name: '任务一', beforeMask: [] },
|
|
// { name: '任务二', beforeMask: ['任务一'] },
|
|
// { name: '任务三', beforeMask: ['任务一', '任务二'] },
|
|
// { name: '任务四', beforeMask: ['任务三'] },
|
|
// { name: '任务五', beforeMask: ['任务一'] },
|
|
// { name: '任务六', beforeMask: ['任务一', '任务三'] }
|
|
// ];
|
|
public class TaskScheduler {
|
|
static class Task {
|
|
String name;
|
|
int level;
|
|
List<String> target;
|
|
int[] value;
|
|
//初始每一个任务
|
|
public Task(String name, int level, List<String> target, int[] value) {
|
|
this.name = name;
|
|
this.level = level;
|
|
this.target = target;
|
|
this.value = value;
|
|
}
|
|
}
|
|
// 存层级,任务序列
|
|
public static List<Task> getResult(List<Map<String, Object>> data) {
|
|
Map<String, Task> taskMap = new HashMap<>();
|
|
for (Map<String, Object> task : data) {
|
|
taskMap.put((String) task.get("name"), new Task((String) task.get("name"), 0, new ArrayList<>(), new int[]{0, 0}));
|
|
}
|
|
function calculateLevel(String taskName, Set<String> visited) {
|
|
// 数据不对检查
|
|
if (visited.contains(taskName)) {
|
|
throw new RuntimeException("检测到循环依赖");
|
|
}
|
|
visited.add(taskName);
|
|
Task task = taskMap.get(taskName);
|
|
List<String> beforeTasks = ((List<String>) data.stream()
|
|
.filter(t -> t.get("name").equals(taskName))
|
|
.findFirst()
|
|
.orElseThrow(() -> new RuntimeException("任务未找到"))
|
|
.get("beforeMask"));
|
|
if (beforeTasks.isEmpty()) {
|
|
task.level = 1;
|
|
} else {
|
|
int maxLevel = 0;
|
|
for (String beforeTask : beforeTasks) {
|
|
maxLevel = Math.max(maxLevel, calculateLevel(beforeTask, visited));
|
|
}
|
|
task.level = maxLevel + 1;
|
|
}
|
|
|
|
visited.remove(taskName);
|
|
return task.level;
|
|
}
|
|
for (Map<String, Object> task : data) {
|
|
calculateLevel((String) task.get("name"), new HashSet<>());
|
|
}
|
|
for (Map<String, Object> task : data) {
|
|
Task taskInfo = taskMap.get(task.get("name"));
|
|
for (Map<String, Object> otherTask : data) {
|
|
if (((List<String>) otherTask.get("beforeMask")).contains(task.get("name"))) {
|
|
taskInfo.target.add((String) otherTask.get("name"));
|
|
}
|
|
}
|
|
}
|
|
List<Task> sortedData = new ArrayList<>(taskMap.values());
|
|
sortedData.sort(Comparator.comparingInt(t -> t.level));
|
|
int currentLevel = 0;
|
|
Map<Integer, Integer> levelMap = new HashMap<>();
|
|
for (Task task : sortedData) {
|
|
if (!levelMap.containsKey(task.level)) {
|
|
levelMap.put(task.level, currentLevel++);
|
|
}
|
|
task.level = levelMap.get(task.level);
|
|
}
|
|
Map<Integer, List<String>> levelTasks = new HashMap<>();
|
|
for (Task task : sortedData) {
|
|
levelTasks.computeIfAbsent(task.level, k -> new ArrayList<>()).add(task.name);
|
|
}
|
|
for (Task task : sortedData) {
|
|
task.value[0] = task.level * 300; // 横坐标
|
|
task.value[1] = levelTasks.get(task.level).indexOf(task.name) * -300; // 纵坐标
|
|
}
|
|
List<Task> result = new ArrayList<>();
|
|
for (Task task : sortedData) {
|
|
result.add(new Task(task.name, task.level, task.target, task.value));
|
|
}
|
|
System.out.println(result);
|
|
return result;
|
|
}
|
|
public static void main(String[] args) {
|
|
List<Map<String, Object>> data = Arrays.asList(
|
|
Map.of("name", "任务一", "beforeMask", new ArrayList<>()),
|
|
Map.of("name", "任务二", "beforeMask", Collections.singletonList("任务一")),
|
|
Map.of("name", "任务三", "beforeMask", Arrays.asList("任务一", "任务二")),
|
|
Map.of("name", "任务四", "beforeMask", Collections.singletonList("任务三")),
|
|
Map.of("name", "任务五", "beforeMask", Collections.singletonList("任务一")),
|
|
Map.of("name", "任务六", "beforeMask", Arrays.asList("任务一", "任务三"))
|
|
);
|
|
List<Task> result = getResult(data);
|
|
for (Task task : result) {
|
|
System.out.println(task.name + ": " + task.level + ", " + task.target + ", " + Arrays.toString(task.value));
|
|
}
|
|
}
|
|
}
|