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

能否在Quarkus中用TimeFold/OptaPlanner解决多类型规划问题?

解决Quarkus中TimeFold多@PlanningSolution类的构建错误

错误原因

Quarkus的TimeFold扩展默认会自动扫描并注册所有带有@PlanningSolution注解的类,但该机制仅支持单个规划解决方案类,当存在多个时就会触发构建错误。

解决方案

1. 禁用自动发现解决方案

在src/main/resources/application.properties中添加配置,关闭自动扫描:

quarkus.timefold.solver.auto-discover-solutions=false

2. 手动创建并注册多个SolverManager实例

创建CDI生产者类,为每个规划解决方案手动加载对应的Solver配置,并生成独立的SolverManager bean:

import ai.timefold.solver.core.api.solver.SolverManager;
import ai.timefold.solver.core.config.solver.SolverConfig;
import ai.timefold.solver.quarkus.runtime.TimefoldRecorder;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Produces;

@ApplicationScoped
public class SolverManagerProducer {

    private final TimefoldRecorder timefoldRecorder;

    // 注入TimefoldRecorder以确保Quarkus扩展能正确处理Solver配置
    public SolverManagerProducer(TimefoldRecorder timefoldRecorder) {
        this.timefoldRecorder = timefoldRecorder;
    }

    // 为Solution1Table生成SolverManager
    @Produces
    @ApplicationScoped
    public SolverManager<Solution1Table, Long> solution1SolverManager() {
        SolverConfig solverConfig = SolverConfig.createFromXmlResource("solution1SolverConfig.xml");
        timefoldRecorder.registerSolverConfig(solverConfig);
        return SolverManager.create(solverConfig);
    }

    // 为Solution2Table生成SolverManager
    @Produces
    @ApplicationScoped
    public SolverManager<Solution2Table, Long> solution2SolverManager() {
        SolverConfig solverConfig = SolverConfig.createFromXmlResource("solution2SolverConfig.xml");
        timefoldRecorder.registerSolverConfig(solverConfig);
        return SolverManager.create(solverConfig);
    }
}

3. 在业务代码中注入使用

在需要求解的类中,分别注入对应的SolverManager实例进行使用:

import jakarta.inject.Inject;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;

@Path("/solve")
public class SolveResource {

    @Inject
    SolverManager<Solution1Table, Long> solution1SolverManager;

    @Inject
    SolverManager<Solution2Table, Long> solution2SolverManager;

    @POST
    @Path("/solution1")
    public String startSolution1Solve(Solution1Table problem) {
        Long problemId = 1L;
        solution1SolverManager.solve(problemId, problem, (id, solution) -> {
            // 处理Solution1的求解结果逻辑
        });
        return "Solution1求解任务已启动";
    }

    @POST
    @Path("/solution2")
    public String startSolution2Solve(Solution2Table problem) {
        Long problemId = 2L;
        solution2SolverManager.solve(problemId, problem, (id, solution) -> {
            // 处理Solution2的求解结果逻辑
        });
        return "Solution2求解任务已启动";
    }
}

注意事项

  • 确保每个SolverConfig.createFromXmlResource()传入的XML文件名与src/main/resources下的配置文件完全匹配。
  • 通过TimefoldRecorder.registerSolverConfig()注册配置,能保证Quarkus的TimeFold扩展提供的监控、指标等功能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:02:26