如何为含多个规划变量的实体使用Recommended Fit API?
Timefold Recommended Fit API 问题求助
问题背景
我正在基于维护调度模板修改的Timefold项目中实现Recommended Fit API。我的规划实体Job(对应代码中的Opdracht)包含多个规划变量:Crew、startDate,还有一个影子变量endDate。当Job未初始化时,这些值均为null。
尝试用Recommended Fit API返回startDate的推荐列表时,Crew会保持null;反过来请求Crew的推荐,startDate又会是null。按照Timefold文档预期,直接返回整个实体时所有值均为null。我对规划和Java都比较陌生,希望得到帮助或解释。
solverConfig.xml 配置
<?xml version="1.0" encoding="UTF-8"?> <solver xmlns="https://timefold.ai/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://timefold.ai/xsd/solver https://timefold.ai/xsd/solver/solver.xsd"> <!-- Define the model --> <solutionClass>nl.heijmans.teamplanning.domain.Teamplanning</solutionClass> <entityClass>nl.heijmans.teamplanning.domain.Opdracht</entityClass> <!-- Define the score function --> <scoreDirectorFactory> <constraintProviderClass>nl.heijmans.teamplanning.solver.TeamplanningConstraintProvider</constraintProviderClass> </scoreDirectorFactory> <!-- Configure the optimization algorithms --> <termination> <spentLimit>PT30S</spentLimit> </termination> <constructionHeuristic> <constructionHeuristicType>FIRST_FIT</constructionHeuristicType> </constructionHeuristic> <localSearch> <!-- <localSearchType>HILL_CLIMBING</localSearchType> --> </localSearch> </solver>
Recommended Fit API 调用代码
@GET @Path("opdracht/proposition") // @Transactional public List<RecommendedFit<LocalDateTime, HardMediumSoftLongScore>> fetch(@QueryParam("id") Long id) { // Check if corresponding opdracht exists and get it Opdracht entity = opdrachtRepository.findById(id); if(entity == null) { throw new NotFoundException(); } Teamplanning solution = findById(SINGLETON_SCHEDULE_ID); List<RecommendedFit<LocalDateTime, HardMediumSoftLongScore>> recommendations = solutionManager.recommendFit(solution, entity, Opdracht::getStartDate); return recommendations; }
问题解答
原因分析
recommendFit方法的设计目标是针对单个规划变量生成推荐值,不会自动填充其他未指定的规划变量。这是因为该API的定位是为特定变量提供可选值,而非生成完整的实体分配方案。当指定Opdracht::getStartDate时,Timefold仅计算该变量的可行推荐,不会处理Crew变量,因此它保持null;反之亦然。
若直接请求整个实体的推荐(不指定变量),由于实体存在多个未初始化的规划变量,Timefold无法确定优化目标,因此返回全null结果,这符合文档描述。
解决方案
若需要同时获取Crew和startDate的组合推荐,可采用以下方案:
- 分步调用推荐API:先调用
recommendFit获取Crew的推荐列表,再针对每个推荐的Crew调用recommendFit获取对应的startDate推荐,最后组合成可行分配方案。该方式适合变量依赖较弱的场景。 - 自定义推荐逻辑:利用Timefold的
ScoreDirector手动评估不同变量组合的得分:- 从
SolutionManager获取ScoreDirector - 遍历所有可能的
Crew候选值,为每个Crew遍历可行的startDate范围 - 临时设置实体的
Crew和startDate,计算得分 - 收集得分较高的组合作为推荐结果
- 从
- 使用构造启发式生成完整分配:若需为未初始化实体生成完整可行分配,可调用
solver.solve(solution)让配置的FIRST_FIT构造启发式为实体分配所有规划变量,再从解中提取该实体的分配结果。此方式会重新优化整个解决方案,适合需要全局最优的场景。
注意事项
- 影子变量
endDate会在Crew、startDate等规划变量设置后自动计算,无需手动处理。 - 调用
recommendFit时,传入的solution需是已求解过的(至少运行过构造启发式),否则推荐的可行性和得分可能不准确。
内容的提问来源于stack exchange,提问作者zwarenelle
相关产品推荐
相关产品推荐

