护士排班修改
Nurse rostering modification
您好,我是 Optaplanner 的新手,我正在尝试调整护士排班以适应机场值机人员排班。我创建了一个 FlightAssignment,其中 Employee 被分配给 Flight.
员工是计划变量。
FlightAssignment 是 PlanningEntity。
CheckinRoster 是 PlanningEntityCollectionProperty
请帮助我,当我 运行 CheckinRosteringApp 时出现此错误:
2017-03-03 16:35:47,574 [main] INFO CloudBalance 1 has 9 flights and 15 employees with a search space of 10^14.
Exception in thread "main" java.lang.IllegalArgumentException: The solutionClass (class org.optaplanner.examples.handler.domain.CheckinRoster)'s entityCollectionProperty (flightAssignmentList) should never return null.
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.extractEntityCollection(SolutionDescriptor.java:657)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.getEntityCount(SolutionDescriptor.java:516)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.cloneSolution(FieldAccessingSolutionCloner.java:201)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.cloneSolution(FieldAccessingSolutionCloner.java:72)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneSolution(AbstractScoreDirector.java:142)
at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope.java:198)
at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:196)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:175)
at org.optaplanner.examples.handler.app.CheckinRosteringApp.main(CheckinRosteringApp.java:30)
如果我初始化 flightAssignmentList,错误就会消失,但解决方案是空的。
2017-03-04 18:31:43,691 [main] INFO CheckinRoster 1 has 8 flights and 20 employees with a search space of 10^18.
2017-03-04 18:31:44,061 [main] INFO Solving started: time spent (350), best score (-25hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
2017-03-04 18:31:44,078 [main] INFO Construction Heuristic phase (0) ended: step total (0), time spent (369), best score (-25hard/0soft).
2017-03-04 18:31:44,090 [main] WARN No doable selected move at step index (0), time spent (382). Terminating phase early.
2017-03-04 18:31:44,091 [main] INFO Local Search phase (1) ended: step total (0), time spent (383), best score (-25hard/0soft).
2017-03-04 18:31:44,091 [main] INFO Solving ended: time spent (383), best score (-25hard/0soft), average calculate count per second (7), environment mode (REPRODUCIBLE).
[...]
我是不是在 xml 配置文件中做错了什么?我在 nurserostering 中使用了删除 unionMoveSelector 块,希望在 optaplanner 中寻找解决方案。
这是checkinRosteringSolverConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>FAST_ASSERT</environmentMode>-->
<solutionClass>org.optaplanner.examples.handler.domain.CheckinRoster</solutionClass>
<entityClass>org.optaplanner.examples.handler.domain.FlightAssignment</entityClass>
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>org/optaplanner/examples/handler/solver/checkinRosteringScoreRules.drl</scoreDrl>
</scoreDirectorFactory>
<termination>
<!--
Official benchmark secondsSpentLimit allowed on:
- ge0ffrey's main pc: sprint 11, medium 700, long 42000
-->
<secondsSpentLimit>700</secondsSpentLimit>
<!--<bestScoreLimit>-0hard/-999999soft</bestScoreLimit>-->
</termination>
<constructionHeuristic>
<constructionHeuristicType>WEAKEST_FIT</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>800</acceptedCountLimit>
</forager>
</localSearch>
</solver>
这是 checkingRosteringScoreRules.drl
/*
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.optaplanner.examples.handler.solver;
dialect "java"
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder;
import org.optaplanner.examples.handler.domain.Employee;
import org.optaplanner.examples.handler.domain.Flight;
import org.optaplanner.examples.handler.domain.FlightAssignment;
import org.optaplanner.examples.handler.domain.CheckinRoster;
global HardSoftScoreHolder scoreHolder;
// ############################################################################
// Hard constraints
// ############################################################################
// This rule is build in
// All demanded shifts must be assigned to a nurse
rule "requiredEmployeeSizePerShift"
when
$flight : Flight(minimumEmployeesNumber > 0, $minimumEmployeesNumber : minimumEmployeesNumber)
$totalEmployeeNumber : Number(intValue <= $minimumEmployeesNumber) from accumulate(
$assignment : FlightAssignment(flight == $flight),
count($assignment)
)
then
scoreHolder.addHardConstraintMatch(kcontext, - Math.abs($minimumEmployeesNumber - $totalEmployeeNumber.intValue()));
end
//a nurse can only work on no clashing flights
//TODO
//TODO
// a nurse can only work one shift per day, i.e. no two shift can be assigned to the same nurse on a day.
//rule "oneShiftPerDay"
// when
// ShiftAssignment($leftId : id, $employee : employee, $shiftDate : shiftDate, employee != null)
// ShiftAssignment(employee == $employee, shiftDate == $shiftDate, id > $leftId)
// then
// scoreHolder.addHardConstraintMatch(kcontext, -1);
//end
// ############################################################################
// Soft constraints
// ############################################################################
rule "employeeCost"
when
$employee : Employee($income : income)
exists FlightAssignment(employee == $employee)
then
scoreHolder.addSoftConstraintMatch(kcontext, - $income);
end
Exception in thread "main" java.lang.IllegalArgumentException: The solutionClass (class org.optaplanner.examples.handler.domain.CheckinRoster)'s entityCollectionProperty (flightAssignmentList) should never return null.
检查你的方法CheckinRoster.getFlightAssignmentList()
。对于该数据集,它显然返回 null。
您好,我是 Optaplanner 的新手,我正在尝试调整护士排班以适应机场值机人员排班。我创建了一个 FlightAssignment,其中 Employee 被分配给 Flight.
员工是计划变量。
FlightAssignment 是 PlanningEntity。
CheckinRoster 是 PlanningEntityCollectionProperty
请帮助我,当我 运行 CheckinRosteringApp 时出现此错误:
2017-03-03 16:35:47,574 [main] INFO CloudBalance 1 has 9 flights and 15 employees with a search space of 10^14.
Exception in thread "main" java.lang.IllegalArgumentException: The solutionClass (class org.optaplanner.examples.handler.domain.CheckinRoster)'s entityCollectionProperty (flightAssignmentList) should never return null.
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.extractEntityCollection(SolutionDescriptor.java:657)
at org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor.getEntityCount(SolutionDescriptor.java:516)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner$FieldAccessingSolutionClonerRun.cloneSolution(FieldAccessingSolutionCloner.java:201)
at org.optaplanner.core.impl.domain.solution.cloner.FieldAccessingSolutionCloner.cloneSolution(FieldAccessingSolutionCloner.java:72)
at org.optaplanner.core.impl.score.director.AbstractScoreDirector.cloneSolution(AbstractScoreDirector.java:142)
at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.setWorkingSolutionFromBestSolution(DefaultSolverScope.java:198)
at org.optaplanner.core.impl.solver.DefaultSolver.solvingStarted(DefaultSolver.java:196)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:175)
at org.optaplanner.examples.handler.app.CheckinRosteringApp.main(CheckinRosteringApp.java:30)
如果我初始化 flightAssignmentList,错误就会消失,但解决方案是空的。
2017-03-04 18:31:43,691 [main] INFO CheckinRoster 1 has 8 flights and 20 employees with a search space of 10^18.
2017-03-04 18:31:44,061 [main] INFO Solving started: time spent (350), best score (-25hard/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
2017-03-04 18:31:44,078 [main] INFO Construction Heuristic phase (0) ended: step total (0), time spent (369), best score (-25hard/0soft).
2017-03-04 18:31:44,090 [main] WARN No doable selected move at step index (0), time spent (382). Terminating phase early.
2017-03-04 18:31:44,091 [main] INFO Local Search phase (1) ended: step total (0), time spent (383), best score (-25hard/0soft).
2017-03-04 18:31:44,091 [main] INFO Solving ended: time spent (383), best score (-25hard/0soft), average calculate count per second (7), environment mode (REPRODUCIBLE).
[...]
我是不是在 xml 配置文件中做错了什么?我在 nurserostering 中使用了删除 unionMoveSelector 块,希望在 optaplanner 中寻找解决方案。
这是checkinRosteringSolverConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>FAST_ASSERT</environmentMode>-->
<solutionClass>org.optaplanner.examples.handler.domain.CheckinRoster</solutionClass>
<entityClass>org.optaplanner.examples.handler.domain.FlightAssignment</entityClass>
<scoreDirectorFactory>
<scoreDefinitionType>HARD_SOFT</scoreDefinitionType>
<scoreDrl>org/optaplanner/examples/handler/solver/checkinRosteringScoreRules.drl</scoreDrl>
</scoreDirectorFactory>
<termination>
<!--
Official benchmark secondsSpentLimit allowed on:
- ge0ffrey's main pc: sprint 11, medium 700, long 42000
-->
<secondsSpentLimit>700</secondsSpentLimit>
<!--<bestScoreLimit>-0hard/-999999soft</bestScoreLimit>-->
</termination>
<constructionHeuristic>
<constructionHeuristicType>WEAKEST_FIT</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>800</acceptedCountLimit>
</forager>
</localSearch>
</solver>
这是 checkingRosteringScoreRules.drl
/*
* Copyright 2010 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.optaplanner.examples.handler.solver;
dialect "java"
import org.optaplanner.core.api.score.buildin.hardsoft.HardSoftScoreHolder;
import org.optaplanner.examples.handler.domain.Employee;
import org.optaplanner.examples.handler.domain.Flight;
import org.optaplanner.examples.handler.domain.FlightAssignment;
import org.optaplanner.examples.handler.domain.CheckinRoster;
global HardSoftScoreHolder scoreHolder;
// ############################################################################
// Hard constraints
// ############################################################################
// This rule is build in
// All demanded shifts must be assigned to a nurse
rule "requiredEmployeeSizePerShift"
when
$flight : Flight(minimumEmployeesNumber > 0, $minimumEmployeesNumber : minimumEmployeesNumber)
$totalEmployeeNumber : Number(intValue <= $minimumEmployeesNumber) from accumulate(
$assignment : FlightAssignment(flight == $flight),
count($assignment)
)
then
scoreHolder.addHardConstraintMatch(kcontext, - Math.abs($minimumEmployeesNumber - $totalEmployeeNumber.intValue()));
end
//a nurse can only work on no clashing flights
//TODO
//TODO
// a nurse can only work one shift per day, i.e. no two shift can be assigned to the same nurse on a day.
//rule "oneShiftPerDay"
// when
// ShiftAssignment($leftId : id, $employee : employee, $shiftDate : shiftDate, employee != null)
// ShiftAssignment(employee == $employee, shiftDate == $shiftDate, id > $leftId)
// then
// scoreHolder.addHardConstraintMatch(kcontext, -1);
//end
// ############################################################################
// Soft constraints
// ############################################################################
rule "employeeCost"
when
$employee : Employee($income : income)
exists FlightAssignment(employee == $employee)
then
scoreHolder.addSoftConstraintMatch(kcontext, - $income);
end
Exception in thread "main" java.lang.IllegalArgumentException: The solutionClass (class org.optaplanner.examples.handler.domain.CheckinRoster)'s entityCollectionProperty (flightAssignmentList) should never return null.
检查你的方法CheckinRoster.getFlightAssignmentList()
。对于该数据集,它显然返回 null。