Ajout de la variation du nombre d'employés à temps partiel dans le solveur pour la génération d'horaires différents.

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.
This commit is contained in:
Francois Berube\frabe 2018-04-08 22:05:34 -04:00
parent 8ffa49c578
commit e775aedf05
7 changed files with 115 additions and 472 deletions

View file

@ -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

View file

@ -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();
}
}

View file

@ -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();
}
}
}

View file

@ -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<Solution> findAllSolution() {
List<Solution> myInitialSchedulesSolutions;
myInitialSchedulesSolutions = solverInitialSchedules.findAllSolutions();
return myInitialSchedulesSolutions;
}
}

View file

@ -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<SchedulesArray> 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<Solution> myInitialFullTimeEmployeesSchedulesSolutions;
myInitialFullTimeEmployeesSchedulesSolutions = solverFullTimeEmployeesInitialSchedules.findAllSolutions();
// solverFullTimeEmployeesInitialSchedules.printStatistics();
SolverInitialSchedules mySolverFullTimeEmployeesInitialSchedules = new SolverInitialSchedules(myModelFullTimeEmployeesInitialSchedules);
List<Solution> 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<Solution> 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<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++;
}
}
}
@ -123,58 +103,6 @@ public class MainClass {
}
// private static List<SchedulesArray> generateInitialSchedules() {
//
// List<SchedulesArray> 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<Solution> 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<BankAbsenceSchedules> GenerateAbsencesSchedules(List<SchedulesArray> initialSchedulesArrayList) {
RandomEngine r = new MersenneTwister(123456789);

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.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++;
}

View file

@ -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++) {