diff --git a/Travail_de_session/ScheduleUtil/SchedulesArray.java b/Travail_de_session/ScheduleUtil/SchedulesArray.java index 6135017..a4a4bd8 100644 --- a/Travail_de_session/ScheduleUtil/SchedulesArray.java +++ b/Travail_de_session/ScheduleUtil/SchedulesArray.java @@ -41,9 +41,11 @@ public class SchedulesArray { } protected boolean[][] getDeepCopyEmployeesSchedules(boolean[][] schedules) { - boolean[][] copySchedules = new boolean[schedules.length][myParametersInitialSchedules.getWorkPeriodsPerSchedule()]; - for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) { - for (int employee = 0; employee < schedules.length; employee++) { + int nbrEmployee = schedules.length; + int nbrWorkPeriod = schedules[0].length; + boolean[][] copySchedules = new boolean[nbrEmployee][nbrWorkPeriod]; + for (int workPeriod = 0; workPeriod < nbrWorkPeriod; workPeriod++) { + for (int employee = 0; employee < nbrEmployee; employee++) { copySchedules[employee][workPeriod] = schedules[employee][workPeriod]; } } diff --git a/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java b/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java index 0fae7a4..3bd580a 100644 --- a/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java +++ b/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java @@ -29,64 +29,79 @@ public class RecoveredSchedulesArray extends SchedulesArray{ boolean[][] currentRecoveredScheduleOfPartTimeEmployees = this.getDeepCopyEmployeesSchedules(this.absenceSchedulesArray.partTimeSchedules); boolean[][] currentRecoveredScheduleOfFullTimeEmployees = this.getDeepCopyEmployeesSchedules(this.absenceSchedulesArray.fullTimeSchedules); - boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees = new boolean[this.getNumberPartTimeEmployee()][myParametersInitialSchedules.getWorkPeriodsPerSchedule()]; - boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees = new boolean[this.getNumberFullTimeEmployee()][myParametersInitialSchedules.getWorkPeriodsPerSchedule()]; + int totalEmployeesCost = EmployeeCostCalculator.getFullScheduleCost(this.absenceSchedulesArray, myParametersInitialSchedules); + int bestScheduleCost = Integer.MAX_VALUE; + int remainingRecoveringAction = this.absenceSchedulesArray.numberOfRecoveringActionsToPerform; + int currentOptimisticTotalEmployeeCost = totalEmployeesCost + remainingRecoveringAction * myParametersInitialSchedules.getMinimumWorkingPeriodCost(); + int optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost; + + boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees = new boolean[this.getNumberPartTimeEmployee()][remainingRecoveringAction]; + boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees = new boolean[this.getNumberFullTimeEmployee()][remainingRecoveringAction]; for (int i = 0 ; i < this.getNumberPartTimeEmployee() ; i++) { Arrays.fill(alreadyRecoveredWorkPeriodByPartTimeEmployees[i], Boolean.FALSE); } for (int i = 0 ; i < this.getNumberFullTimeEmployee() ; i++) { Arrays.fill(alreadyRecoveredWorkPeriodByFullTimeEmployees[i], Boolean.FALSE); } - - int totalEmployeesCost = EmployeeCostCalculator.getFullScheduleCost(this.absenceSchedulesArray, myParametersInitialSchedules); - int bestScheduleCost = Integer.MAX_VALUE; - int remainingRecoveringAction = this.absenceSchedulesArray.numberOfRecoveringActionsToPerform; - int currentOptimisticTotalEmployeeCost = totalEmployeesCost + remainingRecoveringAction * myParametersInitialSchedules.getMinimumWorkingPeriodCost(); - int optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost; - ScheduleStateComparator quartetComparator = new ScheduleStateComparator(); RecoveringActionComparator recoveringActionCostComparator = new RecoveringActionComparator(); - PriorityQueue< Quartet > scheduleStatesOrderedByOptimisticCost = new PriorityQueue<>(quartetComparator); + ScheduleState currentScheduleState = new ScheduleState(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees, + currentOptimisticTotalEmployeeCost, remainingRecoveringAction); + + Stack< ScheduleState > scheduleStatesNodes = new Stack<>(); + scheduleStatesNodes.push(currentScheduleState); RecoveringAction currentRecoveringAction = null; boolean isSolutionFound = true; - // Fouille en profondeur avec calcul de cout optimiste base sur le taux horaire regulier des employes a temps plein. + int backtrack = 0; + // Fouilles en profondeur avec calcul de cout optimiste base sur le taux horaire regulier des employes a temps plein. + // On marque les noeuds dejà visites. while ( bestScheduleCost > currentOptimisticTotalEmployeeCost ) { PriorityQueue recoveringActionsOrderedByCost = getPossibleRecoveringActions(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees, - alreadyRecoveredWorkPeriodByPartTimeEmployees, alreadyRecoveredWorkPeriodByFullTimeEmployees, recoveringActionCostComparator); + alreadyRecoveredWorkPeriodByPartTimeEmployees, alreadyRecoveredWorkPeriodByFullTimeEmployees, remainingRecoveringAction, recoveringActionCostComparator); if (recoveringActionsOrderedByCost.size() > 0){ boolean[][] recoveredScheduleOfPartTimeEmployeesAfterAction = this.getDeepCopyEmployeesSchedules(currentRecoveredScheduleOfPartTimeEmployees); boolean[][] recoveredScheduleOfFullTimeEmployeesAfterAction = this.getDeepCopyEmployeesSchedules(currentRecoveredScheduleOfFullTimeEmployees); + currentRecoveringAction = recoveringActionsOrderedByCost.poll(); + if (currentRecoveringAction.getClass().getName().equals("SchedulesRecovery.RecoveringActionPartTimeEmployee")) { recoveredScheduleOfPartTimeEmployeesAfterAction[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true; - alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true; + alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][remainingRecoveringAction-1] = true; } else if (currentRecoveringAction.getClass().getName().equals("SchedulesRecovery.RecoveringActionFullTimeEmployee")) { recoveredScheduleOfFullTimeEmployeesAfterAction[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true; - alreadyRecoveredWorkPeriodByFullTimeEmployees[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true; + alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][remainingRecoveringAction-1] = true; } - + optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost - myParametersInitialSchedules.getMinimumWorkingPeriodCost() + currentRecoveringAction.recoveringActionCost; - Quartet scheduleState = Quartet.with - (recoveredScheduleOfPartTimeEmployeesAfterAction, recoveredScheduleOfFullTimeEmployeesAfterAction, optimisticTotalEmployeeCost, remainingRecoveringAction - 1); - scheduleStatesOrderedByOptimisticCost.add(scheduleState); + + ScheduleState scheduleState = new ScheduleState(recoveredScheduleOfPartTimeEmployeesAfterAction, recoveredScheduleOfFullTimeEmployeesAfterAction, + optimisticTotalEmployeeCost, remainingRecoveringAction - 1); + + scheduleStatesNodes.push(scheduleState); + } else { + + do{ + scheduleStatesNodes.pop(); + } while(scheduleStatesNodes.size() > 1); + } if (remainingRecoveringAction - 1 == 0){ bestScheduleCost = Math.min(bestScheduleCost, optimisticTotalEmployeeCost); } - if (scheduleStatesOrderedByOptimisticCost.size() > 0) { - Quartet currentScheduleState = scheduleStatesOrderedByOptimisticCost.poll(); - currentRecoveredScheduleOfPartTimeEmployees = currentScheduleState.getValue0(); - currentRecoveredScheduleOfFullTimeEmployees = currentScheduleState.getValue1(); - currentOptimisticTotalEmployeeCost = currentScheduleState.getValue2(); - remainingRecoveringAction = currentScheduleState.getValue3(); + if (scheduleStatesNodes.size() > 0) { + currentScheduleState = scheduleStatesNodes.peek(); + currentRecoveredScheduleOfPartTimeEmployees = currentScheduleState.currentRecoveredScheduleOfPartTimeEmployees; + currentRecoveredScheduleOfFullTimeEmployees = currentScheduleState.currentRecoveredScheduleOfFullTimeEmployees; + currentOptimisticTotalEmployeeCost = currentScheduleState.currentOptimisticTotalEmployeeCost; + remainingRecoveringAction = currentScheduleState.remainingRecoveringAction; } else { isSolutionFound = false; break; } } - + if (isSolutionFound) { this.fullTimeSchedules = currentRecoveredScheduleOfFullTimeEmployees; this.partTimeSchedules = currentRecoveredScheduleOfPartTimeEmployees; @@ -94,19 +109,18 @@ public class RecoveredSchedulesArray extends SchedulesArray{ assert(this.totalScheduleCost == bestScheduleCost); } else { this.totalScheduleCost = Integer.MAX_VALUE; - System.out.println(" No Solution Found "); } - } - private PriorityQueue getPossibleRecoveringActions(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule, boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees, boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees, Comparator recoveringActionCostComparator) { - PriorityQueue recoveringActionsOrderedByCost = new PriorityQueue<>(recoveringActionCostComparator); + private PriorityQueue getPossibleRecoveringActions(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule, + boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees, boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees, int remainingRecoveringAction, Comparator recoveringActionCostComparator) { + PriorityQueue recoveringActionsOrderedByCost = new PriorityQueue(recoveringActionCostComparator); int workPeriod = findEarlierWorkPeriodToRecover(currentPartTimeSchedule, currentFullTimeSchedule); if (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) { for (int partTimeEmployee = 0 ; partTimeEmployee < this.getNumberPartTimeEmployee() ; partTimeEmployee++ ) { - if ( isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, partTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][workPeriod]){ + if ( isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, partTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][remainingRecoveringAction-1]){ RecoveringActionPartTimeEmployee recoveringAction = new RecoveringActionPartTimeEmployee(partTimeEmployee, workPeriod); recoveringAction.calculateRecoveringActionCost (currentPartTimeSchedule, myParametersInitialSchedules); @@ -114,7 +128,7 @@ public class RecoveredSchedulesArray extends SchedulesArray{ } } for (int fullTimeEmployee = 0 ; fullTimeEmployee < this.getNumberFullTimeEmployee() ; fullTimeEmployee++ ) { - if ( isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, fullTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][workPeriod] ){ + if ( isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, fullTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][remainingRecoveringAction-1] ){ RecoveringActionFullTimeEmployee recoveringAction = new RecoveringActionFullTimeEmployee(fullTimeEmployee, workPeriod); recoveringAction.calculateRecoveringActionCost (currentFullTimeSchedule, myParametersInitialSchedules); diff --git a/Travail_de_session/SchedulesRecovery/RecoveringActionComparator.java b/Travail_de_session/SchedulesRecovery/RecoveringActionComparator.java index 3ae64b0..2c3fe92 100644 --- a/Travail_de_session/SchedulesRecovery/RecoveringActionComparator.java +++ b/Travail_de_session/SchedulesRecovery/RecoveringActionComparator.java @@ -17,7 +17,7 @@ public class RecoveringActionComparator implements Comparator< RecoveringAction if (actionCostCmp !=0) { return actionCostCmp; } - int workPeriodCmp = Integer.compare(a1.workPeriod, a2.workPeriod); + int workPeriodCmp = Integer.compare(a1.employee, a2.employee); return workPeriodCmp; } diff --git a/Travail_de_session/SchedulesRecovery/ScheduleState.java b/Travail_de_session/SchedulesRecovery/ScheduleState.java new file mode 100644 index 0000000..f2cc61a --- /dev/null +++ b/Travail_de_session/SchedulesRecovery/ScheduleState.java @@ -0,0 +1,33 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package SchedulesRecovery; + +/** + * + * @author frabe + */ +public class ScheduleState { + + boolean[][] currentRecoveredScheduleOfPartTimeEmployees; + boolean[][] currentRecoveredScheduleOfFullTimeEmployees; +// boolean[][] currentAlreadyRecoveredWorkPeriodByPartTimeEmployees; +// boolean[][] currentAlreadyRecoveredWorkPeriodByFullTimeEmployees; + int currentOptimisticTotalEmployeeCost; + int remainingRecoveringAction; + + public ScheduleState(boolean[][] currentRecoveredScheduleOfPartTimeEmployees, boolean[][] currentRecoveredScheduleOfFullTimeEmployees, + + int currentOptimisticTotalEmployeeCost, int remainingRecoveringAction) { + this.currentRecoveredScheduleOfPartTimeEmployees = currentRecoveredScheduleOfPartTimeEmployees; + this.currentRecoveredScheduleOfFullTimeEmployees = currentRecoveredScheduleOfFullTimeEmployees; +// this.currentAlreadyRecoveredWorkPeriodByPartTimeEmployees = currentAlreadyRecoveredWorkPeriodByPartTimeEmployees; +// this.currentAlreadyRecoveredWorkPeriodByFullTimeEmployees = currentAlreadyRecoveredWorkPeriodByFullTimeEmployees; + this.currentOptimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost; + this.remainingRecoveringAction = remainingRecoveringAction; + + } + +} diff --git a/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java b/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java index e6dce98..d810adb 100644 --- a/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java +++ b/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java @@ -6,19 +6,18 @@ package SchedulesRecovery; import java.util.Comparator; -import org.javatuples.Quartet; /** * * @author frabe */ -public class ScheduleStateComparator implements Comparator< Quartet > { - public int compare(Quartet o1, Quartet o2) { - int totalCostCmp = o1.getValue2().compareTo(o2.getValue2()); +public class ScheduleStateComparator implements Comparator< ScheduleState > { + public int compare(ScheduleState o1, ScheduleState o2) { + int totalCostCmp = Integer.compare(o1.currentOptimisticTotalEmployeeCost,o2.currentOptimisticTotalEmployeeCost); if (totalCostCmp !=0) { return totalCostCmp; } - int remainingActionsCmp = o2.getValue3().compareTo(o1.getValue3()); + int remainingActionsCmp = Integer.compare(o1.remainingRecoveringAction,o2.remainingRecoveringAction); return remainingActionsCmp; } }