Modification du calcul des coûts pour tenir compte des absences des employés à temps plein.

Cleaning du code en ajoutant une classe abstraite ValidationRecoveringAction.
This commit is contained in:
Francois Berube\frabe 2018-04-11 23:11:27 -04:00
parent c1e82d2af0
commit 4b24dc1901
18 changed files with 353 additions and 318 deletions

View file

@ -13,7 +13,7 @@ public class AbsenceSchedulesArray extends SchedulesArray{
super(initialSchedulesArray);
this.initialSchedulesArray = initialSchedulesArray;
generateAbsenceSimulation(r);
this.totalScheduleCost = EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules);
this.totalScheduleCost = EmployeeCostCalculator.getFullAbsenceScheduleCost(this, myParametersInitialSchedules);
}
private void generateAbsenceSimulation(RandomEngine r) {
@ -35,6 +35,22 @@ public class AbsenceSchedulesArray extends SchedulesArray{
calculateNumberOfRecoveringActionsToPerform();
}
public int getAbsencePeriodsPerPartTimeEmployees(int employee) {
int absencePeriodsPerPartTimeEmployees = 0;
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
if (this.isPartTimeEmployeeAbsent(employee, workPeriod)) {absencePeriodsPerPartTimeEmployees += 1;}
}
return absencePeriodsPerPartTimeEmployees;
}
public int getAbsencePeriodsPerFullTimeEmployees(int employee) {
int absencePeriodsPerFullTimeEmployees = 0;
for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {
if (this.isFullTimeEmployeeAbsent(employee, workPeriod)) {absencePeriodsPerFullTimeEmployees += 1;}
}
return absencePeriodsPerFullTimeEmployees;
}
public boolean isPartTimeEmployeeAbsent(int employee, int workPeriod) {
return this.partTimeSchedules[employee][workPeriod] != this.initialSchedulesArray.isPartTimeEmployeeWorking(employee, workPeriod);

View file

@ -4,7 +4,7 @@ import jdistlib.Binomial;
import jdistlib.rng.RandomEngine;
public class AbsencesVector {
private boolean[] AbsencesVector;
private final boolean[] AbsencesVector;
public AbsencesVector(int length, RandomEngine r) {

View file

@ -10,7 +10,7 @@ package AbsenceSchedules;
* @author frabe
*/
public interface ParametersAbsencesSimulator {
public final double probPresence = 0.5;
public final double probPresence = 0.99;
public final double probReturn = 0.99;
public final int numberAbsenceSimulations = 5;
}

View file

@ -83,9 +83,7 @@ public class ParametersInitialSchedules {
this.requiredWorkforce = new int[this.daysPerSchedule * this.getWorkPeriodPerDay()];
int[] dailyRequiredWorkforce = new int[]{2, 2, 4, 4, 3, 3};
for (int day = 0; day < this.daysPerSchedule; day++) {
for(int shift = 0; shift < this.getWorkPeriodPerDay(); shift++) {
this.requiredWorkforce[day * this.getWorkPeriodPerDay() + shift] = dailyRequiredWorkforce[shift];
}
System.arraycopy(dailyRequiredWorkforce, 0, this.requiredWorkforce, day * this.getWorkPeriodPerDay(), this.getWorkPeriodPerDay());
}
}

View file

@ -7,8 +7,6 @@ import SchedulesRecovery.*;
import jdistlib.rng.MersenneTwister;
import jdistlib.rng.RandomEngine;
import org.chocosolver.solver.Solution;
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.exception.ContradictionException;
import java.util.ArrayList;
import java.util.List;
@ -19,16 +17,12 @@ public class MainClass {
public static void main(String[] args) {
List<SchedulesArray> initialSchedulesArrayList = generateInitialSchedules();
// TODO :
// Raffiner banques de solutions en prenant des horaires ayant de bonnes differences
List<BankAbsenceSchedules> listBankAbsenceSchedules = GenerateAbsencesSchedules(initialSchedulesArrayList);
List<BankRecoveredSchedules> bankRecoveredSchedulesOrderedByMeanCost = GenerateOptimalRecoveredSchedules(listBankAbsenceSchedules);
// Afficher les solutions en ordre de cout de recouvrement et comparer avec solution optimale (nbr employes temps plein maximal).
SchedulesWindows.ShowSolutionResultsFrame intialSchedulesViewer = new SchedulesWindows.ShowSolutionResultsFrame(bankRecoveredSchedulesOrderedByMeanCost);
SchedulesWindows.ShowSolutionResultsFrame initialSchedulesViewer = new SchedulesWindows.ShowSolutionResultsFrame(bankRecoveredSchedulesOrderedByMeanCost);
}
@ -36,7 +30,6 @@ public class MainClass {
private static List<SchedulesArray> generateInitialSchedules() {
// Trouver les horaires des employes a temps plein possibles pour different ratio templein/temps partiel
// Cleaner ce code avec des sous-foncitons. Creer une classe Solver.
List<SchedulesArray> initialSchedulesArrayList = new ArrayList<>();
InitialSchedules.ParametersInitialSchedules myScheduleParameters = new InitialSchedules.ParametersInitialSchedules();
@ -44,8 +37,6 @@ public class MainClass {
int minFullTimeEmployee = 2; //La solution avec 1 employes est trop lente
int maxFullTimeEmployee = 9; //C'est le max d'employes a temps plein pour la presente requiredWorkforce
// int maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule()
// / myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule());
int simulationNumber = 1;
@ -85,7 +76,7 @@ public class MainClass {
}
// Pour afficher les horaires initiales
SchedulesWindows.ShowSchedulesFrame intialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules"); // to be removed
SchedulesWindows.ShowSchedulesFrame initialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules"); // to be removed
return initialSchedulesArrayList;

View file

@ -5,79 +5,101 @@
*/
package ScheduleUtil;
import AbsenceSchedules.AbsenceSchedulesArray;
import InitialSchedules.ParametersInitialSchedules;
import SchedulesRecovery.RecoveredSchedulesArray;
/**
*
* @author frabe
*/
public class EmployeeCostCalculator {
public static int getFullScheduleCost( SchedulesArray mySchedule, ParametersInitialSchedules myScheduleParameters) {
public static int getFullInitialScheduleCost( SchedulesArray myInitialSchedule, ParametersInitialSchedules myScheduleParameters) {
int totalCost = 0;
for (int i = 0 ; i < mySchedule.getNumberPartTimeEmployee() ; i++) {
totalCost += getPartTimeEmployeeCost(mySchedule.partTimeSchedules[i], myScheduleParameters);
for (int partTimeEmployee = 0 ; partTimeEmployee < myInitialSchedule.getNumberPartTimeEmployee() ; partTimeEmployee++) {
int numberWorkingPeriod = myInitialSchedule.getWorkingPeriodsPerPartTimeEmployees(partTimeEmployee);
totalCost += myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
numberWorkingPeriod * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate();
}
for (int i = 0 ; i < mySchedule.getNumberFullTimeEmployee() ; i++) {
totalCost += getFullTimeEmployeeCost(mySchedule.fullTimeSchedules[i], myScheduleParameters);
for (int fullTimeEmployee = 0 ; fullTimeEmployee < myInitialSchedule.getNumberFullTimeEmployee() ; fullTimeEmployee++) {
int numberWorkingPeriod = myInitialSchedule.getWorkingPeriodsPerFullTimeEmployees(fullTimeEmployee);
totalCost += myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule() +
numberWorkingPeriod * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
}
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;
int overtimeWorkingPeriods = 0;
int totalWorkingPeriods = 0;
for (int workPeriod = 0; workPeriod < employeeSchedule.length ; workPeriod++) {
if (employeeSchedule[workPeriod]) {
totalWorkingPeriods += 1;
consecutiveWorkingPeriods += 1;
if (consecutiveWorkingPeriods > myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerShiftWork()) {
overtimeWorkingPeriods += 1;
}
} else {
consecutiveWorkingPeriods = 0;
}
public static int getFullAbsenceScheduleCost( AbsenceSchedulesArray myAbsenceSchedule, ParametersInitialSchedules myScheduleParameters) {
int totalCost = 0;
for (int partTimeEmployee = 0 ; partTimeEmployee < myAbsenceSchedule.getNumberPartTimeEmployee() ; partTimeEmployee++) {
int numberWorkingPeriod = myAbsenceSchedule.getWorkingPeriodsPerPartTimeEmployees(partTimeEmployee);
totalCost += myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
numberWorkingPeriod * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate();
}
int additionalOvertimeWorkingPeriods = totalWorkingPeriods - myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule();
if ( additionalOvertimeWorkingPeriods > 0 ){
overtimeWorkingPeriods += additionalOvertimeWorkingPeriods;
for (int fullTimeEmployee = 0 ; fullTimeEmployee < myAbsenceSchedule.getNumberFullTimeEmployee() ; fullTimeEmployee++) {
int numberWorkingPeriod = myAbsenceSchedule.getWorkingPeriodsPerFullTimeEmployees(fullTimeEmployee);
int numberAbsencePeriod = myAbsenceSchedule.getAbsencePeriodsPerFullTimeEmployees(fullTimeEmployee);
totalCost += myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule() +
(numberWorkingPeriod + numberAbsencePeriod) * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
}
int employeeCost = myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
overtimeWorkingPeriods * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtOvertimeHourlyRate() +
(totalWorkingPeriods - overtimeWorkingPeriods) * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate();
return employeeCost;
return totalCost;
}
public static int getFullTimeEmployeeCost( boolean[] employeeSchedule, ParametersInitialSchedules myScheduleParameters) {
int consecutiveWorkingPeriods = 0;
int overtimeWorkingPeriods = 0;
int totalWorkingPeriods = 0;
for (int workPeriod = 0; workPeriod < employeeSchedule.length ; workPeriod++) {
if (employeeSchedule[workPeriod]) {
totalWorkingPeriods += 1;
consecutiveWorkingPeriods += 1;
if (consecutiveWorkingPeriods > myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerShiftWork()) {
overtimeWorkingPeriods += 1;
}
public static int getFullRecoveredScheduleCost( RecoveredSchedulesArray myRecoveredSchedule, ParametersInitialSchedules myScheduleParameters) {
int totalCost = 0;
for (int partTimeEmployee = 0 ; partTimeEmployee < myRecoveredSchedule.getNumberPartTimeEmployee() ; partTimeEmployee++) {
int numberWorkingPeriod = myRecoveredSchedule.getWorkingPeriodsPerPartTimeEmployees(partTimeEmployee);
totalCost += myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
numberWorkingPeriod * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate();
}
AbsenceSchedulesArray myAbsenceSchedule = myRecoveredSchedule.absenceSchedulesArray;
for (int fullTimeEmployee = 0 ; fullTimeEmployee < myRecoveredSchedule.getNumberFullTimeEmployee() ; fullTimeEmployee++) {
int numberWorkingPeriod = myRecoveredSchedule.getWorkingPeriodsPerFullTimeEmployees(fullTimeEmployee);
int numberAbsencePeriod = myAbsenceSchedule.getAbsencePeriodsPerFullTimeEmployees(fullTimeEmployee);
totalCost += myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule();
int regularHourlyRateCost; int overtimeHourlyRateCost;
if (numberWorkingPeriod + numberAbsencePeriod <= myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule() ) {
regularHourlyRateCost = (numberWorkingPeriod + numberAbsencePeriod) * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
overtimeHourlyRateCost = 0;
} else {
consecutiveWorkingPeriods = 0;
regularHourlyRateCost = myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule() *
myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
overtimeHourlyRateCost = (numberWorkingPeriod + numberAbsencePeriod - myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule()) *
myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtOvertimeHourlyRate();
}
totalCost += regularHourlyRateCost + overtimeHourlyRateCost;
}
int additionalOvertimeWorkingPeriods = totalWorkingPeriods - myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule();
if ( additionalOvertimeWorkingPeriods > 0 ){
overtimeWorkingPeriods += additionalOvertimeWorkingPeriods;
return totalCost;
}
public static int getPartTimeEmployeeCost(boolean[][] currentEmployeesSchedule, int employee, ParametersInitialSchedules myScheduleParameters) {
int numberWorkingPeriod = 0;
for (int workPeriod = 0 ; workPeriod < currentEmployeesSchedule.length ; workPeriod++) {
if (currentEmployeesSchedule[employee][workPeriod] == true){numberWorkingPeriod++;}
}
int employeeCost = myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
overtimeWorkingPeriods * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtOvertimeHourlyRate() +
(totalWorkingPeriods - overtimeWorkingPeriods) * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
return employeeCost;
int totalCost = myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() +
numberWorkingPeriod * myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate();
return totalCost;
}
public static int getFullTimeEmployeeCost(boolean[][] currentEmployeesSchedule, AbsenceSchedulesArray myAbsenceSchedule, int employee, ParametersInitialSchedules myScheduleParameters) {
int numberWorkingPeriod = 0;
for (int workPeriod = 0 ; workPeriod < currentEmployeesSchedule.length ; workPeriod++) {
if (currentEmployeesSchedule[employee][workPeriod] == true){numberWorkingPeriod++;}
}
int numberAbsencePeriod = myAbsenceSchedule.getAbsencePeriodsPerFullTimeEmployees(employee);
int regularHourlyRateCost; int overtimeHourlyRateCost;
if (numberWorkingPeriod + numberAbsencePeriod <= myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule() ) {
regularHourlyRateCost = (numberWorkingPeriod + numberAbsencePeriod) * myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
overtimeHourlyRateCost = 0;
} else {
regularHourlyRateCost = myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule() *
myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate();
overtimeHourlyRateCost = (numberWorkingPeriod + numberAbsencePeriod - myScheduleParameters.getWorkingPeriodsPaidAtRegularHourlyRatePerSchedule()) *
myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtOvertimeHourlyRate();
}
int totalCost = myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule() + regularHourlyRateCost + overtimeHourlyRateCost;
return totalCost;
}
}

View file

@ -37,7 +37,7 @@ public class SchedulesArray {
this.partTimeSchedules = pteisa.partTimeSchedules;
this.fullTimeSchedules = fteisa.fullTimeSchedules;
this.totalScheduleCost = EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules);
this.totalScheduleCost = EmployeeCostCalculator.getFullInitialScheduleCost(this, myParametersInitialSchedules);
}
protected boolean[][] getDeepCopyEmployeesSchedules(boolean[][] schedules) {

View file

@ -6,7 +6,6 @@
package SchedulesRecovery;
import AbsenceSchedules.AbsenceSchedulesArray;
import AbsenceSchedules.BankAbsenceSchedules;
import ScheduleUtil.SchedulesArray;
import java.util.ArrayList;
import java.util.List;

View file

@ -7,9 +7,7 @@ package SchedulesRecovery;
import AbsenceSchedules.AbsenceSchedulesArray;
import java.util.*;
import org.javatuples.Quartet;
import ScheduleUtil.*;
import static ScheduleUtil.EmployeeCostCalculator.*;
/**
*
@ -17,7 +15,7 @@ import static ScheduleUtil.EmployeeCostCalculator.*;
*/
public class RecoveredSchedulesArray extends SchedulesArray{
AbsenceSchedulesArray absenceSchedulesArray;
public AbsenceSchedulesArray absenceSchedulesArray;
public RecoveredSchedulesArray(AbsenceSchedulesArray absenceSchedulesArray){
super(absenceSchedulesArray);
@ -29,12 +27,8 @@ public class RecoveredSchedulesArray extends SchedulesArray{
boolean[][] currentRecoveredScheduleOfPartTimeEmployees = this.getDeepCopyEmployeesSchedules(this.absenceSchedulesArray.partTimeSchedules);
boolean[][] currentRecoveredScheduleOfFullTimeEmployees = this.getDeepCopyEmployeesSchedules(this.absenceSchedulesArray.fullTimeSchedules);
int totalEmployeesCost = EmployeeCostCalculator.getFullScheduleCost(this.absenceSchedulesArray, myParametersInitialSchedules);
int bestScheduleCost = Integer.MAX_VALUE;
int remainingRecoveringAction = this.absenceSchedulesArray.numberOfRecoveringActionsToPerform;
int currentOptimisticTotalEmployeeCost = totalEmployeesCost + remainingRecoveringAction * myParametersInitialSchedules.getMinimumWorkingPeriodCost();
int optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost;
boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees = new boolean[this.getNumberPartTimeEmployee()][remainingRecoveringAction];
boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees = new boolean[this.getNumberFullTimeEmployee()][remainingRecoveringAction];
for (int i = 0 ; i < this.getNumberPartTimeEmployee() ; i++) {
@ -46,26 +40,26 @@ public class RecoveredSchedulesArray extends SchedulesArray{
RecoveringActionComparator recoveringActionCostComparator = new RecoveringActionComparator();
ScheduleState currentScheduleState = new ScheduleState(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees,
currentOptimisticTotalEmployeeCost, remainingRecoveringAction);
remainingRecoveringAction);
Stack< ScheduleState > scheduleStatesNodes = new Stack<>();
scheduleStatesNodes.push(currentScheduleState);
RecoveringAction currentRecoveringAction = null;
RecoveringAction currentRecoveringAction;
boolean isSolutionFound = true;
int backtrack = 0;
// Fouilles en profondeur avec calcul de cout optimiste base sur le taux horaire regulier des employes a temps plein.
// On marque les noeuds dejà visites.
while ( bestScheduleCost > currentOptimisticTotalEmployeeCost ) {
boolean isSolutionFound;
isSolutionFound = remainingRecoveringAction == 0;
// Fouilles en profondeur en privilegiant les actions avec cout minimum. On marque les noeuds dejà visites pour avoir des fouilles differentes
while ( !isSolutionFound ) {
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost =
getPossibleRecoveringActions(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees,
alreadyRecoveredWorkPeriodByPartTimeEmployees, alreadyRecoveredWorkPeriodByFullTimeEmployees, remainingRecoveringAction, recoveringActionCostComparator);
if (recoveringActionsOrderedByCost.size() > 0){
// On prend l'action avec un cout minimal
currentRecoveringAction = recoveringActionsOrderedByCost.poll();
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][remainingRecoveringAction-1] = true;
@ -74,39 +68,35 @@ public class RecoveredSchedulesArray extends SchedulesArray{
alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][remainingRecoveringAction-1] = true;
}
optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost - myParametersInitialSchedules.getMinimumWorkingPeriodCost() + currentRecoveringAction.recoveringActionCost;
ScheduleState scheduleState = new ScheduleState(recoveredScheduleOfPartTimeEmployeesAfterAction, recoveredScheduleOfFullTimeEmployeesAfterAction,
optimisticTotalEmployeeCost, remainingRecoveringAction - 1);
remainingRecoveringAction - 1);
scheduleStatesNodes.push(scheduleState);
} else {
} else if (scheduleStatesNodes.size() == 1) {
//Si le sommet n'a plus d'enfants non-visite, la solution n'est pas trouvee.
break;
} else{
// Lorsqu'on est bloque dans l'arbre de recherche, on revient au sommet de l'arbre.
do{
scheduleStatesNodes.pop();
} while(scheduleStatesNodes.size() > 1);
}
if (remainingRecoveringAction - 1 == 0){
bestScheduleCost = Math.min(bestScheduleCost, optimisticTotalEmployeeCost);
isSolutionFound = true;
}
if (scheduleStatesNodes.size() > 0) {
currentScheduleState = scheduleStatesNodes.peek();
currentRecoveredScheduleOfPartTimeEmployees = currentScheduleState.currentRecoveredScheduleOfPartTimeEmployees;
currentRecoveredScheduleOfFullTimeEmployees = currentScheduleState.currentRecoveredScheduleOfFullTimeEmployees;
currentOptimisticTotalEmployeeCost = currentScheduleState.currentOptimisticTotalEmployeeCost;
remainingRecoveringAction = currentScheduleState.remainingRecoveringAction;
} else {
isSolutionFound = false;
break;
}
}
}
if (isSolutionFound) {
this.fullTimeSchedules = currentRecoveredScheduleOfFullTimeEmployees;
this.partTimeSchedules = currentRecoveredScheduleOfPartTimeEmployees;
this.totalScheduleCost = EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules);
assert(this.totalScheduleCost == bestScheduleCost);
this.totalScheduleCost = EmployeeCostCalculator.getFullRecoveredScheduleCost(this, myParametersInitialSchedules);
} else {
this.totalScheduleCost = Integer.MAX_VALUE;
}
@ -114,24 +104,29 @@ public class RecoveredSchedulesArray extends SchedulesArray{
}
private PriorityQueue<RecoveringAction> getPossibleRecoveringActions(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule,
boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees, boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees, int remainingRecoveringAction, Comparator recoveringActionCostComparator) {
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost = new PriorityQueue<RecoveringAction>(recoveringActionCostComparator);
int workPeriod = findEarlierWorkPeriodToRecover(currentPartTimeSchedule, currentFullTimeSchedule);
boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees, boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees,
int remainingRecoveringAction, Comparator recoveringActionCostComparator) {
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost = new PriorityQueue<>(recoveringActionCostComparator);
int workPeriod = findWorkPeriodToRecover(currentPartTimeSchedule, currentFullTimeSchedule);
if (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
for (int partTimeEmployee = 0 ; partTimeEmployee < this.getNumberPartTimeEmployee() ; partTimeEmployee++ ) {
if ( isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, partTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][remainingRecoveringAction-1]){
if ( ValidationRecoveringAction.isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, myParametersInitialSchedules,
absenceSchedulesArray, partTimeEmployee, workPeriod)
&& !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][remainingRecoveringAction-1]){
RecoveringActionPartTimeEmployee recoveringAction =
new RecoveringActionPartTimeEmployee(partTimeEmployee, workPeriod);
recoveringAction.calculateRecoveringActionCost (currentPartTimeSchedule, myParametersInitialSchedules);
recoveringAction.calculateRecoveringActionCost (currentPartTimeSchedule, absenceSchedulesArray, myParametersInitialSchedules);
recoveringActionsOrderedByCost.add(recoveringAction);
}
}
for (int fullTimeEmployee = 0 ; fullTimeEmployee < this.getNumberFullTimeEmployee() ; fullTimeEmployee++ ) {
if ( isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, fullTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][remainingRecoveringAction-1] ){
if ( ValidationRecoveringAction.isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, myParametersInitialSchedules,
absenceSchedulesArray, fullTimeEmployee, workPeriod)
&& !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][remainingRecoveringAction-1] ){
RecoveringActionFullTimeEmployee recoveringAction =
new RecoveringActionFullTimeEmployee(fullTimeEmployee, workPeriod);
recoveringAction.calculateRecoveringActionCost (currentFullTimeSchedule, myParametersInitialSchedules);
recoveringAction.calculateRecoveringActionCost (currentFullTimeSchedule, absenceSchedulesArray, myParametersInitialSchedules);
recoveringActionsOrderedByCost.add(recoveringAction);
}
}
@ -139,7 +134,7 @@ public class RecoveredSchedulesArray extends SchedulesArray{
return recoveringActionsOrderedByCost;
}
private int findEarlierWorkPeriodToRecover(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule){
private int findWorkPeriodToRecover(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule){
int workingEmployees;
for (int workPeriod = 0 ; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() ; workPeriod++) {
workingEmployees = 0;
@ -159,140 +154,4 @@ public class RecoveredSchedulesArray extends SchedulesArray{
}
return myParametersInitialSchedules.getWorkPeriodsPerSchedule();
}
//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[] currentPartTimeEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(currentPartTimeEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod);
}
private boolean isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(boolean[] currentPartTimeEmployeeSchedule){
int employeeWorkingPeriods = 0;
for ( int workPeriod = 0 ; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
if (currentPartTimeEmployeeSchedule[workPeriod]){
employeeWorkingPeriods +=1 ;
}
}
return employeeWorkingPeriods < myParametersInitialSchedules.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule();
}
private boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myParametersInitialSchedules.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork();
}
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
boolean validConsecutivePreviousNonWorkingPeriods = false;
if (compteurWorkPeriod == -1) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
}
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[] currentFullTimeEmployeeSchedule, int workPeriod){
return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentFullTimeEmployeeSchedule) &&
isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod);
}
private boolean isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(boolean[] currentFullTimeEmployeeSchedule){
int employeeWorkingPeriods = 0;
for ( int workPeriod = 0 ; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
if (currentFullTimeEmployeeSchedule[workPeriod]){
employeeWorkingPeriods +=1 ;
}
}
return employeeWorkingPeriods < myParametersInitialSchedules.getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule();
}
private boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myParametersInitialSchedules.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork();
}
private boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
boolean validConsecutivePreviousNonWorkingPeriods = false;
if (compteurWorkPeriod == -1) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule() && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myParametersInitialSchedules.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
}
}

View file

@ -5,8 +5,9 @@
*/
package SchedulesRecovery;
import AbsenceSchedules.AbsenceSchedulesArray;
import InitialSchedules.ParametersInitialSchedules;
import static ScheduleUtil.EmployeeCostCalculator.*;
import ScheduleUtil.*;
/**
*
@ -18,10 +19,10 @@ public class RecoveringActionFullTimeEmployee extends RecoveringAction{
super(employee, workPeriod);
}
public void calculateRecoveringActionCost (boolean[][] currentEmployeesSchedule, ParametersInitialSchedules myScheduleParameters) {
int costBeforeAction = getFullTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
public void calculateRecoveringActionCost (boolean[][] currentEmployeesSchedule, AbsenceSchedulesArray absenceSchedulesArray, ParametersInitialSchedules myScheduleParameters) {
int costBeforeAction = EmployeeCostCalculator.getFullTimeEmployeeCost(currentEmployeesSchedule, absenceSchedulesArray, this.employee, myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = true;
int costAfterAction = getFullTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
int costAfterAction = EmployeeCostCalculator.getFullTimeEmployeeCost(currentEmployeesSchedule, absenceSchedulesArray, this.employee, myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = false;
this.recoveringActionCost = costAfterAction-costBeforeAction;
}

View file

@ -5,8 +5,9 @@
*/
package SchedulesRecovery;
import AbsenceSchedules.AbsenceSchedulesArray;
import InitialSchedules.ParametersInitialSchedules;
import static ScheduleUtil.EmployeeCostCalculator.*;
import ScheduleUtil.*;
/**
*
@ -18,12 +19,13 @@ public class RecoveringActionPartTimeEmployee extends RecoveringAction{
super(employee, workPeriod);
}
public void calculateRecoveringActionCost ( boolean[][] currentEmployeesSchedule, ParametersInitialSchedules myScheduleParameters) {
int costBeforeAction = getPartTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
public void calculateRecoveringActionCost ( boolean[][] currentEmployeesSchedule,AbsenceSchedulesArray absenceSchedulesArray, ParametersInitialSchedules myScheduleParameters) {
int costBeforeAction = EmployeeCostCalculator.getPartTimeEmployeeCost(currentEmployeesSchedule, this.employee, myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = true;
int costAfterAction = getPartTimeEmployeeCost(currentEmployeesSchedule[this.employee], myScheduleParameters);
int costAfterAction = EmployeeCostCalculator.getPartTimeEmployeeCost(currentEmployeesSchedule, this.employee, myScheduleParameters);
currentEmployeesSchedule[this.employee][this.workPeriod] = false;
this.recoveringActionCost = costAfterAction-costBeforeAction;
}
}

View file

@ -13,19 +13,13 @@ public class ScheduleState {
boolean[][] currentRecoveredScheduleOfPartTimeEmployees;
boolean[][] currentRecoveredScheduleOfFullTimeEmployees;
// boolean[][] currentAlreadyRecoveredWorkPeriodByPartTimeEmployees;
// boolean[][] currentAlreadyRecoveredWorkPeriodByFullTimeEmployees;
int currentOptimisticTotalEmployeeCost;
int remainingRecoveringAction;
public ScheduleState(boolean[][] currentRecoveredScheduleOfPartTimeEmployees, boolean[][] currentRecoveredScheduleOfFullTimeEmployees,
int currentOptimisticTotalEmployeeCost, int remainingRecoveringAction) {
int remainingRecoveringAction) {
this.currentRecoveredScheduleOfPartTimeEmployees = currentRecoveredScheduleOfPartTimeEmployees;
this.currentRecoveredScheduleOfFullTimeEmployees = currentRecoveredScheduleOfFullTimeEmployees;
// this.currentAlreadyRecoveredWorkPeriodByPartTimeEmployees = currentAlreadyRecoveredWorkPeriodByPartTimeEmployees;
// this.currentAlreadyRecoveredWorkPeriodByFullTimeEmployees = currentAlreadyRecoveredWorkPeriodByFullTimeEmployees;
this.currentOptimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost;
this.remainingRecoveringAction = remainingRecoveringAction;
}

View file

@ -0,0 +1,159 @@
/*
* 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 InitialSchedules.ParametersInitialSchedules;
/**
*
* @author frabe
*/
// classe statique pour mettre fonction utilitaire
public class ValidationRecoveringAction {
//Toutes les fonctions sont dedoublees. On devrait faire du polymorphisme.
static boolean isPartTimeEmployeeAvailableForAbsenceRecovering(boolean[][] currentPartTimeSchedule, ParametersInitialSchedules myScheduleParameters,
AbsenceSchedulesArray myabsenceSchedule, int employee, int workPeriod){
return !currentPartTimeSchedule[employee][workPeriod] && !myabsenceSchedule.isPartTimeEmployeeAbsent(employee, workPeriod)
&& isValidPartTimeEmployeeWorkPeriod(currentPartTimeSchedule[employee], workPeriod, myScheduleParameters);
}
private static boolean isValidPartTimeEmployeeWorkPeriod(boolean[] currentPartTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
return isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(currentPartTimeEmployeeSchedule, myScheduleParameters) &&
isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod, myScheduleParameters) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(currentPartTimeEmployeeSchedule, workPeriod, myScheduleParameters);
}
private static boolean isValidWorkingPeriodsOfPartTimeEmployeePerSchedule(boolean[] currentPartTimeEmployeeSchedule, ParametersInitialSchedules myScheduleParameters){
int employeeWorkingPeriods = 0;
for ( int workPeriod = 0 ; workPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
if (currentPartTimeEmployeeSchedule[workPeriod]){
employeeWorkingPeriods +=1 ;
}
}
return employeeWorkingPeriods < myScheduleParameters.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule();
}
private static boolean isValidConsecutiveWorkingPeriodsOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfPartTimeEmployeesPerShiftWork();
}
private static boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployee(boolean[] currentPartTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
boolean validConsecutivePreviousNonWorkingPeriods = false;
if (compteurWorkPeriod == -1) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && !currentPartTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == myScheduleParameters.getWorkPeriodsPerSchedule()) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfPartTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
}
public static boolean isFullTimeEmployeeAvailableForAbsenceRecovering(boolean[][] currentFullTimeSchedule, ParametersInitialSchedules myScheduleParameters,
AbsenceSchedulesArray myabsenceSchedule, int employee, int workPeriod){
return !currentFullTimeSchedule[employee][workPeriod] && !myabsenceSchedule.isFullTimeEmployeeAbsent(employee, workPeriod)
&& isValidFullTimeEmployeeWorkPeriod(currentFullTimeSchedule[employee], workPeriod, myScheduleParameters);
}
private static boolean isValidFullTimeEmployeeWorkPeriod(boolean[] currentFullTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
return isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(currentFullTimeEmployeeSchedule, myScheduleParameters) &&
isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod, myScheduleParameters) &&
isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(currentFullTimeEmployeeSchedule, workPeriod, myScheduleParameters);
}
private static boolean isValidWorkingPeriodsOfFullTimeEmployeePerSchedule(boolean[] currentFullTimeEmployeeSchedule, ParametersInitialSchedules myScheduleParameters){
int employeeWorkingPeriods = 0;
for ( int workPeriod = 0 ; workPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() ; workPeriod++ ) {
if (currentFullTimeEmployeeSchedule[workPeriod]){
employeeWorkingPeriods +=1 ;
}
}
return employeeWorkingPeriods < myScheduleParameters.getMaxWorkingPeriodsOfFullTimeEmployeesPerSchedule();
}
private static boolean isValidConsecutiveWorkingPeriodsOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
int consecutiveWorkingPeriods = 1;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod--;
}
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveWorkingPeriods += 1;
compteurWorkPeriod++;
}
return consecutiveWorkingPeriods <= myScheduleParameters.getMaxConsecutiveWorkingPeriodsOfFullTimeEmployeesPerShiftWork();
}
private static boolean isValidConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployee(boolean[] currentFullTimeEmployeeSchedule, int workPeriod, ParametersInitialSchedules myScheduleParameters){
int consecutivePreviousNonWorkingPeriods = 0;
int compteurWorkPeriod = workPeriod - 1;
while ( compteurWorkPeriod >= 0 && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutivePreviousNonWorkingPeriods += 1;
compteurWorkPeriod--;
}
boolean validConsecutivePreviousNonWorkingPeriods = false;
if (compteurWorkPeriod == -1) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods == 0) {
validConsecutivePreviousNonWorkingPeriods = true;
} else if (consecutivePreviousNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutivePreviousNonWorkingPeriods = true;
}
int consecutiveNextNonWorkingPeriods = 0;
compteurWorkPeriod = workPeriod + 1;
while ( compteurWorkPeriod < myScheduleParameters.getWorkPeriodsPerSchedule() && !currentFullTimeEmployeeSchedule[compteurWorkPeriod] ){
consecutiveNextNonWorkingPeriods += 1;
compteurWorkPeriod++;
}
boolean validConsecutiveNextNonWorkingPeriods = false;
if (compteurWorkPeriod == myScheduleParameters.getWorkPeriodsPerSchedule()) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods == 0) {
validConsecutiveNextNonWorkingPeriods = true;
} else if (consecutiveNextNonWorkingPeriods >= myScheduleParameters.getMinConsecutiveNonWorkingPeriodsBetweenShiftWorksOfFullTimeEmployees()) {
validConsecutiveNextNonWorkingPeriods = true;
}
return validConsecutivePreviousNonWorkingPeriods && validConsecutiveNextNonWorkingPeriods;
}
}

View file

@ -23,42 +23,37 @@
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="mainPanel" alignment="0" max="32767" attributes="0"/>
<Component id="mainPanel" min="-2" pref="1283" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="mainPanel" pref="900" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="mainPanel" min="-2" pref="532" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="mainPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1400, 1000]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="changeScheduleNumberScrollBar" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jLabel1" min="-2" pref="115" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="textSolutionNumber" min="-2" pref="81" max="-2" attributes="0"/>
<EmptySpace min="0" pref="1166" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="changeScheduleNumberScrollBar" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="1240" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@ -73,9 +68,9 @@
<Component id="textSolutionNumber" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="changeScheduleNumberScrollBar" min="-2" pref="900" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="900" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jScrollPane1" pref="501" max="32767" attributes="0"/>
<Component id="changeScheduleNumberScrollBar" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>

View file

@ -48,9 +48,6 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
textSolutionNumber = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setPreferredSize(new java.awt.Dimension(1400, 1000));
mainPanel.setPreferredSize(new java.awt.Dimension(1400, 1000));
changeScheduleNumberScrollBar.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
@ -72,17 +69,16 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
mainPanelLayout.setHorizontalGroup(
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(mainPanelLayout.createSequentialGroup()
.addContainerGap()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(mainPanelLayout.createSequentialGroup()
.addComponent(changeScheduleNumberScrollBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1))
.addGroup(mainPanelLayout.createSequentialGroup()
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(textSolutionNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 1166, Short.MAX_VALUE)))
.addComponent(textSolutionNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(mainPanelLayout.createSequentialGroup()
.addComponent(changeScheduleNumberScrollBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 1240, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
);
mainPanelLayout.setVerticalGroup(
@ -92,24 +88,24 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
.addComponent(jLabel1)
.addComponent(textSolutionNumber))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(changeScheduleNumberScrollBar, javax.swing.GroupLayout.PREFERRED_SIZE, 900, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(mainPanelLayout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 900, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 501, Short.MAX_VALUE)
.addComponent(changeScheduleNumberScrollBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(mainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 1283, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(mainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 900, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(mainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 532, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();

View file

@ -3,6 +3,12 @@
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JFrameFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="3"/>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1400, 600]"/>
</Property>
<Property name="size" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1000, 600]"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
@ -29,19 +35,15 @@
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="mainPanel" pref="900" max="32767" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="mainPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="mainPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[1400, 1000]"/>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
@ -58,7 +60,7 @@
<Component id="jLabel1" min="-2" pref="115" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="textSolutionNumber" min="-2" pref="81" max="-2" attributes="0"/>
<EmptySpace min="0" pref="1166" max="32767" attributes="0"/>
<EmptySpace min="0" pref="1016" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
@ -73,9 +75,9 @@
<Component id="textSolutionNumber" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="changeScheduleNumberScrollBar" min="-2" pref="900" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="900" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="jScrollPane1" pref="500" max="32767" attributes="0"/>
<Component id="changeScheduleNumberScrollBar" max="32767" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>

View file

@ -47,8 +47,8 @@ public class ShowSolutionResultsFrame extends javax.swing.JFrame {
textSolutionNumber = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
mainPanel.setPreferredSize(new java.awt.Dimension(1400, 1000));
setPreferredSize(new java.awt.Dimension(1400, 600));
setSize(new java.awt.Dimension(1000, 600));
changeScheduleNumberScrollBar.addAdjustmentListener(new java.awt.event.AdjustmentListener() {
public void adjustmentValueChanged(java.awt.event.AdjustmentEvent evt) {
@ -80,7 +80,7 @@ public class ShowSolutionResultsFrame extends javax.swing.JFrame {
.addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(textSolutionNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 1166, Short.MAX_VALUE)))
.addGap(0, 1016, Short.MAX_VALUE)))
.addContainerGap())
);
mainPanelLayout.setVerticalGroup(
@ -90,9 +90,9 @@ public class ShowSolutionResultsFrame extends javax.swing.JFrame {
.addComponent(jLabel1)
.addComponent(textSolutionNumber))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(changeScheduleNumberScrollBar, javax.swing.GroupLayout.PREFERRED_SIZE, 900, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 900, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE)
.addComponent(changeScheduleNumberScrollBar, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
@ -105,8 +105,9 @@ public class ShowSolutionResultsFrame extends javax.swing.JFrame {
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, 0)
.addComponent(mainPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 900, Short.MAX_VALUE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(mainPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();