Algorithme de recouvrement optimal complété.

Ménage dans les fonctions.
This commit is contained in:
Francois Berube\frabe 2018-04-06 13:21:59 -04:00
parent 6b4f6ff609
commit d51d7d4a35
19 changed files with 617 additions and 598 deletions

View file

@ -1,47 +1,53 @@
package AbsenceSchedules;
import InitialSchedules.ModelInitialSchedules;
import ScheduleUtil.SchedulesArray;
import jdistlib.rng.RandomEngine;
import org.chocosolver.solver.Solution;
public class AbsenceSchedulesArray extends SchedulesArray{
public AbsenceSchedulesArray(SchedulesArray myScheduleArray) {
super(myScheduleArray);
public SchedulesArray initialSchedulesArray;
public int numberOfRecoveringActionsToPerform;
public AbsenceSchedulesArray(SchedulesArray initialSchedulesArray, RandomEngine r) {
super(initialSchedulesArray);
this.initialSchedulesArray = initialSchedulesArray;
generateAbsenceSimulation(r);
}
public AbsenceSchedulesArray(AbsenceSchedulesArray myAbsenceScheduleArray) {
super(myAbsenceScheduleArray);
}
public void generateAbsences(RandomEngine r) {
private void generateAbsenceSimulation(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 < getNumberPartTimeEmployee(); i++) {
boolean[] a = new AbsencesVector(myParametersInitialSchedules.getWorkPeriodsPerSchedule(), r).getAbsencesVector();
for (int j = 0; j < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); j++) {
this.partTimeSchedules[i][j] = this.initialSchedulesArray.isPartTimeEmployeeWorking(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];
for (int i = 0; i < getNumberFullTimeEmployee(); i++) {
boolean[] a = new AbsencesVector(myParametersInitialSchedules.getWorkPeriodsPerSchedule(), r).getAbsencesVector();
for (int j = 0; j < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); j++) {
this.fullTimeSchedules[i][j] = this.initialSchedulesArray.isFullTimeEmployeeWorking(i, j) && a[j];
}
}
updateAllEmployeesPerWorkPeriod();
updateAllWorkingPeriodsPerPartTimeEmployees();
updateAllWorkingPeriodsPerFullTimeEmployees();
calculateNumberOfRecoveringActionsToPerform();
}
public boolean isPartTimeEmployeeAbsent(int employee, int workPeriod) {
return this.partTimeSchedules[employee][workPeriod] != this.initialSchedulesArray.isPartTimeEmployeeWorking(employee, workPeriod);
}
protected boolean isPartTimeEmployeeAbsent(int employee, int workPeriod) {
return this.partTimeSchedules[employee][workPeriod] != this.initialPartTimeSchedules[employee][workPeriod];
public boolean isFullTimeEmployeeAbsent(int employee, int workPeriod) {
return this.fullTimeSchedules[employee][workPeriod] != this.initialSchedulesArray.isFullTimeEmployeeWorking(employee, workPeriod);
}
protected boolean isFullTimeEmployeeAbsent(int employee, int workPeriod) {
return this.fullTimeSchedules[employee][workPeriod] != this.initialFullTimeSchedules[employee][workPeriod];
private void calculateNumberOfRecoveringActionsToPerform() {
this.numberOfRecoveringActionsToPerform = 0;
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
this.numberOfRecoveringActionsToPerform += this.myParametersInitialSchedules.getRequiredWorkForce(workPeriod) - this.getEmployeesWorkingPerWorkPeriod(workPeriod);
}
}
}

View file

@ -5,16 +5,14 @@ import jdistlib.rng.RandomEngine;
public class AbsencesVector {
private boolean[] AbsencesVector;
private double probPresence = 0.80;
private double probReturn = 0.50;
public AbsencesVector(int length, RandomEngine r) {
int current = 1;
AbsencesVector = new boolean[length];
Binomial b1 = new Binomial(1, probPresence);
Binomial b1 = new Binomial(1, ParametersAbsencesGenerator.probPresence);
b1.setRandomEngine(r);
Binomial b2 = new Binomial(1, probReturn);
Binomial b2 = new Binomial(1, ParametersAbsencesGenerator.probReturn);
b2.setRandomEngine(r);
for (int i = 0; i < length; i++) {
if (current == 1) {

View file

@ -0,0 +1,28 @@
/*
* 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 AbsenceSchedules;
import ScheduleUtil.SchedulesArray;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author frabe
*/
public class BankAbsenceSchedules {
public SchedulesArray initialSchedulesArray;
public List<AbsenceSchedulesArray> bankAbsenceSimulation;
public BankAbsenceSchedules(SchedulesArray initialSchedulesArray) {
this.initialSchedulesArray = initialSchedulesArray;
this.bankAbsenceSimulation = new ArrayList<>();
}
public void addAbsenceSchedules(AbsenceSchedulesArray absenceSchedulesArray) {
this.bankAbsenceSimulation.add(absenceSchedulesArray);
}
}

View file

@ -0,0 +1,16 @@
/*
* 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 AbsenceSchedules;
/**
*
* @author frabe
*/
public interface ParametersAbsencesGenerator {
public final double probPresence = 0.5;
public final double probReturn = 0.99;
public final int numberAbsenceSimulations = 5;
}

View file

@ -67,8 +67,8 @@ public class ModelInitialSchedules {
private void createScheduleVariables() {
// Variable pour l'horaire des employes
this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxFullTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule);
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule);
this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxFullTimeEmployee, this.myScheduleParameters.getWorkPeriodsPerSchedule());
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.getWorkPeriodsPerSchedule());
// Vecteur de toutes les variables
/*this.allWorkPeriods = chocoModelInitialSchedules.boolVarArray((this.maxPartTimeEmployee+this.maxFullTimeEmployee)*this.myScheduleParameters.workPeriodsPerSchedule);
@ -88,19 +88,19 @@ public class ModelInitialSchedules {
}*/
// Variable pour faire le compte du nombre d'heures des employes
this.workingPeriodsPerPartTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxPartTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true);
this.workingPeriodsPerFullTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxFullTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true);
this.workingPeriodsPerPartTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxPartTimeEmployee, 0, this.myScheduleParameters.getWorkPeriodsPerSchedule(), true);
this.workingPeriodsPerFullTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxFullTimeEmployee, 0, this.myScheduleParameters.getWorkPeriodsPerSchedule(), true);
// Creer la transpose des horaires pour compter les elements des colonnes
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxPartTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.maxPartTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod][employee]
= this.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod];
}
}
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxFullTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.maxFullTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) {
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod][employee]
= this.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod];
@ -108,9 +108,9 @@ public class ModelInitialSchedules {
}
// Variable pour faire le compte du nombre d'employes par periode de travail
this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule, 0, this.maxPartTimeEmployee, true);
this.fullTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule, 0, this.maxFullTimeEmployee, true);
this.employeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule,
this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.maxPartTimeEmployee, true);
this.fullTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.maxFullTimeEmployee, true);
this.employeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(),
0, this.maxPartTimeEmployee + this.maxFullTimeEmployee, true);
// Variable pour les périodes de travail par jour des travailleurs à temps partiel
@ -168,7 +168,7 @@ public class ModelInitialSchedules {
// Constraintes pour compter le nombre d'employes par periode de travail et s'assurer qu'il
// satisfait la demande en employes
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) {
chocoModelInitialSchedules.count(chocoModelInitialSchedules.intVar(1),
transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod],
this.partTimeEmployeesPerWorkPeriods[workPeriod]).post();
@ -214,15 +214,15 @@ public class ModelInitialSchedules {
// Calcul du nombre de périodes travaillées par chaque type d'employés dans l'horaire
IntVar[] NumberOfPartTimeEmployeesPerPeriod =
chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule,
chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(),
0,
this.maxPartTimeEmployee, true);
IntVar[] NumberOfFullTimeEmployeesPerPeriod =
chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule,
chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(),
0,
this.maxFullTimeEmployee, true);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) {
chocoModelInitialSchedules.sum(transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod],
"=", NumberOfPartTimeEmployeesPerPeriod[workPeriod]).post();
chocoModelInitialSchedules.sum(transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod],
@ -231,10 +231,10 @@ public class ModelInitialSchedules {
IntVar NumberOfPartTimeEmployeesPeriods =
chocoModelInitialSchedules.intVar(
0, this.maxPartTimeEmployee * this.myScheduleParameters.workPeriodsPerSchedule, true);
0, this.maxPartTimeEmployee * this.myScheduleParameters.getWorkPeriodsPerSchedule(), true);
IntVar NumberOfFullTimeEmployeesPeriods =
chocoModelInitialSchedules.intVar(
0, this.maxPartTimeEmployee * this.myScheduleParameters.workPeriodsPerSchedule, true);
0, this.maxPartTimeEmployee * this.myScheduleParameters.getWorkPeriodsPerSchedule(), true);
chocoModelInitialSchedules.sum(NumberOfPartTimeEmployeesPerPeriod, "=", NumberOfPartTimeEmployeesPeriods).post();
chocoModelInitialSchedules.sum(NumberOfFullTimeEmployeesPerPeriod, "=", NumberOfFullTimeEmployeesPeriods).post();
@ -242,32 +242,35 @@ public class ModelInitialSchedules {
// Calcul du salaire versé
IntVar PartTimeEmployeesSalary =
chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee *
this.myScheduleParameters.workPeriodsPerSchedule *
this.myScheduleParameters.regularHourlyRateOfPartTimeEmployees, true);
this.myScheduleParameters.getWorkPeriodsPerSchedule() *
this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate(), true);
IntVar FullTimeEmployeesSalary =
chocoModelInitialSchedules.intVar(0, this.maxFullTimeEmployee *
this.myScheduleParameters.workPeriodsPerSchedule *
this.myScheduleParameters.regularHourlyRateOfFullTimeEmployees, true);
this.myScheduleParameters.getWorkPeriodsPerSchedule() *
this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate(), true);
this.TotalEmployeesSalary = chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee *
this.myScheduleParameters.workPeriodsPerSchedule *
this.myScheduleParameters.regularHourlyRateOfPartTimeEmployees +
this.myScheduleParameters.getWorkPeriodsPerSchedule() *
this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate() +
this.maxFullTimeEmployee *
this.myScheduleParameters.workPeriodsPerSchedule *
this.myScheduleParameters.regularHourlyRateOfFullTimeEmployees, true);
this.myScheduleParameters.getWorkPeriodsPerSchedule() *
this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate(), true);
IntVar HourlyRateOfPartTimeEmployees =
chocoModelInitialSchedules.intVar(this.myScheduleParameters.regularHourlyRateOfPartTimeEmployees);
IntVar regularHourlyRateOfFullTimeEmployees =
chocoModelInitialSchedules.intVar(this.myScheduleParameters.regularHourlyRateOfFullTimeEmployees);
IntVar workingPeriodCostOfPartTimeEmployees =
chocoModelInitialSchedules.intVar(this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate());
IntVar workingPeriodCostOfFullTimeEmployees =
chocoModelInitialSchedules.intVar(this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate());
chocoModelInitialSchedules.arithm(NumberOfPartTimeEmployeesPeriods, "*", HourlyRateOfPartTimeEmployees, "=", PartTimeEmployeesSalary).post();
chocoModelInitialSchedules.arithm(NumberOfFullTimeEmployeesPeriods, "*", regularHourlyRateOfFullTimeEmployees, "=", FullTimeEmployeesSalary).post();
chocoModelInitialSchedules.arithm(NumberOfPartTimeEmployeesPeriods, "*", workingPeriodCostOfPartTimeEmployees, "=", PartTimeEmployeesSalary).post();
chocoModelInitialSchedules.arithm(NumberOfFullTimeEmployeesPeriods, "*", workingPeriodCostOfFullTimeEmployees, "=", FullTimeEmployeesSalary).post();
chocoModelInitialSchedules.arithm(PartTimeEmployeesSalary, "+", FullTimeEmployeesSalary, "=", this.TotalEmployeesSalary).post();
//TODO: Inclure les frais fixes par employé
//TODO: Inclure les frais fixes par employé. Jai defini des accesseurs dans la classe ParametersInitialSchedules
// this.scheduleProfit = chocoModelInitialSchedules.intVar("TOTAL_COST", 0, 20 * N * p, true);

View file

@ -3,31 +3,28 @@ package InitialSchedules;
import org.chocosolver.solver.constraints.extension.Tuples;
public class ParametersInitialSchedules {
public int workPeriodsPerDay;
//mettre les attributs prives et definir accesseurs
int NbFullTimeSolutions;
int NbPartTimeSolutions;
int shiftWorkPerDay;
public int daysPerSchedule;
public int workPeriodsPerSchedule;
int totalWorkedPeriodsInSchedule;
int daysPerSchedule;
int hoursPerWorkPeriod;
int totalWorkedPeriodsInSchedule;
int hourlyRateOfPartTimeEmployees;
public int fixedCostOfPartTimeEmployeesPerSchedule;
public int regularHourlyRateOfPartTimeEmployees;
public int overtimeHourlyRateOfPartTimeEmployees;
int fixedCostOfPartTimeEmployeesPerSchedule;
int regularHourlyRateOfPartTimeEmployees;
int overtimeHourlyRateOfPartTimeEmployees;
int minWorkingHoursOfPartTimeEmployeesPerSchedule;
int maxWorkingHoursOfPartTimeEmployeesPerSchedule;
int maxConsecutiveWorkingHoursOfPartTimeEmployeesPerShiftWork;
int minConsecutiveNonWorkingHoursBetweenShiftWorksOfPartTimeEmployees;
public int fixedCostOfFullTimeEmployeesPerSchedule;
public int regularHourlyRateOfFullTimeEmployees;
public int overtimeHourlyRateOfFullTimeEmployees;
int fixedCostOfFullTimeEmployeesPerSchedule;
int regularHourlyRateOfFullTimeEmployees;
int overtimeHourlyRateOfFullTimeEmployees;
int maxWorkingHoursOfFullTimeEmployeesPerSchedule;
int minWorkingHoursOfPartTimeEmployeesPerSchedule
int maxWorkingHoursOfPartTimeEmployeesPerSchedule;
int workingHoursOfFullTimeEmployeesPerSchedule;
int maxConsecutiveWorkingHoursOfFullTimeEmployeesPerShiftWork;
@ -36,9 +33,7 @@ public class ParametersInitialSchedules {
int workingHoursPaidAtRegularHourlyRatePerSchedule;
int workingHoursPaidAtRegularHourlyRatePerShiftWork;
private int fixedCostOfPartTimeEmployeesPerSchedule;
public int[] requiredWorkforce;
int[] requiredWorkforce;
Tuples enumerationWorkPeriodsSchedulesOfFullTimeEmployees;
Tuples enumerationWorkPeriodsSchedulesOfPartTimeEmployees;
Tuples ValidPartTimeEmployeeShiftTuples;
@ -56,11 +51,9 @@ public class ParametersInitialSchedules {
}
private void setGeneralParameters() {
this.workPeriodsPerDay = 6;
this.shiftWorkPerDay = 3;
this.daysPerSchedule = 14;
this.hoursPerWorkPeriod = 24 / this.workPeriodsPerDay;
this.workPeriodsPerSchedule = this.workPeriodsPerDay * this.daysPerSchedule;
this.hoursPerWorkPeriod = 4;
this.workingHoursPaidAtRegularHourlyRatePerSchedule = 80;
this.workingHoursPaidAtRegularHourlyRatePerShiftWork = 8;
}
@ -87,12 +80,12 @@ public class ParametersInitialSchedules {
private void setRequiredWorkforce() {
this.requiredWorkforce = new int[this.daysPerSchedule * this.workPeriodsPerDay];
this.requiredWorkforce = new int[this.daysPerSchedule * this.getWorkPeriodPerDay()];
this.totalWorkedPeriodsInSchedule = 0;
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];
for(int shift = 0; shift < this.getWorkPeriodPerDay(); shift++) {
this.requiredWorkforce[day * this.getWorkPeriodPerDay() + shift] = dailyRequiredWorkforce[shift];
this.totalWorkedPeriodsInSchedule += dailyRequiredWorkforce[shift];
}
}
@ -115,40 +108,40 @@ public class ParametersInitialSchedules {
int[][] dailySchedulesOfFullTimeEmployees = validDailyFullTimeSchedules.getValidSchedules();
int[][] workPeriodsSchedulesOfFullTimeEmployees
= new int[NbFullTimeSolutions * this.shiftWorkPerDay][this.workPeriodsPerSchedule];
= new int[NbFullTimeSolutions * this.shiftWorkPerDay][this.getWorkPeriodsPerSchedule()];
// Cette fonction sera a ameliorer avec des sous-fonctions, car elle n'est pas tres explicite.
for (int scheduleNumber = 0; scheduleNumber < NbFullTimeSolutions; scheduleNumber++) {
for (int day = 0; day < this.daysPerSchedule; day++) {
for (int shiftNumber = 0; shiftNumber < this.shiftWorkPerDay; shiftNumber++) {
if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 0) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
} else if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 1) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
} else if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 2) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 1;
} else if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 0) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
}
}
}
@ -177,48 +170,47 @@ public class ParametersInitialSchedules {
int maxShiftConfig = 5;
int[][] workPeriodsSchedulesOfPartTimeEmployees
= new int[NbPartTimeSolutions * 5][this.workPeriodsPerSchedule];
= new int[NbPartTimeSolutions * 5][this.getWorkPeriodsPerSchedule()];
// Cette fonction sera a ameliorer avec des sous-fonctions, car elle n'est pas tres explicite.
for (int scheduleNumber = 0; scheduleNumber < NbPartTimeSolutions; scheduleNumber++) {
for (int day = 0; day < this.daysPerSchedule; day++) {
for (int shiftNumber = 0; shiftNumber < maxShiftConfig; shiftNumber++) {
System.out.println("Schedule:" + scheduleNumber + "day:" + day + "Shift:" + shiftNumber);
if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 0) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
} else if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 1) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 2] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
} else if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 2) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 2] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 3] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
} else if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 3) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 3] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
} else if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 4) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 1;
/*} else if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 5) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 1;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
@ -262,12 +254,12 @@ public class ParametersInitialSchedules {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 1;*/
} else if (dailySchedulesOfPartTimeEmployees[scheduleNumber][day] == 0) {
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 0] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 1] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 2] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 3] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 4] = 0;
workPeriodsSchedulesOfPartTimeEmployees[scheduleNumber * maxShiftConfig + shiftNumber][day * this.getWorkPeriodPerDay() + 5] = 0;
}
}
}
@ -278,10 +270,33 @@ public class ParametersInitialSchedules {
= new Tuples(workPeriodsSchedulesOfPartTimeEmployees, true);
}
private void setValidPartTimeEmployeeShiftTuples() {
this.ValidPartTimeEmployeeShiftTuples = new ValidPartTimeEmployeeShift().makeTuples();
}
public int getRequiredWorkForce(int workPeriod) {
return this.requiredWorkforce[workPeriod];
}
public int getDaysPerSchedule() {
return daysPerSchedule;
}
public int getWorkPeriodsPerSchedule() {
return this.getWorkPeriodPerDay() * this.daysPerSchedule;
}
public int getWorkPeriodPerDay() {
return (int) 24/this.hoursPerWorkPeriod;
}
public int getFixedCostOfPartTimeEmployeesPerSchedule() {
return this.fixedCostOfPartTimeEmployeesPerSchedule;
}
public int getFixedCostOfFullTimeEmployeesPerSchedule() {
return this.fixedCostOfFullTimeEmployeesPerSchedule;
}
public int getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule () {
return (int) (workingHoursPaidAtRegularHourlyRatePerSchedule / this.hoursPerWorkPeriod);
@ -298,6 +313,10 @@ public class ParametersInitialSchedules {
public int getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate () {
return (int) (regularHourlyRateOfFullTimeEmployees * this.hoursPerWorkPeriod);
}
public int getMinimumWorkingPeriodCost () {
return (int) (regularHourlyRateOfFullTimeEmployees * this.hoursPerWorkPeriod);
}
public int getWorkingPeriodCostOfPartTimeEmployeesPaidAtOvertimeHourlyRate () {
return (int) (overtimeHourlyRateOfPartTimeEmployees * this.hoursPerWorkPeriod);
@ -340,49 +359,7 @@ public class ParametersInitialSchedules {
return (int) (this.workingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod);
}
// A implementer plus tard si l'on veut travailler avec des fichiers texte
public ParametersInitialSchedules(String fileName) {
// String line = null;
// try {
// FileReader fileReader =
// new FileReader(fileName);
//
// BufferedReader bufferedReader =
// new BufferedReader(fileReader);
//
// if((line = bufferedReader.readLine()) != null) {
// String[] arrayLine= line.split("\\s+");
// PARAMETRES_HORAIRE[0] = Integer.parseInt(arrayLine[0]);
// PARAMETRES_HORAIRE[1] = Integer.parseInt(arrayLine[1]);
// PARAMETRES_HORAIRE[2] = Integer.parseInt(arrayLine[2]);
// PARAMETRES_HORAIRE[3] = Integer.parseInt(arrayLine[3]);
// }
// if((line = bufferedReader.readLine()) != null) {
// String[] arrayLine= line.split("\\s+");
// for (int i = 0 ; i < p ; i++) {
// NBR_EMPLOYES_REQUIS[i] = Integer.parseInt(arrayLine[i]);
// }
// }
// if((line = bufferedReader.readLine()) != null) {
// String[] arrayLine= line.split("\\s+");
// for (int i = 0 ; i < p ; i++) {
// NBR_EMPLOYES_SOUHAITES[i] = Integer.parseInt(arrayLine[i]);
// }
// }
// bufferedReader.close();
// }
// catch(FileNotFoundException ex) {
// System.out.println(
// "Unable to open file '" +
// fileName + "'");
// }
// catch(IOException ex) {
// System.out.println(
// "Error reading file '"
// + fileName + "'");
// }
}
public ParametersInitialSchedules(String fileName) {}
}

View file

@ -6,7 +6,6 @@ import org.chocosolver.solver.constraints.nary.automata.FA.FiniteAutomaton;
import org.chocosolver.solver.constraints.nary.automata.FA.IAutomaton;
import org.chocosolver.solver.variables.BoolVar;
import org.chocosolver.solver.variables.IntVar;
import java.util.List;
public class ValidDailySchedules {
@ -59,25 +58,18 @@ public class ValidDailySchedules {
/* Itérer sur les solutions */
int iterSolutions = 0;
System.out.println("Valid Full Time Schedules:");
for (Solution solution : solutions) {
if (solution != null) {
System.out.print(iterSolutions + "::");
for (int iterPeriod = 0; iterPeriod < nbPeriodes; iterPeriod++) {
ValidSchedules[iterSolutions][iterPeriod] = solution.getIntVal(horaire[iterPeriod]);
System.out.print(ValidSchedules[iterSolutions][iterPeriod]);
}
System.out.print("\n");
iterSolutions++;
}
}
/* La solution additionnelle où le travailleur ne travaille pas*/
System.out.print(this.nbSolutions - 1 + "::");
for (int iterPeriod = 0; iterPeriod < nbPeriodes; iterPeriod++) {
ValidSchedules[this.nbSolutions - 1][iterPeriod] = 0;
System.out.print(ValidSchedules[this.nbSolutions - 1][iterPeriod]);
}
System.out.print("\n");
}
public int getNbSolutions() {

View file

@ -1,8 +1,9 @@
//import AbsenceSchedules.AbsenceSchedulesArray;
import AbsenceSchedules.AbsenceSchedulesArray;
import ScheduleUtil.SchedulesArray;
import SchedulesRecovery.RecoveredSchedulesArray;
import AbsenceSchedules.*;
import ScheduleUtil.*;
import SchedulesRecovery.*;
//import SchedulesRecovery.RecoveredSchedulesArray;
import jdistlib.rng.MersenneTwister;
import jdistlib.rng.RandomEngine;
import org.chocosolver.solver.Solution;
@ -12,20 +13,23 @@ import org.chocosolver.solver.exception.ContradictionException;
import java.util.ArrayList;
import java.util.List;
public class MainClass {
public static void main(String[] args) {
// Le main ne devrait contenir que les 5 fonctions correspondantes aux etapes du pipeline
List<SchedulesArray> initialSchedulesArrayList = generateInitialSchedules();
// TODO :
// Raffiner banques de solutions en prenant des horaires ayant de bonnes differences
List<SchedulesArray> absenceSchedulesArrayList = GenerateAbsencesSchedules(initialSchedulesArrayList);
List<BankAbsenceSchedules> listBankAbsenceSchedules = GenerateAbsencesSchedules(initialSchedulesArrayList);
List<SchedulesArray> recoveredSchedulesArrayList = GenerateOptimalRecoveredSchedules(absenceSchedulesArrayList);
// Algo de recouvrement d'absences. Faire un nouveau package de fonctions.
// Trouver meilleure solution et l'afficher.
List<BankRecoveredSchedules> recoveredSchedulesArrayList = GenerateOptimalRecoveredSchedules(listBankAbsenceSchedules);
// TODO :
// calcul des moyennes de cout de recouvrement
// Afficher les solutions en ordre de cout de recouvrement et comparer avec solution optimale (nbr employes temps plein maximal).
}
private static List<SchedulesArray> generateInitialSchedules() {
@ -50,9 +54,10 @@ public class MainClass {
}
solverInitialSchedules.showDashboard();
/*solverInitialSchedules.setSearch(Search.domOverWDegSearch(myModelInitialSchedules.allWorkPeriods));*/
// solverInitialSchedules.setRestartOnSolutions(); /*Sans restart, toutes les horaires sont identiques*/
solverInitialSchedules.limitSolution(5);
solverInitialSchedules.limitSolution(1);
//solverInitialSchedules.limitTime(10000);
List<Solution> myInitialSchedulesSolutions;
/* myInitialSchedulesSolutions = solverInitialSchedules.findAllOptimalSolutions
@ -69,38 +74,50 @@ public class MainClass {
}
// Pour afficher les horaires initiales
SchedulesWindows.ShowSchedulesFrame intialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules");
SchedulesWindows.ShowSchedulesFrame intialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules"); // to be removed
return initialSchedulesArrayList;
}
private static List<SchedulesArray> GenerateAbsencesSchedules(List<SchedulesArray> initialSchedulesArrayList) {
private static List<BankAbsenceSchedules> GenerateAbsencesSchedules(List<SchedulesArray> initialSchedulesArrayList) {
RandomEngine r = new MersenneTwister(123456789);
List<SchedulesArray> absenceSchedulesArrayList = new ArrayList<>();
List<BankAbsenceSchedules> listBankAbsenceSchedules = new ArrayList<>();
List<SchedulesArray> listAbsenceSchedules = new ArrayList<>(); // to be removed
for (SchedulesArray initialSchedule : initialSchedulesArrayList) {
AbsenceSchedulesArray absenceSchedule = new AbsenceSchedulesArray(initialSchedule);
absenceSchedule.generateAbsences(r);
absenceSchedulesArrayList.add(absenceSchedule);
BankAbsenceSchedules bankAbsenceSimulations = new BankAbsenceSchedules(initialSchedule);
for (int simNum = 0 ; simNum < ParametersAbsencesGenerator.numberAbsenceSimulations ; simNum++) {
AbsenceSchedulesArray absenceSchedule = new AbsenceSchedulesArray(initialSchedule, r);
listAbsenceSchedules.add(absenceSchedule); // to be removed
bankAbsenceSimulations.addAbsenceSchedules(absenceSchedule);
}
listBankAbsenceSchedules.add(bankAbsenceSimulations);
}
// Pour afficher les horaires avec absence
SchedulesWindows.ShowSchedulesFrame absenceSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(absenceSchedulesArrayList, "Absence Schedules");
return absenceSchedulesArrayList;
// Pour afficher les horaires avec absence
SchedulesWindows.ShowSchedulesFrame absenceSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(listAbsenceSchedules, "Absence Schedules"); // to be removed
return listBankAbsenceSchedules;
}
private static List<SchedulesArray> GenerateOptimalRecoveredSchedules(List<SchedulesArray> absenceSchedulesArrayList) {
private static List<BankRecoveredSchedules> GenerateOptimalRecoveredSchedules(List<BankAbsenceSchedules> listBankAbsenceSchedules) {
List<SchedulesArray> recoveredSchedulesArrayList = new ArrayList<>();
for (SchedulesArray absenceSchedule : absenceSchedulesArrayList) {
RecoveredSchedulesArray recoveredSchedule = new RecoveredSchedulesArray((AbsenceSchedulesArray) absenceSchedule);
recoveredSchedule.recoverAbsenceScheduleOptimally();
recoveredSchedulesArrayList.add(recoveredSchedule);
List<BankRecoveredSchedules> listBankRecoveredSchedules = new ArrayList<>();
List<SchedulesArray> listRecoveredSchedules = new ArrayList<>(); // to be removed
for (BankAbsenceSchedules bankAbsenceSchedule : listBankAbsenceSchedules) {
SchedulesArray initialSchedulesArray = bankAbsenceSchedule.initialSchedulesArray;
BankRecoveredSchedules bankRecoveredSimulation = new BankRecoveredSchedules(initialSchedulesArray, bankAbsenceSchedule.bankAbsenceSimulation);
for (AbsenceSchedulesArray absenceSchedule : bankAbsenceSchedule.bankAbsenceSimulation) {
RecoveredSchedulesArray recoveredSchedule = new RecoveredSchedulesArray(absenceSchedule);
listRecoveredSchedules.add(recoveredSchedule); // to be removed
bankRecoveredSimulation.addRecoveredSchedules(recoveredSchedule);
}
listBankRecoveredSchedules.add(bankRecoveredSimulation);
}
// Pour afficher les horaires avec absence
SchedulesWindows.ShowSchedulesFrame recoveredSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(recoveredSchedulesArrayList, "Recovered Schedules");
// Pour afficher les horaires de recouvrement
SchedulesWindows.ShowSchedulesFrame recoveredSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(listRecoveredSchedules, "Recovered Schedules"); // to be removed
return recoveredSchedulesArrayList;
return listBankRecoveredSchedules;
}
}

View file

@ -6,29 +6,23 @@
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);
public static int getFullScheduleCost( SchedulesArray mySchedule, ParametersInitialSchedules myScheduleParameters) {
int totalCost = 0;
for (int i = 0 ; i < mySchedule.getNumberPartTimeEmployee() ; i++) {
totalCost += getPartTimeEmployeeCost(mySchedule.partTimeSchedules[i], myScheduleParameters);
}
return actionCost;
for (int i = 0 ; i < mySchedule.getNumberFullTimeEmployee() ; i++) {
totalCost += getFullTimeEmployeeCost(mySchedule.fullTimeSchedules[i], myScheduleParameters);
}
return totalCost;
}
//Dans cette classe, toutes les fonctions sont dedoublees. On devrait faire du polymorphisme et mettre ces fonctions dans les nouvelles classes schedules crees.
public static int getPartTimeEmployeeCost( boolean[] employeeSchedule, ParametersInitialSchedules myScheduleParameters) {
int consecutiveWorkingPeriods = 0;
@ -51,7 +45,7 @@ public class EmployeeCostCalculator {
overtimeWorkingPeriods += additionalOvertimeWorkingPeriods;
}
int employeeCost = myScheduleParameters.fixedCostOfPartTimeEmployeesPerSchedule +
int employeeCost = myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
overtimeWorkingPeriods * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtOvertimeHourlyRate() +
(totalWorkingPeriods - overtimeWorkingPeriods) * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate();
@ -80,7 +74,7 @@ public class EmployeeCostCalculator {
overtimeWorkingPeriods += additionalOvertimeWorkingPeriods;
}
int employeeCost = myScheduleParameters.fixedCostOfFullTimeEmployeesPerSchedule +
int employeeCost = myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
overtimeWorkingPeriods * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtOvertimeHourlyRate() +
(totalWorkingPeriods - overtimeWorkingPeriods) * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();

View file

@ -5,7 +5,6 @@
*/
package ScheduleUtil;
/**
*
* @author frabe
@ -15,17 +14,17 @@ package ScheduleUtil;
public class PrintSchedules {
public static String getFormattedSchedule(SchedulesArray schedule) {
// Cette fonction sera a ameliorer avec des sous-fonctions, car elle n'est pas tres explicite.
// Cette fonction devrait etre ameliorer avec du polymorphisme car on dedouble le code pour les 2 types d'horaire.
StringBuilder sbuf = new StringBuilder();
sbuf.append(String.format("%-31s", "Schedule Day"));
for (int day = 1; day <= schedule.getDaysPerSchedule(); day++) {
for (int day = 1; day <= schedule.myParametersInitialSchedules.getDaysPerSchedule(); day++) {
sbuf.append(String.format("%02d" + "%18s" + "%s", day, "" , "|"));
}
sbuf.append(" Worked Periods\n");
sbuf.append("Part-Time Employees\n");
for (int employee = 0; employee < schedule.getMaxPartTimeEmployee(); employee++) {
sbuf.append(String.format("%s" + "%02d" + "%-20s","Employee ", employee, " "));
for (int employee = 0; employee < schedule.getNumberPartTimeEmployee(); employee++) {
sbuf.append(String.format("%s" + "%02d" + "%-20s","Employee ", employee + 1, " "));
for (int workPeriod = 0; workPeriod < schedule.getWorkPeriodsPerSchedule(); workPeriod++) {
if (schedule.isPartTimeEmployeeWorking(employee,workPeriod)) {
@ -33,7 +32,7 @@ public class PrintSchedules {
} else {
sbuf.append(String.format("%2d", 0));
}
if (workPeriod % schedule.getWorkPeriodPerDay()== 5 && workPeriod != 0) {
if (workPeriod % schedule.myParametersInitialSchedules.getWorkPeriodPerDay()== 5 && workPeriod != 0) {
sbuf.append(String.format("%2s" + "%-2s", "" , "|"));
}
}
@ -42,8 +41,8 @@ public class PrintSchedules {
}
sbuf.append("Full-Time Employees\n");
for (int employee = 0; employee < schedule.getMaxFullTimeEmployee(); employee++) {
sbuf.append(String.format("%-5s" + "%02d" + "%-20s","Employee ", employee, " "));
for (int employee = 0; employee < schedule.getNumberFullTimeEmployee(); employee++) {
sbuf.append(String.format("%-5s" + "%02d" + "%-20s","Employee ", employee + 1, " "));
for (int workPeriod = 0; workPeriod < schedule.getWorkPeriodsPerSchedule(); workPeriod++) {
if (schedule.isFullTimeEmployeeWorking(employee,workPeriod)) {
@ -51,7 +50,7 @@ public class PrintSchedules {
} else {
sbuf.append(String.format("%2d", 0));
}
if (workPeriod % schedule.getWorkPeriodPerDay()== 5 && workPeriod != 0) {
if (workPeriod % schedule.myParametersInitialSchedules.getWorkPeriodPerDay()== 5 && workPeriod != 0) {
sbuf.append(String.format("%2s" + "%-2s", "" , "|"));
}
}
@ -61,8 +60,8 @@ public class PrintSchedules {
sbuf.append(String.format("%-24s", "Working Employees "));
for (int workPeriod = 0; workPeriod < schedule.getWorkPeriodsPerSchedule(); workPeriod++) {
sbuf.append(String.format("%2d", schedule.getEmployeesPerWorkPeriod(workPeriod)));
if (workPeriod % schedule.getWorkPeriodPerDay() == 5 && workPeriod != 0) {
sbuf.append(String.format("%2d", schedule.getEmployeesWorkingPerWorkPeriod(workPeriod)));
if (workPeriod % schedule.myParametersInitialSchedules.getWorkPeriodPerDay() == 5 && workPeriod != 0) {
sbuf.append(String.format("%2s" + "%-2s", "" , "|"));
}
}
@ -70,12 +69,13 @@ public class PrintSchedules {
sbuf.append(String.format("%-25s", "Required Workforce "));
for (int workPeriod = 0; workPeriod < schedule.getWorkPeriodsPerSchedule(); workPeriod++) {
sbuf.append(String.format("%2d", schedule.getRequiredWorkForce(workPeriod)));
if (workPeriod % schedule.getWorkPeriodPerDay() == 5 && workPeriod != 0) {
sbuf.append(String.format("%2d", schedule.myParametersInitialSchedules.getRequiredWorkForce(workPeriod)));
if (workPeriod % schedule.myParametersInitialSchedules.getWorkPeriodPerDay() == 5 && workPeriod != 0) {
sbuf.append(String.format("%2s" + "%-2s", "" , "|"));
}
}
sbuf.append("\n");
sbuf.append(String.format("%-5s" + "%02d","Total schedule Cost ", EmployeeCostCalculator.getFullScheduleCost(schedule, schedule.myParametersInitialSchedules)));
return sbuf.toString();

View file

@ -6,212 +6,146 @@
package ScheduleUtil;
import InitialSchedules.*;
import jdistlib.rng.RandomEngine;
import org.chocosolver.solver.Solution;
/**
*
* @author frabe
*/
//Dans cette classe, toutes les fonctions sont dedoublees. On devrait faire du polymorphisme.
public class SchedulesArray {
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;
protected int workPeriodsPerDay;
protected int daysPerSchedule;
protected ModelInitialSchedules myModelInitialSchedules;
protected SchedulesArray() {
}
public boolean[][] partTimeSchedules;
public boolean[][] fullTimeSchedules;
protected ParametersInitialSchedules myParametersInitialSchedules;
// Constructeur Copie
protected SchedulesArray(SchedulesArray myScheduleArray) {
this.maxPartTimeEmployee = myScheduleArray.maxPartTimeEmployee;
this.maxFullTimeEmployee = myScheduleArray.maxFullTimeEmployee;
this.workPeriodsPerSchedule = myScheduleArray.workPeriodsPerSchedule;
this.workPeriodsPerDay = myScheduleArray.workPeriodsPerDay;
this.daysPerSchedule = myScheduleArray.daysPerSchedule;
this.myModelInitialSchedules = myScheduleArray.myModelInitialSchedules;
this.myParametersInitialSchedules = myScheduleArray.myParametersInitialSchedules;
this.partTimeSchedules = getDeepCopyEmployeesSchedules(myScheduleArray.partTimeSchedules);
this.fullTimeSchedules = getDeepCopyEmployeesSchedules(myScheduleArray.fullTimeSchedules);
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 = 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];
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;
this.myParametersInitialSchedules = m.myScheduleParameters;
Solution mySolution = s;
this.maxPartTimeEmployee = myModelInitialSchedules.maxPartTimeEmployee;
this.maxFullTimeEmployee = myModelInitialSchedules.maxFullTimeEmployee;
this.workPeriodsPerSchedule = myModelInitialSchedules.myScheduleParameters.workPeriodsPerSchedule;
this.workPeriodsPerDay = myModelInitialSchedules.myScheduleParameters.workPeriodsPerDay;
this.daysPerSchedule = myModelInitialSchedules.myScheduleParameters.daysPerSchedule;
this.partTimeSchedules = new boolean[getNumberOfPartTimeEmployees(s, m)][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
this.fullTimeSchedules = new boolean[getNumberOfFullTimeEmployees(s, m)][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
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;
int partTimeEmployee = 0;
for (int i = 0; i < m.maxPartTimeEmployee; i++) {
if (isPartTimeEmployeeActive (i, s, m)) {
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
this.partTimeSchedules[partTimeEmployee][workPeriod] = mySolution.getIntVal(m.workPeriodsSchedulesOfPartTimeEmployees[i][workPeriod]) == 1;
}
partTimeEmployee++;
}
}
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]) == 1;
this.initialPartTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]) == 1;
int fullTimeEmployee = 0;
for (int i = 0; i < m.maxFullTimeEmployee; i++) {
if (isFullTimeEmployeeActive (i, s, m)) {
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
this.fullTimeSchedules[fullTimeEmployee][workPeriod] = mySolution.getIntVal(m.workPeriodsSchedulesOfFullTimeEmployees[i][workPeriod]) == 1;
}
fullTimeEmployee++;
}
}
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]) == 1;
this.initialFullTimeSchedules[employee][workPeriod] = mySolution.getIntVal(myModelInitialSchedules.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]) == 1;
}
private int getNumberOfPartTimeEmployees( Solution s, ModelInitialSchedules m ) {
int numberPartTimeEmployee = 0;
for (int employee = 0; employee < m.maxPartTimeEmployee; employee++) {
if (isPartTimeEmployeeActive (employee, s, m)) {
numberPartTimeEmployee++;
}
}
this.employeesPerWorkPeriod = new int[this.workPeriodsPerSchedule];
this.workingPeriodsPerPartTimeEmployees = new int[this.maxPartTimeEmployee];
this.workingPeriodsPerFullTimeEmployees = new int[this.maxFullTimeEmployee];
updateAllEmployeesPerWorkPeriod();
updateAllWorkingPeriodsPerPartTimeEmployees();
updateAllWorkingPeriodsPerFullTimeEmployees();
return numberPartTimeEmployee;
}
protected void updateAllEmployeesPerWorkPeriod() {
for (int workPeriod = 0; workPeriod < this.workPeriodsPerSchedule; workPeriod++) {
updateEmployeesPerWorkPeriod(workPeriod);
private int getNumberOfFullTimeEmployees( Solution s, ModelInitialSchedules m ) {
int numberFullTimeEmployee = 0;
for (int employee = 0; employee < m.maxFullTimeEmployee; employee++) {
if (isFullTimeEmployeeActive (employee, s, m)) {
numberFullTimeEmployee++;
}
}
return numberFullTimeEmployee;
}
protected void updateEmployeesPerWorkPeriod(int workPeriod) {
this.employeesPerWorkPeriod[workPeriod] = 0;
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
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;}
private boolean isPartTimeEmployeeActive ( int employee, Solution s, ModelInitialSchedules m ) {
int workPeriod = 0;
while (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
if (s.getIntVal(m.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]) == 1){
return true;
}
workPeriod++;
}
return false;
}
protected void updateAllWorkingPeriodsPerPartTimeEmployees() {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
updateWorkingPeriodsPerPartTimeEmployees(employee);
private boolean isFullTimeEmployeeActive ( int employee, Solution s, ModelInitialSchedules m ) {
int workPeriod = 0;
while (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
if (s.getIntVal(m.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]) == 1){
return true;
}
workPeriod++;
}
return false;
}
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 boolean[][] getDeepCopyEmployeesSchedules(boolean[][] schedules) {
boolean[][] copySchedules = new boolean[schedules.length][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
for (int employee = 0; employee < schedules.length; employee++) {
copySchedules[employee][workPeriod] = schedules[employee][workPeriod];
}
}
return copySchedules;
}
protected void updateAllWorkingPeriodsPerFullTimeEmployees() {
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
updateWorkingPeriodsPerFullTimeEmployees(employee);
protected int getEmployeesWorkingPerWorkPeriod(int workPeriod) {
int employeesWorking = 0;
for (int employee = 0; employee < this.getNumberPartTimeEmployee(); employee++) {
if (this.partTimeSchedules[employee][workPeriod]) {employeesWorking += 1;}
}
for (int employee = 0; employee < this.getNumberFullTimeEmployee(); employee++) {
if (this.fullTimeSchedules[employee][workPeriod]) {employeesWorking += 1;}
}
return employeesWorking;
}
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;}
protected int getWorkingPeriodsPerPartTimeEmployees(int employee) {
int workingPeriodsPerPartTimeEmployees = 0;
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
if (this.partTimeSchedules[employee][workPeriod]) {workingPeriodsPerPartTimeEmployees += 1;}
}
return workingPeriodsPerPartTimeEmployees;
}
public int getMaxFullTimeEmployee() {
return maxFullTimeEmployee;
protected int getWorkingPeriodsPerFullTimeEmployees(int employee) {
int workingPeriodsPerFullTimeEmployees = 0;
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
if (this.fullTimeSchedules[employee][workPeriod]) {workingPeriodsPerFullTimeEmployees += 1;}
}
return workingPeriodsPerFullTimeEmployees;
}
public int getNumberFullTimeEmployee() {
return this.fullTimeSchedules.length;
}
public int getMaxPartTimeEmployee() {
return maxPartTimeEmployee;
public int getNumberPartTimeEmployee() {
return this.partTimeSchedules.length;
}
public int getWorkPeriodsPerSchedule() {
return workPeriodsPerSchedule;
}
public int getDaysPerSchedule() {
return daysPerSchedule;
}
public int getWorkPeriodPerDay() {
return workPeriodsPerDay;
}
public boolean[][] getFullTimeSchedules() {
return fullTimeSchedules;
}
public boolean[][] getPartTimeSchedules() {
return partTimeSchedules;
return myParametersInitialSchedules.getWorkPeriodsPerSchedule();
}
public boolean isPartTimeEmployeeWorking(int employee, int workPeriod) {
@ -222,27 +156,4 @@ public class SchedulesArray {
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) {
return myModelInitialSchedules.myScheduleParameters.requiredWorkforce[workPeriod];
}
public int getEmployeesPerWorkPeriod(int workPeriod) {
return employeesPerWorkPeriod[workPeriod];
}
public int getWorkingPeriodsPerPartTimeEmployees(int employee) {
return workingPeriodsPerPartTimeEmployees[employee];
}
public int getWorkingPeriodsPerFullTimeEmployees(int employee) {
return workingPeriodsPerFullTimeEmployees[employee];
}
}

View file

@ -0,0 +1,32 @@
/*
* 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 AbsenceSchedules.AbsenceSchedulesArray;
import AbsenceSchedules.BankAbsenceSchedules;
import ScheduleUtil.SchedulesArray;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author frabe
*/
public class BankRecoveredSchedules {
public SchedulesArray initialSchedulesArray;
public List<SchedulesArray> bankRecoveredSimulation;
public List<AbsenceSchedulesArray> bankAbsenceSimulation;
public BankRecoveredSchedules(SchedulesArray initialSchedulesArray, List<AbsenceSchedulesArray> bankAbsenceSimulation) {
this.initialSchedulesArray = initialSchedulesArray;
this.bankAbsenceSimulation = bankAbsenceSimulation;
this.bankRecoveredSimulation = new ArrayList<>();
}
public void addRecoveredSchedules(SchedulesArray absenceSchedulesArray) {
this.bankRecoveredSimulation.add(absenceSchedulesArray);
}
}

View file

@ -7,164 +7,173 @@ package SchedulesRecovery;
import AbsenceSchedules.AbsenceSchedulesArray;
import java.util.*;
import org.javatuples.Triplet;
import org.javatuples.Quartet;
import ScheduleUtil.*;
import static ScheduleUtil.EmployeeCostCalculator.*;
/**
*
* @author frabe
*/
public class RecoveredSchedulesArray extends AbsenceSchedulesArray{
public class RecoveredSchedulesArray extends SchedulesArray{
public RecoveredSchedulesArray(AbsenceSchedulesArray myAbsenceScheduleArray){
super(myAbsenceScheduleArray);
AbsenceSchedulesArray absenceSchedulesArray;
public RecoveredSchedulesArray(AbsenceSchedulesArray absenceSchedulesArray){
super(absenceSchedulesArray);
this.absenceSchedulesArray = absenceSchedulesArray;
recoverAbsenceScheduleOptimally();
}
// 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;
private void recoverAbsenceScheduleOptimally() {
boolean[][] currentRecoveredScheduleOfPartTimeEmployees = this.getDeepCopyEmployeesSchedules(this.absenceSchedulesArray.partTimeSchedules);
boolean[][] currentRecoveredScheduleOfFullTimeEmployees = this.getDeepCopyEmployeesSchedules(this.absenceSchedulesArray.fullTimeSchedules);
boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees = new boolean[this.getNumberPartTimeEmployee()][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees = new boolean[this.getNumberFullTimeEmployee()][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
for (int i = 0 ; i < this.getNumberPartTimeEmployee() ; i++) {
Arrays.fill(alreadyRecoveredWorkPeriodByPartTimeEmployees[i], Boolean.FALSE);
}
for (int i = 0 ; i < this.getNumberFullTimeEmployee() ; i++) {
Arrays.fill(alreadyRecoveredWorkPeriodByFullTimeEmployees[i], Boolean.FALSE);
}
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);
int totalEmployeesCost = EmployeeCostCalculator.getFullScheduleCost(this.absenceSchedulesArray, myParametersInitialSchedules);
int bestScheduleCost = Integer.MAX_VALUE;
int remainingRecoveringAction = this.absenceSchedulesArray.numberOfRecoveringActionsToPerform;
int currentOptimisticTotalEmployeeCost = totalEmployeesCost + remainingRecoveringAction * myParametersInitialSchedules.getMinimumWorkingPeriodCost();
int optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost;
ScheduleStateComparator quartetComparator = new ScheduleStateComparator();
RecoveringActionComparator recoveringActionCostComparator = new RecoveringActionComparator();
PriorityQueue< Quartet<boolean[][], boolean[][], Integer, Integer> > scheduleStatesOrderedByOptimisticCost = new PriorityQueue<>(quartetComparator);
RecoveringAction currentRecoveringAction = null;
// Fouille en profondeur avec calcul de cout optimiste base sur le taux horaire regulier des employes a temps plein.
while ( bestScheduleCost > currentOptimisticTotalEmployeeCost ) {
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost =
getPossibleRecoveringActions(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees,
alreadyRecoveredWorkPeriodByPartTimeEmployees, alreadyRecoveredWorkPeriodByFullTimeEmployees, recoveringActionCostComparator);
boolean[][] recoveredScheduleOfPartTimeEmployeesAfterAction = this.getDeepCopyEmployeesSchedules(currentRecoveredScheduleOfPartTimeEmployees);
boolean[][] recoveredScheduleOfFullTimeEmployeesAfterAction = this.getDeepCopyEmployeesSchedules(currentRecoveredScheduleOfFullTimeEmployees);
currentRecoveringAction = recoveringActionsOrderedByCost.poll();
if (currentRecoveringAction.getClass().getName().equals("SchedulesRecovery.RecoveringActionPartTimeEmployee")) {
recoveredScheduleOfPartTimeEmployeesAfterAction[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true;
alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true;
} else if (currentRecoveringAction.getClass().getName().equals("SchedulesRecovery.RecoveringActionFullTimeEmployee")) {
recoveredScheduleOfFullTimeEmployeesAfterAction[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true;
alreadyRecoveredWorkPeriodByFullTimeEmployees[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true;
}
Triplet<RecoveringAction, RecoveringAction, Integer> currentScheduleState = priorityQueueScheduleStatesOrderedByTotalCost.poll();
currentTotalEmployeesCost = currentScheduleState.getValue2();
previousRecoveringAction = currentScheduleState.getValue1();
optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost - myParametersInitialSchedules.getMinimumWorkingPeriodCost() + currentRecoveringAction.recoveringActionCost;
Quartet<boolean[][], boolean[][], Integer, Integer> scheduleState = Quartet.with
(recoveredScheduleOfPartTimeEmployeesAfterAction, recoveredScheduleOfFullTimeEmployeesAfterAction, optimisticTotalEmployeeCost, remainingRecoveringAction - 1);
scheduleStatesOrderedByOptimisticCost.add(scheduleState);
//recalculer les currentRecoveredScheduleOfPartTimeEmployees et ajuster la workPeriod
//en trouvent la workPeriod la plus petite avec une demande incomplète.
//workPeriod++;
if (remainingRecoveringAction - 1 == 0){
bestScheduleCost = Math.min(bestScheduleCost, optimisticTotalEmployeeCost);
}
Quartet<boolean[][], boolean[][], Integer, Integer> currentScheduleState = scheduleStatesOrderedByOptimisticCost.poll();
currentRecoveredScheduleOfPartTimeEmployees = currentScheduleState.getValue0();
currentRecoveredScheduleOfFullTimeEmployees = currentScheduleState.getValue1();
currentOptimisticTotalEmployeeCost = currentScheduleState.getValue2();
remainingRecoveringAction = currentScheduleState.getValue3();
}
this.fullTimeSchedules = currentRecoveredScheduleOfFullTimeEmployees;
this.partTimeSchedules = currentRecoveredScheduleOfPartTimeEmployees;
assert(EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules) == bestScheduleCost);
}
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);
private PriorityQueue<RecoveringAction> getPossibleRecoveringActions(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule, boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees, boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees, Comparator recoveringActionCostComparator) {
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost = new PriorityQueue<>(recoveringActionCostComparator);
int workPeriod = findEarlierWorkPeriodToRecover(currentPartTimeSchedule, currentFullTimeSchedule);
if (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
for (int partTimeEmployee = 0 ; partTimeEmployee < this.getNumberPartTimeEmployee() ; partTimeEmployee++ ) {
if ( isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, partTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][workPeriod]){
RecoveringActionPartTimeEmployee recoveringAction =
new RecoveringActionPartTimeEmployee(partTimeEmployee, workPeriod);
recoveringAction.calculateRecoveringActionCost (currentPartTimeSchedule, myParametersInitialSchedules);
recoveringActionsOrderedByCost.add(recoveringAction);
}
}
for (int fullTimeEmployee = 0 ; fullTimeEmployee < this.getNumberFullTimeEmployee() ; fullTimeEmployee++ ) {
if ( isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, fullTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][workPeriod] ){
RecoveringActionFullTimeEmployee recoveringAction =
new RecoveringActionFullTimeEmployee(fullTimeEmployee, workPeriod);
recoveringAction.calculateRecoveringActionCost (currentFullTimeSchedule, myParametersInitialSchedules);
recoveringActionsOrderedByCost.add(recoveringAction);
}
}
}
return stackRecoveringActionsOfPartTimeEmployee;
return recoveringActionsOrderedByCost;
}
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);
private int findEarlierWorkPeriodToRecover(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule){
int workingEmployees;
for (int workPeriod = 0 ; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() ; workPeriod++) {
workingEmployees = 0;
for (int partTimeEmployee = 0 ; partTimeEmployee < currentPartTimeSchedule.length ; partTimeEmployee++) {
if ( currentPartTimeSchedule[partTimeEmployee][workPeriod] ) {
workingEmployees++;
}
}
for (int fullTimeEmployee = 0 ; fullTimeEmployee < currentFullTimeSchedule.length ; fullTimeEmployee++) {
if ( currentFullTimeSchedule[fullTimeEmployee][workPeriod] ) {
workingEmployees++;
}
}
if (workingEmployees < this.myParametersInitialSchedules.getRequiredWorkForce(workPeriod) ) {
return workPeriod;
}
}
return stackRecoveringActionsOfFullTimeEmployees;
return myParametersInitialSchedules.getWorkPeriodsPerSchedule();
}
private boolean isPartTimeEmployeeAvailableForAbsenceRecovering(int employee, int workPeriod, boolean[] currentEmployeeSchedule){
return !currentEmployeeSchedule[workPeriod] && !isPartTimeEmployeeAbsent(employee, workPeriod) && isValidPartTimeEmployeeWorkPeriod(currentEmployeeSchedule, workPeriod);
//Toutes les fonctions sont dedoublees. On devrait faire du polymorphisme.
private boolean isPartTimeEmployeeAvailableForAbsenceRecovering(boolean[][] currentPartTimeSchedule, int employee, int workPeriod){
return !currentPartTimeSchedule[employee][workPeriod] && !absenceSchedulesArray.isPartTimeEmployeeAbsent(employee, workPeriod) && isValidPartTimeEmployeeWorkPeriod(currentPartTimeSchedule[employee], workPeriod);
}
private boolean isValidPartTimeEmployeeWorkPeriod(boolean[] currentEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(currentEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(currentEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(currentEmployeeSchedule, workPeriod);
private boolean isValidPartTimeEmployeeWorkPeriod(boolean[] currentPartTimeEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(currentPartTimeEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod);
}
private boolean isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(boolean[] currentEmployeeSchedule){
private boolean isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(boolean[] currentPartTimeEmployeeSchedule){
int employeeWorkingPeriods = 0;
for ( int workPeriod = 0 ; workPeriod < this.workPeriodsPerSchedule ; workPeriod++ ) {
if (currentEmployeeSchedule[workPeriod]){
for ( int workPeriod = 0 ; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
if (currentPartTimeEmployeeSchedule[workPeriod]){
employeeWorkingPeriods +=1 ;
}
}
return employeeWorkingPeriods < myModelInitialSchedules.myScheduleParameters.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule();
return employeeWorkingPeriods < myParametersInitialSchedules.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule();
}
private boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){
private boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod >= 0 && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork();
return consecutiveWorkingPeriods <= myParametersInitialSchedules.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork();
}
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod >= 0 && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
@ -173,66 +182,66 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
} else if (consecutivePreviousNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == workPeriodsPerSchedule) {
if (compteurWorkPeriod == myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
} else if (consecutiveNextNonWorkingPeriods >= myParametersInitialSchedules.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 isFullTimeEmployeeAvailableForAbsenceRecovering(boolean[][] currentFullTimeSchedule, int employee, int workPeriod){
return !currentFullTimeSchedule[employee][workPeriod] && !absenceSchedulesArray.isFullTimeEmployeeAbsent(employee, workPeriod) && isValidFullTimeEmployeeWorkPeriod(currentFullTimeSchedule[employee], workPeriod);
}
private boolean isValidFullTimeEmployeeWorkPeriod(boolean[] currentEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentEmployeeSchedule, workPeriod);
private boolean isValidFullTimeEmployeeWorkPeriod(boolean[] currentFullTimeEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentFullTimeEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod);
}
private boolean isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(boolean[] currentEmployeeSchedule){
private boolean isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(boolean[] currentFullTimeEmployeeSchedule){
int employeeWorkingPeriods = 0;
for ( int workPeriod = 0 ; workPeriod < this.workPeriodsPerSchedule ; workPeriod++ ) {
if (currentEmployeeSchedule[workPeriod]){
for ( int workPeriod = 0 ; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
if (currentFullTimeEmployeeSchedule[workPeriod]){
employeeWorkingPeriods +=1 ;
}
}
return employeeWorkingPeriods < myModelInitialSchedules.myScheduleParameters.getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule();
return employeeWorkingPeriods < myParametersInitialSchedules.getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule();
}
private boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){
private boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod >= 0 && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myModelInitialSchedules.myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork();
return consecutiveWorkingPeriods <= myParametersInitialSchedules.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork();
}
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentEmployeeSchedule, int workPeriod){
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod >= 0 && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
@ -241,21 +250,21 @@ public class RecoveredSchedulesArray extends AbsenceSchedulesArray{
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
} else if (consecutivePreviousNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < this.workPeriodsPerSchedule && !currentEmployeeSchedule[compteurWorkPeriod] ){
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == workPeriodsPerSchedule) {
if (compteurWorkPeriod == myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myModelInitialSchedules.myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
} else if (consecutiveNextNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;

View file

@ -12,22 +12,11 @@ package SchedulesRecovery;
public class RecoveringAction {
public int employee;
public int workPeriod;
public boolean[] employeeScheduleBeforeRecoveringAction;
public boolean[] employeeScheduleAfterRecoveringAction;
public int recoveringActionCost;
public RecoveringAction( int employee, int workPeriod, boolean[] employeeSchedule){
public RecoveringAction( int employee, int workPeriod){
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,24 @@
/*
* 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;
/**
*
* @author frabe
*/
public class RecoveringActionComparator implements Comparator< RecoveringAction > {
public int compare(RecoveringAction a1, RecoveringAction a2) {
int actionCostCmp = Integer.compare(a1.recoveringActionCost, a2.recoveringActionCost);
if (actionCostCmp !=0) {
return actionCostCmp;
}
int workPeriodCmp = Integer.compare(a1.workPeriod, a2.workPeriod);
return workPeriodCmp;
}
}

View file

@ -5,14 +5,24 @@
*/
package SchedulesRecovery;
import InitialSchedules.ParametersInitialSchedules;
import static ScheduleUtil.EmployeeCostCalculator.*;
/**
*
* @author frabe
*/
public class RecoveringActionFullTimeEmployee extends RecoveringAction{
public RecoveringActionFullTimeEmployee( int employee, int workPeriod, boolean[] employeeSchedule){
super(employee, workPeriod, employeeSchedule);
public RecoveringActionFullTimeEmployee( int employee, int workPeriod){
super(employee, workPeriod);
}
public void calculateRecoveringActionCost (boolean[][] currentEmployeesSchedule, ParametersInitialSchedules myScheduleParameters) {
int costBeforeAction = getFullTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = true;
int costAfterAction = getFullTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = false;
this.recoveringActionCost = costAfterAction-costBeforeAction;
}
}

View file

@ -5,15 +5,25 @@
*/
package SchedulesRecovery;
import InitialSchedules.ParametersInitialSchedules;
import static ScheduleUtil.EmployeeCostCalculator.*;
/**
*
* @author frabe
*/
public class RecoveringActionPartTimeEmployee extends RecoveringAction{
public RecoveringActionPartTimeEmployee( int employee, int workPeriod, boolean[] employeeSchedule){
super(employee, workPeriod, employeeSchedule);
public RecoveringActionPartTimeEmployee( int employee, int workPeriod){
super(employee, workPeriod);
}
public void calculateRecoveringActionCost ( boolean[][] currentEmployeesSchedule, ParametersInitialSchedules myScheduleParameters) {
int costBeforeAction = getPartTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = true;
int costAfterAction = getPartTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = false;
this.recoveringActionCost = costAfterAction-costBeforeAction;
}
}

View file

@ -6,14 +6,19 @@
package SchedulesRecovery;
import java.util.Comparator;
import org.javatuples.Triplet;
import org.javatuples.Quartet;
/**
*
* @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());
public class ScheduleStateComparator implements Comparator< Quartet<boolean[][], boolean[][], Integer, Integer> > {
public int compare(Quartet<boolean[][], boolean[][], Integer, Integer> o1, Quartet<boolean[][], boolean[][], Integer, Integer> o2) {
int totalCostCmp = o1.getValue2().compareTo(o2.getValue2());
if (totalCostCmp !=0) {
return totalCostCmp;
}
int remainingActionsCmp = o2.getValue3().compareTo(o1.getValue3());
return remainingActionsCmp;
}
}

View file

@ -36,8 +36,6 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
changeScheduleNumberScrollBar.setUnitIncrement(1);
}
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {