From 3ddd68afba5ee1a789c18f3505cb90037cd89d79 Mon Sep 17 00:00:00 2001 From: "Francois Berube\\frabe" Date: Mon, 9 Apr 2018 22:39:38 -0400 Subject: [PATCH] =?UTF-8?q?Retour=20=C3=A0=20la=20m=C3=A9thode=20pr=C3=A9c?= =?UTF-8?q?=C3=A9dente=20pour=20la=20g=C3=A9n=C3=A9ration=20des=20horaires?= =?UTF-8?q?=20qui=20est=20beaucoup=20plus=20rapide,=20mais=20qui=20n'offre?= =?UTF-8?q?=20pas=20une=20tr=C3=A8s=20grande=20diversit=C3=A9=20d'horaires?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajout Fonction Restart dans le solver des horaires des employés à temps partiel. --- ...odelPartTimeEmployeesInitialSchedules.java | 28 +++++------ .../ParametersInitialSchedules.java | 2 +- .../SolverInitialSchedules.java | 14 ++++-- Travail_de_session/MainClass.java | 46 +++++++------------ .../PartTimeEmployeeScheduleArray.java | 4 +- .../SchedulesWindows/ShowSchedulesFrame.java | 2 - 6 files changed, 42 insertions(+), 54 deletions(-) diff --git a/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java b/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java index c1ead03..5b4e1e8 100644 --- a/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java @@ -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(); - } } } diff --git a/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java b/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java index b512512..7e308d6 100644 --- a/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java @@ -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++) { diff --git a/Travail_de_session/InitialSchedules/SolverInitialSchedules.java b/Travail_de_session/InitialSchedules/SolverInitialSchedules.java index 1ffa237..b101481 100644 --- a/Travail_de_session/InitialSchedules/SolverInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/SolverInitialSchedules.java @@ -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(); + } + } diff --git a/Travail_de_session/MainClass.java b/Travail_de_session/MainClass.java index cd2feec..985067d 100644 --- a/Travail_de_session/MainClass.java +++ b/Travail_de_session/MainClass.java @@ -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 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 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 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 diff --git a/Travail_de_session/ScheduleUtil/PartTimeEmployeeScheduleArray.java b/Travail_de_session/ScheduleUtil/PartTimeEmployeeScheduleArray.java index 3bff6c2..fd5f4e7 100644 --- a/Travail_de_session/ScheduleUtil/PartTimeEmployeeScheduleArray.java +++ b/Travail_de_session/ScheduleUtil/PartTimeEmployeeScheduleArray.java @@ -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++; } diff --git a/Travail_de_session/SchedulesWindows/ShowSchedulesFrame.java b/Travail_de_session/SchedulesWindows/ShowSchedulesFrame.java index 39a0544..41cc23f 100644 --- a/Travail_de_session/SchedulesWindows/ShowSchedulesFrame.java +++ b/Travail_de_session/SchedulesWindows/ShowSchedulesFrame.java @@ -19,7 +19,6 @@ public class ShowSchedulesFrame extends javax.swing.JFrame { * Creates new form ShowSchedulesFrame **/ public ShowSchedulesFrame(List 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);