Merge branches 'horairesquotidiensvalides' and 'master' of gitlab.com:franc00018/tpIFT7020 into horairesquotidiensvalides

# Conflicts:
#	Travail_de_session/InitialSchedules/ParametersInitialSchedules.java
This commit is contained in:
François Pelletier 2018-04-04 10:59:27 -04:00
commit 44afa75668
13 changed files with 670 additions and 115 deletions

View file

@ -11,22 +11,37 @@ public class AbsenceSchedulesArray extends SchedulesArray{
super(myScheduleArray);
}
public void generateAbsences(RandomEngine r) {
for (int i = 0; i < this.maxPartTimeEmployee; i++) {
int[] a = new AbsencesVector(this.workPeriodsPerSchedule, r).getAbsencesVector();
for (int j = 0; j < this.workPeriodsPerSchedule; j++) {
this.PartTimeSchedules[i][j] = this.PartTimeSchedules[i][j] * a[j];
}
}
for (int i = 0; i < this.maxFullTimeEmployee; i++) {
int[] a = new AbsencesVector(this.workPeriodsPerSchedule, r).getAbsencesVector();
for (int j = 0; j < this.workPeriodsPerSchedule; j++) {
this.FullTimeSchedules[i][j] = this.FullTimeSchedules[i][j] * a[j];
}
}
updateEmployeesPerWorkPeriod();
updateWorkingPeriodsPerPartTimeEmployees();
updateWorkingPeriodsPerFullTimeEmployees();
public AbsenceSchedulesArray(AbsenceSchedulesArray myAbsenceScheduleArray) {
super(myAbsenceScheduleArray);
}
public void generateAbsences(RandomEngine r) {
for (int i = 0; i < this.maxPartTimeEmployee; i++) {
boolean[] a = new AbsencesVector(this.workPeriodsPerSchedule, r).getAbsencesVector();
for (int j = 0; j < this.workPeriodsPerSchedule; j++) {
this.partTimeSchedules[i][j] = this.initialPartTimeSchedules[i][j] && a[j];
}
}
for (int i = 0; i < this.maxFullTimeEmployee; i++) {
boolean[] a = new AbsencesVector(this.workPeriodsPerSchedule, r).getAbsencesVector();
for (int j = 0; j < this.workPeriodsPerSchedule; j++) {
this.fullTimeSchedules[i][j] = this.fullTimeSchedules[i][j] && a[j];
}
}
updateAllEmployeesPerWorkPeriod();
updateAllWorkingPeriodsPerPartTimeEmployees();
updateAllWorkingPeriodsPerFullTimeEmployees();
}
protected boolean isPartTimeEmployeeAbsent(int employee, int workPeriod) {
return this.partTimeSchedules[employee][workPeriod] != this.initialPartTimeSchedules[employee][workPeriod];
}
protected boolean isFullTimeEmployeeAbsent(int employee, int workPeriod) {
return this.fullTimeSchedules[employee][workPeriod] != this.initialFullTimeSchedules[employee][workPeriod];
}
}

View file

@ -4,30 +4,30 @@ import jdistlib.Binomial;
import jdistlib.rng.RandomEngine;
public class AbsencesVector {
private int[] AbsencesVector;
private double probAbsence = 0.02;
private double probReturn = 0.80;
private boolean[] AbsencesVector;
private double probPresence = 0.80;
private double probReturn = 0.50;
public AbsencesVector(int length, RandomEngine r) {
int current = 1;
AbsencesVector = new int[length];
Binomial b1 = new Binomial(1, probAbsence);
AbsencesVector = new boolean[length];
Binomial b1 = new Binomial(1, probPresence);
b1.setRandomEngine(r);
Binomial b2 = new Binomial(1, probReturn);
b2.setRandomEngine(r);
for (int i = 0; i < length; i++) {
if (current == 1) {
current = (int) b1.random();
AbsencesVector[i] = current;
AbsencesVector[i] = current == 1;
} else {
current = (int) b2.random();
AbsencesVector[i] = current;
AbsencesVector[i] = current == 1;
}
}
}
public int[] getAbsencesVector() {
public boolean[] getAbsencesVector() {
return AbsencesVector;
}
}

View file

@ -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());
}
@ -161,9 +161,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
@ -243,7 +243,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 *
@ -252,13 +252,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);

View file

@ -6,33 +6,42 @@ public class ParametersInitialSchedules {
public int workPeriodsPerDay;
int NbFullTimeSolutions;
int NbPartTimeSolutions;
int shiftWorkPerDay;
public int daysPerSchedule;
public int workPeriodsPerSchedule;
int totalWorkedPeriodsInSchedule;
int NbPartTimeSolutions;
Tuples enumerationWorkPeriodsSchedulesOfPartTimeEmployees;
int hoursPerWorkPeriod;
int hourlyRateOfPartTimeEmployees;
private int shiftWorkPerDay;
private int hoursPerWorkPeriod;
int minWorkingPeriodsOfPartTimeEmployeesPerSchedule;
int maxWorkingPeriodsOfPartTimeEmployeesPerSchedule;
int fixedCostOfFullTimeEmployeesPerSchedule;
int regularHourlyRateOfFullTimeEmployees;
int overtimeHourlyRateOfFullTimeEmployees;
int workingHoursOfFullTimeEmployeesPerSchedule;
public int fixedCostOfPartTimeEmployeesPerSchedule;
public int regularHourlyRateOfPartTimeEmployees;
public int overtimeHourlyRateOfPartTimeEmployees;
int minWorkingHoursOfPartTimeEmployeesPerSchedule;
int maxWorkingHoursOfPartTimeEmployeesPerSchedule;
int maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork;
int minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees;
public int fixedCostOfFullTimeEmployeesPerSchedule;
public int regularHourlyRateOfFullTimeEmployees;
public int overtimeHourlyRateOfFullTimeEmployees;
int maxWorkingHoursOfFullTimeEmployeesPerSchedule;
int workingPeriodsOfFullTimeEmployeesPerSchedule;
int maxWorkingPeriodsOfFullTimeEmployeesPerSchedule;
int minWorkingHoursOfPartTimeEmployeesPerSchedule
int maxWorkingHoursOfPartTimeEmployeesPerSchedule;
int workingHoursOfFullTimeEmployeesPerSchedule;
int maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork;
int minConsecutiveNonWorkingHoursBetweenShiftWorksOfFullTimeEmployees;
int workingHoursPaidAtRegularHourlyRatePerSchedule;
int workingHoursPaidAtRegularHourlyRatePerShiftWork;
private int fixedCostOfPartTimeEmployeesPerSchedule;
private int minWorkingHoursOfPartTimeEmployeesPerSchedule;
public int[] requiredWorkforce;
Tuples enumerationWorkPeriodsSchedulesOfFullTimeEmployees;
private int maxWorkingHoursOfPartTimeEmployeesPerSchedule;
private Tuples ValidPartTimeEmployeeShiftTuples;
Tuples enumerationWorkPeriodsSchedulesOfPartTimeEmployees;
Tuples ValidPartTimeEmployeeShiftTuples;
public ParametersInitialSchedules() {
@ -52,39 +61,35 @@ 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;
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;
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() {
this.requiredWorkforce = new int[this.daysPerSchedule * this.workPeriodsPerDay];
this.totalWorkedPeriodsInSchedule = 0;
int[] dailyRequiredWorkforce = new int[]{2, 2, 3, 3, 1, 1};
int[] dailyRequiredWorkforce = new int[]{2, 2, 4, 4, 3, 3};
for (int day = 0; day < this.daysPerSchedule; day++) {
for(int shift = 0; shift < this.workPeriodsPerDay; shift++) {
this.requiredWorkforce[day * this.workPeriodsPerDay + shift] = dailyRequiredWorkforce[shift];
@ -278,6 +283,63 @@ 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) {

View file

@ -23,7 +23,7 @@ public class MainClass {
List<SchedulesArray> absenceSchedulesArrayList = GenerateAbsencesSchedules(initialSchedulesArrayList);
List<SchedulesArray> recoveredSchedulesArrayList = GenerateRecoveredSchedules(absenceSchedulesArrayList);
List<SchedulesArray> recoveredSchedulesArrayList = GenerateOptimalRecoveredSchedules(absenceSchedulesArrayList);
// Algo de recouvrement d'absences. Faire un nouveau package de fonctions.
// Trouver meilleure solution et l'afficher.
}
@ -90,11 +90,11 @@ public class MainClass {
return absenceSchedulesArrayList;
}
private static List<SchedulesArray> GenerateRecoveredSchedules(List<SchedulesArray> absenceSchedulesArrayList) {
private static List<SchedulesArray> GenerateOptimalRecoveredSchedules(List<SchedulesArray> absenceSchedulesArrayList) {
List<SchedulesArray> recoveredSchedulesArrayList = new ArrayList<>();
for (SchedulesArray absenceSchedule : absenceSchedulesArrayList) {
RecoveredSchedulesArray recoveredSchedule = new RecoveredSchedulesArray(absenceSchedule);
RecoveredSchedulesArray recoveredSchedule = new RecoveredSchedulesArray((AbsenceSchedulesArray) absenceSchedule);
recoveredSchedule.recoverAbsenceScheduleOptimally();
recoveredSchedulesArrayList.add(recoveredSchedule);
}

View file

@ -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;
}
}

View file

@ -17,11 +17,15 @@ import org.chocosolver.solver.Solution;
*/
public class SchedulesArray {
protected int[][] PartTimeSchedules;
protected int[][] FullTimeSchedules;
protected boolean[][] initialPartTimeSchedules;
protected boolean[][] initialFullTimeSchedules;
protected boolean[][] partTimeSchedules;
protected boolean[][] fullTimeSchedules;
protected int[] employeesPerWorkPeriod;
protected int[] workingPeriodsPerPartTimeEmployees;
protected int[] workingPeriodsPerFullTimeEmployees;
protected boolean[] isPartTimeEmployeeActive;
protected boolean[] isFullTimeEmployeeActive;
protected int maxPartTimeEmployee;
protected int maxFullTimeEmployee;
protected int workPeriodsPerSchedule;
@ -43,30 +47,51 @@ public class SchedulesArray {
this.daysPerSchedule = myScheduleArray.daysPerSchedule;
this.myModelInitialSchedules = myScheduleArray.myModelInitialSchedules;
this.PartTimeSchedules = new int[this.maxPartTimeEmployee][this.workPeriodsPerSchedule];
this.FullTimeSchedules = new int[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.isPartTimeEmployeeActive = new boolean[this.maxPartTimeEmployee];
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.isPartTimeEmployeeActive[employee] = myScheduleArray.isPartTimeEmployeeActive[employee];
}
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.isFullTimeEmployeeActive = new boolean[this.maxFullTimeEmployee];
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
this.isFullTimeEmployeeActive[employee] = myScheduleArray.isFullTimeEmployeeActive[employee];
}
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];
this.workingPeriodsPerFullTimeEmployees = new int[this.maxFullTimeEmployee];
updateEmployeesPerWorkPeriod();
updateWorkingPeriodsPerPartTimeEmployees();
updateWorkingPeriodsPerFullTimeEmployees();
updateAllEmployeesPerWorkPeriod();
updateAllWorkingPeriodsPerPartTimeEmployees();
updateAllWorkingPeriodsPerFullTimeEmployees();
}
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;
@ -76,17 +101,35 @@ public class SchedulesArray {
this.workPeriodsPerDay = myModelInitialSchedules.myScheduleParameters.workPeriodsPerDay;
this.daysPerSchedule = myModelInitialSchedules.myScheduleParameters.daysPerSchedule;
this.PartTimeSchedules = new int[this.maxPartTimeEmployee][this.workPeriodsPerSchedule];
this.FullTimeSchedules = new int[this.maxFullTimeEmployee][this.workPeriodsPerSchedule];
this.isPartTimeEmployeeActive = new boolean[this.maxPartTimeEmployee];
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
if (mySolution.getIntVal(myModelInitialSchedules.workingPeriodsPerPartTimeEmployees[employee]) > 0){
this.isPartTimeEmployeeActive[employee] = true;
}
}
this.isFullTimeEmployeeActive = new boolean[this.maxFullTimeEmployee];
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
if (mySolution.getIntVal(myModelInitialSchedules.workingPeriodsPerFullTimeEmployees[employee]) > 0){
this.isFullTimeEmployeeActive[employee] = true;
}
}
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] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]);
this.partTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]) == 1;
this.initialPartTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]) == 1;
}
}
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
this.FullTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]);
this.fullTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]) == 1;
this.initialFullTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]) == 1;
}
}
@ -94,42 +137,52 @@ public class SchedulesArray {
this.workingPeriodsPerPartTimeEmployees = new int[this.maxPartTimeEmployee];
this.workingPeriodsPerFullTimeEmployees = new int[this.maxFullTimeEmployee];
updateEmployeesPerWorkPeriod();
updateWorkingPeriodsPerPartTimeEmployees();
updateWorkingPeriodsPerFullTimeEmployees();
updateAllEmployeesPerWorkPeriod();
updateAllWorkingPeriodsPerPartTimeEmployees();
updateAllWorkingPeriodsPerFullTimeEmployees();
}
protected void updateEmployeesPerWorkPeriod() {
protected void updateAllEmployeesPerWorkPeriod() {
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
this.employeesPerWorkPeriod[workPeriod] = 0;
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.employeesPerWorkPeriod[workPeriod] += this.PartTimeSchedules[employee][workPeriod];
}
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
this.employeesPerWorkPeriod[workPeriod] += this.FullTimeSchedules[employee][workPeriod];
}
updateEmployeesPerWorkPeriod(workPeriod);
}
}
protected void updateWorkingPeriodsPerPartTimeEmployees() {
protected void updateEmployeesPerWorkPeriod(int workPeriod) {
this.employeesPerWorkPeriod[workPeriod] = 0;
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.workingPeriodsPerPartTimeEmployees[employee] = 0;
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
this.workingPeriodsPerPartTimeEmployees[employee] += this.PartTimeSchedules[employee][workPeriod];
}
if (this.partTimeSchedules[employee][workPeriod]) {this.employeesPerWorkPeriod[workPeriod] += 1;}
}
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
if (this.fullTimeSchedules[employee][workPeriod]) {this.employeesPerWorkPeriod[workPeriod] += 1;}
}
}
protected void updateWorkingPeriodsPerFullTimeEmployees() {
protected void updateAllWorkingPeriodsPerPartTimeEmployees() {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
updateWorkingPeriodsPerPartTimeEmployees(employee);
}
}
protected void updateWorkingPeriodsPerPartTimeEmployees(int employee) {
this.workingPeriodsPerPartTimeEmployees[employee] = 0;
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
if (this.partTimeSchedules[employee][workPeriod]) {this.workingPeriodsPerPartTimeEmployees[employee] += 1;}
}
}
protected void updateAllWorkingPeriodsPerFullTimeEmployees() {
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
this.workingPeriodsPerFullTimeEmployees[employee] = 0;
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
this.workingPeriodsPerFullTimeEmployees[employee] += this.FullTimeSchedules[employee][workPeriod];
}
updateWorkingPeriodsPerFullTimeEmployees(employee);
}
}
protected void updateWorkingPeriodsPerFullTimeEmployees(int employee) {
this.workingPeriodsPerFullTimeEmployees[employee] = 0;
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
if (this.fullTimeSchedules[employee][workPeriod]) {this.workingPeriodsPerFullTimeEmployees[employee] += 1;}
}
}
@ -153,20 +206,28 @@ public class SchedulesArray {
return workPeriodsPerDay;
}
public int[][] getFullTimeSchedules() {
return FullTimeSchedules;
public boolean[][] getFullTimeSchedules() {
return fullTimeSchedules;
}
public int[][] getPartTimeSchedules() {
return PartTimeSchedules;
public boolean[][] getPartTimeSchedules() {
return partTimeSchedules;
}
public boolean isPartTimeEmployeeWorking(int employee, int workPeriod) {
return PartTimeSchedules[employee][workPeriod] == 1;
return partTimeSchedules[employee][workPeriod] == true;
}
public boolean isFullTimeEmployeeWorking(int employee, int workPeriod) {
return FullTimeSchedules[employee][workPeriod] == 1;
return fullTimeSchedules[employee][workPeriod] == true;
}
public boolean isPartTimeEmployeeActive(int employee) {
return isPartTimeEmployeeActive[employee] == true;
}
public boolean isFullTimeEmployeeActive(int employee) {
return isFullTimeEmployeeActive[employee] == true;
}
public int getRequiredWorkForce(int workPeriod) {

View file

@ -6,7 +6,9 @@
package SchedulesRecovery;
import AbsenceSchedules.AbsenceSchedulesArray;
import ScheduleUtil.SchedulesArray;
import java.util.*;
import org.javatuples.Triplet;
import ScheduleUtil.*;
/**
*
@ -14,11 +16,248 @@ import ScheduleUtil.SchedulesArray;
*/
public class RecoveredSchedulesArray extends AbsenceSchedulesArray{
public RecoveredSchedulesArray(SchedulesArray myScheduleArray){
super(myScheduleArray);
public RecoveredSchedulesArray(AbsenceSchedulesArray myAbsenceScheduleArray){
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() {
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<RecoveringAction, RecoveringAction, Integer> > priorityQueueScheduleStatesOrderedByTotalCost = new PriorityQueue<>(totalCostComparator);
List< Triplet<RecoveringAction, RecoveringAction, Integer> > listVisitedScheduleStates = new ArrayList<>();
RecoveringAction currentRecoveringAction = null;
RecoveringAction previousRecoveringAction = null;
while ( workPeriod < this.workPeriodsPerSchedule ) {
Stack<RecoveringActionPartTimeEmployee> stackRecoveringActionsOfPartTimeEmployee =
getPossibleActionOfPartTimeEmployees(workPeriod, currentRecoveredScheduleOfPartTimeEmployees);
Stack<RecoveringActionFullTimeEmployee> 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<RecoveringAction, RecoveringAction, Integer> scheduleState = Triplet.with(previousRecoveringAction, currentRecoveringAction, totalEmployeesCost);
priorityQueueScheduleStatesOrderedByTotalCost.add(scheduleState);
listVisitedScheduleStates.add(scheduleState);
}
Triplet<RecoveringAction, RecoveringAction, Integer> 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<RecoveringActionPartTimeEmployee> getPossibleActionOfPartTimeEmployees(int workPeriod, boolean[][] currentRecoveredSchedule) {
// inclure un attribut pour dire si la requiredWorkForce est satifaite avec l'action.
Stack<RecoveringActionPartTimeEmployee> 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 Stack<RecoveringActionFullTimeEmployee> getPossibleActionOfFullTimeEmployees(int workPeriod, boolean[][] currentRecoveredSchedule) {
Stack<RecoveringActionFullTimeEmployee> 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 isPartTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod, boolean[] currentEmployeeSchedule){
return !currentEmployeeSchedule[workPeriod] && !isPartTimeEmployeeAbsent(employee, workPeriod) && isValidPartTimeEmployeeWorkPeriod(currentEmployeeSchedule, workPeriod);
}
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(boolean[] currentEmployeeSchedule, int workPeriod){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && currentEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork();
}
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
boolean validConsecutivePreviousNonWorkingPeriods = false;
if (compteurWorkPeriod == -1) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !currentEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == workPeriodsPerSchedule) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
}
private boolean isFullTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod, boolean[] currentEmployeeSchedule){
return !currentEmployeeSchedule[workPeriod] && !isFullTimeEmployeeAbsent(employee, workPeriod) && isValidFullTimeEmployeeWorkPeriod(currentEmployeeSchedule, workPeriod);
}
private boolean isValidFullTimeEmployeeWorkPeriod(boolean[] currentEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentEmployeeSchedule, workPeriod);
}
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(boolean[] currentEmployeeSchedule, int workPeriod){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && currentEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork();
}
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
boolean validConsecutivePreviousNonWorkingPeriods = false;
if (compteurWorkPeriod == -1) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !currentEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == workPeriodsPerSchedule) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
}
}

View file

@ -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];
}
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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<RecoveringAction, RecoveringAction, Integer> > {
public int compare(Triplet<RecoveringAction, RecoveringAction, Integer> o1, Triplet<RecoveringAction, RecoveringAction, Integer> o2) {
return o1.getValue2().compareTo(o2.getValue2());
}
}

Binary file not shown.