Timefold构造启发式中移动选择及pickEarlyType失效问题咨询
问题:Timefold构造启发式中组合笛卡尔积与顺序移动的配置问题
我尝试在Timefold中使用Recommended fit,需要设置4个规划变量,希望在构造启发式中结合笛卡尔积(cartesian product)和顺序移动。但无论将哪个移动选择器放在首位,构造启发式只会运行第一个,其余移动选择均被忽略。目前我只能通过组合笛卡尔积选择器来设置所有4个变量,但该方式扩展性不佳。请问这是API的限制还是存在解决方法?此外,pickEarlyType似乎也被忽略,即使在结果列表中较早找到可行解,仍会返回所有可能的组合。
配置代码如下:
<scoreDirectorFactory> <constraintProviderClass>MyConstraintProvider</constraintProviderClass> <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend> </scoreDirectorFactory> <termination> <unimprovedSecondsSpentLimit>180</unimprovedSecondsSpentLimit> </termination> <constructionHeuristic> <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType> <cartesianProductMoveSelector> <changeMoveSelector> <valueSelector variableName="timeBlock"> <filterClass>TimeBlockSelectionFilter</filterClass> </valueSelector> </changeMoveSelector> <changeMoveSelector> <valueSelector variableName="worker"> <filterClass>NoNullVariableAndNoKompetencer</filterClass> </valueSelector> </changeMoveSelector> </cartesianProductMoveSelector> <changeMoveSelector> <valueSelector variableName="room"> <filterClass>NoNullVariable</filterClass> </valueSelector> </changeMoveSelector> <changeMoveSelector> <valueSelector variableName="assistant"> <filterClass>NoNullVariable</filterClass> </valueSelector> </changeMoveSelector> <forager> <pickEarlyType>FIRST_FEASIBLE_SCORE_OR_NON_DETERIORATING_HARD</pickEarlyType> </forager> </constructionHeuristic>
解答
1. 多移动选择器被忽略的问题:并非API限制,是配置方式错误
构造启发式默认只会使用<constructionHeuristic>下的第一个移动选择器,并列的后续选择器会被忽略。要实现「先执行笛卡尔积移动,再依次执行单个变量的顺序移动」,需要将每个移动逻辑拆分为独立的构造启发式阶段,用<phase>标签嵌套每个阶段的配置。
这种分阶段的方式不仅能实现顺序执行,还能针对每个阶段单独调整策略(比如不同的constructionHeuristicType或筛选器),扩展性更好。
2. 修改后的配置示例
<scoreDirectorFactory> <constraintProviderClass>MyConstraintProvider</constraintProviderClass> <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend> </scoreDirectorFactory> <termination> <unimprovedSecondsSpentLimit>180</unimprovedSecondsSpentLimit> </termination> <!-- 阶段1:用笛卡尔积同时分配timeBlock和worker --> <phase> <constructionHeuristic> <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType> <cartesianProductMoveSelector> <changeMoveSelector> <valueSelector variableName="timeBlock"> <filterClass>TimeBlockSelectionFilter</filterClass> </valueSelector> </changeMoveSelector> <changeMoveSelector> <valueSelector variableName="worker"> <filterClass>NoNullVariableAndNoKompetencer</filterClass> </valueSelector> </changeMoveSelector> </cartesianProductMoveSelector> <forager> <pickEarlyType>FIRST_FEASIBLE_SCORE_OR_NON_DETERIORATING_HARD</pickEarlyType> </forager> </constructionHeuristic> </phase> <!-- 阶段2:单独分配room --> <phase> <constructionHeuristic> <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType> <changeMoveSelector> <valueSelector variableName="room"> <filterClass>NoNullVariable</filterClass> </valueSelector> </changeMoveSelector> <forager> <pickEarlyType>FIRST_FEASIBLE_SCORE_OR_NON_DETERIORATING_HARD</pickEarlyType> </forager> </constructionHeuristic> </phase> <!-- 阶段3:单独分配assistant --> <phase> <constructionHeuristic> <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType> <changeMoveSelector> <valueSelector variableName="assistant"> <filterClass>NoNullVariable</filterClass> </valueSelector> </changeMoveSelector> <forager> <pickEarlyType>FIRST_FEASIBLE_SCORE_OR_NON_DETERIORATING_HARD</pickEarlyType> </forager> </constructionHeuristic> </phase>
3. pickEarlyType未生效的问题排查
- 阶段独立配置:确保每个构造启发式阶段都单独配置
<forager>,全局的<forager>不会自动作用于所有阶段。 - 可行解识别:检查你的约束提供者(
MyConstraintProvider)是否正确标记了「可行解」——即硬约束完全满足的状态。如果硬约束始终不满足,pickEarlyType会继续搜索所有候选。 - 移动选择逻辑:确认筛选器(如
TimeBlockSelectionFilter)没有过滤掉所有可行的候选值,导致没有符合条件的可行移动供pickEarlyType触发。
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

