2016-03-17 1 views
2

Je travaille sur une solution d'un problème proche de l'exemple Infirmier Rostering dans optaplanner. Les employés sont affectés aux quarts de travail comme dans la liste des infirmières, mais la principale différence est qu'il y a aussi des exigences de compétences (affectations) qui durent 20 minutes. Un employé peut être affecté à un besoin de compétences s'il est affecté à un quart de travail qui couvre le temps requis. Disons que nous avons un besoin de compétences pour Skill1 de 12h00 à 12h20 et qu'un employé est affecté sur un poste de 08h00 à 16h00, alors il ne peut être affecté à cette compétence que s'il possède cette compétence.Problèmes liés à la configuration du solveur pour deux classes d'entités de planification

J'ai 2 classes d'entités de planification. L'affectation de décalage par défaut dans l'exemple, et j'ai mis en place 2 classes de classe SkillRequirement qui tiendra une exigence de compétences dans le délai donné (ce sera un fait de planification), et la deuxième classe d'entité de planification sera entre l'employé et le La classe SkillRequirement et son nom seront EmployeeSkillRequirement. Maintenant, je pense que j'ai fait tout bon J'ai annoté la classe EmployeeSkillRequirement comme @PlanningEntity et la variable de planification avec la plage de valeurs appropriée, dans la solution de planification j'ai ajouté les listes pour les besoins de compétences (qui sont des faits et aussi aller dans la mémoire de travail drools) et la liste des employés sur les exigences de compétences qui sont les entités de planification et sont correctement annotées avec @PlanningEntitySolutionProperty

J'ai du mal à configurer le solveur, j'ai essayé beaucoup de différentes configurations de solveur, je lire dans la documentation que lorsqu'il y a plus d'entités de planification et/ou de variables de planification, une union de sélecteurs de mouvement doit être utilisée lorsque vous dites à OptaPlanner le nom du planni ng classe d'entité et variable de planification, car elle ne peut pas le trouver par défaut.

Aucun semblent fonctionner et je reçois cette exception tout le temps

Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/nurserostering/solver/nurseRosteringSolverConfig.xml) fails. 

Voici les configurations i » ai essayé d'utiliser:

Config 1:

Dans ce configuration les sélecteurs de mouvement par défaut sont utilisés pour la classe d'affectation de décalage d'entité de planification dans la recherche locale et se déplacer sélecteurs sont "EmployeeSkillRequirement" est ajouté pour la classe d'entité de planification et tout est combiné dans un et l'heuristique de construction est remplacée par des sélecteurs de mouvement combinés dans une union à.

<?xml version="1.0" encoding="UTF-8"?> 
<solver> 
<!--<environmentMode>FAST_ASSERT</environmentMode> --> 
<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster 
</solutionClass> 
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
</entityClass> 
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
</entityClass> 
<scoreDirectorFactory> 
    <scoreDefinitionType>HARD_SOFT</scoreDefinitionType> 
    <scoreDrl>org/optaplanner/examples/nurserostering/solver/nurseRosteringScoreRules.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> 
    <queuedEntityPlacer> 
     <unionMoveSelector> 
      <changeMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </downcastEntityClass> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </changeMoveSelector> 
      <swapMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </downcastEntityClass> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </swapMoveSelector> 
      <changeMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </changeMoveSelector> 
      <swapMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </swapMoveSelector> 
     </unionMoveSelector> 
    </queuedEntityPlacer> 
</constructionHeuristic> 
<localSearch> 
    <unionMoveSelector> 

     <!-- Move Selectors for ShiftAssignment this was the default configuration 
      from the example --> 
     <moveListFactory> 
      <cacheType>PHASE</cacheType> 
      <moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.EmployeeChangeMoveFactory 
      </moveListFactoryClass> 
     </moveListFactory> 
     <moveListFactory> 
      <cacheType>PHASE</cacheType> 
      <moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentSwapMoveFactory 
      </moveListFactoryClass> 
     </moveListFactory> 
     <moveListFactory> 
      <cacheType>STEP</cacheType> 
      <moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentPillarPartSwapMoveFactory 
      </moveListFactoryClass> 
     </moveListFactory> 


     <!-- The move selectors for the second plannig entity class EmployeeSkillRequirement --> 
     <changeMoveSelector> 
      <entitySelector> 
       <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
       </entityClass> 
      </entitySelector> 
      <valueSelector> 
       <variableName>employee</variableName> 
      </valueSelector> 
     </changeMoveSelector> 
     <swapMoveSelector> 
      <entitySelector> 
       <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
       </entityClass> 
      </entitySelector> 
      <valueSelector> 
       <variableName>employee</variableName> 
      </valueSelector> 
     </swapMoveSelector> 
    </unionMoveSelector> 
    <acceptor> 
     <entityTabuSize>7</entityTabuSize> 
    </acceptor> 
    <forager> 
     <acceptedCountLimit>800</acceptedCountLimit> 
    </forager> 
</localSearch> 

Config 2:

Deuxièmement, je regardais la documentation et a trouvé cette astuce qui dit qu'il est plus facile de traiter avec de multiples classes d'entités de planification s'il y a deux heuristique de construction différents pièces pour chacun d'eux http://docs.jboss.org/optaplanner/release/6.3.0.Final/optaplanner-docs/html_single/index.html#allocateEntityFromQueueMultipleEntityClasses donc j'ai essayé cette configuration aussi.

<?xml version="1.0" encoding="UTF-8"?> 
<solver> 
<!--<environmentMode>FAST_ASSERT</environmentMode> --> 
<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster 
</solutionClass> 
<entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
</entityClass> 
<entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
</entityClass> 
<scoreDirectorFactory> 
    <scoreDefinitionType>HARD_SOFT</scoreDefinitionType> 
    <scoreDrl>org/optaplanner/examples/nurserostering/solver/nurseRosteringScoreRules.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> 
    <queuedEntityPlacer> 
     <unionMoveSelector> 
      <changeMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </downcastEntityClass> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </changeMoveSelector> 
      <swapMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
        </downcastEntityClass> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </swapMoveSelector> 
     </unionMoveSelector> 
    </queuedEntityPlacer> 
</constructionHeuristic> 
<constructionHeuristic> 
    <queuedEntityPlacer> 
     <unionMoveSelector> 
      <changeMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
        </downcastEntityClass> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </changeMoveSelector> 
      <swapMoveSelector> 
       <entitySelector> 
        <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
        </entityClass> 
       </entitySelector> 
       <valueSelector> 
        <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
        </downcastEntityClass> 
        <variableName>employee</variableName> 
       </valueSelector> 
      </swapMoveSelector> 
     </unionMoveSelector> 
    </queuedEntityPlacer> 
</constructionHeuristic> 
<localSearch> 
    <unionMoveSelector> 

     <!-- Move Selectors for ShiftAssignment this was the default configuration 
      from the example --> 
     <moveListFactory> 
      <cacheType>PHASE</cacheType> 
      <moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.EmployeeChangeMoveFactory 
      </moveListFactoryClass> 
     </moveListFactory> 
     <moveListFactory> 
      <cacheType>PHASE</cacheType> 
      <moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentSwapMoveFactory 
      </moveListFactoryClass> 
     </moveListFactory> 
     <moveListFactory> 
      <cacheType>STEP</cacheType> 
      <moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentPillarPartSwapMoveFactory 
      </moveListFactoryClass> 
     </moveListFactory> 
     <!-- besides this default configuration from optaplaner i also tried this here 

     <changeMoveSelector> 
      <entitySelector> 
       <entityClass>org.optaplanner.examples.nurserostering.domain. 
       </entityClass> 
      </entitySelector> 
      <valueSelector> 
       <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
       </downcastEntityClass> 
       <variableName>employee</variableName> 
      </valueSelector> 
     </changeMoveSelector> 
     <swapMoveSelector> 
      <entitySelector> 
       <entityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
       </entityClass> 
      </entitySelector> 
      <valueSelector> 
       <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.ShiftAssignment 
       </downcastEntityClass> 
       <variableName>employee</variableName> 
      </valueSelector> 
     </swapMoveSelector>--> 


     <!-- The move selectors for the second plannig entity class EmployeeSkillRequirement --> 
     <changeMoveSelector> 
      <entitySelector> 
       <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
       </entityClass> 
      </entitySelector> 
      <valueSelector> 
       <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
       </downcastEntityClass> 
       <variableName>employee</variableName> 
      </valueSelector> 
     </changeMoveSelector> 
     <swapMoveSelector> 
      <entitySelector> 
       <entityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
       </entityClass> 
      </entitySelector> 
      <valueSelector> 
       <downcastEntityClass>org.optaplanner.examples.nurserostering.domain.EmployeeSkillRequirement 
       </downcastEntityClass> 
       <variableName>employee</variableName> 
      </valueSelector> 
     </swapMoveSelector> 
    </unionMoveSelector> 
    <acceptor> 
     <entityTabuSize>7</entityTabuSize> 
    </acceptor> 
    <forager> 
     <acceptedCountLimit>800</acceptedCountLimit> 
    </forager> 
</localSearch> 

J'ai essayé aussi d'autres configurations qui sont semblables à celles-ci, encore, pas de chance.

Comment puis-je résoudre ce problème et le faire fonctionner?

Edit:

Exception in thread "main" java.lang.IllegalArgumentException: Unmarshalling of solverConfigResource (org/optaplanner/examples/nurserostering/solver/nurseRosteringSolverConfig.xml) fails. 
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:114) 
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:66) 
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.createSolver(NurseRosteringApp.java:50) 
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:90) 
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:77) 
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:73) 
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.main(NurseRosteringApp.java:38) 
Caused by: " com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelectorConfig.valueSelector 
---- Debugging information ---- 
field    : valueSelector 
class    :  org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelect orConfig 
required-type  :  org.optaplanner.core.config.heuristic.selector.move.generic.SwapMoveSelect orConfig 
converter-type  : com.thoughtworks.xstream.converters.reflection.ReflectionConverter 
line number   : 98 
class[1]   :  org.optaplanner.core.config.heuristic.selector.move.composite.UnionMoveSel ectorConfig 
class[2]   : org.optaplanner.core.config.localsearch.LocalSearchPhaseConfig 
class[3]   : org.optaplanner.core.config.solver.SolverConfig 
version    : 1.4.7 
------------------------------- 
at org.optaplanner.core.impl.solver.XStreamXmlSolverFactory.configure(XStreamXmlSolverFactory.java:114) 
at org.optaplanner.core.api.solver.SolverFactory.createFromXmlResource(SolverFactory.java:66) 
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.createSolver(NurseRosteringApp.java:50) 
at org.optaplanner.examples.common.app.CommonApp.createSolutionBusiness(CommonApp.java:90) 
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:77) 
at org.optaplanner.examples.common.app.CommonApp.init(CommonApp.java:73) 
at org.optaplanner.examples.nurserostering.app.NurseRosteringApp.main(NurseRosteringApp.java:38) 
+0

Quelle est la cause de cette exception par illegalargument? Le message d'exception XStream doit indiquer clairement ce qui n'a pas été analysé. Je suppose que cela peut être différent pour les deux configurations que vous avez écrites ici. Nous avons l'intention de fournir un schéma XSD tôt ou tard. –

+1

A propos de config 1: Un 'swapMoveSelector' imbriqué dans un' constructionHeuristic' n'a pas de sens. Voir [cette section] (http://docs.jboss.org/optaplanner/release/latest/optaplanner-docs/html_single/index.html#allocateEntityFromQueueMultipleEntityClasses) des documents. –

Répondre

2

Une erreur commune est d'ajouter des espaces dans les propriétés de className qui ne soit pas analysé correctement. Cela échoue lors de l'analyse syntaxique:

<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster 
</solutionClass> 

mais réussit à s'analysable:

<solutionClass>org.optaplanner.examples.nurserostering.domain.NurseRoster</solutionClass> 
+0

Cela a fonctionné comme un charme. Merci. J'ai également supprimé le swapMoveSelector de l'heuristique de construction comme vous l'avez suggéré. Maintenant, je reçois une autre erreur, je l'ai posté comme un edit. –

+1

Il est préférable de créer une nouvelle question pour les nouvelles questions, sinon elle devient trop longue à lire (et aussi pour intéresser les autres utilisateurs ayant le même problème pour l'identifier comme telle). Cela étant dit, c'est une autre erreur d'unmarshalling de Xstream. Si vous vérifiez le message d'erreur, cela indique essentiellement que vous avez un élément '' dans un élément ', mais si vous regardez le' SwapMoveSelectorConfig', vous remarquerez qu'il n'y a pas de champ de ce type. –

+1

Oh oui: ** pour trouver la classe Java pour un élément XML, il suffit d'ajouter le suffixe 'Config' à son nom **. –