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

在Timefold中创建多ConstraintProviders进行基准测试的异常解决及配置建议

异常原因与解决思路

你遇到的异常是因为Spring自动扫描时发现多个ConstraintProvider实现类,Timefold默认会自动识别该接口的实现,但存在多个实现时会导致Bean冲突。解决思路如下:

1. 显式指定ConstraintProvider

不要依赖Spring自动扫描,而是在每个测试/基准配置中手动指定要使用的ConstraintProvider类:

  • 在SolverConfig中通过setConstraintProviderClass()方法指定具体实现;
  • 若使用XML配置,在<scoreDirectorFactory>节点内添加<constraintProviderClass>标签指定类路径。

2. Spring环境临时兼容方案(仅单方案测试用)

如果只是临时测试单个方案,可通过Spring注解控制Bean选择:

  • 给其中一个ConstraintProvider添加@Primary注解,让Spring优先注入;
  • 在@ComponentScan中通过excludeFilters排除不需要的ConstraintProvider实现类。

多ConstraintProviders基准测试实现建议

推荐使用Timefold官方的Benchmark模块来对比多方案,它能自动运行所有配置组合、收集性能数据并生成可视化报告,完美适配你的需求(对比约束方案、CH类型、LS配置)。

步骤1:准备约束实现

根据你的两个方案,有两种实现方式:

方式A:创建独立ConstraintProvider

  • FullConstraintProvider:包含所有约束(对应方案一);
  • ReducedConstraintProvider:移除assignHighPriorityFirst约束(对应方案二)。

方式B:用约束过滤减少重复代码(更简洁)

只维护一个FullConstraintProvider,通过ConstraintFilter禁用指定约束:

public class ExcludeHighPriorityConstraintFilter implements ConstraintFilter {
    @Override
    public boolean accept(String constraintName) {
        return !"assignHighPriorityFirst".equals(constraintName);
    }
}

步骤2:配置Benchmark(XML示例)

创建benchmarkConfig.xml,定义所有需要对比的方案组合:

<?xml version="1.0" encoding="UTF-8"?>
<benchmark xmlns="https://timefold.ai/xsd/benchmark"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="https://timefold.ai/xsd/benchmark https://timefold.ai/xsd/benchmark/benchmark.xsd">

  <benchmarkDirectory>./benchmark-results</benchmarkDirectory>

  <!-- 所有方案共享的基础配置 -->
  <inheritedSolverBenchmark>
    <solver>
      <solutionClass>your.package.TaskAssignmentSolution</solutionClass>
      <entityClass>your.package.TaskAssignment</entityClass>
      <termination>
        <secondsSpentLimit>30</secondsSpentLimit> <!-- 每个方案运行30秒 -->
      </termination>
    </solver>
  </inheritedSolverBenchmark>

  <!-- 方案一:ONLY_DOWN + FIRST_FIT_DECREASING + 全约束 -->
  <solverBenchmark name="Scheme1-FullConstraints-OnlyDown-FFD">
    <solver>
      <scoreDirectorFactory>
        <constraintProviderClass>your.package.FullConstraintProvider</constraintProviderClass>
      </scoreDirectorFactory>
      <constructionHeuristic>
        <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
        <changeMoveSelector>
          <selectionOrder>ONLY_DOWN</selectionOrder>
        </changeMoveSelector>
      </constructionHeuristic>
      <localSearch>
        <localSearchType>HILL_CLIMBING</localSearchType>
      </localSearch>
    </solver>
  </solverBenchmark>

  <!-- 方案二:WEAKEST_FIT_DECREASING + 禁用指定约束 -->
  <solverBenchmark name="Scheme2-ReducedConstraints-WFD">
    <solver>
      <scoreDirectorFactory>
        <constraintProviderClass>your.package.FullConstraintProvider</constraintProviderClass>
        <constraintFilter>your.package.ExcludeHighPriorityConstraintFilter</constraintFilter>
      </scoreDirectorFactory>
      <constructionHeuristic>
        <constructionHeuristicType>WEAKEST_FIT_DECREASING</constructionHeuristicType>
      </constructionHeuristic>
      <localSearch>
        <localSearchType>TABU_SEARCH</localSearchType>
        <tabuSize>7</tabuSize>
      </localSearch>
    </solverBenchmark>

  <!-- 可添加更多组合:比如方案一搭配TABU搜索、方案二搭配HILL_CLIMBING等 -->
  <solverBenchmark name="Scheme1-FullConstraints-OnlyDown-FFD-Tabu">
    <solver>
      <scoreDirectorFactory>
        <constraintProviderClass>your.package.FullConstraintProvider</constraintProviderClass>
      </scoreDirectorFactory>
      <constructionHeuristic>
        <constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
        <changeMoveSelector>
          <selectionOrder>ONLY_DOWN</selectionOrder>
        </changeMoveSelector>
      </constructionHeuristic>
      <localSearch>
        <localSearchType>TABU_SEARCH</localSearchType>
        <tabuSize>5</tabuSize>
      </localSearch>
    </solver>
  </solverBenchmark>
</benchmark>

步骤3:运行基准测试

通过Java代码启动Benchmark:

public class TaskAssignmentBenchmarkRunner {
    public static void main(String[] args) {
        BenchmarkFactory.createFromXmlResource("benchmarkConfig.xml")
                        .benchmark();
    }
}

运行完成后,benchmark-results目录会生成HTML报告,包含各方案的得分、求解时间、内存占用等对比数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:17:16