为什么求解后PlanningVariable的值不改变? #OptaPlanner

问题描述 投票:0回答:2

我正在使用Optaplanner进行医院病床分配项目。我正在使用Spring Boot,Spring JPA和Postgres作为数据库。我已经用@PlanningEntity和@PlanningSolution批注设置了所有类,@PlanningVariable,使用drool编写约束,并使用'.xml'文件进行配置。在解决了计划变量的值之后,该变量在我的cas“床”中保持不变!]

这是主要类别:

@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());
            });


       };
       }

结果:

before solving
2020-06-03 21:33:05.256  WARN 9228 --- [           main] o.d.c.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] o.o.core.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] o.o.c.i.l.DefaultLocalSearchPhase        : 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] o.o.core.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] o.s.boot.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:

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
java spring-boot jboss drools optaplanner
2个回答
0
投票

当您在Spring Boot中手动创建SolverFactory时(​​而不是使用optaplanner-spring-boot-starter自动装配),请传递ClassLoader参数以避免常见问题。

如果复制了optaplanner-example的PatientAdmissionSchedule域类,请注意,它在nullable=true上具有@PlanningVariable,因此它可以返回未分配的实体。实际上,如果您没有最小化约束(通常是中等约束),则所有实体都可能被分配为null。


0
投票

[如果您的@ PlanningSolution.PlanningEntity:(@ PlanningEntityCollectionProperty / @PlanningEntityProperty)不变,则应查看您的Drool文件,调试.drl文件可能有点困难,您可以通过java尝试ConstraintProvider intreface,将更易于理解解决例行/规则。另外,更改与注释为“ @ValueRangeProvider”的“范围属性”有关,您可以从中计划/优化解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.