Optaplanner Construction Heuristics Phase Unique ValueRange - optaplanner

I am working on optimizing the Construction Heuristics for the solution domain
I have a ValueRangerProvider as the following.
#ValueRangeProvider(id = "timeRange")
public CountableValueRange<LocalDateTime> timeRange() {
final LocalDateTime start = LocalDateTime.now().plusHours(1).truncatedTo(ChronoUnit.HOURS);
final LocalDateTime end = LocalDateTime.now().plusYears(1).truncatedTo(ChronoUnit.HOURS);
return Stream.iterate(start, d -> d.plusHours(1))
.takeWhile(localDateTime -> localDateTime.isBefore(end))
.collect(Collectors.toList());
}
This #ValueRangeProvider provides LocalDateTime instances for every hour between the start and end to be used in a Time Grain model. The timeRange value range is the only #PlannningVariable in the #PlanningEntity class.
I also have a following solverConfig.xml:
<?xml version="1.0" encoding="UTF-8"?>
<solver xmlns="https://www.optaplanner.org/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.optaplanner.org/xsd/solver/solver.xsd">
<scanAnnotatedClasses/>
<scoreDirectorFactory>
<constraintProviderClass>org.acme.optaplanner.solver.MyConstraintProvider</constraintProviderClass>
<initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
</scoreDirectorFactory>
<termination>
<bestScoreFeasible>true</bestScoreFeasible>
</termination>
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
<changeMoveSelector>
<selectionOrder>ORIGINAL</selectionOrder>
</changeMoveSelector>
<constructionHeuristic>
</solver>
During the Construction Heuristics, the objects initialization is more important than the quality of the solution. Given there is enough time slot that no hard constraint can occur.
I realized that the #ValueRangeProvider(id = "timeRange") values used by the previous steps are being re-used in the later steps during the Construction Heuristics.
1772 [main] DEBUG o.o.c.i.c.DefaultConstructionHeuristicPhase - CH step (0), time spent (157), score (-999init/0hard/-1soft), selected move count (1), picked move (Lesson{id=1, subject='Math I', pinned=false, startTime=null, durationInGrains=3} {null -> 2020-09-27T09:00}).
.
.
.
02:01:26.494 [main ] DEBUG CH step (497), time spent (14513), score (-502init/0hard/-5542soft), selected move count (664), picked move (Lesson{id=498, subject='Math I', pinned=false, startTime=null, durationInGrains=3} {null -> 2020-11-10T12:00}).
02:01:26.565 [main ] DEBUG CH step (498), time spent (14584), score (-501init/0hard/-5548soft), selected move count (666), picked move (Lesson{id=499, subject='Math I', pinned=false, startTime=null, durationInGrains=1} {null -> 2020-11-10T14:00}).
.
.
.
17456 [main] TRACE o.o.c.i.c.d.ConstructionHeuristicDecider - Move index (0), score (-500init/-2hard/-5571soft), move (Lesson{id=500, subject='Math I', pinned=false, startTime=null, durationInGrains=2} {null -> 2020-09-27T09:00}).
.
.
.
02:01:26.637 [main ] DEBUG CH step (499), time spent (14656), score (-500init/0hard/-5557soft), selected move count (667), picked move (Lesson{id=500, subject='Math I', pinned=false, startTime=null, durationInGrains=2} {null -> 2020-11-10T15:00}).
02:01:26.711 [main ] DEBUG CH step (500), time spent (14730), score (-499init/0hard/-5568soft), selected move count (668), picked move (Lesson{id=501, subject='Math I', pinned=false, startTime=null, durationInGrains=3} {null -> 2020-11-10T16:00}).
02:01:26.787 [main ] DEBUG CH step (501), time spent (14806), score (-498init/0hard/-5581soft), selected move count (670), picked move (Lesson{id=502, subject='Math I', pinned=false, startTime=null, durationInGrains=1} {null -> 2020-11-10T18:00}).
.
.
.
02:17:46.156 [main ] INFO Construction Heuristic phase (0) ended: time spent (98518), best score (0hard/-11165soft), score calculation speed (6783/sec), step total (1000).
02:17:46.165 [main ] INFO Solving ended: time spent (98527), best score (0hard/-11165soft), score calculation speed (6776/sec), phase total (2), environment mode (NON_REPRODUCIBLE).
The LocalDateTime of 2020-10-01T09:00 was used in the CH step(0) and CH step(499).
Since I have a hard constraint that constrains that two #PlanningEntity cannot use the same timeRange value I was wondering if the used timeRange value can be removed for future steps to use?
As an example;
I have changed the constructionHeuristic configuration
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
<changeMoveSelector>
<selectionOrder>RANDOM</selectionOrder>
</changeMoveSelector>
<forager>
<pickEarlyType>FIRST_FEASIBLE_SCORE_OR_NON_DETERIORATING_HARD</pickEarlyType>
</forager>
</constructionHeuristic>
Which lead to a much fast Construction Heuristics performance because the step was choosing #Planningvariables for #PlanningRangeProvider at random.
.
.
.
2535 [main] TRACE o.o.c.i.c.d.ConstructionHeuristicDecider - Move index (0), score (-2init/0hard/-3303soft), move (Lesson{id=998, subject='Math I', pinned=false, startTime=null, durationInGrains=2} {null -> 2020-10-13T20:00}).
2535 [main] DEBUG o.o.c.i.c.DefaultConstructionHeuristicPhase - CH step (997), time spent (1046), score (-2init/0hard/-3303soft), selected move count (1), picked move (Lesson{id=998, subject='Math I', pinned=false, startTime=null, durationInGrains=2} {null -> 2020-10-13T20:00}).
2536 [main] TRACE o.o.c.i.c.d.ConstructionHeuristicDecider - Move index (0), score (-1init/0hard/-3312soft), move (Lesson{id=999, subject='Math I', pinned=false, startTime=null, durationInGrains=3} {null -> 2021-08-26T22:00}).
2536 [main] DEBUG o.o.c.i.c.DefaultConstructionHeuristicPhase - CH step (998), time spent (1047), score (-1init/0hard/-3312soft), selected move count (1), picked move (Lesson{id=999, subject='Math I', pinned=false, startTime=null, durationInGrains=3} {null -> 2021-08-26T22:00}).
2537 [main] TRACE o.o.c.i.c.d.ConstructionHeuristicDecider - Move index (0), score (0hard/-3317soft), move (Lesson{id=1000, subject='Math I', pinned=false, startTime=null, durationInGrains=1} {null -> 2021-03-10T15:00}).
2537 [main] DEBUG o.o.c.i.c.DefaultConstructionHeuristicPhase - CH step (999), time spent (1048), score (0hard/-3317soft), selected move count (1), picked move (Lesson{id=1000, subject='Math I', pinned=false, startTime=null, durationInGrains=1} {null -> 2021-03-10T15:00}).
2540 [main] INFO o.o.c.i.c.DefaultConstructionHeuristicPhase - Construction Heuristic phase (0) ended: time spent (1051), best score (0hard/-3317soft), score calculation speed (1304/sec), step total (1000).
2549 [main] INFO o.o.core.impl.solver.DefaultSolver - Solving ended: time spent (1059), best score (0hard/-3317soft), score calculation speed (1169/sec), phase total (2), environment mode (NON_REPRODUCIBLE).
Is there a sufficient way to restrict steps from using pre-used value ranges? Would there be any draw backs?

Related

How to apply multithread function in optaplanner

I want to use multithread function in optaplaner.
I edited cloudBalancingSolverConfig.xml
and set multithread count 4
but I think it does not work.
All thread name is the same.
19:37:12.980 [l-4-thread-1] DEBUG CH step (1533), time spent (5839), score (-3266init/0hard/-909220soft), selected move count (1276), picked move (CloudProcess-1262 {null -> CloudComputer-1112}).
19:37:12.982 [l-4-thread-1] DEBUG CH step (1534), time spent (5841), score (-3265init/0hard/-909710soft), selected move count (1600), picked move (CloudProcess-1053 {null -> CloudComputer-908}).
19:37:12.984 [l-4-thread-1] DEBUG CH step (1535), time spent (5843), score (-3264init/0hard/-909710soft), selected move count (1277), picked move (CloudProcess-1049 {null -> CloudComputer-1138}).
19:37:12.987 [l-4-thread-1] DEBUG CH step (1536), time spent (5846), score (-3263init/0hard/-912110soft), selected move count (1600), picked move (CloudProcess-1003 {null -> CloudComputer-1231}).
19:37:12.990 [l-4-thread-1] DEBUG CH step (1537), time spent (5849), score (-3262init/0hard/-912110soft), selected move count (1278), picked move (CloudProcess-941 {null -> CloudComputer-1231}).
19:37:12.992 [l-4-thread-1] DEBUG CH step (1538), time spent (5851), score (-3261init/0hard/-912110soft), selected move count (1278), picked move (CloudProcess-893 {null -> CloudComputer-1231}).
19:37:12.994 [l-4-thread-1] DEBUG CH step (1539), time spent (5853), score (-3260init/0hard/-914510soft), selected move count (1600), picked move (CloudProcess-840 {null -> CloudComputer-1286}).
19:37:12.996 [l-4-thread-1] DEBUG CH step (1540), time spent (5855), score (-3259init/0hard/-916910soft), selected move count (1600), picked move (CloudProcess-820 {null -> CloudComputer-1311}).
19:37:12.998 [l-4-thread-1] DEBUG CH step (1541), time spent (5857), score (-3258init/0hard/-916910soft), selected move count (1278), picked move (CloudProcess-779 {null -> CloudComputer-1231}).
19:37:13.000 [l-4-thread-1] DEBUG CH step (1542), time spent (5859), score (-3257init/0hard/-916910soft), selected move count (1279), picked move (CloudProcess-768 {null -> CloudComputer-1286}).
19:37:13.003 [l-4-thread-1] DEBUG CH step (1543), time spent (5862), score (-3256init/0hard/-917470soft), selected move count (1600), picked move (CloudProcess-739 {null -> CloudComputer-750}).
19:37:13.005 [l-4-thread-1] DEBUG CH step (1544), time spent (5864), score (-3255init/0hard/-917470soft), selected move count (1278), picked move (CloudProcess-728 {null -> CloudComputer-1231}).
19:37:13.007 [l-4-thread-1] DEBUG CH step (1545), time spent (5866), score (-3254init/0hard/-917470soft), selected move count (1278), picked move (CloudProcess-671 {null -> CloudComputer-1231}).
19:37:13.009 [l-4-thread-1] DEBUG CH step (1546), time spent (5868), score (-3253init/0hard/-917470soft), selected move count (1279), picked move (CloudProcess-615 {null -> CloudComputer-1286}).
I checked rebased implementation in cloudChangeMove, couldSwapMove.
It was already implemented like belows.
#Override
public CloudComputerChangeMove rebase(ScoreDirector<CloudBalance> destinationScoreDirector) {
return new CloudComputerChangeMove(destinationScoreDirector.lookUpWorkingObject(cloudProcess),
destinationScoreDirector.lookUpWorkingObject(toCloudComputer));
}
Did I forget something?
The version of optaplaner is 7.23.
But it was the same previous version(7.22)
Please let me know my problem.
Turn on TRACE logging. The steps are done by the solver thread, the move evaluations (only visible in trace logging) are done by the move threads.

Optaplanner result is not reproducible

I have migrated from Optaplanner version 7.5 to 7.10. While migration I saw bulk(Output) is not the same. While running for another time I am not getting the same output. Can you share which are necessary steps I need to consider while migration? Can you help me out?
The Job schedule is different too. Screenshot attached below:
The primary difference is for Run 1 executes LS 11040 but Run 2 for the same time gets to reach LS 11600 plus with environment and other run parameters maintained without being changed.
Job Schedule diffference
log1_run
11:35:06.421 [main ] INFO Solving started: time spent (225), best score (-1722init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
11:35:06.682 [main ] DEBUG CH step (0), time spent (487), score (-1721init/0hard/0medium/-900000soft), selected move count (543), picked move (TimeWindowedCustomer-1 {null -> Vehicle-393}).
11:35:06.756 [main ] DEBUG CH step (1), time spent (561), score (-1720init/0hard/0medium/-1560000soft), selected move count (544), picked move (TimeWindowedCustomer-2 {null -> TimeWindowedCustomer-7}).
11:35:07.229 [main ] DEBUG CH step (2), time spent (1034), score (-1719init/0hard/0medium/-2520000soft), selected move count (545), picked move (TimeWindowedCustomer-3 {null -> Vehicle-396}).
11:35:07.266 [main ] DEBUG CH step (3), time spent (1071), score (-1718init/0hard/0medium/-3360000soft), selected move count (546), picked move (TimeWindowedCustomer-4 {null -> Vehicle-328}).
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
--------------------------------------------------
11:37:06.194 [main ] DEBUG LS step (11039), time spent (119999), score (0hard/-45187medium/-1556640000soft), best score (0hard/-45154medium/-1549560000soft), accepted/selected move count (1/3), picked move (TimeWindowedCustomer-1 {Vehicle-220} <-tailChainSwap-> TimeWindowedCustomer-8 {Vehicle-78}).
11:37:06.200 [main ] DEBUG LS step (11040), time spent (120005), score (-54512774442hard/-30651medium/-1659540000soft), best score (0hard/-45154medium/-1549560000soft), accepted/selected move count (0/1), picked move (TimeWindowedCustomer-12 {TimeWindowedCustomer-4} <-tailChainSwap-> null {TimeWindowedCustomer-16}).
11:37:06.203 [main ] INFO Local Search phase (1) ended: time spent (120008), best score (0hard/-45154medium/-1549560000soft), score calculation speed (5349/sec), step total (11041).
11:37:06.203 [main ] INFO Solving ended: time spent (120008), best score (0hard/-45154medium/-1549560000soft), score calculation speed (22645/sec), phase total (2), environment mode (REPRODUCIBLE).
log2 _run
11:38:29.684 [main ] INFO Solving started: time spent (213), best score (-1722init/0hard/0medium/0soft), environment mode (REPRODUCIBLE), random (JDK with seed 0).
11:38:29.955 [main ] DEBUG CH step (0), time spent (485), score (-1721init/0hard/0medium/-900000soft), selected move count (543), picked move (TimeWindowedCustomer-97041025 {null -> Vehicle-393}).
11:38:30.027 [main ] DEBUG CH step (1), time spent (557), score (-1720init/0hard/0medium/-1560000soft), selected move count (544), picked move (TimeWindowedCustomer-1 {null -> TimeWindowedCustomer-6}).
11:38:30.075 [main ] DEBUG CH step (2), time spent (605), score (-1719init/0hard/0medium/-2520000soft), selected move count (545), picked move (TimeWindowedCustomer-2 {null -> Vehicle-396}).
11:38:30.114 [main ] DEBUG CH step (3), time spent (644), score (-1718init/0hard/0medium/-3360000soft), selected move count (546), picked move (TimeWindowedCustomer-3 {null -> Vehicle-328}).
-------------------------------------------
--------------------------------------------
11:40:25.467 [main ] DEBUG LS step (11039), time spent (116004), score (0hard/-45187medium/-1556640000soft), best score (0hard/-45154medium/-1549560000soft), accepted/selected move count (1/3), picked move (TimeWindowedCustomer-1 {Vehicle-220} <-tailChainSwap-> TimeWindowedCustomer-8 {Vehicle-78}).
11:40:25.470 [main ] DEBUG LS step (11040), time spent (116011), score (0hard/-45187medium/-1556640000soft), best score (0hard/-45154medium/-1549560000soft), accepted/selected move count (0/1), picked move (TimeWindowedCustomer-12 {TimeWindowedCustomer-4} <-tailChainSwap-> null {TimeWindowedCustomer-16}).
--------------------------------------------
--------------------------------------------
11:40:29.474 [main ] DEBUG LS step (11674), time spent (120004), score (-4200029hard/-45093medium/-1554780000soft), best score (0hard/-45064medium/-1558380000soft), accepted/selected move count (0/1), picked move (TimeWindowedCustomer-9 {TimeWindowedCustomer-5 -> TimeWindowedCustomer-2}).
11:40:29.477 [main ] INFO Local Search phase (1) ended: time spent (120007), best score (0hard/-45064medium/-1558380000soft), score calculation speed (5451/sec), step total (11675).
11:40:29.477 [main ] INFO Solving ended: time spent (120007), best score (0hard/-45064medium/-1558380000soft), score calculation speed (22762/sec), phase total (2), environment mode (REPRODUCIBLE).
Reproducibility is only guaranteed on each step index, not on time (although they are correlated). When using time spent termination, for example 2 minutes, there is no guarantee how much CPU cycles OptaPlanner will get and how and when the JVM will hotspot optimize. In some situations, it might actually get almost no CPU cycles. In other situations it gets plenty - in any case OptaPlanner uses what it gets, nothing goes to waste.
Looking at the step index level, the two runs are exactly the same (except for the time spent):
First run:
11:37:06.194 ...LS step (11039), time spent (119999), score (0hard/-45187medium/-1556640000soft), best score (0hard/-45154medium/-1549560000soft), accepted/selected move count (1/3), picked move (TimeWindowedCustomer-1 {Vehicle-220} <-tailChainSwap-> TimeWindowedCustomer-8 {Vehicle-78}).
Second run:
11:40:25.467 ...LS step (11039), time spent (116004), score (0hard/-45187medium/-1556640000soft), best score (0hard/-45154medium/-1549560000soft), accepted/selected move count (1/3), picked move (TimeWindowedCustomer-1 {Vehicle-220} <-tailChainSwap-> TimeWindowedCustomer-8 {Vehicle-78}).
To get the exact same result between 2 results, use a step limit termination instead.

Nurse rostering modification

Hi I'm new on Optaplanner and I'm trying to adapt nurse rostering for airport checkin agent rostering. I've created A FlightAssignment in which an Employee is assigned to a Flight.
The Employee is the PlanningVariable.
The FlightAssignment is the PlanningEntity.
The CheckinRoster is the PlanningEntityCollectionProperty
Please help me, when I run the CheckinRosteringApp I get this error:
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)
And if I initialize the flightAssignmentList the error disappear but the solution is empty.
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).
[...]
Did I make something wrong in the xml config file? I used the one in nurserostering deleting the unionMoveSelector block hoping in optaplanner searching for a solution.
This is the 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>
And this is the 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.
Check your method CheckinRoster.getFlightAssignmentList(). For that dataset, it's apparently returning null.

Optaplanner - local phase 0 step in total in 1 minute

I have set up a solver with two local search phases and it works fine. However, there was a time that the 2nd phase didn't make any move in about 1 minute, as the log shows below:
...
2016-05-07 14:14:55,847 [main] DEBUG LS step (10069), time spent (593822), score (0hard/-81medium/5395020soft), best score (0hard/-80medium/5393781soft), accepted/selected move count (5/48), picked move (CL [cID=1147576, id=27246 => SL [id=49, sID=E942648]] <=> CL [cID=1133912, id=14716 => SL [ id=7, sID=E942592]]).
2016-05-07 14:14:55,858 [main] DEBUG LS step (10070), time spent (593833), score (0hard/-81medium/5395390soft), best score (0hard/-80medium/5393781soft), accepted/selected move count (5/18), picked move (CL [cID=1142322, id=22533 => SL [ id=51, sID=E943251]] <=> CL [cID=1134362, id=14118 => SL [ id=49, sID=E942648]]).
2016-05-07 14:14:55,858 [main] INFO Local Search phase (1) ended: step total (10071), time spent (593833), best score (0hard/-80medium/5393781soft).
2016-05-07 14:16:05,042 [main] INFO Local Search phase (2) ended: step total (0), time spent (663017), best score (0hard/-80medium/5393781soft).
2016-05-07 14:16:05,042 [main] INFO Solving ended: time spent (663017), best score (0hard/-80medium/5393781soft), average calculate count per second (2771).
Before phase 1 ended, there wasn't any improvement in the last couple of steps. And phase 2 started but made 0 step in a minute. The solver then ended because it has reached the maximum time allowed.
I'm a bit surprised that phase 2 made no step at all. Is it simply because it didn't manage to find any better score?
If you don't see any moves in TRACE log (as suggested in comments), it could be because you're using a custom move list factory and that's taken too long to initialize.

Optaplanner - Local search phase terminated without picking a nextStep

I ran into a situation where only two valid moves that is allowed happens during the construction phase. This results in a situation where there is no valid moves to perform during local search phase. All the moves tried during the local search phase is not doable.
This results in NullPointerException at the end of local search phase.
Exception in thread "main" java.lang.NullPointerException
at org.optaplanner.core.impl.solver.scope.DefaultSolverScope.getBestScoreWithUninitializedPrefix(DefaultSolverScope.java:205)
at org.optaplanner.core.impl.solver.DefaultSolver.outerSolvingEnded(DefaultSolver.java:216)
at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:161)
at com.example.jobplanner.Application.main(Application.java:328)
Here is the trace of the two valid moves that happens during the construction phase.
CH step (0), time spent (151), score (0hard/0soft), selected move count (1), picked move (com.example.jobplanner.domain.ServiceJobChip#981500 => com.example.jobplanner.domain.ShopFloorBay#9da471).
Update [fact 0:5:4216052:4216052:10:DEFAULT:NON_TRAIT:com.example.jobplanner.domain.ServiceJobChip#4054f4]
CH step (1), time spent (158), score (0hard/0soft), selected move count (1), picked move (com.example.jobplanner.domain.ServiceJobChip#4054f4 => com.example.jobplanner.domain.ShopFloorBay#15ac5d5).
Construction Heuristic phase (0) ended: step total (2), time spent (159), best score (null).
The model of the domain I am trying to optimize would be something like:
Each bay has --> set of tasks that can be performed
Job -> collection of tasks to be performed
Task --> can be scheduled to bays which can perform the task