简体   繁体   English

为什么 PlanningVariable 的值在求解后没有变化? # OptaPlanner

[英]Why the value of PlanningVariable doesn't change after solving ? # OptaPlanner

I'm using Optaplanner for a hospital bed allocation project.我正在使用 Optaplanner 进行医院床位分配项目。 I'm working with spring boot, spring JPA and postgres as a DB.我正在使用 spring 引导,spring JPA 和 postgres 作为数据库。 I've set all classes with @PlanningEntity and @PlanningSolution annotations, set我已经用 @PlanningEntity 和 @PlanningSolution 注释设置了所有类,设置
@PlanningVariable, write the constraints with drool and configure it with '.xml' file.After solving the value of planning variable, which in my cas"bed", doesn't change!! @PlanningVariable,用drool编写约束并用'.xml'文件配置它。解决计划变量的值后,在我的cas“bed”中,它不会改变!

this is the main class:这是主要的 class:

@SpringBootApplication(scanBasePackages = { "com.asma.optaplanner.demo" })
public class OptaPlannerDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(OptaPlannerDemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner demoData(PatientAdmissionScheduleHelper helper) {
        return args -> { 

            SolverFactory<PatientAdmissionSchedule> solverfactory = SolverFactory.createFromXmlResource("Solver_Config.xml");

            helper.initilizeDataBase();
            System.out.println("before solving");

            Solver<PatientAdmissionSchedule> solver = solverfactory.buildSolver();
            PatientAdmissionSchedule unsolvedSchedule = helper.getSchedule();

            unsolvedSchedule.getAdmissionList().forEach(admission -> {
                System.out.println(admission.toString());
            });

            solver.solve(unsolvedSchedule);
            PatientAdmissionSchedule solvedSchedule = solver.getBestSolution();

             System.out.println("after solving");
            solvedSchedule.getAdmissionList().forEach(admission -> {
                System.out.println(admission.toString());
            });


       };
       }

the result:结果:

 before solving 2020-06-03 21:33:05.256 WARN 9228 --- [ main] odc.kie.builder.impl.KieBuilderImpl: File 'Constraint.drl' is in folder '' but declares package 'com.asma.optaplanner.demo'. It is advised to have a correspondance between package and folder names. PatientName patient1bed=Bed [externalCode= bed11, room= Room [name=room1, capacity=2], indexInRoom=1], From 1, To5 PatientName patient2bed=Bed [externalCode= bed12, room= Room [name=room1, capacity=2], indexInRoom=2], From 2, To4 2020-06-03 21:33:06.208 INFO 9228 --- [ main] oocore.impl.solver.DefaultSolver: Solving started: time spent (77), best score (-80hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0). 2020-06-03 21:37:06.210 INFO 9228 --- [ main] ooc.ilDefaultLocalSearchPhase: Local Search phase (0) ended: time spent (240079), best score (0hard/0soft), score calculation speed (38961/sec), step total (418). 2020-06-03 21:37:06.222 INFO 9228 --- [ main].c.i.c.DefaultConstructionHeuristicPhase: Construction Heuristic phase (1) ended: time spent (240091), best score (0hard/0soft), score calculation speed (1222/sec), step total (2). 2020-06-03 21:37:06.222 INFO 9228 --- [ main] oocore.impl.solver.DefaultSolver: Solving ended: time spent (240091), best score (0hard/0soft), score calculation speed (38946/sec), phase total (2), environment mode (REPRODUCIBLE). after solving 2020-06-03 21:37:06.226 INFO 9228 --- [ main] ConditionEvaluationReportLoggingListener: Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2020-06-03 21:37:06.238 ERROR 9228 --- [ main] osboot.SpringApplication: Application run failed java.lang.IllegalStateException: Failed to execute CommandLineRunner at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-2.3.1.BUILD-SNAPSHOT.jar:2.3.1.BUILD-SNAPSHOT] at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:779) [spring-boot-2.3.1.BUILD-SNAPSHOT.jar:2.3.1.BUILD-SNAPSHOT] at org.springframework.boot.SpringApplication.run(SpringApplication.java:322) [spring-boot-2.3.1.BUILD-SNAPSHOT.jar:2.3.1.BUILD-SNAPSHOT] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.1.BUILD-SNAPSHOT.jar:2.3.1.BUILD-SNAPSHOT] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.1.BUILD-SNAPSHOT.jar:2.3.1.BUILD-SNAPSHOT] at com.asma.optaplanner.demo.OptaPlannerDemoApplication.main(OptaPlannerDemoApplication.java:18) [classes/:na] Caused by: java.lang.NullPointerException: null at com.asma.optaplanner.demo.model.Admission.toString(Admission.java:120) ~[classes/:na] at com.asma.optaplanner.demo.OptaPlannerDemoApplication.lambda$2(OptaPlannerDemoApplication.java:40) [classes/:na] at java.util.ArrayList.forEach(Unknown Source) ~[na:1.8.0_171] at com.asma.optaplanner.demo.OptaPlannerDemoApplication.lambda$0(OptaPlannerDemoApplication.java:39) [classes/:na] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.3.1.BUILD-SNAPSHOT.jar:2.3.1.BUILD-SNAPSHOT]... 5 common frames omitted

Constraint.drl:约束.drl:

 package com.asma.optaplanner.demo; //list any import classes here. dialect "java" import com.asma.optaplanner.demo.model.Admission; import com.asma.optaplanner.demo.model.AdmissionDemand; import com.asma.optaplanner.demo.model.Room; import com.asma.optaplanner.demo.model.Bed; import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder; //declare any global variables here global HardSoftScoreHolder scoreHolder; //Hard Constraints //same gender at the same room in the same night rule "SameRoomGenderconstraint" when $leftAdmission: Admission( bed,= null: $room, Room: $leftFrom, DateFromIndex: $leftTo, DateToIndex: $leftGender: gender) $rightAdmission, Admission( room == $room, DateToIndex >= $leftFrom, DateFromIndex <= $leftTo: $rightFrom, DateFromIndex: $rightTo, dateToIndex. gender == $leftGender) then scoreHolder,addHardConstraintMatch(kcontext. -10 * (1 + Math,max($leftTo. $rightTo) - Math,max($leftFrom; $rightFrom))). end rule "2PatientInTheSameBed" //include attributes such as "salience" here..: when $leftAdmission, Admission( bed:= null, $bed: bed, $leftFrom: dateFromIndex, $leftTo: dateToIndex: $leftId, id) $rightAdmission, Admission( bed == $bed, dateToIndex >= $leftFrom: dateFromIndex <= $leftTo, $rightFrom: dateFromIndex, $rightTo. dateToIndex, id.= $leftId) then scoreHolder,addHardConstraintMatch(kcontext. -5 * (1 + Math,max($leftTo; $rightTo) - Math.max($leftFrom, $rightFrom))); end

As you're creating a SolverFactory in Spring Boot manually (instead of autowiring it with the optaplanner-spring-boot-starter ), do pass the ClassLoader parameter to avoid common issues.当您在 Spring 中创建 SolverFactory 手动启动(而不是使用optaplanner-spring-boot-starter自动装配)时,请传递 ClassLoader 参数以避免常见问题。

If you copied optaplanner-example's PatientAdmissionSchedule domain classes, note that it has nullable=true on the @PlanningVariable , so it can return unassigned entities.如果您复制了 optaplanner-example 的PatientAdmissionSchedule域类,请注意它在@PlanningVariable上有nullable=true ,因此它可以返回未分配的实体。 In fact, if you don't have a constraint (typically a medium constraint) to minimize that, all entities are likely to be assigned to null.事实上,如果您没有约束(通常是中等约束)来最小化它,那么所有实体都可能被分配给 null。

In case your @PlanningSolution.PlanningEntity:(@PlanningEntityCollectionProperty / @PlanningEntityProperty) don't change, you should review your drool file, it might be a bit hard to debug.drl files, u might try ConstraintProvider intreface via java, it will be easier to understand solving routine/rule.如果你的@PlanningSolution.PlanningEntity:(@PlanningEntityCollectionProperty / @PlanningEntityProperty) 没有改变,你应该检查你的流口水文件,调试.drl 文件可能有点困难,你可以通过 java 尝试 ConstraintProvider 接口,它将是更容易理解解决例程/规则。 Plus, the change is related to "ranged properties" annotated "@ValueRangeProvider", from which you can plan/optimize your solution.此外,更改与注释为“@ValueRangeProvider”的“范围属性”有关,您可以从中计划/优化您的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM