From e775aedf0593994ba50943649cf7472e8969500d Mon Sep 17 00:00:00 2001 From: "Francois Berube\\frabe" Date: Sun, 8 Apr 2018 22:05:34 -0400 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20la=20variation=20du=20nombre=20d'e?= =?UTF-8?q?mploy=C3=A9s=20=C3=A0=20temps=20partiel=20dans=20le=20solveur?= =?UTF-8?q?=20pour=20la=20g=C3=A9n=C3=A9ration=20d'horaires=20diff=C3=A9re?= =?UTF-8?q?nts.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Certains cas sont assez lent pour les horaires à temps partiels. Penser à diminuer le nombre d'horaires possibles. TODO: une fois la banque d'horaires générées, on pourrait l'enregistrer dans un .json pour la regénérer plus rapidement. --- ...odelFullTimeEmployeesInitialSchedules.java | 9 - .../ModelInitialSchedules.java | 255 ------------------ ...odelPartTimeEmployeesInitialSchedules.java | 45 ++-- .../SolverInitialSchedules.java | 61 +++++ Travail_de_session/MainClass.java | 138 +++------- .../PartTimeEmployeeScheduleArray.java | 4 +- .../ScheduleUtil/SchedulesArray.java | 75 ------ 7 files changed, 115 insertions(+), 472 deletions(-) delete mode 100644 Travail_de_session/InitialSchedules/ModelInitialSchedules.java create mode 100644 Travail_de_session/InitialSchedules/SolverInitialSchedules.java diff --git a/Travail_de_session/InitialSchedules/ModelFullTimeEmployeesInitialSchedules.java b/Travail_de_session/InitialSchedules/ModelFullTimeEmployeesInitialSchedules.java index a8ba9f9..e0ad052 100644 --- a/Travail_de_session/InitialSchedules/ModelFullTimeEmployeesInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ModelFullTimeEmployeesInitialSchedules.java @@ -16,7 +16,6 @@ import org.chocosolver.solver.variables.IntVar; public class ModelFullTimeEmployeesInitialSchedules { public ParametersInitialSchedules myScheduleParameters; -// public int maxFullTimeEmployee; public int numberOfFullTimeEmployees; public BoolVar workPeriodsSchedulesOfFullTimeEmployees[][]; @@ -32,19 +31,11 @@ public class ModelFullTimeEmployeesInitialSchedules { this.chocoModelInitialSchedules = new Model("Model Full Time Employees Initial Schedules"); this.numberOfFullTimeEmployees = numberOfFullTimeEmployees; - this.createEmployeesVariables(); this.createScheduleVariables(); this.createModelConstraints(); } - private void createEmployeesVariables() { - -// this.maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule() -// / myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule()); - - } - private void createScheduleVariables() { // Variable pour l'horaire des employes diff --git a/Travail_de_session/InitialSchedules/ModelInitialSchedules.java b/Travail_de_session/InitialSchedules/ModelInitialSchedules.java deleted file mode 100644 index a808835..0000000 --- a/Travail_de_session/InitialSchedules/ModelInitialSchedules.java +++ /dev/null @@ -1,255 +0,0 @@ -package InitialSchedules; - -import org.chocosolver.solver.Model; -import org.chocosolver.solver.variables.BoolVar; -import org.chocosolver.solver.variables.IntVar; - -public class ModelInitialSchedules { - - // 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; -// private final String COHERENCE_BORNES = "BC"; -// private final String COHERENCE_DOMAINES = "AC"; -// private final int RESTART_AUCUN = 0; -// private final int RESTART_LUBY = 1; -// private final int RESTART_GEOMETRIQUE = 2; - public ParametersInitialSchedules myScheduleParameters; - - public int maxPartTimeEmployee; - public int maxFullTimeEmployee; - - public BoolVar workPeriodsSchedulesOfPartTimeEmployees[][]; - private BoolVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][]; - public BoolVar workPeriodsSchedulesOfFullTimeEmployees[][]; - private BoolVar transposeWorkPeriodsSchedulesOfFullTimeEmployees[][]; - - private BoolVar allWorkPeriods[]; - - private IntVar partTimeEmployeesPerWorkPeriods[]; - private IntVar fullTimeEmployeesPerWorkPeriods[]; - - public Model chocoModelInitialSchedules; - public IntVar totalEmployeesCost; - - public ModelInitialSchedules(ParametersInitialSchedules myScheduleParameters) { - - this.myScheduleParameters = myScheduleParameters; - - this.chocoModelInitialSchedules = new Model("Model Initial Schedules"); - - this.createEmployeesVariables(); - this.createScheduleVariables(); - - this.createModelConstraints(); - - this.createModelObjectiveFunction(); - - } - - private void createEmployeesVariables() { - - this.maxPartTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule() - / myScheduleParameters.getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule()); - this.maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule() - / myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule()); - - } - - private void createScheduleVariables() { - - // Variable pour l'horaire des employes - this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxFullTimeEmployee, this.myScheduleParameters.getWorkPeriodsPerSchedule()); - this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.getWorkPeriodsPerSchedule()); - - // Vecteur de toutes les variables - /*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++){ - this.allWorkPeriods[employee*this.myScheduleParameters.workPeriodsPerSchedule+workPeriod] = - this.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]; - } - } - for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) { - for(int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++){ - this.allWorkPeriods[this.maxPartTimeEmployee*this.myScheduleParameters.workPeriodsPerSchedule+ - employee*this.myScheduleParameters.workPeriodsPerSchedule+workPeriod] = - this.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]; - } - }*/ - - // Creer la transpose des horaires pour compter les elements des colonnes - this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.maxPartTimeEmployee); - for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) { - for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { - this.transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod][employee] - = this.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]; - } - } - this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.maxFullTimeEmployee); - for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) { - for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) { - this.transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod][employee] - = this.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]; - } - } - - // Variable pour faire le compte du nombre d'employes par periode de travail - this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.maxPartTimeEmployee, true); - this.fullTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.maxFullTimeEmployee, true); - - } - - private void createModelConstraints() { - - // Constraintes tableau pour choisir un type d'horaire dans les horaires possibles - for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) { - chocoModelInitialSchedules.table(this.workPeriodsSchedulesOfFullTimeEmployees[employee], - this.myScheduleParameters.enumerationWorkPeriodsSchedulesOfFullTimeEmployees).post(); - } - for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { - chocoModelInitialSchedules.table(this.workPeriodsSchedulesOfPartTimeEmployees[employee], - this.myScheduleParameters.enumerationWorkPeriodsSchedulesOfPartTimeEmployees).post(); - } - - // 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.getWorkPeriodsPerSchedule(); workPeriod++) { - chocoModelInitialSchedules.count(chocoModelInitialSchedules.intVar(1), - transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod], - this.partTimeEmployeesPerWorkPeriods[workPeriod]).post(); - chocoModelInitialSchedules.count(chocoModelInitialSchedules.intVar(1), - transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod], - this.fullTimeEmployeesPerWorkPeriods[workPeriod]).post(); - chocoModelInitialSchedules.arithm(this.partTimeEmployeesPerWorkPeriods[workPeriod], "+", - this.fullTimeEmployeesPerWorkPeriods[workPeriod], "=", - this.myScheduleParameters.requiredWorkforce[workPeriod]).post(); - } - - // 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.maxPartTimeEmployee-1); employee++){ -// chocoModelInitialSchedules.lexLessEq(this.workPeriodsSchedulesOfPartTimeEmployees[employee], -// this.workPeriodsSchedulesOfPartTimeEmployees[employee+1]).post(); -// } - for (int employee = 0; employee < (this.maxFullTimeEmployee-1); employee++){ - chocoModelInitialSchedules.lexLessEq(this.workPeriodsSchedulesOfFullTimeEmployees[employee], - this.workPeriodsSchedulesOfFullTimeEmployees[employee+1]).post(); - } - - } - - private void createModelObjectiveFunction() { - - // Nombre total de périodes travaillées - IntVar numberOfPartTimeEmployeesWorkingPeriods = - chocoModelInitialSchedules.intVar( - 0, this.maxPartTimeEmployee * this.myScheduleParameters.getWorkPeriodsPerSchedule(), true); - IntVar numberOfFullTimeEmployeesWorkingPeriods = - chocoModelInitialSchedules.intVar( - 0, this.maxPartTimeEmployee * this.myScheduleParameters.getWorkPeriodsPerSchedule(), true); - - chocoModelInitialSchedules.sum(this.partTimeEmployeesPerWorkPeriods, "=", numberOfPartTimeEmployeesWorkingPeriods).post(); - chocoModelInitialSchedules.sum(this.fullTimeEmployeesPerWorkPeriods, "=", numberOfFullTimeEmployeesWorkingPeriods).post(); - - // Calcul du salaire versé - IntVar partTimeEmployeesSalary = - chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee * - this.myScheduleParameters.getWorkPeriodsPerSchedule() * - this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate(), true); - - IntVar fullTimeEmployeesSalary = - chocoModelInitialSchedules.intVar(0, this.maxFullTimeEmployee * - this.myScheduleParameters.getWorkPeriodsPerSchedule() * - this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate(), true); - - IntVar workingPeriodCostOfPartTimeEmployees = - chocoModelInitialSchedules.intVar(this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate()); - IntVar workingPeriodCostOfFullTimeEmployees = - chocoModelInitialSchedules.intVar(this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate()); - - chocoModelInitialSchedules.arithm(numberOfPartTimeEmployeesWorkingPeriods, "*", workingPeriodCostOfPartTimeEmployees, "=", partTimeEmployeesSalary).post(); - chocoModelInitialSchedules.arithm(numberOfFullTimeEmployeesWorkingPeriods, "*", workingPeriodCostOfFullTimeEmployees, "=", fullTimeEmployeesSalary).post(); - - // Compter le nombre d'heures travaillees par les differents employes pour determiner les employes actifs - IntVar[] workingPeriodsPerPartTimeEmployees = - chocoModelInitialSchedules.intVarArray(this.maxPartTimeEmployee,0,this.myScheduleParameters.getWorkPeriodsPerSchedule(), true); - BoolVar[] isWorkingPartTimeEmployees = - chocoModelInitialSchedules.boolVarArray(this.maxPartTimeEmployee); - for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { - chocoModelInitialSchedules.sum(workPeriodsSchedulesOfPartTimeEmployees[employee], - "=", workingPeriodsPerPartTimeEmployees[employee]).post(); - BoolVar isWorkingEmployee = chocoModelInitialSchedules.arithm( - workingPeriodsPerPartTimeEmployees[employee], ">", 0).reify(); - chocoModelInitialSchedules.ifThen(isWorkingEmployee, - chocoModelInitialSchedules.arithm(isWorkingPartTimeEmployees[employee], "=", chocoModelInitialSchedules.boolVar(true))); - } - IntVar workingPartTimeEmployees = chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee); - chocoModelInitialSchedules.sum(isWorkingPartTimeEmployees, "=", workingPartTimeEmployees).post(); - - IntVar[] workingPeriodsPerFullTimeEmployees = - chocoModelInitialSchedules.intVarArray(this.maxFullTimeEmployee,0,this.myScheduleParameters.getWorkPeriodsPerSchedule(), true); - BoolVar[] isWorkingFullTimeEmployees = - chocoModelInitialSchedules.boolVarArray(this.maxFullTimeEmployee); - for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) { - chocoModelInitialSchedules.sum(workPeriodsSchedulesOfFullTimeEmployees[employee], - "=", workingPeriodsPerFullTimeEmployees[employee]).post(); - BoolVar isWorkingEmployee = chocoModelInitialSchedules.arithm( - workingPeriodsPerFullTimeEmployees[employee], ">", 0).reify(); - chocoModelInitialSchedules.ifThen(isWorkingEmployee, - chocoModelInitialSchedules.arithm(isWorkingFullTimeEmployees[employee], "=", chocoModelInitialSchedules.boolVar(true))); - } - IntVar workingFullTimeEmployees = chocoModelInitialSchedules.intVar(0, this.maxFullTimeEmployee); - chocoModelInitialSchedules.sum(isWorkingFullTimeEmployees, "=", workingFullTimeEmployees).post(); - - // Calcul des couts fixes - IntVar partTimeEmployeesFixedCost = - chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee * - this.myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule(), true); - - IntVar fullTimeEmployeesFixedCost = - chocoModelInitialSchedules.intVar(0, this.maxFullTimeEmployee * - this.myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule(), true); - - chocoModelInitialSchedules.arithm(workingPartTimeEmployees, "*", chocoModelInitialSchedules.intVar(this.myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule()), - "=", partTimeEmployeesFixedCost).post(); - chocoModelInitialSchedules.arithm(workingPartTimeEmployees, "*", chocoModelInitialSchedules.intVar(this.myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule()), - "=", partTimeEmployeesFixedCost).post(); - - // Calcul des couts totaux - IntVar partTimeEmployeesCost = - chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee * - this.myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() + - this.maxPartTimeEmployee * - this.myScheduleParameters.getWorkPeriodsPerSchedule() * - this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate(), true); - - IntVar fullTimeEmployeesCost = - chocoModelInitialSchedules.intVar(0, this.maxFullTimeEmployee * - this.myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule() + - this.maxFullTimeEmployee * - this.myScheduleParameters.getWorkPeriodsPerSchedule() * - this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate(), true); - - chocoModelInitialSchedules.arithm(partTimeEmployeesFixedCost, "+", partTimeEmployeesSalary, "=", partTimeEmployeesCost).post(); - chocoModelInitialSchedules.arithm(fullTimeEmployeesFixedCost, "+", fullTimeEmployeesSalary, "=", fullTimeEmployeesCost).post(); - - this.totalEmployeesCost = chocoModelInitialSchedules.intVar(0, this.maxPartTimeEmployee * - this.myScheduleParameters.getFixedCostOfPartTimeEmployeesPerSchedule() + - this.maxPartTimeEmployee * - this.myScheduleParameters.getWorkPeriodsPerSchedule() * - this.myScheduleParameters.getWorkingPeriodCostOfPartTimeEmployeesPaidAtRegularHourlyRate() + - this.maxFullTimeEmployee * - this.myScheduleParameters.getFixedCostOfFullTimeEmployeesPerSchedule() + - this.maxFullTimeEmployee * - this.myScheduleParameters.getWorkPeriodsPerSchedule() * - this.myScheduleParameters.getWorkingPeriodCostOfFullTimeEmployeesPaidAtRegularHourlyRate(), true); - - chocoModelInitialSchedules.arithm(partTimeEmployeesCost, "+", fullTimeEmployeesCost, "=", this.totalEmployeesCost).post(); - - } - -} diff --git a/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java b/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java index 6cd7017..c1ead03 100644 --- a/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java +++ b/Travail_de_session/InitialSchedules/ModelPartTimeEmployeesInitialSchedules.java @@ -6,18 +6,9 @@ import org.chocosolver.solver.variables.IntVar; public class ModelPartTimeEmployeesInitialSchedules { - // 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; -// private final String COHERENCE_BORNES = "BC"; -// private final String COHERENCE_DOMAINES = "AC"; -// private final int RESTART_AUCUN = 0; -// private final int RESTART_LUBY = 1; -// private final int RESTART_GEOMETRIQUE = 2; public ParametersInitialSchedules myScheduleParameters; - public int maxPartTimeEmployee; + public int numberOfPartTimeEmployees; public BoolVar workPeriodsSchedulesOfPartTimeEmployees[][]; private BoolVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][]; @@ -26,48 +17,42 @@ public class ModelPartTimeEmployeesInitialSchedules { public Model chocoModelInitialSchedules; - public ModelPartTimeEmployeesInitialSchedules(ParametersInitialSchedules myScheduleParameters) { + public ModelPartTimeEmployeesInitialSchedules(ParametersInitialSchedules myScheduleParameters, int numberOfPartTimeEmployees) { this.myScheduleParameters = myScheduleParameters; - + this.chocoModelInitialSchedules = new Model("Model Part Time Employees Initial Schedules"); + + this.numberOfPartTimeEmployees = numberOfPartTimeEmployees; - this.createEmployeesVariables(); this.createScheduleVariables(); this.createModelConstraints(); } - private void createEmployeesVariables() { - - this.maxPartTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule() - / myScheduleParameters.getMinWorkingPeriodsOfPartTimeEmployeesPerSchedule()); - - } - private void createScheduleVariables() { // Variable pour l'horaire des employes - this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.getWorkPeriodsPerSchedule()); + this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.numberOfPartTimeEmployees, this.myScheduleParameters.getWorkPeriodsPerSchedule()); // Creer la transpose des horaires pour compter les elements des colonnes - this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.maxPartTimeEmployee); + this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.numberOfPartTimeEmployees); for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) { - for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { + for (int employee = 0; employee < this.numberOfPartTimeEmployees; 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.maxPartTimeEmployee, true); + this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.numberOfPartTimeEmployees, true); } private void createModelConstraints() { // Constraintes tableau pour choisir un type d'horaire dans les horaires possibles - for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) { + for (int employee = 0; employee < this.numberOfPartTimeEmployees; employee++) { chocoModelInitialSchedules.table(this.workPeriodsSchedulesOfPartTimeEmployees[employee], this.myScheduleParameters.enumerationWorkPeriodsSchedulesOfPartTimeEmployees).post(); } @@ -85,10 +70,18 @@ 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.maxPartTimeEmployee-1); employee++){ + for (int employee = 0; employee < (this.numberOfPartTimeEmployees-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/SolverInitialSchedules.java b/Travail_de_session/InitialSchedules/SolverInitialSchedules.java new file mode 100644 index 0000000..1ffa237 --- /dev/null +++ b/Travail_de_session/InitialSchedules/SolverInitialSchedules.java @@ -0,0 +1,61 @@ +/* + * 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 InitialSchedules; + +import java.util.List; +import org.chocosolver.solver.Solution; +import org.chocosolver.solver.Solver; +import org.chocosolver.solver.exception.ContradictionException; + +/** + * + * @author frabe + */ +public class SolverInitialSchedules { + + Solver solverInitialSchedules; + + public SolverInitialSchedules (ModelFullTimeEmployeesInitialSchedules myModelFullTimeEmployeesInitialSchedules){ + + this.solverInitialSchedules = myModelFullTimeEmployeesInitialSchedules.chocoModelInitialSchedules.getSolver(); + try { + solverInitialSchedules.propagate(); + } catch (ContradictionException e) { + System.err.println("Caught ContradictionException: " + e.getMessage()); + solverInitialSchedules.getEngine().flush(); + } catch (Exception e) { + System.err.println("Caught Exception: " + e.getMessage()); + } + solverInitialSchedules.setRestartOnSolutions(); + solverInitialSchedules.limitSolution(1); +// solverInitialSchedules.limitTime(10000); + + } + + public SolverInitialSchedules (ModelPartTimeEmployeesInitialSchedules myModelPartTimeEmployeesInitialSchedules){ + + this.solverInitialSchedules = myModelPartTimeEmployeesInitialSchedules.chocoModelInitialSchedules.getSolver(); + try { + solverInitialSchedules.propagate(); + } catch (ContradictionException e) { + System.err.println("Caught ContradictionException: " + e.getMessage()); + solverInitialSchedules.getEngine().flush(); + } catch (Exception e) { + System.err.println("Caught Exception: " + e.getMessage()); + } + solverInitialSchedules.setRestartOnSolutions(); + solverInitialSchedules.limitSolution(1); +// solverInitialSchedules.limitTime(100000); + + } + + public List findAllSolution() { + List myInitialSchedulesSolutions; + myInitialSchedulesSolutions = solverInitialSchedules.findAllSolutions(); + return myInitialSchedulesSolutions; + } + +} diff --git a/Travail_de_session/MainClass.java b/Travail_de_session/MainClass.java index a281543..cd2feec 100644 --- a/Travail_de_session/MainClass.java +++ b/Travail_de_session/MainClass.java @@ -1,7 +1,7 @@ //import AbsenceSchedules.AbsenceSchedulesArray; import AbsenceSchedules.*; -import InitialSchedules.ModelPartTimeEmployeesInitialSchedules; +import InitialSchedules.*; import ScheduleUtil.*; import SchedulesRecovery.*; import jdistlib.rng.MersenneTwister; @@ -39,76 +39,56 @@ public class MainClass { // Cleaner ce code avec des sous-foncitons. Creer une classe Solver. List initialSchedulesArrayList = new ArrayList<>(); - InitialSchedules.ParametersInitialSchedules myScheduleParameters - = new InitialSchedules.ParametersInitialSchedules(); + InitialSchedules.ParametersInitialSchedules myScheduleParameters = new InitialSchedules.ParametersInitialSchedules(); + + int minFullTimeEmployee = 1; int maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule() - / myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule()); + / myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule()); int simulationNumber = 1; - for (int numberFullTimeEmployees = 4 ; numberFullTimeEmployees <= maxFullTimeEmployee ; numberFullTimeEmployees++) { + for (int numberFullTimeEmployees = minFullTimeEmployee ; numberFullTimeEmployees <= maxFullTimeEmployee ; numberFullTimeEmployees++) { System.out.println("numberFullTimeEmployees: " + numberFullTimeEmployees); InitialSchedules.ModelFullTimeEmployeesInitialSchedules myModelFullTimeEmployeesInitialSchedules = new InitialSchedules.ModelFullTimeEmployeesInitialSchedules(myScheduleParameters, numberFullTimeEmployees); - Solver solverFullTimeEmployeesInitialSchedules = myModelFullTimeEmployeesInitialSchedules.chocoModelInitialSchedules.getSolver(); - - try { - solverFullTimeEmployeesInitialSchedules.propagate(); - } catch (ContradictionException e) { - System.err.println("Caught ContradictionException: " + e.getMessage()); - solverFullTimeEmployeesInitialSchedules.getEngine().flush(); - } catch (Exception e) { - System.err.println("Caught Exception: " + e.getMessage()); - } - solverFullTimeEmployeesInitialSchedules.setRestartOnSolutions(); - solverFullTimeEmployeesInitialSchedules.limitSolution(5); -// solverFullTimeEmployeesInitialSchedules.limitTime(10000); -// solverFullTimeEmployeesInitialSchedules.showDashboard(); - List myInitialFullTimeEmployeesSchedulesSolutions; - myInitialFullTimeEmployeesSchedulesSolutions = solverFullTimeEmployeesInitialSchedules.findAllSolutions(); -// solverFullTimeEmployeesInitialSchedules.printStatistics(); + SolverInitialSchedules mySolverFullTimeEmployeesInitialSchedules = new SolverInitialSchedules(myModelFullTimeEmployeesInitialSchedules); + List myInitialFullTimeEmployeesSchedulesSolutions = mySolverFullTimeEmployeesInitialSchedules.findAllSolution(); - System.out.println("numberFullTimeEmployeesScheduleFound: " + myInitialFullTimeEmployeesSchedulesSolutions.size()); + 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) { - FullTimeEmployeeScheduleArray fteisa = new FullTimeEmployeeScheduleArray(myModelFullTimeEmployeesInitialSchedules, CurrentFullTimeEmployeesSolution); + FullTimeEmployeeScheduleArray fullTimeSchedulesArray = new FullTimeEmployeeScheduleArray(myModelFullTimeEmployeesInitialSchedules, CurrentFullTimeEmployeesSolution); - InitialSchedules.ParametersInitialSchedules myPartTimeScheduleParameters - = new InitialSchedules.ParametersInitialSchedules(); - myPartTimeScheduleParameters.adjustRequiredWorkforce(fteisa); + InitialSchedules.ParametersInitialSchedules myPartTimeScheduleParameters = new InitialSchedules.ParametersInitialSchedules(); + myPartTimeScheduleParameters.adjustRequiredWorkforce(fullTimeSchedulesArray); - // Faire varier le nombre de PartTimeEmployees de la même façon que pour les fullTimeEmployees. On pourra ainsi avoir des horaires differents. - InitialSchedules.ModelPartTimeEmployeesInitialSchedules myModelPartTimeEmployeesInitialSchedules - = new InitialSchedules.ModelPartTimeEmployeesInitialSchedules(myPartTimeScheduleParameters); + 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); - Solver solverPartTimeEmployeesInitialSchedules = myModelPartTimeEmployeesInitialSchedules.chocoModelInitialSchedules.getSolver(); - - try { - solverPartTimeEmployeesInitialSchedules.propagate(); - } catch (ContradictionException e) { - System.err.println("Caught ContradictionException: " + e.getMessage()); - solverPartTimeEmployeesInitialSchedules.getEngine().flush(); - } catch (Exception e) { - System.err.println("Caught Exception: " + e.getMessage()); - } - solverPartTimeEmployeesInitialSchedules.setRestartOnSolutions(); - solverPartTimeEmployeesInitialSchedules.limitSolution(1); -// solverPartTimeEmployeesInitialSchedules.showDashboard(); - List myInitialPartTimeEmployeesSchedulesSolutions; - myInitialPartTimeEmployeesSchedulesSolutions = solverPartTimeEmployeesInitialSchedules.findAllSolutions(); -// solverPartTimeEmployeesInitialSchedules.printStatistics(); - System.out.println("numberScheduleFound: " + myInitialPartTimeEmployeesSchedulesSolutions.size()); - for (Solution CurrentPartTimeEmployeesSolution : myInitialPartTimeEmployeesSchedulesSolutions) { - PartTimeEmployeeScheduleArray pteisa = new PartTimeEmployeeScheduleArray(myModelPartTimeEmployeesInitialSchedules, CurrentPartTimeEmployeesSolution); - SchedulesArray isa = new SchedulesArray(fteisa, pteisa, simulationNumber); - initialSchedulesArrayList.add(isa); - System.out.println("simulationNumber: " + simulationNumber); - simulationNumber++; + 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++; + } } } @@ -123,58 +103,6 @@ public class MainClass { } -// private static List generateInitialSchedules() { -// -// List initialSchedulesArrayList = new ArrayList<>(); -// -// InitialSchedules.ParametersInitialSchedules myScheduleParameters -// = new InitialSchedules.ParametersInitialSchedules(); -// -// InitialSchedules.ModelInitialSchedules myModelInitialSchedules -// = new InitialSchedules.ModelInitialSchedules(myScheduleParameters); -// -// Solver solverInitialSchedules = myModelInitialSchedules.chocoModelInitialSchedules.getSolver(); -// -// try { -// solverInitialSchedules.propagate(); -// } catch (ContradictionException e) { -// System.err.println("Caught ContradictionException: " + e.getMessage()); -// solverInitialSchedules.getEngine().flush(); -// } catch (Exception e) { -// System.err.println("Caught Exception: " + e.getMessage()); -// } -// -// -// -// solverInitialSchedules.showDashboard(); -// -// /*solverInitialSchedules.setSearch(Search.domOverWDegSearch(myModelInitialSchedules.allWorkPeriods));*/ -//// solverInitialSchedules.setRestartOnSolutions(); /*Sans restart, toutes les horaires sont identiques*/ -// solverInitialSchedules.limitSolution(5); -// //solverInitialSchedules.limitTime(10000); -// List myInitialSchedulesSolutions; -//// myInitialSchedulesSolutions = solverInitialSchedules.findAllOptimalSolutions -//// (myModelInitialSchedules.totalEmployeesCost, myModelInitialSchedules.chocoModelInitialSchedules.MINIMIZE); -// -//// solverInitialSchedules.findSolution(); -// myInitialSchedulesSolutions = solverInitialSchedules.findAllSolutions(); -// solverInitialSchedules.printStatistics(); -// -// // Création de l'objet banque d'horaire, qui est une liste d'objets de type InitialSchedulesArray, qui contiennent chacun deux tableaux. -// int simulationNumber = 1; -// for (Solution CurrentSolution : myInitialSchedulesSolutions) { -// SchedulesArray isa = new SchedulesArray(myModelInitialSchedules, CurrentSolution, simulationNumber); -// initialSchedulesArrayList.add(isa); -// simulationNumber++; -// } -// -// // Pour afficher les horaires initiales -// SchedulesWindows.ShowSchedulesFrame intialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules"); // to be removed -// -// return initialSchedulesArrayList; -// -// } - private static List GenerateAbsencesSchedules(List initialSchedulesArrayList) { RandomEngine r = new MersenneTwister(123456789); diff --git a/Travail_de_session/ScheduleUtil/PartTimeEmployeeScheduleArray.java b/Travail_de_session/ScheduleUtil/PartTimeEmployeeScheduleArray.java index fd5f4e7..3bff6c2 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.maxPartTimeEmployee; i++) { + for (int i = 0; i < m.numberOfPartTimeEmployees; 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.maxPartTimeEmployee; employee++) { + for (int employee = 0; employee < m.numberOfPartTimeEmployees; employee++) { if (isPartTimeEmployeeActive (employee, s, m)) { numberPartTimeEmployee++; } diff --git a/Travail_de_session/ScheduleUtil/SchedulesArray.java b/Travail_de_session/ScheduleUtil/SchedulesArray.java index 5fb6fa0..6135017 100644 --- a/Travail_de_session/ScheduleUtil/SchedulesArray.java +++ b/Travail_de_session/ScheduleUtil/SchedulesArray.java @@ -40,81 +40,6 @@ public class SchedulesArray { this.totalScheduleCost = EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules); } - public SchedulesArray(ModelInitialSchedules m, Solution s, int scheduleNumber) { - this.initialScheduleSolutionNumber = scheduleNumber; - this.myParametersInitialSchedules = m.myScheduleParameters; - Solution mySolution = s; - - this.partTimeSchedules = new boolean[getNumberOfPartTimeEmployees(s, m)][myParametersInitialSchedules.getWorkPeriodsPerSchedule()]; - this.fullTimeSchedules = new boolean[getNumberOfFullTimeEmployees(s, m)][myParametersInitialSchedules.getWorkPeriodsPerSchedule()]; - - int partTimeEmployee = 0; - 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; - } - partTimeEmployee++; - } - } - - int fullTimeEmployee = 0; - for (int i = 0; i < m.maxFullTimeEmployee; i++) { - if (isFullTimeEmployeeActive (i, s, m)) { - for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) { - this.fullTimeSchedules[fullTimeEmployee][workPeriod] = mySolution.getIntVal(m.workPeriodsSchedulesOfFullTimeEmployees[i][workPeriod]) == 1; - } - fullTimeEmployee++; - } - } - - this.totalScheduleCost = EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules); - assert(this.totalScheduleCost == s.getIntVal(m.totalEmployeesCost)); - - } - - private int getNumberOfPartTimeEmployees( Solution s, ModelInitialSchedules m ) { - int numberPartTimeEmployee = 0; - for (int employee = 0; employee < m.maxPartTimeEmployee; employee++) { - if (isPartTimeEmployeeActive (employee, s, m)) { - numberPartTimeEmployee++; - } - } - return numberPartTimeEmployee; - } - - private int getNumberOfFullTimeEmployees( Solution s, ModelInitialSchedules m ) { - int numberFullTimeEmployee = 0; - for (int employee = 0; employee < m.maxFullTimeEmployee; employee++) { - if (isFullTimeEmployeeActive (employee, s, m)) { - numberFullTimeEmployee++; - } - } - return numberFullTimeEmployee; - } - - private boolean isPartTimeEmployeeActive ( int employee, Solution s, ModelInitialSchedules m ) { - int workPeriod = 0; - while (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) { - if (s.getIntVal(m.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]) == 1){ - return true; - } - workPeriod++; - } - return false; - } - - private boolean isFullTimeEmployeeActive ( int employee, Solution s, ModelInitialSchedules m ) { - int workPeriod = 0; - while (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) { - if (s.getIntVal(m.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]) == 1){ - return true; - } - workPeriod++; - } - return false; - } - protected boolean[][] getDeepCopyEmployeesSchedules(boolean[][] schedules) { boolean[][] copySchedules = new boolean[schedules.length][myParametersInitialSchedules.getWorkPeriodsPerSchedule()]; for (int workPeriod = 0; workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule(); workPeriod++) {