OptaPlanner 基准测试不会 运行

OptaPlanner benchmarking won't run

我正在尝试 运行 使用以下配置的 OptaPlanner 基准测试:

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

    <inheritedSolverBenchmark>
        <solver>
            <solutionClass>org.acme.domain.Main</solutionClass>
            <entityClass>org.acme.domain.Standstill</entityClass>
            <entityClass>org.acme.domain.Visit</entityClass>
            <scoreDirectorFactory>
                <constraintProviderClass>org.acme.solver.MainConstraintProvider</constraintProviderClass>
                <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
            </scoreDirectorFactory>
            <termination>
                <secondsSpentLimit>30</secondsSpentLimit>
            </termination>
        </solver>
        <problemBenchmarks>
            <solutionFileIOClass>org.acme.bootstrap.AcmeSolutionIO</solutionFileIOClass>
            <inputSolutionFile>data/latest.xml</inputSolutionFile>
        </problemBenchmarks>
    </inheritedSolverBenchmark>
    <solverBenchmark>
        <solver>
            <constructionHeuristic>
                <constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
            </constructionHeuristic>
            <localSearch>
                <localSearchType>LATE_ACCEPTANCE</localSearchType>
            </localSearch>
        </solver>
    </solverBenchmark>
</plannerBenchmark>

但是,我收到此错误消息:

Exception in thread "main" org.optaplanner.benchmark.api.PlannerBenchmarkException: Benchmarking failed: failureCount (1). The exception of the firstFailureSingleBenchmarkRunner (blankData_Config_0_0) is chained.
    at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkingEnded(DefaultPlannerBenchmark.java:326)
    at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmark(DefaultPlannerBenchmark.java:100)
    at org.optaplanner.benchmark.impl.DefaultPlannerBenchmark.benchmarkAndShowReportInBrowser(DefaultPlannerBenchmark.java:424)
    at org.acme.bootstrap.BenchmarkApp.main(BenchmarkApp.kt:29)
Caused by: java.lang.IllegalStateException: The class (class java.lang.Long) should have a no-arg constructor to create a planning clone.
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.lambda$retrieveCachedConstructor[=12=](FieldAccessingSolutionCloner.java:90)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
    at org.optaplanner.core.impl.domain.common.ConcurrentMemoization.computeIfAbsent(ConcurrentMemoization.java:44)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.retrieveCachedConstructor(FieldAccessingSolutionCloner.java:85)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.constructClone(FieldAccessingSolutionCloner.java:158)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.clone(FieldAccessingSolutionCloner.java:150)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.process(FieldAccessingSolutionCloner.java:207)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.processQueue(FieldAccessingSolutionCloner.java:194)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.cloneSolution(FieldAccessingSolutionCloner.java:136)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.cloneSolution(FieldAccessingSolutionCloner.java:73)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneSolution(AbstractScoreDirector.java:257)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneWorkingSolution(AbstractScoreDirector.java:250)
    at org.optaplanner.core.impl.solver.recaller.BestSolutionRecaller.updateBestSolutionAndFire(BestSolutionRecaller.java:129)
    at org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.phaseEnded(DefaultConstructionHeuristicPhase.java:146)
    at org.optaplanner.core.impl.constructionheuristic.DefaultConstructionHeuristicPhase.solve(DefaultConstructionHeuristicPhase.java:98)
    at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:99)
    at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:192)
    at org.optaplanner.benchmark.impl.SubSingleBenchmarkRunner.call(SubSingleBenchmarkRunner.java:122)
    at org.optaplanner.benchmark.impl.SubSingleBenchmarkRunner.call(SubSingleBenchmarkRunner.java:42)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoSuchMethodException: java.lang.Long.<init>()
    at java.base/java.lang.Class.getConstructor0(Class.java:3585)
    at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754)
    at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.lambda$retrieveCachedConstructor[=12=](FieldAccessingSolutionCloner.java:88)
    ... 22 more

我尝试了许多其他基准配置,包括 <solverBenchmarkBluePrintType>CONSTRUCTION_HEURISTIC_WITH_AND_WITHOUT_LOCAL_SEARCH</solverBenchmarkBluePrintType>,但其中 none 也可以。

我以前用过它,但经过多次更改后我又回到了它,但它不再起作用了。

我现在使用 SimpleLongScore 而不是 SimpleScore 我想知道这是否与错误有关,因为之前它没有抛出此异常。

有什么想法吗?

编辑#1:
我希望我能提供更多代码,但我真的不知道该包含什么代码。

奇怪的是 OptaPlanner 运行 在 mvn compile quarkus:dev 之前都很好,但是当我 运行 我的基准测试应用程序从主条目开始时,它给出了前面提到的错误, java.lang.IllegalStateException: The class (class java.lang.Long) should have a no-arg constructor to create a planning clone.

这是我的主要内容:

    fun main(args: Array<String>) {
        val plannerBenchmarkFactory:PlannerBenchmarkFactory = PlannerBenchmarkFactory.createFromXmlResource("benchmarkBluePrintConfig.xml")
        val plannerBenchmark: PlannerBenchmark = plannerBenchmarkFactory.buildPlannerBenchmark()
        plannerBenchmark.benchmarkAndShowReportInBrowser()
    }

两者的 solverConfig.xml 也可以相同,但只有基准应用程序会抛出错误。这对我来说很奇怪。

我想出来了

在我的 Visit class 中,我使用的是 @CustomShadowVariable:

    @DeepPlanningClone
    @CustomShadowVariable(
        variableListenerClass = ArrivalTimeUpdatingVariableListener::class,
        sources = [PlanningVariableReference(variableName = "previousStandstill")]
    )
    var arrivalTime: Long? = null

删除 @DeepPlanningClone 解决了问题。

我不知道为什么当 SolverManager@Inject 时它运行良好,而不是在通过创建 SolverConfig/SolverManager 时抛出错误API(因为它在我的基准应用程序中)。