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

TimeFold AI调度:如何让序列末尾无法调度的任务留空?

基于TimeFold的任务调度末尾未分配实现方案

一、核心模型调整

1. 新增任务序列序号字段

给Schedule规划实体添加固定的任务序号字段taskOrder,用来明确任务的业务序列顺序(如1到N),该字段为非规划变量,初始化时按业务要求的序列顺序赋值:

public class Schedule {
    // 任务序列序号,1到N,固定值,初始化时赋值
    private Integer taskOrder;

    @PlanningVariable(allowsUnassigned = true, valueRangeProviderRefs = "userRange")
    private User user;

    @PlanningVariable(allowsUnassigned = true, valueRangeProviderRefs = "timeRange")
    private OffsetDateTime start;

    @ShadowVariable(sourceVariableName = "start", variableListenerClass = EndTimeListener.class)
    private OffsetDateTime end;

    // 依赖的前置任务
    private Schedule dependency;

    // Getter、Setter方法
}

2. 规划变量配置

保持allowsUnassigned=true,允许任务未分配,但通过后续约束限制未分配任务的位置。

二、约束规则设计

1. 硬约束:强制未分配任务为连续末尾序列

这是实现需求的核心约束,确保只要有任务未分配,所有序号更大的任务必须同样未分配,禁止中间任务留空:

constraintFactory.from(Schedule.class)
    // 筛选未分配任务(user或start为null)
    .filter(task -> task.getUser() == null || task.getStart() == null)
    // 关联序号更大的任务
    .join(Schedule.class, Joiners.greaterThan(Schedule::getTaskOrder))
    // 若更大序号的任务已分配,则违反硬约束
    .filter((unassignedTask, laterTask) -> laterTask.getUser() != null && laterTask.getStart() != null)
    .penalize("禁止中间任务未分配", HardSoftScore.ONE_HARD)
    .asConstraint();

2. 调整依赖约束

仅对已分配的任务对生效,避免未分配任务干扰依赖检查:

constraintFactory.from(Schedule.class)
    .filter(task -> task.getDependency() != null 
        // 当前任务已分配
        && task.getUser() != null && task.getStart() != null
        // 依赖任务必然已分配(因依赖任务序号更小,受上述硬约束限制)
        && task.getDependency().getEnd() != null)
    // 检查当前任务起始时间是否晚于依赖任务结束时间
    .filter(task -> task.getStart().isBefore(task.getDependency().getEnd()))
    .penalize("依赖任务未完成不能开始", HardSoftScore.ONE_HARD)
    .asConstraint();

3. 保留并适配原有硬约束

避免用户任务重叠

仅检查已分配任务:

constraintFactory.from(Schedule.class)
    .filter(task -> task.getUser() != null && task.getStart() != null)
    .join(Schedule.class, 
        Joiners.equal(Schedule::getUser),
        Joiners.overlapping(Schedule::getStart, Schedule::getEnd))
    // 避免重复检查同一任务对
    .filter((task1, task2) -> task1.getTaskOrder() < task2.getTaskOrder())
    .penalize("用户任务时间重叠", HardSoftScore.ONE_HARD)
    .asConstraint();

角色兼容约束

仅检查已分配任务:

constraintFactory.from(Schedule.class)
    .filter(task -> task.getUser() != null && task.getStart() != null)
    .filter(task -> !task.getUser().getRoles().contains(task.getRequiredRole()))
    .penalize("用户角色不兼容", HardSoftScore.ONE_HARD)
    .asConstraint();

4. 软约束:最大化已分配任务数量

驱动求解器尽量减少未分配任务的数量:

constraintFactory.from(Schedule.class)
    .filter(task -> task.getUser() != null && task.getStart() != null)
    .reward("已分配任务奖励", HardSoftScore.ONE_SOFT)
    .asConstraint();

三、求解器配置优化

1. 自定义初始解构建器

优先给序号靠前的任务分配资源,降低求解器的搜索成本:

public class ScheduleInitialSolutionBuilder implements InitialSolutionBuilder<ScheduleSolution> {
    @Override
    public ScheduleSolution buildInitialSolution(ScheduleSolution problem, Random random) {
        List<Schedule> tasks = problem.getTaskList();
        // 按taskOrder升序排序
        tasks.sort(Comparator.comparingInt(Schedule::getTaskOrder));
        // 尝试为前序任务分配资源(可根据业务逻辑实现更智能的初始分配)
        // 示例逻辑:先全部分配,若出现冲突则移除末尾任务
        return problem;
    }
}

在@PlanningSolution中配置:

@PlanningSolution
public class ScheduleSolution {
    // 规划实体集合
    private List<Schedule> taskList;
    // 值范围提供者
    private List<User> userList;
    private List<OffsetDateTime> timeList;

    @PlanningSolver(
        initialSolutionBuilder = ScheduleInitialSolutionBuilder.class,
        termination = @Termination(secondsSpentLimit = 30)
    )
    private HardSoftScore score;

    // Getter、Setter方法
}

2. 合理设置终止条件

根据任务规模设置足够的求解时间,确保求解器能找到符合硬约束的最优解。

四、常见问题排查

  1. 依赖顺序不遵守:检查依赖约束是否仅针对已分配任务,同时确认taskOrder的赋值是否符合业务序列顺序(依赖任务的序号必须小于当前任务)。
  2. 任务起始时间重复:检查重叠约束的时间比较逻辑是否正确(OffsetDateTime的isBefore/isAfter判断是否准确)。
  3. 未分配任务非末尾:检查“禁止中间任务未分配”的硬约束是否正确,确认taskOrder的赋值无重复或顺序错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:05:20