前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OptaPlanner笔记4

OptaPlanner笔记4

作者头像
路过君
发布2023-08-13 11:37:42
2560
发布2023-08-13 11:37:42
举报

2.2.8. 创建应用程序

  1. 创建SolverFactory 来为每个数据集构建Solver
  2. 加载数据集
  3. 使用Solver.solve()进行求解
  4. 输出数据集的解决方案

通常一个应用包含一个SolverFactory 来为每个要求解的问题数据集构建新的Solver实例。SolverFactory是线程安全的,但Solver不是。

代码语言:javascript
复制
import org.optaplanner.core.api.solver.Solver;
import org.optaplanner.core.api.solver.SolverFactory;
import org.optaplanner.core.config.solver.SolverConfig;
public class TimeTableApp {
	...
	public static void main(String[] args) {
		// 创建求解器工厂实例
		SolverFactory<TimeTable> solverFactory = SolverFactory.create(new SolverConfig()
				// 注册规划方案类 @PlanningSolution
                .withSolutionClass(TimeTable.class)
                // 注册规划实体类 @PlanningEntity
                .withEntityClasses(Lesson.class)
                // 注册约束提供者类 ConstraintProvider
                .withConstraintProviderClass(TimeTableConstraintProvider.class)
                // 配置求解器执行时间限制,建议至少5分钟
                .withTerminationSpentLimit(Duration.ofSeconds(5)));
		// 加载问题数据集
        TimeTable problem = generateDemoData();
        // 求解问题
        Solver<TimeTable> solver = solverFactory.buildSolver();
        TimeTable solution = solver.solve(problem);
        // 输出解决方案
        printTimetable(solution);
	}
	...
}

注意:如果没有终止设置或者terminationEarly()事件,求解器将一直运行。

OptaPlanner返回在可用终止时间内找到的最优方案。 由于NP困难问题的性质(9.2),最优方案可能不是最佳的,尤其是对于较大的数据集。 增加终止时间以可能找到更好的方案。

2.2.9.2. 测试应用程序
2.2.9.2.1. 测试约束

可使用ConstraintVerifier对每一种约束条件进行单元测试

代码语言:javascript
复制
import org.junit.jupiter.api.Test;
import org.optaplanner.test.api.score.stream.ConstraintVerifier;

class TimeTableConstraintProviderTest {

    private static final Room ROOM1 = new Room("Room1");
    private static final Timeslot TIMESLOT1 = new Timeslot(DayOfWeek.MONDAY, LocalTime.NOON);
    private static final Timeslot TIMESLOT2 = new Timeslot(DayOfWeek.TUESDAY, LocalTime.NOON);
	
	// 构建约束校验器,入参:约束供应者实例,规划方案类,规划实体类
    ConstraintVerifier<TimeTableConstraintProvider, TimeTable> constraintVerifier = ConstraintVerifier.build(
            new TimeTableConstraintProvider(), TimeTable.class, Lesson.class);

    @Test
    void roomConflict() {
    	// 构建规划实体数据集合,验证约束是否正确的进行惩罚
        Lesson firstLesson = new Lesson(1, "Subject1", "Teacher1", "Group1", TIMESLOT1, ROOM1);
        Lesson conflictingLesson = new Lesson(2, "Subject2", "Teacher2", "Group2", TIMESLOT1, ROOM1);
        Lesson nonConflictingLesson = new Lesson(3, "Subject3", "Teacher3", "Group3", TIMESLOT2, ROOM1);
        constraintVerifier.verifyThat(TimeTableConstraintProvider::roomConflict)
                .given(firstLesson, conflictingLesson, nonConflictingLesson)
                .penalizesBy(1);
    }

}

注意:因为约束权重在投入生产运行前经常更改。ConstraintVerifier在测试中忽略约束权重,即使这些约束权重是在ConstraintProvider中硬编码的。这样,约束权重的调整就不会破坏单元测试。

如果测试失败将报错如:

java.lang.AssertionError: Broken expectation. Constraint: example.domain/Room conflict Expected penalty: 2 (class java.lang.Integer) Actual penalty: 1 (class java.lang.Integer) Explanation of score (-1hard/0soft): Constraint match totals: -1hard: constraint (Room conflict) has 1 matches: -1hard: justifications ([Subject1(1), Subject2(2)]) Indictments: -1hard: indicted object (Subject1(1)) has 1 matches: -1hard: constraint (Room conflict) -1hard: indicted object (Subject2(2)) has 1 matches: -1hard: constraint (Room conflict)

参考Testing Constraint Streams

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.2.8. 创建应用程序
    • 2.2.9.2. 测试应用程序
      • 2.2.9.2.1. 测试约束
相关产品与服务
腾讯云服务器利旧
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档