You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无重叠合并多场景公共任务的Java实现算法咨询

多任务链路公共任务去重合并实现方案

需求说明

现有多组有固定执行顺序的任务链路,需合并公共任务实现仅执行一次,合并规则要求新增公共任务不能与已合并的作业范围产生重叠,避免逻辑冲突。

可选算法方案

采用公共任务匹配+区间重叠校验的组合方案即可覆盖需求,复杂多依赖场景可扩展使用DAG拓扑排序优化:

1. 预处理阶段

为每个任务生成唯一标识,规则为任务类型ID + 入参哈希值,仅逻辑完全一致的任务会被判定为可合并的公共任务,避免同名不同逻辑的任务被错误合并。

2. 公共任务筛选

遍历所有输入链路,提取在所有链路中都存在、且相对执行顺序完全一致的任务,作为待合并的候选公共任务集合。

3. 重叠校验与合并

  • 初始化集合记录所有已合并任务在各链路中的位置区间
  • 遍历候选公共任务,校验该任务在各链路中的位置是否与已合并区间重叠,若重叠直接跳过,若不重叠则标记为全局公共任务,将对应位置加入已合并区间集合

4. 生成最终执行链路

保留原始链路的执行顺序,将重复的公共任务替换为全局执行结果引用,非公共任务保留原执行逻辑,得到最终无重复执行的合并链路。

Java实现示例

import lombok.Data;
import java.util.*;
import java.util.stream.Collectors;

// 任务实体定义
@Data
class Task {
    // 唯一标识:任务ID+入参哈希,确保相同逻辑的任务标识一致
    private String uniqueId;
    private String taskName;
    // 任务在所属链路中的位置索引
    private int position;
}

// 任务合并工具类
public class TaskMergeHelper {
    /**
     * 合并多组任务链路,去重公共不重叠任务
     * @param taskChains 输入的多组任务链路
     * @return 合并后的最终执行链路
     */
    public List<Task> mergeTaskChains(List<List<Task>> taskChains) {
        if (taskChains == null || taskChains.isEmpty()) {
            return Collections.emptyList();
        }
        // 提取所有链路的公共任务ID集合
        Set<String> commonTaskIds = getCommonTaskUniqueIds(taskChains);
        // 记录已合并的任务位置集合,用于重叠校验
        Set<Integer> mergedPositions = new HashSet<>();
        List<Task> mergedResult = new ArrayList<>();
        // 以第一条链路为基准遍历生成合并结果
        for (Task baseTask : taskChains.get(0)) {
            String taskId = baseTask.getUniqueId();
            // 非公共任务直接加入结果
            if (!commonTaskIds.contains(taskId)) {
                mergedResult.add(baseTask);
                continue;
            }
            // 校验当前任务是否和已合并区间重叠
            boolean isOverlap = checkTaskOverlap(taskId, taskChains, mergedPositions);
            if (!isOverlap) {
                mergedResult.add(baseTask);
                // 将该任务在所有链路中的位置标记为已合并
                markTaskPositionAsMerged(taskId, taskChains, mergedPositions);
            }
        }
        return mergedResult;
    }

    private Set<String> getCommonTaskUniqueIds(List<List<Task>> taskChains) {
        Set<String> commonIds = taskChains.get(0).stream()
                .map(Task::getUniqueId)
                .collect(Collectors.toSet());
        for (int i = 1; i < taskChains.size(); i++) {
            Set<String> currentChainIds = taskChains.get(i).stream()
                    .map(Task::getUniqueId)
                    .collect(Collectors.toSet());
            commonIds.retainAll(currentChainIds);
        }
        return commonIds;
    }

    private boolean checkTaskOverlap(String taskUniqueId, List<List<Task>> taskChains, Set<Integer> mergedPositions) {
        for (List<Task> chain : taskChains) {
            Optional<Task> targetTask = chain.stream()
                    .filter(t -> taskUniqueId.equals(t.getUniqueId()))
                    .findFirst();
            if (targetTask.isPresent() && mergedPositions.contains(targetTask.get().getPosition())) {
                return true;
            }
        }
        return false;
    }

    private void markTaskPositionAsMerged(String taskUniqueId, List<List<Task>> taskChains, Set<Integer> mergedPositions) {
        for (List<Task> chain : taskChains) {
            chain.stream()
                    .filter(t -> taskUniqueId.equals(t.getUniqueId()))
                    .forEach(t -> mergedPositions.add(t.getPosition()));
        }
    }
}

注:上述代码使用lombok简化实体类代码,若项目未引入lombok,手动为Task类添加getter、setter、equals、hashCode方法即可正常运行。

扩展优化

如果任务链路存在复杂的前后依赖关系,可将任务链路转换为有向无环图(DAG),基于拓扑排序做公共节点的去重合并,能更好地保证执行顺序的正确性。

内容的提问来源于stack exchange,提问作者Anish Aravind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 20:24:00