From 57b45430fa803122cdf4cf83b232cbfb076587b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Pelletier?= Date: Sat, 24 Mar 2018 10:30:23 -0400 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20contrainte=20des=20journ?= =?UTF-8?q?=C3=A9es=20valides=20pour=20les=20travailleurs=20=C3=A0=20temps?= =?UTF-8?q?=20partiel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ajout de classes pour mettre les tableaux d'horaires valides --- .../ModelInitialSchedules.java | 35 ++++++++++++++-- .../ParametersInitialSchedules.java | 40 +++++++------------ .../InitialSchedules/ValidDailySchedules.java | 34 ++++++++++++++++ .../ValidPartTimeEmployeeShift.java | 32 +++++++++++++++ Travail_de_session/MainClass.java | 7 ++-- 5 files changed, 114 insertions(+), 34 deletions(-) create mode 100644 Travail_de_session/InitialSchedules/ValidDailySchedules.java create mode 100644 Travail_de_session/InitialSchedules/ValidPartTimeEmployeeShift.java diff --git a/Travail_de_session/InitialSchedules/ModelInitialSchedules.java b/Travail_de_session/InitialSchedules/ModelInitialSchedules.java index ea9d829..594a3dd 100644 --- a/Travail_de_session/InitialSchedules/ModelInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ModelInitialSchedules.java @@ -6,7 +6,7 @@ import org.chocosolver.solver.variables.IntVar; public class ModelInitialSchedules { -// private final int HEURISTIQUE_DEFAUT = 0; + // private final int HEURISTIQUE_DEFAUT = 0; // private final int HEURISTIQUE_DOMOVERWDEG = 1; // private final int HEURISTIQUE_IMPACT_BASED_SEARCH = 2; // private final int HEURISTIQUE_ACTIVITY = 3; @@ -25,6 +25,9 @@ public class ModelInitialSchedules { public BoolVar workPeriodsSchedulesOfFullTimeEmployees[][]; private BoolVar transposeWorkPeriodsSchedulesOfFullTimeEmployees[][]; + private BoolVar workPeriodsOfPartTimeEmployees[][]; + private BoolVar workPeriodsOfFullTimeEmployees[][]; + public BoolVar allWorkPeriods[]; public IntVar workingPeriodsPerPartTimeEmployees[]; @@ -67,7 +70,7 @@ public class ModelInitialSchedules { this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxFullTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule); // Vecteur de toutes les variables - this.allWorkPeriods = chocoModelInitialSchedules.boolVarArray((this.maxPartTimeEmployee+this.maxFullTimeEmployee)*this.myScheduleParameters.workPeriodsPerSchedule); + /*this.allWorkPeriods = chocoModelInitialSchedules.boolVarArray((this.maxPartTimeEmployee+this.maxFullTimeEmployee)*this.myScheduleParameters.workPeriodsPerSchedule); for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { for(int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++){ @@ -81,7 +84,7 @@ public class ModelInitialSchedules { employee*this.myScheduleParameters.workPeriodsPerSchedule+workPeriod] = this.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]; } - } + }*/ // Variable pour faire le compte du nombre d'heures des employes this.workingPeriodsPerPartTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxPartTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true); @@ -109,6 +112,19 @@ public class ModelInitialSchedules { this.employeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule, 0, this.maxPartTimeEmployee + this.maxFullTimeEmployee, true); + // Variable pour les périodes de travail par jour des travailleurs à temps partiel + this.workPeriodsOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee * this.myScheduleParameters.daysPerSchedule + , this.myScheduleParameters.workPeriodsPerDay); + + for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { + for (int day = 0; day < this.myScheduleParameters.daysPerSchedule; day++) { + System.arraycopy(this.workPeriodsSchedulesOfPartTimeEmployees[employee], + day * this.myScheduleParameters.workPeriodsPerDay + 0, + this.workPeriodsOfPartTimeEmployees[employee * this.myScheduleParameters.daysPerSchedule + day], + 0, this.myScheduleParameters.workPeriodsPerDay); + + } + } } private void createModelConstraints() { @@ -143,7 +159,7 @@ public class ModelInitialSchedules { this.myScheduleParameters.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule).post(); } - // Constraintes pour compter le nombre d'employes par periode de travail et s'assurer qu'il + // Constraintes pour compter le nombre d'employes par periode de travail et s'assurer qu'il // satisfait la demande en employes for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) { chocoModelInitialSchedules.count(chocoModelInitialSchedules.intVar(1), @@ -160,6 +176,17 @@ public class ModelInitialSchedules { this.employeesPerWorkPeriods[workPeriod]).post(); } + // Contrainte pour heures consécutives des employés à temps partiel + + for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { + for (int day = 0; day < this.myScheduleParameters.daysPerSchedule; day++) { + chocoModelInitialSchedules.table( + this.workPeriodsOfPartTimeEmployees[employee * this.myScheduleParameters.daysPerSchedule + day], + this.myScheduleParameters.ValidPartTimeEmployeeShiftTuples).post(); + } + } + + // Contrainte de bris de symétrie: // chaque horaire d'employé est léxicographiquement inférieure à la suivante, par type d'employé diff --git a/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java b/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java index 09a8ea7..df1f8f0 100644 --- a/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ParametersInitialSchedules.java @@ -31,6 +31,8 @@ public class ParametersInitialSchedules { public int[] requiredWorkforce; Tuples enumerationWorkPeriodsSchedulesOfFullTimeEmployees; + Tuples ValidPartTimeEmployeeShiftTuples; + public ParametersInitialSchedules() { this.setGeneralParameters(); @@ -38,6 +40,7 @@ public class ParametersInitialSchedules { this.setFullTimeEmployeesParameters(); this.setRequiredWorkforce(); this.setWorkPeriodsSchedulesOfFullTimeEmployees(); + this.setValidPartTimeEmployeeShiftTuples(); } @@ -79,7 +82,7 @@ public class ParametersInitialSchedules { this.requiredWorkforce = new int[this.daysPerSchedule * this.workPeriodsPerDay]; this.totalWorkedPeriodsInSchedule = 0; - int[] dailyRequiredWorkforce = new int[]{4,4,5,5,3,3}; + int[] dailyRequiredWorkforce = new int[]{2, 2, 4, 4, 3, 3}; for (int day = 0; day < this.daysPerSchedule; day++) { for(int shift = 0; shift < this.workPeriodsPerDay; shift++) { this.requiredWorkforce[day * this.workPeriodsPerDay + shift] = dailyRequiredWorkforce[shift]; @@ -88,38 +91,18 @@ public class ParametersInitialSchedules { } } + private void setWorkPeriodsSchedulesOfFullTimeEmployees() { - int[][] dailySchedulesOfFullTimeEmployees = new int[][]{ - {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1}, - {0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1}, - {0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, - {0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, - {1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1}, - {1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, - {1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, - {1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, - {1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, - {1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, - {1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, - {1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, - {1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0}, - {1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, - {1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0}, - {1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0}, - {1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0}, - {1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0}, - {1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0}, - {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0},}; + ValidDailySchedules v = new ValidDailySchedules(); - int possibleDailyScheduleOfFullTimeEmployees = dailySchedulesOfFullTimeEmployees.length; + int[][] dailySchedulesOfFullTimeEmployees = v.dailySchedulesOfFullTimeEmployees; int[][] workPeriodsSchedulesOfFullTimeEmployees - = new int[possibleDailyScheduleOfFullTimeEmployees * this.shiftWorkPerDay][this.workPeriodsPerSchedule]; + = new int[v.length() * this.shiftWorkPerDay][this.workPeriodsPerSchedule]; // Cette fonction sera a ameliorer avec des sous-fonctions, car elle n'est pas tres explicite. - for (int scheduleNumber = 0; scheduleNumber < possibleDailyScheduleOfFullTimeEmployees; scheduleNumber++) { + for (int scheduleNumber = 0; scheduleNumber < v.length(); scheduleNumber++) { for (int day = 0; day < this.daysPerSchedule; day++) { for (int shiftNumber = 0; shiftNumber < this.shiftWorkPerDay; shiftNumber++) { if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 0) { @@ -160,6 +143,11 @@ public class ParametersInitialSchedules { = new Tuples(workPeriodsSchedulesOfFullTimeEmployees, true); } + private void setValidPartTimeEmployeeShiftTuples() { + this.ValidPartTimeEmployeeShiftTuples = new ValidPartTimeEmployeeShift().makeTuples(); + } + + // A implementer plus tard si l'on veut travailler avec des fichiers texte public ParametersInitialSchedules(String fileName) { diff --git a/Travail_de_session/InitialSchedules/ValidDailySchedules.java b/Travail_de_session/InitialSchedules/ValidDailySchedules.java new file mode 100644 index 0000000..7524c32 --- /dev/null +++ b/Travail_de_session/InitialSchedules/ValidDailySchedules.java @@ -0,0 +1,34 @@ +package InitialSchedules; + +public class ValidDailySchedules { + int[][] dailySchedulesOfFullTimeEmployees; + + public ValidDailySchedules() { + this.dailySchedulesOfFullTimeEmployees = new int[][]{ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1}, + {0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, + {0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, + {1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1}, + {1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, + {1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, + {1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1}, + {1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, + {1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1}, + {1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0}, + {1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0}, + {1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0}, + {1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0},}; + } + + public int length() { + return this.dailySchedulesOfFullTimeEmployees.length; + } +} diff --git a/Travail_de_session/InitialSchedules/ValidPartTimeEmployeeShift.java b/Travail_de_session/InitialSchedules/ValidPartTimeEmployeeShift.java new file mode 100644 index 0000000..b9792e0 --- /dev/null +++ b/Travail_de_session/InitialSchedules/ValidPartTimeEmployeeShift.java @@ -0,0 +1,32 @@ +package InitialSchedules; + +import org.chocosolver.solver.constraints.extension.Tuples; + +public class ValidPartTimeEmployeeShift { + int[][] shiftsOfPartTimeEmployees; + + public ValidPartTimeEmployeeShift() { + this.shiftsOfPartTimeEmployees = new int[][]{ + {0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 1}, + {0, 0, 0, 0, 1, 0}, + {0, 0, 0, 1, 0, 0}, + {0, 0, 1, 0, 0, 0}, + {0, 1, 0, 0, 0, 0}, + {1, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 1, 1}, + {0, 0, 0, 1, 1, 0}, + {0, 0, 1, 1, 0, 0}, + {0, 1, 1, 0, 0, 0}, + {1, 1, 0, 0, 0, 0}, + {0, 0, 0, 1, 1, 1}, + {0, 0, 0, 1, 1, 1}, + {0, 0, 0, 1, 1, 1}, + {0, 0, 0, 1, 1, 1} + }; + } + + public Tuples makeTuples() { + return new Tuples(this.shiftsOfPartTimeEmployees, true); + } +} diff --git a/Travail_de_session/MainClass.java b/Travail_de_session/MainClass.java index e3c20ef..787c605 100644 --- a/Travail_de_session/MainClass.java +++ b/Travail_de_session/MainClass.java @@ -1,6 +1,4 @@ - import org.chocosolver.solver.Solver; -import org.chocosolver.solver.search.strategy.Search; public class MainClass { @@ -23,9 +21,10 @@ public class MainClass { = new InitialSchedules.ModelInitialSchedules(myScheduleParameters); Solver solverInitialSchedules = myModelInitialSchedules.chocoModelInitialSchedules.getSolver(); - solverInitialSchedules.setSearch(Search.domOverWDegSearch(myModelInitialSchedules.allWorkPeriods)); + /*solverInitialSchedules.setSearch(Search.domOverWDegSearch(myModelInitialSchedules.allWorkPeriods)); solverInitialSchedules.limitSolution(10); - solverInitialSchedules.findAllSolutions(); + solverInitialSchedules.findAllSolutions();*/ + solverInitialSchedules.findSolution(); // Solution bestInitialSchedules = solverInitialSchedules.findOptimalSolution // (myModelInitialSchedules.scheduleProfit, Model.MINIMIZE);