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

优化Timefold课程排课项目中全局状态约束的性能

优化Timefold全局状态约束的高效写法

你当前的约束写法通过groupBy(t->0, toList())实现了“每次Lesson变更时仅计算一次全局状态影响”的需求,但冗余的分组操作确实会带来性能开销。以下是更高效的优化方案:

优化后的约束定义

直接使用ConstraintCollectors.count()作为分组收集器,无需手动指定无意义的groupKey,同时避免了创建全量Lesson列表的开销:

factory.forEach(Lesson.class)
    .groupBy(ConstraintCollectors.count())
    .impact(HardMediumSoft.ofHard(1), (count) -> GlobalState.getSingleton().getImpact())
    .asConstraint(id);

优化原理

  1. 去掉冗余groupKey:使用单参数的groupBy(Collector)会自动将所有Lesson归为单一分组,无需手动指定t->0这类无意义的分组键,彻底避免了Group1Mapping0CollectorUniNode.createGroupKey的热点调用。
  2. 轻量收集器替代:count()收集器仅统计Lesson数量,相比toList()无需创建和维护全量Lesson列表,内存占用和计算开销更低。
  3. 保持触发逻辑不变:只要任意Lesson的Timeslot规划变量变更,该约束仍会重新计算,确保全局状态的影响能实时反映到分数中。

为什么不能直接遍历GlobalState

你提到的factory.forEach(GlobalState.class).impact(...)写法无法满足需求,核心原因是:
Timefold的约束触发依赖于规划变量或问题事实的变更检测,GlobalState作为单例对象,Timefold无法感知到它是由Lesson变更间接更新的,因此不会在Lesson变更时重新计算该约束,导致分数与实际全局状态脱节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:43:21