2017-03-03 4 views
0

Hallo, ich bin neu auf Optaplanner und ich versuche, Krankenschwester Dienstplan für Flughafen Checkin Agent Dienstplan anzupassen. Ich habe eine FlightAssignment erstellt, in der ein Mitarbeiter einem Flug zugeordnet ist.Krankenschwester Planung Änderung

Die Mitarbeiter ist die PlanningVariable.

Die FlightAssignment ist die PlanningEntity.

Die CheckinRoster ist die PlanningEntityCollectionProperty

Bitte helfen Sie mir, wenn ich die CheckinRosteringApp laufen bekomme ich diesen Fehler:

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) 

Und wenn ich die flightAssignmentList initialisieren der Fehler verschwinden, aber die Lösung ist leer.

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). 
[...] 

Habe ich in der XML-Konfigurationsdatei etwas falsch gemacht? Ich habe das in Nurserostering verwendet, um den unionMoveSelector-Block zu löschen, in der Hoffnung, dass der optaplanner nach einer Lösung sucht.

Dies ist der 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> 

Und das ist die 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 
+0

Dies ist eine schreckliche Menge an Informationen zu sortieren. Vielleicht zu viel für eine Stackoverflow-Frage. – hatchet

+0

Ich habe gerade alle beteiligten Klassen und Dateien hinzugefügt. Etwas, das ich gefunden habe, ist, dass die Initialisierung flightAssignmentList in CheckinRoster Klasse der Fehler verschwindet, aber es gibt eine leere Lösung. Ich dachte, dass flightAssignmentList von optaplanner selbst initialisiert werden könnte. – Giancarlo

+0

Bitte erstellen Sie ein [minimales, vollständiges und verifizierbares Beispiel] (http://stackoverflow.com/help/mcve), das ist viel zu viel Code. –

Antwort

0

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() Ihre Methode überprüfen. Für dieses Dataset wird scheinbar null zurückgegeben.

+0

Danke Geoffry. Das war es. Die flightAssignmentList sollte nicht null sein. Und dann habe ich es auch mit flightAssignments mit einem Flug besetzt. So ist das Programm jetzt in der Lage, Dienstpläne zu erstellen. – Giancarlo