Correction de l'algo de recouvrement d'horaire.
This commit is contained in:
parent
3ddd68afba
commit
c1e82d2af0
5 changed files with 88 additions and 40 deletions
|
@ -41,9 +41,11 @@ public class SchedulesArray {
|
|||
}
|
||||
|
||||
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++) {
|
||||
int nbrEmployee = schedules.length;
|
||||
int nbrWorkPeriod = schedules[0].length;
|
||||
boolean[][] copySchedules = new boolean[nbrEmployee][nbrWorkPeriod];
|
||||
for (int workPeriod = 0; workPeriod < nbrWorkPeriod; workPeriod++) {
|
||||
for (int employee = 0; employee < nbrEmployee; employee++) {
|
||||
copySchedules[employee][workPeriod] = schedules[employee][workPeriod];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,64 +29,79 @@ public class RecoveredSchedulesArray extends SchedulesArray{
|
|||
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()];
|
||||
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++) {
|
||||
Arrays.fill(alreadyRecoveredWorkPeriodByPartTimeEmployees[i], Boolean.FALSE);
|
||||
}
|
||||
for (int i = 0 ; i < this.getNumberFullTimeEmployee() ; i++) {
|
||||
Arrays.fill(alreadyRecoveredWorkPeriodByFullTimeEmployees[i], Boolean.FALSE);
|
||||
}
|
||||
|
||||
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);
|
||||
ScheduleState currentScheduleState = new ScheduleState(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees,
|
||||
currentOptimisticTotalEmployeeCost, remainingRecoveringAction);
|
||||
|
||||
Stack< ScheduleState > scheduleStatesNodes = new Stack<>();
|
||||
scheduleStatesNodes.push(currentScheduleState);
|
||||
RecoveringAction currentRecoveringAction = null;
|
||||
|
||||
boolean isSolutionFound = true;
|
||||
// Fouille en profondeur avec calcul de cout optimiste base sur le taux horaire regulier des employes a temps plein.
|
||||
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 ) {
|
||||
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost =
|
||||
getPossibleRecoveringActions(currentRecoveredScheduleOfPartTimeEmployees, currentRecoveredScheduleOfFullTimeEmployees,
|
||||
alreadyRecoveredWorkPeriodByPartTimeEmployees, alreadyRecoveredWorkPeriodByFullTimeEmployees, recoveringActionCostComparator);
|
||||
alreadyRecoveredWorkPeriodByPartTimeEmployees, alreadyRecoveredWorkPeriodByFullTimeEmployees, remainingRecoveringAction, recoveringActionCostComparator);
|
||||
if (recoveringActionsOrderedByCost.size() > 0){
|
||||
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;
|
||||
alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][remainingRecoveringAction-1] = true;
|
||||
} else if (currentRecoveringAction.getClass().getName().equals("SchedulesRecovery.RecoveringActionFullTimeEmployee")) {
|
||||
recoveredScheduleOfFullTimeEmployeesAfterAction[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true;
|
||||
alreadyRecoveredWorkPeriodByFullTimeEmployees[currentRecoveringAction.employee][currentRecoveringAction.workPeriod] = true;
|
||||
alreadyRecoveredWorkPeriodByPartTimeEmployees[currentRecoveringAction.employee][remainingRecoveringAction-1] = true;
|
||||
}
|
||||
|
||||
|
||||
optimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost - myParametersInitialSchedules.getMinimumWorkingPeriodCost() + currentRecoveringAction.recoveringActionCost;
|
||||
Quartet<boolean[][], boolean[][], Integer, Integer> scheduleState = Quartet.with
|
||||
(recoveredScheduleOfPartTimeEmployeesAfterAction, recoveredScheduleOfFullTimeEmployeesAfterAction, optimisticTotalEmployeeCost, remainingRecoveringAction - 1);
|
||||
scheduleStatesOrderedByOptimisticCost.add(scheduleState);
|
||||
|
||||
ScheduleState scheduleState = new ScheduleState(recoveredScheduleOfPartTimeEmployeesAfterAction, recoveredScheduleOfFullTimeEmployeesAfterAction,
|
||||
optimisticTotalEmployeeCost, remainingRecoveringAction - 1);
|
||||
|
||||
scheduleStatesNodes.push(scheduleState);
|
||||
} else {
|
||||
|
||||
do{
|
||||
scheduleStatesNodes.pop();
|
||||
} while(scheduleStatesNodes.size() > 1);
|
||||
|
||||
}
|
||||
if (remainingRecoveringAction - 1 == 0){
|
||||
bestScheduleCost = Math.min(bestScheduleCost, optimisticTotalEmployeeCost);
|
||||
}
|
||||
if (scheduleStatesOrderedByOptimisticCost.size() > 0) {
|
||||
Quartet<boolean[][], boolean[][], Integer, Integer> currentScheduleState = scheduleStatesOrderedByOptimisticCost.poll();
|
||||
currentRecoveredScheduleOfPartTimeEmployees = currentScheduleState.getValue0();
|
||||
currentRecoveredScheduleOfFullTimeEmployees = currentScheduleState.getValue1();
|
||||
currentOptimisticTotalEmployeeCost = currentScheduleState.getValue2();
|
||||
remainingRecoveringAction = currentScheduleState.getValue3();
|
||||
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;
|
||||
|
@ -94,19 +109,18 @@ public class RecoveredSchedulesArray extends SchedulesArray{
|
|||
assert(this.totalScheduleCost == bestScheduleCost);
|
||||
} else {
|
||||
this.totalScheduleCost = Integer.MAX_VALUE;
|
||||
System.out.println(" No Solution Found ");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private PriorityQueue<RecoveringAction> getPossibleRecoveringActions(boolean[][] currentPartTimeSchedule, boolean[][] currentFullTimeSchedule, boolean[][] alreadyRecoveredWorkPeriodByPartTimeEmployees, boolean[][] alreadyRecoveredWorkPeriodByFullTimeEmployees, Comparator recoveringActionCostComparator) {
|
||||
PriorityQueue<RecoveringAction> recoveringActionsOrderedByCost = new PriorityQueue<>(recoveringActionCostComparator);
|
||||
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);
|
||||
|
||||
if (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
|
||||
for (int partTimeEmployee = 0 ; partTimeEmployee < this.getNumberPartTimeEmployee() ; partTimeEmployee++ ) {
|
||||
if ( isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, partTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][workPeriod]){
|
||||
if ( isPartTimeEmployeeAvailableForAbsenceRecovering(currentPartTimeSchedule, partTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByPartTimeEmployees[partTimeEmployee][remainingRecoveringAction-1]){
|
||||
RecoveringActionPartTimeEmployee recoveringAction =
|
||||
new RecoveringActionPartTimeEmployee(partTimeEmployee, workPeriod);
|
||||
recoveringAction.calculateRecoveringActionCost (currentPartTimeSchedule, myParametersInitialSchedules);
|
||||
|
@ -114,7 +128,7 @@ public class RecoveredSchedulesArray extends SchedulesArray{
|
|||
}
|
||||
}
|
||||
for (int fullTimeEmployee = 0 ; fullTimeEmployee < this.getNumberFullTimeEmployee() ; fullTimeEmployee++ ) {
|
||||
if ( isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, fullTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][workPeriod] ){
|
||||
if ( isFullTimeEmployeeAvailableForAbsenceRecovering(currentFullTimeSchedule, fullTimeEmployee, workPeriod) && !alreadyRecoveredWorkPeriodByFullTimeEmployees[fullTimeEmployee][remainingRecoveringAction-1] ){
|
||||
RecoveringActionFullTimeEmployee recoveringAction =
|
||||
new RecoveringActionFullTimeEmployee(fullTimeEmployee, workPeriod);
|
||||
recoveringAction.calculateRecoveringActionCost (currentFullTimeSchedule, myParametersInitialSchedules);
|
||||
|
|
|
@ -17,7 +17,7 @@ public class RecoveringActionComparator implements Comparator< RecoveringAction
|
|||
if (actionCostCmp !=0) {
|
||||
return actionCostCmp;
|
||||
}
|
||||
int workPeriodCmp = Integer.compare(a1.workPeriod, a2.workPeriod);
|
||||
int workPeriodCmp = Integer.compare(a1.employee, a2.employee);
|
||||
return workPeriodCmp;
|
||||
}
|
||||
|
||||
|
|
33
Travail_de_session/SchedulesRecovery/ScheduleState.java
Normal file
33
Travail_de_session/SchedulesRecovery/ScheduleState.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package SchedulesRecovery;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author frabe
|
||||
*/
|
||||
public class ScheduleState {
|
||||
|
||||
boolean[][] currentRecoveredScheduleOfPartTimeEmployees;
|
||||
boolean[][] currentRecoveredScheduleOfFullTimeEmployees;
|
||||
// boolean[][] currentAlreadyRecoveredWorkPeriodByPartTimeEmployees;
|
||||
// boolean[][] currentAlreadyRecoveredWorkPeriodByFullTimeEmployees;
|
||||
int currentOptimisticTotalEmployeeCost;
|
||||
int remainingRecoveringAction;
|
||||
|
||||
public ScheduleState(boolean[][] currentRecoveredScheduleOfPartTimeEmployees, boolean[][] currentRecoveredScheduleOfFullTimeEmployees,
|
||||
|
||||
int currentOptimisticTotalEmployeeCost, int remainingRecoveringAction) {
|
||||
this.currentRecoveredScheduleOfPartTimeEmployees = currentRecoveredScheduleOfPartTimeEmployees;
|
||||
this.currentRecoveredScheduleOfFullTimeEmployees = currentRecoveredScheduleOfFullTimeEmployees;
|
||||
// this.currentAlreadyRecoveredWorkPeriodByPartTimeEmployees = currentAlreadyRecoveredWorkPeriodByPartTimeEmployees;
|
||||
// this.currentAlreadyRecoveredWorkPeriodByFullTimeEmployees = currentAlreadyRecoveredWorkPeriodByFullTimeEmployees;
|
||||
this.currentOptimisticTotalEmployeeCost = currentOptimisticTotalEmployeeCost;
|
||||
this.remainingRecoveringAction = remainingRecoveringAction;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -6,19 +6,18 @@
|
|||
package SchedulesRecovery;
|
||||
|
||||
import java.util.Comparator;
|
||||
import org.javatuples.Quartet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author frabe
|
||||
*/
|
||||
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());
|
||||
public class ScheduleStateComparator implements Comparator< ScheduleState > {
|
||||
public int compare(ScheduleState o1, ScheduleState o2) {
|
||||
int totalCostCmp = Integer.compare(o1.currentOptimisticTotalEmployeeCost,o2.currentOptimisticTotalEmployeeCost);
|
||||
if (totalCostCmp !=0) {
|
||||
return totalCostCmp;
|
||||
}
|
||||
int remainingActionsCmp = o2.getValue3().compareTo(o1.getValue3());
|
||||
int remainingActionsCmp = Integer.compare(o1.remainingRecoveringAction,o2.remainingRecoveringAction);
|
||||
return remainingActionsCmp;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue