diff --git a/Travail_de_session/AbsenceSchedules/AbsencesVector.java b/Travail_de_session/AbsenceSchedules/AbsencesVector.java index 46351e9..cf09152 100644 --- a/Travail_de_session/AbsenceSchedules/AbsencesVector.java +++ b/Travail_de_session/AbsenceSchedules/AbsencesVector.java @@ -5,7 +5,7 @@ import jdistlib.rng.RandomEngine; public class AbsencesVector { private boolean[] AbsencesVector; - private double probPresence = 0.90; + private double probPresence = 0.80; private double probReturn = 0.50; public AbsencesVector(int length, RandomEngine r) { diff --git a/Travail_de_session/InitialSchedules/ModelInitialSchedules.java b/Travail_de_session/InitialSchedules/ModelInitialSchedules.java index f899b7f..33b1a65 100644 --- a/Travail_de_session/InitialSchedules/ModelInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ModelInitialSchedules.java @@ -58,9 +58,9 @@ public class ModelInitialSchedules { private void createEmployeesVariables() { this.maxPartTimeEmployee = (int) Math.ceil((double) myScheduleParameters.totalWorkedPeriodsInSchedule - / myScheduleParameters.minWorkingPeriodsOfPartTimeEmployeesPerSchedule); + / myScheduleParameters.getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule()); this.maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.totalWorkedPeriodsInSchedule - / myScheduleParameters.workingPeriodsOfFullTimeEmployeesPerSchedule); + / myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule()); } @@ -155,9 +155,9 @@ public class ModelInitialSchedules { chocoModelInitialSchedules.ifThen(isWorkingEmployee, chocoModelInitialSchedules.arithm( this.workingPeriodsPerPartTimeEmployees[employee], ">=", - this.myScheduleParameters.minWorkingPeriodsOfPartTimeEmployeesPerSchedule)); + this.myScheduleParameters.getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule())); chocoModelInitialSchedules.arithm(this.workingPeriodsPerPartTimeEmployees[employee], "<=", - this.myScheduleParameters.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule).post(); + this.myScheduleParameters.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule()).post(); } // Constraintes pour compter le nombre d'employes par periode de travail et s'assurer qu'il @@ -237,7 +237,7 @@ public class ModelInitialSchedules { IntVar PartTimeEmployeesSalary = chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee * this.myScheduleParameters.workPeriodsPerSchedule * - this.myScheduleParameters.hourlyRateOfPartTimeEmployees, true); + this.myScheduleParameters.regularHourlyRateOfPartTimeEmployees, true); IntVar FullTimeEmployeesSalary = chocoModelInitialSchedules.intVar(0, this.maxFullTimeEmployee * @@ -246,13 +246,13 @@ public class ModelInitialSchedules { this.TotalEmployeesSalary = chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee * this.myScheduleParameters.workPeriodsPerSchedule * - this.myScheduleParameters.hourlyRateOfPartTimeEmployees + + this.myScheduleParameters.regularHourlyRateOfPartTimeEmployees + this.maxFullTimeEmployee * this.myScheduleParameters.workPeriodsPerSchedule * this.myScheduleParameters.regularHourlyRateOfFullTimeEmployees, true); IntVar HourlyRateOfPartTimeEmployees = - chocoModelInitialSchedules.intVar(this.myScheduleParameters.hourlyRateOfPartTimeEmployees); + chocoModelInitialSchedules.intVar(this.myScheduleParameters.regularHourlyRateOfPartTimeEmployees); IntVar regularHourlyRateOfFullTimeEmployees = chocoModelInitialSchedules.intVar(this.myScheduleParameters.regularHourlyRateOfFullTimeEmployees); diff --git a/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java b/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java index 2208548..73335c9 100644 --- a/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java @@ -11,26 +11,24 @@ public class ParametersInitialSchedules { int totalWorkedPeriodsInSchedule; int hoursPerWorkPeriod; - int fixedCostOfPartTimeEmployeesPerSchedule; - int hourlyRateOfPartTimeEmployees; + public int fixedCostOfPartTimeEmployeesPerSchedule; + public int regularHourlyRateOfPartTimeEmployees; + public int overtimeHourlyRateOfPartTimeEmployees; int minWorkingHoursOfPartTimeEmployeesPerSchedule; int maxWorkingHoursOfPartTimeEmployeesPerSchedule; - int minWorkingPeriodsOfPartTimeEmployeesPerSchedule; - public int maxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork; - public int minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees; - public int maxWorkingPeriodsOfPartTimeEmployeesPerSchedule; + int maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork; + int minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees; - int fixedCostOfFullTimeEmployeesPerSchedule; - int regularHourlyRateOfFullTimeEmployees; - int overtimeHourlyRateOfFullTimeEmployees; - int workingHoursOfFullTimeEmployeesPerSchedule; + public int fixedCostOfFullTimeEmployeesPerSchedule; + public int regularHourlyRateOfFullTimeEmployees; + public int overtimeHourlyRateOfFullTimeEmployees; int maxWorkingHoursOfFullTimeEmployeesPerSchedule; - int workingPeriodsOfFullTimeEmployeesPerSchedule; - public int maxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork; - public int minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees; - public int maxWorkingPeriodsOfFullTimeEmployeesPerSchedule; + int workingHoursOfFullTimeEmployeesPerSchedule; + int maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork; + int minConsecutiveNonWorkingHoursBetweenShiftWorksOfFullTimeEmployees; int workingHoursPaidAtRegularHourlyRatePerSchedule; + int workingHoursPaidAtRegularHourlyRatePerShiftWork; public int[] requiredWorkforce; Tuples enumerationWorkPeriodsSchedulesOfFullTimeEmployees; @@ -54,44 +52,28 @@ public class ParametersInitialSchedules { this.daysPerSchedule = 14; this.hoursPerWorkPeriod = 24 / this.workPeriodsPerDay; this.workPeriodsPerSchedule = this.workPeriodsPerDay * this.daysPerSchedule; + this.workingHoursPaidAtRegularHourlyRatePerSchedule = 80; + this.workingHoursPaidAtRegularHourlyRatePerShiftWork = 8; } private void setPartTimeEmployeesParameters() { this.fixedCostOfPartTimeEmployeesPerSchedule = 50; - this.hourlyRateOfPartTimeEmployees = 12; // To simulate lower productivity + this.regularHourlyRateOfPartTimeEmployees = 12; // To simulate lower productivity + this.overtimeHourlyRateOfPartTimeEmployees = 17; // To simulate lower productivity this.minWorkingHoursOfPartTimeEmployeesPerSchedule = 32; this.maxWorkingHoursOfPartTimeEmployeesPerSchedule = 64; - int maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork = 12; - this.maxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork - = (int) (maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork / this.hoursPerWorkPeriod); - int minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees = 12; - this.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees - = (int) (minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees / this.hoursPerWorkPeriod); - this.minWorkingPeriodsOfPartTimeEmployeesPerSchedule - = (int) (this.minWorkingHoursOfPartTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); - this.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule - = (int) (this.maxWorkingHoursOfPartTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); + this.maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork = 12; + this.minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees = 12; } private void setFullTimeEmployeesParameters() { this.fixedCostOfFullTimeEmployeesPerSchedule = 50; this.regularHourlyRateOfFullTimeEmployees = 10; this.overtimeHourlyRateOfFullTimeEmployees = 15; - this.workingHoursOfFullTimeEmployeesPerSchedule = 80; this.maxWorkingHoursOfFullTimeEmployeesPerSchedule = 120; - int maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork = 12; - this.maxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork - = (int) (maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork / this.hoursPerWorkPeriod); - int minConsecutiveNonWorkingHoursBetweenShiftWorksOfFullTimeEmployees = 12; - this.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees - = (int) (minConsecutiveNonWorkingHoursBetweenShiftWorksOfFullTimeEmployees / this.hoursPerWorkPeriod); - this.workingPeriodsOfFullTimeEmployeesPerSchedule - = (int) (this.workingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); - this.maxWorkingPeriodsOfFullTimeEmployeesPerSchedule - = (int) (this.maxWorkingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); - - this.workingHoursPaidAtRegularHourlyRatePerSchedule = 80; + this.maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork = 12; + this.minConsecutiveNonWorkingHoursBetweenShiftWorksOfFullTimeEmployees = 12; } private void setRequiredWorkforce() { @@ -163,7 +145,64 @@ public class ParametersInitialSchedules { this.ValidPartTimeEmployeeShiftTuples = new ValidPartTimeEmployeeShift().makeTuples(); } - + public int getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule () { + return (int) (workingHoursPaidAtRegularHourlyRatePerSchedule / this.hoursPerWorkPeriod); + } + + public int getWorkingPeriodsPaidAtRegularHourlyRatePerShiftWork () { + return (int) (workingHoursPaidAtRegularHourlyRatePerShiftWork / this.hoursPerWorkPeriod); + } + + public int getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate () { + return (int) (regularHourlyRateOfPartTimeEmployees * this.hoursPerWorkPeriod); + } + + public int getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate () { + return (int) (regularHourlyRateOfFullTimeEmployees * this.hoursPerWorkPeriod); + } + + public int getWorkingPeriodCostOfPartTimeEmployeesPaidAtOvertimeHourlyRate () { + return (int) (overtimeHourlyRateOfPartTimeEmployees * this.hoursPerWorkPeriod); + } + + public int getWorkingPeriodCostOfFullTimeEmployeesPaidAtOvertimeHourlyRate () { + return (int) (overtimeHourlyRateOfFullTimeEmployees * this.hoursPerWorkPeriod); + } + + public int getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork () { + return (int) (maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork / this.hoursPerWorkPeriod); + } + + public int getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork () { + return (int) (maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork / this.hoursPerWorkPeriod); + } + + public int getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees () { + return (int) (minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees / this.hoursPerWorkPeriod); + } + + public int getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees () { + return (int) (minConsecutiveNonWorkingHoursBetweenShiftWorksOfFullTimeEmployees / this.hoursPerWorkPeriod); + } + + public int getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule () { + return (int) (this.maxWorkingHoursOfPartTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); + } + + public int getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule () { + return (int) (this.maxWorkingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); + } + + public int getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule () { + return (int) (this.minWorkingHoursOfPartTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); + + } + + public int getWorkingPeriodsOfFullTimeEmployeesPerSchedule () { + return (int) (this.workingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod); + } + + // A implementer plus tard si l'on veut travailler avec des fichiers texte public ParametersInitialSchedules(String fileName) { diff --git a/Travail_de_session/MainClass.java b/Travail_de_session/MainClass.java index 4970690..396b5e5 100644 --- a/Travail_de_session/MainClass.java +++ b/Travail_de_session/MainClass.java @@ -24,7 +24,7 @@ public class MainClass { List absenceSchedulesArrayList = GenerateAbsencesSchedules(initialSchedulesArrayList); - List recoveredSchedulesArrayList = GenerateRecoveredSchedules(absenceSchedulesArrayList); + List recoveredSchedulesArrayList = GenerateOptimalRecoveredSchedules(absenceSchedulesArrayList); // Algo de recouvrement d'absences. Faire un nouveau package de fonctions. // Trouver meilleure solution et l'afficher. } @@ -90,7 +90,7 @@ public class MainClass { return absenceSchedulesArrayList; } - private static List GenerateRecoveredSchedules(List absenceSchedulesArrayList) { + private static List GenerateOptimalRecoveredSchedules(List absenceSchedulesArrayList) { List recoveredSchedulesArrayList = new ArrayList<>(); for (SchedulesArray absenceSchedule : absenceSchedulesArrayList) { diff --git a/Travail_de_session/ScheduleUtil/EmployeeCostCalculator.java b/Travail_de_session/ScheduleUtil/EmployeeCostCalculator.java new file mode 100644 index 0000000..fdc0c92 --- /dev/null +++ b/Travail_de_session/ScheduleUtil/EmployeeCostCalculator.java @@ -0,0 +1,89 @@ +/* + * 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 ScheduleUtil; + +import InitialSchedules.ParametersInitialSchedules; +import SchedulesRecovery.*; +/** + * + * @author frabe + */ +public class EmployeeCostCalculator { + + public static int getFullScheduleCost( boolean[][] partTimeEmployeesSchedule , boolean[][] fullTimeEmployeesSchedule, ParametersInitialSchedules myScheduleParameters) { + return 0; + } + + public static int getRecoveringActionCost (RecoveringAction action, ParametersInitialSchedules myScheduleParameters) { + int actionCost = 0; + if (action.getClass().getName() == "RecoveringActionPartTimeEmployee") { + actionCost = getPartTimeEmployeeCost(action.employeeScheduleAfterRecoveringAction, myScheduleParameters) - + getPartTimeEmployeeCost(action.employeeScheduleBeforeRecoveringAction, myScheduleParameters); + } else if (action.getClass().getName() == "RecoveringActionFullTimeEmployee") { + actionCost = getFullTimeEmployeeCost(action.employeeScheduleAfterRecoveringAction, myScheduleParameters) - + getFullTimeEmployeeCost(action.employeeScheduleBeforeRecoveringAction, myScheduleParameters); + } + return actionCost; + } + + public static int getPartTimeEmployeeCost( boolean[] employeeSchedule, ParametersInitialSchedules myScheduleParameters) { + + int consecutiveWorkingPeriods = 0; + int overtimeWorkingPeriods = 0; + int totalWorkingPeriods = 0; + for (int workPeriod = 0; workPeriod < employeeSchedule.length ; workPeriod++) { + if (employeeSchedule[workPeriod]) { + totalWorkingPeriods += 1; + consecutiveWorkingPeriods += 1; + if (consecutiveWorkingPeriods > myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerShiftWork()) { + overtimeWorkingPeriods += 1; + } + } else { + consecutiveWorkingPeriods = 0; + } + } + + int additionalOvertimeWorkingPeriods = totalWorkingPeriods - myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule(); + if ( additionalOvertimeWorkingPeriods > 0 ){ + overtimeWorkingPeriods += additionalOvertimeWorkingPeriods; + } + + int employeeCost = myScheduleParameters.fixedCostOfPartTimeEmployeesPerSchedule + + overtimeWorkingPeriods * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtOvertimeHourlyRate() + + (totalWorkingPeriods - overtimeWorkingPeriods) * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate(); + + return employeeCost; + } + + public static int getFullTimeEmployeeCost( boolean[] employeeSchedule, ParametersInitialSchedules myScheduleParameters) { + + int consecutiveWorkingPeriods = 0; + int overtimeWorkingPeriods = 0; + int totalWorkingPeriods = 0; + for (int workPeriod = 0; workPeriod < employeeSchedule.length ; workPeriod++) { + if (employeeSchedule[workPeriod]) { + totalWorkingPeriods += 1; + consecutiveWorkingPeriods += 1; + if (consecutiveWorkingPeriods > myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerShiftWork()) { + overtimeWorkingPeriods += 1; + } + } else { + consecutiveWorkingPeriods = 0; + } + } + + int additionalOvertimeWorkingPeriods = totalWorkingPeriods - myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule(); + if ( additionalOvertimeWorkingPeriods > 0 ){ + overtimeWorkingPeriods += additionalOvertimeWorkingPeriods; + } + + int employeeCost = myScheduleParameters.fixedCostOfFullTimeEmployeesPerSchedule + + overtimeWorkingPeriods * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtOvertimeHourlyRate() + + (totalWorkingPeriods - overtimeWorkingPeriods) * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate(); + + return employeeCost; + } +} diff --git a/Travail_de_session/ScheduleUtil/SchedulesArray.java b/Travail_de_session/ScheduleUtil/SchedulesArray.java index b21b14a..666f53a 100644 --- a/Travail_de_session/ScheduleUtil/SchedulesArray.java +++ b/Travail_de_session/ScheduleUtil/SchedulesArray.java @@ -57,23 +57,10 @@ public class SchedulesArray { this.isFullTimeEmployeeActive[employee] = myScheduleArray.isFullTimeEmployeeActive[employee]; } - this.partTimeSchedules = new boolean[this.maxPartTimeEmployee][this.workPeriodsPerSchedule]; - this.fullTimeSchedules = new boolean[this.maxFullTimeEmployee][this.workPeriodsPerSchedule]; - this.initialPartTimeSchedules = new boolean[this.maxPartTimeEmployee][this.workPeriodsPerSchedule]; - this.initialFullTimeSchedules = new boolean[this.maxFullTimeEmployee][this.workPeriodsPerSchedule]; - for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) { - for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { - this.partTimeSchedules[employee][workPeriod] = myScheduleArray.partTimeSchedules[employee][workPeriod]; - this.initialPartTimeSchedules[employee][workPeriod] = myScheduleArray.initialPartTimeSchedules[employee][workPeriod]; - } - } - - for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) { - for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) { - this.fullTimeSchedules[employee][workPeriod] = myScheduleArray.fullTimeSchedules[employee][workPeriod]; - this.initialFullTimeSchedules[employee][workPeriod] = myScheduleArray.initialFullTimeSchedules[employee][workPeriod]; - } - } + this.partTimeSchedules = deepCopyPartTimeEmployeesSchedule(myScheduleArray.partTimeSchedules); + this.initialPartTimeSchedules = deepCopyPartTimeEmployeesSchedule(myScheduleArray.initialPartTimeSchedules); + this.fullTimeSchedules = deepCopyFullTimeEmployeesSchedule(myScheduleArray.fullTimeSchedules); + this.initialFullTimeSchedules = deepCopyFullTimeEmployeesSchedule(myScheduleArray.initialFullTimeSchedules); this.employeesPerWorkPeriod = new int[this.workPeriodsPerSchedule]; this.workingPeriodsPerPartTimeEmployees = new int[this.maxPartTimeEmployee]; @@ -85,6 +72,26 @@ public class SchedulesArray { } + protected boolean[][] deepCopyPartTimeEmployeesSchedule(boolean[][] partTimeSchedules) { + boolean[][] copyPartTimeSchedules = new boolean[this.maxPartTimeEmployee][this.workPeriodsPerSchedule]; + for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) { + for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { + copyPartTimeSchedules[employee][workPeriod] = partTimeSchedules[employee][workPeriod]; + } + } + return copyPartTimeSchedules; + } + + protected boolean[][] deepCopyFullTimeEmployeesSchedule(boolean[][] fullTimeSchedules) { + boolean[][] copyFullTimeSchedules = new boolean[this.maxFullTimeEmployee][this.workPeriodsPerSchedule]; + for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) { + for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) { + copyFullTimeSchedules[employee][workPeriod] = fullTimeSchedules[employee][workPeriod]; + } + } + return copyFullTimeSchedules; + } + public SchedulesArray(ModelInitialSchedules m, Solution s) { this.myModelInitialSchedules = m; Solution mySolution = s; diff --git a/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java b/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java index f506635..2ea3241 100644 --- a/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java +++ b/Travail_de_session/SchedulesRecovery/RecoveredSchedulesArray.java @@ -6,7 +6,9 @@ package SchedulesRecovery; import AbsenceSchedules.AbsenceSchedulesArray; - +import java.util.*; +import org.javatuples.Triplet; +import ScheduleUtil.*; /** * @@ -18,73 +20,151 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{ super(myAbsenceScheduleArray); } +// public void oldRecoverAbsenceScheduleOptimally() { +// for ( int workPeriod = 0 ; workPeriod < this.workPeriodsPerSchedule ; workPeriod++ ) { +// boolean noEmployeeAvailable = false; +// while (!noEmployeeAvailable && getEmployeesPerWorkPeriod(workPeriod) < getRequiredWorkForce(workPeriod)) { +// boolean absenceRecoveryDone = false; +// int employee = 0; +// while (!absenceRecoveryDone && employee < this.maxFullTimeEmployee) { +// if ( isFullTimeEmployeeAvailableForAbsenceRecovering(employee, workPeriod) ){ +// fullTimeSchedules[employee][workPeriod] = true; +// updateEmployeesPerWorkPeriod(workPeriod); +// updateWorkingPeriodsPerFullTimeEmployees(employee); +// absenceRecoveryDone = true; +// } +// employee++; +// } +// employee = 0; +// while (!absenceRecoveryDone && employee < this.maxPartTimeEmployee) { +// if (isPartTimeEmployeeAvailableForAbsenceRecovering(employee, workPeriod) ){ +// partTimeSchedules[employee][workPeriod] = true; +// updateEmployeesPerWorkPeriod(workPeriod); +// updateWorkingPeriodsPerPartTimeEmployees(employee); +// absenceRecoveryDone = true; +// } +// employee++; +// } +// if (!absenceRecoveryDone) { +// noEmployeeAvailable = true; +// } +// } +// } +// +// } + public void recoverAbsenceScheduleOptimally() { - for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) { - boolean noEmployeeAvailable = false; - while (!noEmployeeAvailable && getEmployeesPerWorkPeriod(workPeriod) < getRequiredWorkForce(workPeriod)) { - boolean absenceRecoveryDone = false; - int employee = 0; - while (!absenceRecoveryDone && employee < this.maxFullTimeEmployee) { - if (isFullTimeEmployeeAvailableForAbsenceRecovering(employee, workPeriod) && !isFullTimeEmployeeWorking(employee, workPeriod)){ - fullTimeSchedules[employee][workPeriod] = true; - updateEmployeesPerWorkPeriod(workPeriod); - updateWorkingPeriodsPerFullTimeEmployees(employee); - absenceRecoveryDone = true; - } - employee++; - } - employee = 0; - while (!absenceRecoveryDone && employee < this.maxPartTimeEmployee) { - if (isPartTimeEmployeeAvailableForAbsenceRecovering(employee, workPeriod) && !isPartTimeEmployeeWorking(employee, workPeriod)){ - partTimeSchedules[employee][workPeriod] = true; - updateEmployeesPerWorkPeriod(workPeriod); - updateWorkingPeriodsPerPartTimeEmployees(employee); - absenceRecoveryDone = true; - } - employee++; - } - if (!absenceRecoveryDone) { - noEmployeeAvailable = true; + int workPeriod = 0; + boolean[][] currentRecoveredScheduleOfPartTimeEmployees = deepCopyPartTimeEmployeesSchedule(partTimeSchedules); + boolean[][] currentRecoveredScheduleOfFullTimeEmployees = deepCopyFullTimeEmployeesSchedule(fullTimeSchedules); + int totalEmployeesCost = EmployeeCostCalculator.getFullScheduleCost(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees, this.myModelInitialSchedules.myScheduleParameters); + int currentTotalEmployeesCost = totalEmployeesCost; + ScheduleStateComparator totalCostComparator = new ScheduleStateComparator(); + // mettre les Schedules dans les Tuples currentRecoveredScheduleOfPartTimeEmployees et currentRecoveredScheduleOfFullTimeEmployees au lieu de previousActions + PriorityQueue< Triplet > priorityQueueScheduleStatesOrderedByTotalCost = new PriorityQueue<>(totalCostComparator); + List< Triplet > listVisitedScheduleStates = new ArrayList<>(); + RecoveringAction currentRecoveringAction = null; + RecoveringAction previousRecoveringAction = null; + + while ( workPeriod < this.workPeriodsPerSchedule ) { + + Stack stackRecoveringActionsOfPartTimeEmployee = + getPossibleActionOfPartTimeEmployees(workPeriod, currentRecoveredScheduleOfPartTimeEmployees); + Stack stackRecoveringActionsOfFullTimeEmployees = + getPossibleActionOfFullTimeEmployees(workPeriod, currentRecoveredScheduleOfFullTimeEmployees); + while ( !stackRecoveringActionsOfPartTimeEmployee.isEmpty() && !stackRecoveringActionsOfFullTimeEmployees.isEmpty() ) { + if (stackRecoveringActionsOfPartTimeEmployee.isEmpty()) { + currentRecoveringAction = stackRecoveringActionsOfFullTimeEmployees.pop(); + } else { + currentRecoveringAction = stackRecoveringActionsOfPartTimeEmployee.pop(); } + + // On pourrait comparer currentRecoveredScheduleOfPartTimeEmployees pour voir si on ne l'a pas deja visite avec un coût plus faible. Dans ce cas, on ne pousse pas l'etat dans la liste. + int actionCost = EmployeeCostCalculator.getRecoveringActionCost( currentRecoveringAction, this.myModelInitialSchedules.myScheduleParameters ); + totalEmployeesCost = currentTotalEmployeesCost + actionCost; + Triplet scheduleState = Triplet.with(previousRecoveringAction, currentRecoveringAction, totalEmployeesCost); + priorityQueueScheduleStatesOrderedByTotalCost.add(scheduleState); + listVisitedScheduleStates.add(scheduleState); } + Triplet currentScheduleState = priorityQueueScheduleStatesOrderedByTotalCost.poll(); + currentTotalEmployeesCost = currentScheduleState.getValue2(); + previousRecoveringAction = currentScheduleState.getValue1(); + + //recalculer les currentRecoveredScheduleOfPartTimeEmployees et ajuster la workPeriod + //en trouvent la workPeriod la plus petite avec une demande incomplète. + //workPeriod++; } + } + + private Stack getPossibleActionOfPartTimeEmployees(int workPeriod, boolean[][] currentRecoveredSchedule) { + // inclure un attribut pour dire si la requiredWorkForce est satifaite avec l'action. + Stack stackRecoveringActionsOfPartTimeEmployee = new Stack<>(); + for (int employee = 0 ; employee < this.maxPartTimeEmployee ; employee++) { + boolean[] currentEmployeeSchedule = currentRecoveredSchedule[employee]; + if ( isPartTimeEmployeeActive(employee) && isPartTimeEmployeeAvailableForAbsenceRecovering(employee, workPeriod, currentEmployeeSchedule) ){ + RecoveringActionPartTimeEmployee recoveringAction = + new RecoveringActionPartTimeEmployee(employee, workPeriod, currentEmployeeSchedule); + stackRecoveringActionsOfPartTimeEmployee.push(recoveringAction); + } + } + return stackRecoveringActionsOfPartTimeEmployee; } - private boolean isPartTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod){ - return isPartTimeEmployeeActive(employee) && !isPartTimeEmployeeAbsent(employee, workPeriod) && isValidPartTimeEmployeeWorkPeriod(employee,workPeriod); + private Stack getPossibleActionOfFullTimeEmployees(int workPeriod, boolean[][] currentRecoveredSchedule) { + + Stack stackRecoveringActionsOfFullTimeEmployees = new Stack<>(); + for (int employee = 0 ; employee < this.maxFullTimeEmployee ; employee++) { + boolean[] currentEmployeeSchedule = currentRecoveredSchedule[employee]; + if ( isFullTimeEmployeeActive(employee) && isFullTimeEmployeeAvailableForAbsenceRecovering(employee, workPeriod, currentEmployeeSchedule) ){ + RecoveringActionFullTimeEmployee recoveringAction = + new RecoveringActionFullTimeEmployee(employee, workPeriod, currentEmployeeSchedule); + stackRecoveringActionsOfFullTimeEmployees.push(recoveringAction); + } + } + return stackRecoveringActionsOfFullTimeEmployees; } - private boolean isValidPartTimeEmployeeWorkPeriod(int employee, int workPeriod){ - return isValidWorkingPeriodsOfPartTimeEmployee(employee) && - isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(employee, workPeriod) && - isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(employee, workPeriod); + private boolean isPartTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod, boolean[] currentEmployeeSchedule){ + return !currentEmployeeSchedule[workPeriod] && !isPartTimeEmployeeAbsent(employee, workPeriod) && isValidPartTimeEmployeeWorkPeriod(currentEmployeeSchedule, workPeriod); } - private boolean isValidWorkingPeriodsOfPartTimeEmployee(int employee){ - return this.workingPeriodsPerPartTimeEmployees[employee] < myModelInitialSchedules.myScheduleParameters.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule; + private boolean isValidPartTimeEmployeeWorkPeriod(boolean[] currentEmployeeSchedule, int workPeriod){ + return isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(currentEmployeeSchedule) && + isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(currentEmployeeSchedule, workPeriod) && + isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(currentEmployeeSchedule, workPeriod); + } + + private boolean isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(boolean[] currentEmployeeSchedule){ + int employeeWorkingPeriods = 0; + for ( int workPeriod = 0 ; workPeriod < this.workPeriodsPerSchedule ; workPeriod++ ) { + if (currentEmployeeSchedule[workPeriod]){ + employeeWorkingPeriods +=1 ; + } + } + return employeeWorkingPeriods < myModelInitialSchedules.myScheduleParameters.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule(); } - private boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(int employee, int workPeriod){ + private boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){ int consecutiveWorkingPeriods = 1; int compteurWorkPeriod = workPeriod - 1; - while ( compteurWorkPeriod >= 0 && isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod >= 0 && currentEmployeeSchedule[compteurWorkPeriod] ){ consecutiveWorkingPeriods += 1; compteurWorkPeriod--; } compteurWorkPeriod = workPeriod + 1; - while ( compteurWorkPeriod < this.workPeriodsPerSchedule && isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod < this.workPeriodsPerSchedule && currentEmployeeSchedule[compteurWorkPeriod] ){ consecutiveWorkingPeriods += 1; compteurWorkPeriod++; } - return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.maxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork; + return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork(); } - private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(int employee, int workPeriod){ + private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){ int consecutivePreviousNonWorkingPeriods = 0; int compteurWorkPeriod = workPeriod - 1; - while ( compteurWorkPeriod >= 0 && !isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod >= 0 && !currentEmployeeSchedule[compteurWorkPeriod] ){ consecutivePreviousNonWorkingPeriods += 1; compteurWorkPeriod--; } @@ -93,12 +173,12 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{ validConsecutivePreviousNonWorkingPeriods = true; } else if (consecutivePreviousNonWorkingPeriods == 0) { validConsecutivePreviousNonWorkingPeriods = true; - } else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees) { + } else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) { validConsecutivePreviousNonWorkingPeriods = true; } int consecutiveNextNonWorkingPeriods = 0; compteurWorkPeriod = workPeriod + 1; - while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !currentEmployeeSchedule[compteurWorkPeriod] ){ consecutiveNextNonWorkingPeriods += 1; compteurWorkPeriod++; } @@ -107,46 +187,52 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{ validConsecutiveNextNonWorkingPeriods = true; } else if (consecutiveNextNonWorkingPeriods == 0) { validConsecutiveNextNonWorkingPeriods = true; - } else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees) { + } else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) { validConsecutiveNextNonWorkingPeriods = true; } return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods; } - private boolean isFullTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod){ - return isFullTimeEmployeeActive(employee) && !isFullTimeEmployeeAbsent(employee, workPeriod) && isValidFullTimeEmployeeWorkPeriod(employee,workPeriod); + private boolean isFullTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod, boolean[] currentEmployeeSchedule){ + return !currentEmployeeSchedule[workPeriod] && !isFullTimeEmployeeAbsent(employee, workPeriod) && isValidFullTimeEmployeeWorkPeriod(currentEmployeeSchedule, workPeriod); } - private boolean isValidFullTimeEmployeeWorkPeriod(int employee, int workPeriod){ - return isValidWorkingPeriodsOfFullTimeEmployee(employee) && - isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(employee, workPeriod) && - isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(employee, workPeriod); + private boolean isValidFullTimeEmployeeWorkPeriod(boolean[] currentEmployeeSchedule, int workPeriod){ + return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentEmployeeSchedule) && + isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentEmployeeSchedule, workPeriod) && + isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentEmployeeSchedule, workPeriod); } - private boolean isValidWorkingPeriodsOfFullTimeEmployee(int employee){ - return this.workingPeriodsPerFullTimeEmployees[employee] < myModelInitialSchedules.myScheduleParameters.maxWorkingPeriodsOfFullTimeEmployeesPerSchedule; + private boolean isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(boolean[] currentEmployeeSchedule){ + int employeeWorkingPeriods = 0; + for ( int workPeriod = 0 ; workPeriod < this.workPeriodsPerSchedule ; workPeriod++ ) { + if (currentEmployeeSchedule[workPeriod]){ + employeeWorkingPeriods +=1 ; + } + } + return employeeWorkingPeriods < myModelInitialSchedules.myScheduleParameters.getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule(); } - private boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(int employee, int workPeriod){ + private boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){ int consecutiveWorkingPeriods = 1; int compteurWorkPeriod = workPeriod - 1; - while ( compteurWorkPeriod >= 0 && isFullTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod >= 0 && currentEmployeeSchedule[compteurWorkPeriod] ){ consecutiveWorkingPeriods += 1; compteurWorkPeriod--; } compteurWorkPeriod = workPeriod + 1; - while ( compteurWorkPeriod < this.workPeriodsPerSchedule && isFullTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod < this.workPeriodsPerSchedule && currentEmployeeSchedule[compteurWorkPeriod] ){ consecutiveWorkingPeriods += 1; compteurWorkPeriod++; } - return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.maxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork; + return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork(); } - private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(int employee, int workPeriod){ + private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){ int consecutivePreviousNonWorkingPeriods = 0; int compteurWorkPeriod = workPeriod - 1; - while ( compteurWorkPeriod >= 0 && !isFullTimeEmployeeWorking(employee, compteurWorkPeriod)){ + while ( compteurWorkPeriod >= 0 && !currentEmployeeSchedule[compteurWorkPeriod] ){ consecutivePreviousNonWorkingPeriods += 1; compteurWorkPeriod--; } @@ -155,12 +241,12 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{ validConsecutivePreviousNonWorkingPeriods = true; } else if (consecutivePreviousNonWorkingPeriods == 0) { validConsecutivePreviousNonWorkingPeriods = true; - } else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees) { + } else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) { validConsecutivePreviousNonWorkingPeriods = true; } int consecutiveNextNonWorkingPeriods = 0; compteurWorkPeriod = workPeriod + 1; - while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !isFullTimeEmployeeWorking(employee, compteurWorkPeriod) ){ + while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !currentEmployeeSchedule[compteurWorkPeriod] ){ consecutiveNextNonWorkingPeriods += 1; compteurWorkPeriod++; } @@ -169,7 +255,7 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{ validConsecutiveNextNonWorkingPeriods = true; } else if (consecutiveNextNonWorkingPeriods == 0) { validConsecutiveNextNonWorkingPeriods = true; - } else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees) { + } else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) { validConsecutiveNextNonWorkingPeriods = true; } return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods; diff --git a/Travail_de_session/SchedulesRecovery/RecoveringAction.java b/Travail_de_session/SchedulesRecovery/RecoveringAction.java new file mode 100644 index 0000000..48ff6c9 --- /dev/null +++ b/Travail_de_session/SchedulesRecovery/RecoveringAction.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 RecoveringAction { + public int employee; + public int workPeriod; + public boolean[] employeeScheduleBeforeRecoveringAction; + public boolean[] employeeScheduleAfterRecoveringAction; + + public RecoveringAction( int employee, int workPeriod, boolean[] employeeSchedule){ + this.employee = employee; + this.workPeriod = workPeriod; + this.employeeScheduleBeforeRecoveringAction = new boolean[employeeSchedule.length]; + this.employeeScheduleAfterRecoveringAction = new boolean[employeeSchedule.length]; + for (int i = 0 ; i < employeeSchedule.length ; i++) { + this.employeeScheduleBeforeRecoveringAction[i] = employeeSchedule[i]; + if (i == workPeriod) { + this.employeeScheduleAfterRecoveringAction[i] = true; + } else { + this.employeeScheduleAfterRecoveringAction[i] = employeeSchedule[i]; + } + } + } + +} diff --git a/Travail_de_session/SchedulesRecovery/RecoveringActionFullTimeEmployee.java b/Travail_de_session/SchedulesRecovery/RecoveringActionFullTimeEmployee.java new file mode 100644 index 0000000..5a4ac25 --- /dev/null +++ b/Travail_de_session/SchedulesRecovery/RecoveringActionFullTimeEmployee.java @@ -0,0 +1,18 @@ +/* + * 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 RecoveringActionFullTimeEmployee extends RecoveringAction{ + + public RecoveringActionFullTimeEmployee( int employee, int workPeriod, boolean[] employeeSchedule){ + super(employee, workPeriod, employeeSchedule); + } + +} diff --git a/Travail_de_session/SchedulesRecovery/RecoveringActionPartTimeEmployee.java b/Travail_de_session/SchedulesRecovery/RecoveringActionPartTimeEmployee.java new file mode 100644 index 0000000..4411ee8 --- /dev/null +++ b/Travail_de_session/SchedulesRecovery/RecoveringActionPartTimeEmployee.java @@ -0,0 +1,19 @@ +/* + * 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 RecoveringActionPartTimeEmployee extends RecoveringAction{ + + public RecoveringActionPartTimeEmployee( int employee, int workPeriod, boolean[] employeeSchedule){ + super(employee, workPeriod, employeeSchedule); + } + +} + diff --git a/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java b/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java new file mode 100644 index 0000000..a8c81e3 --- /dev/null +++ b/Travail_de_session/SchedulesRecovery/ScheduleStateComparator.java @@ -0,0 +1,19 @@ +/* + * 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; + +import java.util.Comparator; +import org.javatuples.Triplet; + +/** + * + * @author frabe + */ +public class ScheduleStateComparator implements Comparator< Triplet > { + public int compare(Triplet o1, Triplet o2) { + return o1.getValue2().compareTo(o2.getValue2()); + } +} diff --git a/Travail_de_session/javatuples-1.2.jar b/Travail_de_session/javatuples-1.2.jar new file mode 100644 index 0000000..8944308 Binary files /dev/null and b/Travail_de_session/javatuples-1.2.jar differ