[jboss-svn-commits] JBL Code SVN: r33440 - labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Jun 10 13:42:53 EDT 2010
Author: ge0ffrey
Date: 2010-06-10 13:42:53 -0400 (Thu, 10 Jun 2010)
New Revision: 33440
Added:
labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength2MoveFactory.java
labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength3MoveFactory.java
Log:
The Sequence Switch Length 2 and 3
Copied: labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength2MoveFactory.java (from rev 33370, labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchMoveFactory.java)
===================================================================
--- labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength2MoveFactory.java (rev 0)
+++ labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength2MoveFactory.java 2010-06-10 17:42:53 UTC (rev 33440)
@@ -0,0 +1,142 @@
+package org.drools.planner.examples.nurserostering.solver.move.factory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.drools.planner.core.move.CompositeMove;
+import org.drools.planner.core.move.Move;
+import org.drools.planner.core.move.factory.AbstractMoveFactory;
+import org.drools.planner.core.solution.Solution;
+import org.drools.planner.examples.nurserostering.domain.Assignment;
+import org.drools.planner.examples.nurserostering.domain.Employee;
+import org.drools.planner.examples.nurserostering.domain.NurseRoster;
+import org.drools.planner.examples.nurserostering.domain.solver.EmployeeWorkSequence;
+import org.drools.planner.examples.nurserostering.solver.move.EmployeeChangeMove;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class AssignmentSequenceSwitchLength2MoveFactory extends AbstractMoveFactory {
+
+ public List<Move> createMoveList(Solution solution) {
+ NurseRoster nurseRoster = (NurseRoster) solution;
+ List<Employee> employeeList = nurseRoster.getEmployeeList();
+ // This code assumes the assignmentList is sorted
+ List<Assignment> assignmentList = nurseRoster.getAssignmentList();
+
+ // Hash the assignments per employee
+ Map<Employee, List<AssignmentSequence>> employeeToAssignmentSequenceListMap
+ = new HashMap<Employee, List<AssignmentSequence>>(employeeList.size());
+ int assignmentSequenceCapacity = nurseRoster.getShiftDateList().size() + 1 / 2;
+ for (Employee employee : employeeList) {
+ employeeToAssignmentSequenceListMap.put(employee,
+ new ArrayList<AssignmentSequence>(assignmentSequenceCapacity));
+ }
+ for (Assignment assignment : assignmentList) {
+ Employee employee = assignment.getEmployee();
+ List<AssignmentSequence> assignmentSequenceList = employeeToAssignmentSequenceListMap.get(employee);
+ if (assignmentSequenceList.isEmpty()) {
+ AssignmentSequence assignmentSequence = new AssignmentSequence(assignment);
+ assignmentSequenceList.add(assignmentSequence);
+ } else {
+ AssignmentSequence lastAssignmentSequence = assignmentSequenceList // getLast()
+ .get(assignmentSequenceList.size() - 1);
+ if (lastAssignmentSequence.belongsHere(assignment)) {
+ lastAssignmentSequence.add(assignment);
+ } else {
+ AssignmentSequence assignmentSequence = new AssignmentSequence(assignment);
+ assignmentSequenceList.add(assignmentSequence);
+ }
+ }
+ }
+
+ // The create the move list
+ List<Move> moveList = new ArrayList<Move>();
+ // For every 2 distinct employees
+ for (ListIterator<Employee> leftEmployeeIt = employeeList.listIterator(); leftEmployeeIt.hasNext();) {
+ Employee leftEmployee = leftEmployeeIt.next();
+ List<AssignmentSequence> leftAssignmentSequenceList
+ = employeeToAssignmentSequenceListMap.get(leftEmployee);
+ for (ListIterator<Employee> rightEmployeeIt = employeeList.listIterator(leftEmployeeIt.nextIndex());
+ rightEmployeeIt.hasNext();) {
+ Employee rightEmployee = rightEmployeeIt.next();
+ List<AssignmentSequence> rightAssignmentSequenceList
+ = employeeToAssignmentSequenceListMap.get(rightEmployee);
+
+ final int SWITCH_LENGTH = 2;
+ for (AssignmentSequence leftAssignmentSequence : leftAssignmentSequenceList) {
+ List<Assignment> leftAssignmentList = leftAssignmentSequence.getAssignmentList();
+ for (int leftIndex = 0; leftIndex <= leftAssignmentList.size() - SWITCH_LENGTH; leftIndex++) {
+
+ for (AssignmentSequence rightAssignmentSequence : rightAssignmentSequenceList) {
+ List<Assignment> rightAssignmentList = rightAssignmentSequence.getAssignmentList();
+ for (int rightIndex = 0; rightIndex <= rightAssignmentList.size() - SWITCH_LENGTH; rightIndex++) {
+
+ List<Move> subMoveList = new ArrayList<Move>(SWITCH_LENGTH * 2);
+ for (Assignment leftAssignment : leftAssignmentList
+ .subList(leftIndex, leftIndex + SWITCH_LENGTH)) {
+ subMoveList.add(new EmployeeChangeMove(leftAssignment, rightEmployee));
+ }
+ for (Assignment rightAssignment : rightAssignmentList
+ .subList(rightIndex, rightIndex + SWITCH_LENGTH)) {
+ subMoveList.add(new EmployeeChangeMove(rightAssignment, leftEmployee));
+ }
+ moveList.add(new CompositeMove(subMoveList));
+ }
+ }
+ }
+ }
+ }
+ }
+ return moveList;
+ }
+
+ /**
+ * TODO DRY with {@link EmployeeWorkSequence}
+ */
+ private static class AssignmentSequence {
+
+ private List<Assignment> assignmentList;
+ private int firstDayIndex;
+ private int lastDayIndex;
+
+ private AssignmentSequence(Assignment assignment) {
+ assignmentList = new ArrayList<Assignment>();
+ firstDayIndex = assignment.getShiftDateDayIndex();
+ lastDayIndex = firstDayIndex;
+ }
+
+ public List<Assignment> getAssignmentList() {
+ return assignmentList;
+ }
+
+ public int getFirstDayIndex() {
+ return firstDayIndex;
+ }
+
+ public int getLastDayIndex() {
+ return lastDayIndex;
+ }
+
+ private void add(Assignment assignment) {
+ assignmentList.add(assignment);
+ int dayIndex = assignment.getShiftDateDayIndex();
+ if (dayIndex < lastDayIndex) {
+ throw new IllegalStateException("The assignmentList is expected to be sorted by shiftDate.");
+ }
+ lastDayIndex = dayIndex;
+ }
+
+ private boolean belongsHere(Assignment assignment) {
+ return assignment.getShiftDateDayIndex() <= (lastDayIndex + 1);
+ }
+
+ }
+
+}
Copied: labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength3MoveFactory.java (from rev 33370, labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchMoveFactory.java)
===================================================================
--- labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength3MoveFactory.java (rev 0)
+++ labs/jbossrules/trunk/drools-planner/drools-planner-examples/src/main/java/org/drools/planner/examples/nurserostering/solver/move/factory/AssignmentSequenceSwitchLength3MoveFactory.java 2010-06-10 17:42:53 UTC (rev 33440)
@@ -0,0 +1,139 @@
+package org.drools.planner.examples.nurserostering.solver.move.factory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.drools.planner.core.move.CompositeMove;
+import org.drools.planner.core.move.Move;
+import org.drools.planner.core.move.factory.AbstractMoveFactory;
+import org.drools.planner.core.solution.Solution;
+import org.drools.planner.examples.nurserostering.domain.Assignment;
+import org.drools.planner.examples.nurserostering.domain.Employee;
+import org.drools.planner.examples.nurserostering.domain.NurseRoster;
+import org.drools.planner.examples.nurserostering.domain.solver.EmployeeWorkSequence;
+import org.drools.planner.examples.nurserostering.solver.move.EmployeeChangeMove;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class AssignmentSequenceSwitchLength3MoveFactory extends AbstractMoveFactory {
+
+ public List<Move> createMoveList(Solution solution) {
+ NurseRoster nurseRoster = (NurseRoster) solution;
+ List<Employee> employeeList = nurseRoster.getEmployeeList();
+ // This code assumes the assignmentList is sorted
+ List<Assignment> assignmentList = nurseRoster.getAssignmentList();
+
+ // Hash the assignments per employee
+ Map<Employee, List<AssignmentSequence>> employeeToAssignmentSequenceListMap
+ = new HashMap<Employee, List<AssignmentSequence>>(employeeList.size());
+ int assignmentSequenceCapacity = nurseRoster.getShiftDateList().size() + 1 / 2;
+ for (Employee employee : employeeList) {
+ employeeToAssignmentSequenceListMap.put(employee,
+ new ArrayList<AssignmentSequence>(assignmentSequenceCapacity));
+ }
+ for (Assignment assignment : assignmentList) {
+ Employee employee = assignment.getEmployee();
+ List<AssignmentSequence> assignmentSequenceList = employeeToAssignmentSequenceListMap.get(employee);
+ if (assignmentSequenceList.isEmpty()) {
+ AssignmentSequence assignmentSequence = new AssignmentSequence(assignment);
+ assignmentSequenceList.add(assignmentSequence);
+ } else {
+ AssignmentSequence lastAssignmentSequence = assignmentSequenceList // getLast()
+ .get(assignmentSequenceList.size() - 1);
+ if (lastAssignmentSequence.belongsHere(assignment)) {
+ lastAssignmentSequence.add(assignment);
+ } else {
+ AssignmentSequence assignmentSequence = new AssignmentSequence(assignment);
+ assignmentSequenceList.add(assignmentSequence);
+ }
+ }
+ }
+
+ // The create the move list
+ List<Move> moveList = new ArrayList<Move>();
+ // For every 2 distinct employees
+ for (ListIterator<Employee> leftEmployeeIt = employeeList.listIterator(); leftEmployeeIt.hasNext();) {
+ Employee leftEmployee = leftEmployeeIt.next();
+ List<AssignmentSequence> leftAssignmentSequenceList
+ = employeeToAssignmentSequenceListMap.get(leftEmployee);
+ for (ListIterator<Employee> rightEmployeeIt = employeeList.listIterator(leftEmployeeIt.nextIndex());
+ rightEmployeeIt.hasNext();) {
+ Employee rightEmployee = rightEmployeeIt.next();
+ List<AssignmentSequence> rightAssignmentSequenceList
+ = employeeToAssignmentSequenceListMap.get(rightEmployee);
+
+ final int SWITCH_LENGTH = 3;
+ for (AssignmentSequence leftAssignmentSequence : leftAssignmentSequenceList) {
+ List<Assignment> leftAssignmentList = leftAssignmentSequence.getAssignmentList();
+ for (int leftIndex = 0; leftIndex <= leftAssignmentList.size() - SWITCH_LENGTH; leftIndex++) {
+
+ for (AssignmentSequence rightAssignmentSequence : rightAssignmentSequenceList) {
+ List<Assignment> rightAssignmentList = rightAssignmentSequence.getAssignmentList();
+ for (int rightIndex = 0; rightIndex <= rightAssignmentList.size() - SWITCH_LENGTH; rightIndex++) {
+
+ List<Move> subMoveList = new ArrayList<Move>(SWITCH_LENGTH * 2);
+ for (Assignment leftAssignment : leftAssignmentList
+ .subList(leftIndex, leftIndex + SWITCH_LENGTH)) {
+ subMoveList.add(new EmployeeChangeMove(leftAssignment, rightEmployee));
+ }
+ for (Assignment rightAssignment : rightAssignmentList
+ .subList(rightIndex, rightIndex + SWITCH_LENGTH)) {
+ subMoveList.add(new EmployeeChangeMove(rightAssignment, leftEmployee));
+ }
+ moveList.add(new CompositeMove(subMoveList));
+ }
+ }
+ }
+ }
+ }
+ }
+ return moveList;
+ }
+
+ /**
+ * TODO DRY with {@link EmployeeWorkSequence}
+ */
+ private static class AssignmentSequence {
+
+ private List<Assignment> assignmentList;
+ private int firstDayIndex;
+ private int lastDayIndex;
+
+ private AssignmentSequence(Assignment assignment) {
+ assignmentList = new ArrayList<Assignment>();
+ firstDayIndex = assignment.getShiftDateDayIndex();
+ lastDayIndex = firstDayIndex;
+ }
+
+ public List<Assignment> getAssignmentList() {
+ return assignmentList;
+ }
+
+ public int getFirstDayIndex() {
+ return firstDayIndex;
+ }
+
+ public int getLastDayIndex() {
+ return lastDayIndex;
+ }
+
+ private void add(Assignment assignment) {
+ assignmentList.add(assignment);
+ int dayIndex = assignment.getShiftDateDayIndex();
+ if (dayIndex < lastDayIndex) {
+ throw new IllegalStateException("The assignmentList is expected to be sorted by shiftDate.");
+ }
+ lastDayIndex = dayIndex;
+ }
+
+ private boolean belongsHere(Assignment assignment) {
+ return assignment.getShiftDateDayIndex() <= (lastDayIndex + 1);
+ }
+
+ }
+
+}
More information about the jboss-svn-commits
mailing list