Employee rostering

http://docs.jboss.org/optaplanner/release/latest/optaplanner-docs/html_single/index.html#nurseRostering
従業員のシフト最適化です。"Nurse Rostering Competition" ていう競技があって (http://www.kuleuven-kulak.be/nrpcompetition)、その問題を実装しています。
- NurseRoster : @PlanningSolution
- ShiftAssignment : @PlanningEntity
- Employee : @PlanningVariable
- Shift shift
- int indexInShift
@PlanningEntity、@PlanningVariable がひとつずつなので比較的シンプルです。Skill や Contract など Employee に関する属性はいろいろあって、制約に使われます。Soft制約がかなりたくさんある。。。けど特筆するものは無いかな。
<localSearch>
<unionMoveSelector>
<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>
<!--<moveListFactory>-->
<!--<cacheType>STEP</cacheType>-->
<!--<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentSequenceSwitchLength2MoveFactory</moveListFactoryClass>-->
<!--</moveListFactory>-->
<!--<moveListFactory>-->
<!--<cacheType>STEP</cacheType>-->
<!--<moveListFactoryClass>org.optaplanner.examples.nurserostering.solver.move.factory.ShiftAssignmentSequenceSwitchLength3MoveFactory</moveListFactoryClass>-->
<!--</moveListFactory>-->
</unionMoveSelector>
<acceptor>
<entityTabuSize>7</entityTabuSize>
</acceptor>
<forager>
<acceptedCountLimit>800</acceptedCountLimit>
</forager>
</localSearch>指定された EmployeeChangeMoveFactory, ShiftAssignmentSwapMoveFactory, ShiftAssignmentPillarPartSwapMoveFactory は基本的に MovableShiftAssignmentSelectionFilter を使って isInPlanningWindow、つまり現在プランニング対象の期間のシフトだけ、Move の対象にしています。
あと、ShiftAssignmentPillarPartSwapMoveFactory は複雑です。。。ぐぬぬ、自信が無いが、同じ Employee のシフトをまとめて動かして CompositeMove にしているようです。