Creation des bases de l'algorithmes de recouvrement des horaires avec absences.
TODO : Il reste a trouver le recouvrement qui minimise le cout des employes. Cela nécessite de trouver le coût de l'horaire optimal.
This commit is contained in:
parent
fb03247b26
commit
466ccdd681
6 changed files with 318 additions and 70 deletions
|
@ -6,27 +6,57 @@ import jdistlib.rng.RandomEngine;
|
|||
import org.chocosolver.solver.Solution;
|
||||
|
||||
public class AbsenceSchedulesArray extends SchedulesArray{
|
||||
|
||||
|
||||
protected boolean[][] partTimeEmployeeUnavailabilitySchedules;
|
||||
protected boolean[][] fullTimeEmployeeUnavailabilitySchedules;
|
||||
|
||||
public AbsenceSchedulesArray(SchedulesArray myScheduleArray) {
|
||||
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];
|
||||
public AbsenceSchedulesArray(AbsenceSchedulesArray myAbsenceScheduleArray) {
|
||||
super(myAbsenceScheduleArray);
|
||||
this.partTimeEmployeeUnavailabilitySchedules = new boolean[this.maxPartTimeEmployee][this.workPeriodsPerSchedule];
|
||||
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
|
||||
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
|
||||
this.partTimeEmployeeUnavailabilitySchedules[employee][workPeriod] = myAbsenceScheduleArray.partTimeEmployeeUnavailabilitySchedules[employee][workPeriod];
|
||||
}
|
||||
}
|
||||
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];
|
||||
this.fullTimeEmployeeUnavailabilitySchedules = new boolean[this.maxFullTimeEmployee][this.workPeriodsPerSchedule];
|
||||
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
|
||||
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
|
||||
this.fullTimeEmployeeUnavailabilitySchedules[employee][workPeriod] = myAbsenceScheduleArray.fullTimeEmployeeUnavailabilitySchedules[employee][workPeriod];
|
||||
}
|
||||
}
|
||||
updateEmployeesPerWorkPeriod();
|
||||
updateWorkingPeriodsPerPartTimeEmployees();
|
||||
updateWorkingPeriodsPerFullTimeEmployees();
|
||||
}
|
||||
|
||||
|
||||
public void generateAbsences(RandomEngine r) {
|
||||
this.partTimeEmployeeUnavailabilitySchedules = new boolean[this.maxPartTimeEmployee][this.workPeriodsPerSchedule];
|
||||
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];
|
||||
}
|
||||
}
|
||||
this.fullTimeEmployeeUnavailabilitySchedules = new boolean[this.maxFullTimeEmployee][this.workPeriodsPerSchedule];
|
||||
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];
|
||||
}
|
||||
|
||||
}
|
|
@ -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.90;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@ public class ParametersInitialSchedules {
|
|||
int minWorkingHoursOfPartTimeEmployeesPerSchedule;
|
||||
int maxWorkingHoursOfPartTimeEmployeesPerSchedule;
|
||||
int minWorkingPeriodsOfPartTimeEmployeesPerSchedule;
|
||||
int maxWorkingPeriodsOfPartTimeEmployeesPerSchedule;
|
||||
public int maxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork;
|
||||
public int minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees;
|
||||
public int maxWorkingPeriodsOfPartTimeEmployeesPerSchedule;
|
||||
|
||||
int fixedCostOfFullTimeEmployeesPerSchedule;
|
||||
int regularHourlyRateOfFullTimeEmployees;
|
||||
|
@ -24,7 +26,9 @@ public class ParametersInitialSchedules {
|
|||
int workingHoursOfFullTimeEmployeesPerSchedule;
|
||||
int maxWorkingHoursOfFullTimeEmployeesPerSchedule;
|
||||
int workingPeriodsOfFullTimeEmployeesPerSchedule;
|
||||
int maxWorkingPeriodsOfFullTimeEmployeesPerSchedule;
|
||||
public int maxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork;
|
||||
public int minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees;
|
||||
public int maxWorkingPeriodsOfFullTimeEmployeesPerSchedule;
|
||||
|
||||
int workingHoursPaidAtRegularHourlyRatePerSchedule;
|
||||
|
||||
|
@ -57,6 +61,12 @@ public class ParametersInitialSchedules {
|
|||
this.hourlyRateOfPartTimeEmployees = 12; // 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
|
||||
|
@ -70,6 +80,12 @@ public class ParametersInitialSchedules {
|
|||
|
||||
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
|
||||
|
|
|
@ -94,7 +94,7 @@ public class MainClass {
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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,17 +47,31 @@ 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];
|
||||
this.isPartTimeEmployeeActive = new boolean[this.maxPartTimeEmployee];
|
||||
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
|
||||
this.isPartTimeEmployeeActive[employee] = myScheduleArray.isPartTimeEmployeeActive[employee];
|
||||
}
|
||||
|
||||
this.isFullTimeEmployeeActive = new boolean[this.maxFullTimeEmployee];
|
||||
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
|
||||
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.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.fullTimeSchedules[employee][workPeriod] = myScheduleArray.fullTimeSchedules[employee][workPeriod];
|
||||
this.initialFullTimeSchedules[employee][workPeriod] = myScheduleArray.initialFullTimeSchedules[employee][workPeriod];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,9 +79,9 @@ public class SchedulesArray {
|
|||
this.workingPeriodsPerPartTimeEmployees = new int[this.maxPartTimeEmployee];
|
||||
this.workingPeriodsPerFullTimeEmployees = new int[this.maxFullTimeEmployee];
|
||||
|
||||
updateEmployeesPerWorkPeriod();
|
||||
updateWorkingPeriodsPerPartTimeEmployees();
|
||||
updateWorkingPeriodsPerFullTimeEmployees();
|
||||
updateAllEmployeesPerWorkPeriod();
|
||||
updateAllWorkingPeriodsPerPartTimeEmployees();
|
||||
updateAllWorkingPeriodsPerFullTimeEmployees();
|
||||
|
||||
}
|
||||
|
||||
|
@ -76,17 +94,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 +130,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 +199,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) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
package SchedulesRecovery;
|
||||
|
||||
import AbsenceSchedules.AbsenceSchedulesArray;
|
||||
import ScheduleUtil.SchedulesArray;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -14,11 +14,159 @@ import ScheduleUtil.SchedulesArray;
|
|||
*/
|
||||
public class RecoveredSchedulesArray extends AbsenceSchedulesArray{
|
||||
|
||||
public RecoveredSchedulesArray(SchedulesArray myScheduleArray){
|
||||
super(myScheduleArray);
|
||||
protected boolean[][] partTimeEmployeeAbsenceRecoveringAvailabilitySchedules;
|
||||
protected boolean[][] fullTimeEmployeeAbsenceRecoveringAvailabilitySchedules;
|
||||
|
||||
public RecoveredSchedulesArray(AbsenceSchedulesArray myAbsenceScheduleArray){
|
||||
super(myAbsenceScheduleArray);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isPartTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod){
|
||||
return isPartTimeEmployeeActive(employee) && !isPartTimeEmployeeAbsent(employee, workPeriod) && isValidPartTimeEmployeeWorkPeriod(employee,workPeriod);
|
||||
}
|
||||
|
||||
private boolean isValidPartTimeEmployeeWorkPeriod(int employee, int workPeriod){
|
||||
return isValidWorkingPeriodsOfPartTimeEmployee(employee) &&
|
||||
isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(employee, workPeriod) &&
|
||||
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(employee, workPeriod);
|
||||
}
|
||||
|
||||
private boolean isValidWorkingPeriodsOfPartTimeEmployee(int employee){
|
||||
return this.workingPeriodsPerPartTimeEmployees[employee] < myModelInitialSchedules.myScheduleParameters.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule;
|
||||
}
|
||||
|
||||
private boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(int employee, int workPeriod){
|
||||
int consecutiveWorkingPeriods = 1;
|
||||
int compteurWorkPeriod = workPeriod - 1;
|
||||
while ( compteurWorkPeriod >= 0 && isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutiveWorkingPeriods += 1;
|
||||
compteurWorkPeriod--;
|
||||
}
|
||||
compteurWorkPeriod = workPeriod + 1;
|
||||
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutiveWorkingPeriods += 1;
|
||||
compteurWorkPeriod++;
|
||||
}
|
||||
return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.maxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork;
|
||||
}
|
||||
|
||||
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(int employee, int workPeriod){
|
||||
int consecutivePreviousNonWorkingPeriods = 0;
|
||||
int compteurWorkPeriod = workPeriod - 1;
|
||||
while ( compteurWorkPeriod >= 0 && !isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutivePreviousNonWorkingPeriods += 1;
|
||||
compteurWorkPeriod--;
|
||||
}
|
||||
boolean validConsecutivePreviousNonWorkingPeriods = false;
|
||||
if (compteurWorkPeriod == -1) {
|
||||
validConsecutivePreviousNonWorkingPeriods = true;
|
||||
} else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees) {
|
||||
validConsecutivePreviousNonWorkingPeriods = true;
|
||||
}
|
||||
int consecutiveNextNonWorkingPeriods = 0;
|
||||
compteurWorkPeriod = workPeriod + 1;
|
||||
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !isPartTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutiveNextNonWorkingPeriods += 1;
|
||||
compteurWorkPeriod++;
|
||||
}
|
||||
boolean validConsecutiveNextNonWorkingPeriods = false;
|
||||
if (compteurWorkPeriod == workPeriodsPerSchedule) {
|
||||
validConsecutiveNextNonWorkingPeriods = true;
|
||||
} else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees) {
|
||||
validConsecutiveNextNonWorkingPeriods = true;
|
||||
}
|
||||
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
|
||||
}
|
||||
|
||||
private boolean isFullTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod){
|
||||
return isFullTimeEmployeeActive(employee) && !isFullTimeEmployeeAbsent(employee, workPeriod) && isValidFullTimeEmployeeWorkPeriod(employee,workPeriod);
|
||||
}
|
||||
|
||||
private boolean isValidFullTimeEmployeeWorkPeriod(int employee, int workPeriod){
|
||||
return isValidWorkingPeriodsOfFullTimeEmployee(employee) &&
|
||||
isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(employee, workPeriod) &&
|
||||
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(employee, workPeriod);
|
||||
}
|
||||
|
||||
private boolean isValidWorkingPeriodsOfFullTimeEmployee(int employee){
|
||||
return this.workingPeriodsPerFullTimeEmployees[employee] < myModelInitialSchedules.myScheduleParameters.maxWorkingPeriodsOfFullTimeEmployeesPerSchedule;
|
||||
}
|
||||
|
||||
|
||||
private boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(int employee, int workPeriod){
|
||||
int consecutiveWorkingPeriods = 1;
|
||||
int compteurWorkPeriod = workPeriod - 1;
|
||||
while ( compteurWorkPeriod >= 0 && isFullTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutiveWorkingPeriods += 1;
|
||||
compteurWorkPeriod--;
|
||||
}
|
||||
compteurWorkPeriod = workPeriod + 1;
|
||||
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && isFullTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutiveWorkingPeriods += 1;
|
||||
compteurWorkPeriod++;
|
||||
}
|
||||
return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.maxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork;
|
||||
}
|
||||
|
||||
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(int employee, int workPeriod){
|
||||
int consecutivePreviousNonWorkingPeriods = 0;
|
||||
int compteurWorkPeriod = workPeriod - 1;
|
||||
while ( compteurWorkPeriod >= 0 && !isFullTimeEmployeeWorking(employee, compteurWorkPeriod)){
|
||||
consecutivePreviousNonWorkingPeriods += 1;
|
||||
compteurWorkPeriod--;
|
||||
}
|
||||
boolean validConsecutivePreviousNonWorkingPeriods = false;
|
||||
if (compteurWorkPeriod == -1) {
|
||||
validConsecutivePreviousNonWorkingPeriods = true;
|
||||
} else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees) {
|
||||
validConsecutivePreviousNonWorkingPeriods = true;
|
||||
}
|
||||
int consecutiveNextNonWorkingPeriods = 0;
|
||||
compteurWorkPeriod = workPeriod + 1;
|
||||
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !isFullTimeEmployeeWorking(employee, compteurWorkPeriod) ){
|
||||
consecutiveNextNonWorkingPeriods += 1;
|
||||
compteurWorkPeriod++;
|
||||
}
|
||||
boolean validConsecutiveNextNonWorkingPeriods = false;
|
||||
if (compteurWorkPeriod == workPeriodsPerSchedule) {
|
||||
validConsecutiveNextNonWorkingPeriods = true;
|
||||
} else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.minConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees) {
|
||||
validConsecutiveNextNonWorkingPeriods = true;
|
||||
}
|
||||
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue