Retour à la méthode précédente pour la génération des horaires qui est beaucoup plus rapide, mais qui n'offre pas une très grande diversité d'horaires.

Ajout Fonction Restart dans le solver des horaires des employés à temps partiel.
This commit is contained in:
Francois Berube\frabe 2018-04-09 22:39:38 -04:00
parent e775aedf05
commit 3ddd68afba
6 changed files with 42 additions and 54 deletions

View file

@ -8,7 +8,7 @@ public class ModelPartTimeEmployeesInitialSchedules {
public ParametersInitialSchedules myScheduleParameters;
public int numberOfPartTimeEmployees;
public int maxPartTimeEmployee;
public BoolVar workPeriodsSchedulesOfPartTimeEmployees[][];
private BoolVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][];
@ -17,14 +17,15 @@ public class ModelPartTimeEmployeesInitialSchedules {
public Model chocoModelInitialSchedules;
public ModelPartTimeEmployeesInitialSchedules(ParametersInitialSchedules myScheduleParameters, int numberOfPartTimeEmployees) {
public ModelPartTimeEmployeesInitialSchedules(ParametersInitialSchedules myScheduleParameters) {
this.myScheduleParameters = myScheduleParameters;
this.chocoModelInitialSchedules = new Model("Model Part Time Employees Initial Schedules");
this.maxPartTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule()
/ myScheduleParameters.getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule());
this.numberOfPartTimeEmployees = numberOfPartTimeEmployees;
this.createScheduleVariables();
this.createModelConstraints();
@ -33,26 +34,26 @@ public class ModelPartTimeEmployeesInitialSchedules {
private void createScheduleVariables() {
// Variable pour l'horaire des employes
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.numberOfPartTimeEmployees, this.myScheduleParameters.getWorkPeriodsPerSchedule());
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.getWorkPeriodsPerSchedule());
// Creer la transpose des horaires pour compter les elements des colonnes
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.numberOfPartTimeEmployees);
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.maxPartTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) {
for (int employee = 0; employee < this.numberOfPartTimeEmployees; employee++) {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod][employee]
= this.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod];
}
}
// Variable pour faire le compte du nombre d'employes par periode de travail
this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.numberOfPartTimeEmployees, true);
this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.maxPartTimeEmployee, true);
}
private void createModelConstraints() {
// Constraintes tableau pour choisir un type d'horaire dans les horaires possibles
for (int employee = 0; employee < this.numberOfPartTimeEmployees; employee++) {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
chocoModelInitialSchedules.table(this.workPeriodsSchedulesOfPartTimeEmployees[employee],
this.myScheduleParameters.enumerationWorkPeriodsSchedulesOfPartTimeEmployees).post();
}
@ -70,18 +71,11 @@ public class ModelPartTimeEmployeesInitialSchedules {
// Contrainte de bris de symétrie:
// chaque horaire d'employé est léxicographiquement inférieure à la suivante, par type d'employé
// Ne fonctionne pas avec l'heuristique par défaut
for (int employee = 0; employee < (this.numberOfPartTimeEmployees-1); employee++){
for (int employee = 0; employee < (this.maxPartTimeEmployee-1); employee++){
chocoModelInitialSchedules.lexLessEq(this.workPeriodsSchedulesOfPartTimeEmployees[employee],
this.workPeriodsSchedulesOfPartTimeEmployees[employee+1]).post();
}
IntVar[] workingPeriodsPerPartTimeEmployees =
chocoModelInitialSchedules.intVarArray(this.numberOfPartTimeEmployees,0,this.myScheduleParameters.getWorkPeriodsPerSchedule(), true);
for (int employee = 0; employee < this.numberOfPartTimeEmployees; employee++) {
chocoModelInitialSchedules.sum(workPeriodsSchedulesOfPartTimeEmployees[employee],
"=", workingPeriodsPerPartTimeEmployees[employee]).post();
chocoModelInitialSchedules.arithm(workingPeriodsPerPartTimeEmployees[employee], ">", 0).post();
}
}
}

View file

@ -184,7 +184,7 @@ public class ParametersInitialSchedules {
int maxShiftConfig = 5;
int[][] workPeriodsSchedulesOfPartTimeEmployees
= new int[NbPartTimeSolutions * 5][this.getWorkPeriodsPerSchedule()];
= new int[NbPartTimeSolutions * maxShiftConfig][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++) {

View file

@ -9,6 +9,8 @@ import java.util.List;
import org.chocosolver.solver.Solution;
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.exception.ContradictionException;
import org.chocosolver.solver.search.limits.BacktrackCounter;
import org.chocosolver.solver.search.restart.MonotonicRestartStrategy;
/**
*
@ -31,7 +33,7 @@ public class SolverInitialSchedules {
}
solverInitialSchedules.setRestartOnSolutions();
solverInitialSchedules.limitSolution(1);
// solverInitialSchedules.limitTime(10000);
solverInitialSchedules.limitTime(1000000);
}
@ -47,8 +49,10 @@ public class SolverInitialSchedules {
System.err.println("Caught Exception: " + e.getMessage());
}
solverInitialSchedules.setRestartOnSolutions();
solverInitialSchedules.limitSolution(1);
// solverInitialSchedules.limitTime(100000);
BacktrackCounter restartCriterion = new BacktrackCounter(myModelPartTimeEmployeesInitialSchedules.chocoModelInitialSchedules, 100000);
solverInitialSchedules.setRestarts(restartCriterion, new MonotonicRestartStrategy(50000), 1000);
solverInitialSchedules.limitSolution(2);
solverInitialSchedules.limitTime(1000000);
}
@ -58,4 +62,8 @@ public class SolverInitialSchedules {
return myInitialSchedulesSolutions;
}
public void printStatistics(){
solverInitialSchedules.printShortStatistics();
}
}

View file

@ -41,10 +41,11 @@ public class MainClass {
InitialSchedules.ParametersInitialSchedules myScheduleParameters = new InitialSchedules.ParametersInitialSchedules();
int minFullTimeEmployee = 1;
int minFullTimeEmployee = 2; //La solution avec 1 employes est trop lente
int maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule()
/ myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule());
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;
@ -57,8 +58,6 @@ public class MainClass {
SolverInitialSchedules mySolverFullTimeEmployeesInitialSchedules = new SolverInitialSchedules(myModelFullTimeEmployeesInitialSchedules);
List<Solution> myInitialFullTimeEmployeesSchedulesSolutions = mySolverFullTimeEmployeesInitialSchedules.findAllSolution();
System.out.println("numberFullTimeEmployeesSchedulesFound: " + myInitialFullTimeEmployeesSchedulesSolutions.size());
// Création de l'objet banque d'horaire, qui est une liste d'objets de type InitialSchedulesArray, qui contiennent chacun deux tableaux.
for (Solution CurrentFullTimeEmployeesSolution : myInitialFullTimeEmployeesSchedulesSolutions) {
@ -66,36 +65,25 @@ public class MainClass {
InitialSchedules.ParametersInitialSchedules myPartTimeScheduleParameters = new InitialSchedules.ParametersInitialSchedules();
myPartTimeScheduleParameters.adjustRequiredWorkforce(fullTimeSchedulesArray);
int minPartTimeEmployee = (int) Math.ceil((double) myPartTimeScheduleParameters.getTotalWorkedPeriodsInSchedule()
/ myPartTimeScheduleParameters.getMaxWorkingPeriodsOfPartTimeEmployeesPerSchedule());
int maxPartTimeEmployee = (int) Math.ceil((double) myPartTimeScheduleParameters.getTotalWorkedPeriodsInSchedule()
/ myPartTimeScheduleParameters.getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule());
for (int numberPartTimeEmployees = minPartTimeEmployee ; numberPartTimeEmployees <= maxPartTimeEmployee ; numberPartTimeEmployees++){
System.out.println("numberPartTimeEmployees: " + numberPartTimeEmployees);
InitialSchedules.ModelPartTimeEmployeesInitialSchedules myModelPartTimeEmployeesInitialSchedules
= new InitialSchedules.ModelPartTimeEmployeesInitialSchedules(myPartTimeScheduleParameters, numberPartTimeEmployees);
SolverInitialSchedules mySolverPartTimeEmployeesInitialSchedules = new SolverInitialSchedules(myModelPartTimeEmployeesInitialSchedules);
List<Solution> myInitialPartTimeEmployeesSchedulesSolutions = mySolverPartTimeEmployeesInitialSchedules.findAllSolution();
System.out.println("numberPartTimeEmployeesSchedulesFound: " + myInitialPartTimeEmployeesSchedulesSolutions.size());
for (Solution CurrentPartTimeEmployeesSolution : myInitialPartTimeEmployeesSchedulesSolutions) {
PartTimeEmployeeScheduleArray partTimeSchedulesArray = new PartTimeEmployeeScheduleArray(myModelPartTimeEmployeesInitialSchedules, CurrentPartTimeEmployeesSolution);
SchedulesArray initialSchedulesArray = new SchedulesArray(fullTimeSchedulesArray, partTimeSchedulesArray, simulationNumber);
initialSchedulesArrayList.add(initialSchedulesArray);
simulationNumber++;
}
InitialSchedules.ModelPartTimeEmployeesInitialSchedules myModelPartTimeEmployeesInitialSchedules
= new InitialSchedules.ModelPartTimeEmployeesInitialSchedules(myPartTimeScheduleParameters);
SolverInitialSchedules mySolverPartTimeEmployeesInitialSchedules = new SolverInitialSchedules(myModelPartTimeEmployeesInitialSchedules);
List<Solution> myInitialPartTimeEmployeesSchedulesSolutions = mySolverPartTimeEmployeesInitialSchedules.findAllSolution();
mySolverPartTimeEmployeesInitialSchedules.printStatistics();
for (Solution CurrentPartTimeEmployeesSolution : myInitialPartTimeEmployeesSchedulesSolutions) {
PartTimeEmployeeScheduleArray partTimeSchedulesArray = new PartTimeEmployeeScheduleArray(myModelPartTimeEmployeesInitialSchedules, CurrentPartTimeEmployeesSolution);
SchedulesArray initialSchedulesArray = new SchedulesArray(fullTimeSchedulesArray, partTimeSchedulesArray, simulationNumber);
initialSchedulesArrayList.add(initialSchedulesArray);
simulationNumber++;
}
}
}
System.out.println("totalNumberScheduleFound: " + initialSchedulesArrayList.size());
// Pour afficher les horaires initiales
SchedulesWindows.ShowSchedulesFrame intialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules"); // to be removed

View file

@ -25,7 +25,7 @@ public class PartTimeEmployeeScheduleArray {
this.partTimeSchedules = new boolean[getNumberOfFullTimeEmployees(s, m)][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
int partTimeEmployee = 0;
for (int i = 0; i < m.numberOfPartTimeEmployees; i++) {
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;
@ -38,7 +38,7 @@ public class PartTimeEmployeeScheduleArray {
private int getNumberOfFullTimeEmployees( Solution s, ModelPartTimeEmployeesInitialSchedules m ) {
int numberPartTimeEmployee = 0;
for (int employee = 0; employee < m.numberOfPartTimeEmployees; employee++) {
for (int employee = 0; employee < m.maxPartTimeEmployee; employee++) {
if (isPartTimeEmployeeActive (employee, s, m)) {
numberPartTimeEmployee++;
}

View file

@ -19,7 +19,6 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
* Creates new form ShowSchedulesFrame
**/
public ShowSchedulesFrame(List<ScheduleUtil.SchedulesArray> schedulesArrayList, String title) {
System.out.println("totalNumberScheduleFound: " + schedulesArrayList.size());
this.schedulesArrayList = schedulesArrayList;
this.title = title;
initComponents();
@ -30,7 +29,6 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
setTitle(title);
setVisible(true);
changeScheduleNumberScrollBar.setMinimum(1);
System.out.println("totalNumberScheduleFound: " + this.schedulesArrayList.size());
int numberOfSchedules = this.schedulesArrayList.size();
changeScheduleNumberScrollBar.setMaximum(numberOfSchedules);
changeScheduleNumberScrollBar.setBlockIncrement(1);