quelques améliorations, ajout de fonction de bris de symétrie et vecteur de toutes les variables pour utiliser avec les appels d'heuristiques de recherche

This commit is contained in:
François Pelletier 2018-03-24 01:06:01 -04:00
parent 94369ddcee
commit 76c125998f
10 changed files with 551 additions and 21 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
choco-4.0.6
/tp/code/TP/Travail_de_session/nbproject/private/

View file

@ -0,0 +1,152 @@
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;
private ParametersInitialSchedules myScheduleParameters;
public int maxPartTimeEmployee;
public int maxFullTimeEmployee;
public IntVar workPeriodsSchedulesOfPartTimeEmployees[][];
private IntVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][];
public IntVar workPeriodsSchedulesOfFullTimeEmployees[][];
private IntVar transposeWorkPeriodsSchedulesOfFullTimeEmployees[][];
public IntVar workingPeriodsPerPartTimeEmployees[];
public IntVar partTimeEmployeesPerWorkPeriods[];
public IntVar workingPeriodsPerFullTimeEmployees[];
public IntVar fullTimeEmployeesPerWorkPeriods[];
public IntVar employeesPerWorkPeriods[];
public Model chocoModelInitialSchedules;
public IntVar scheduleProfit;
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.totalWorkedPeriodsInSchedule
/ myScheduleParameters.minWorkingPeriodsOfPartTimeEmployeesPerSchedule);
this.maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.totalWorkedPeriodsInSchedule
/ myScheduleParameters.workingPeriodsOfFullTimeEmployeesPerSchedule);
}
private void createScheduleVariables() {
// Variable pour l'horaire des employes
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule, 0, 1);
this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.maxFullTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule, 0, 1);
// Variable pour faire le compte du nombre d'heures des employes
this.workingPeriodsPerPartTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxPartTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true);
this.workingPeriodsPerFullTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxFullTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true);
// Creer la transpose des horaires pour compter les elements des colonnes
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxPartTimeEmployee, 0, 1);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod][employee]
= this.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod];
}
}
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxFullTimeEmployee, 0, 1);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; 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.workPeriodsPerSchedule, 0, this.maxPartTimeEmployee, true);
this.fullTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule, 0, this.maxFullTimeEmployee, true);
this.employeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.workPeriodsPerSchedule,
0, this.maxPartTimeEmployee + this.maxFullTimeEmployee, true);
}
private void createModelConstraints() {
// Constrainte 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();
}
// Constraintes pour compter le nombre d'heures travaillees par les differents employes
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
chocoModelInitialSchedules.count(chocoModelInitialSchedules.intVar(1),
this.workPeriodsSchedulesOfPartTimeEmployees[employee],
this.workingPeriodsPerPartTimeEmployees[employee]).post();
}
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
chocoModelInitialSchedules.count(chocoModelInitialSchedules.intVar(1),
this.workPeriodsSchedulesOfFullTimeEmployees[employee],
this.workingPeriodsPerFullTimeEmployees[employee]).post();
}
// Constraintes pour borner le nombre d'heures travaillees par les employes a temps partiel
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
BoolVar isWorkingEmployee = chocoModelInitialSchedules.arithm(
this.workingPeriodsPerPartTimeEmployees[employee], ">", 0).reify();
chocoModelInitialSchedules.ifThen(isWorkingEmployee,
chocoModelInitialSchedules.arithm(
this.workingPeriodsPerPartTimeEmployees[employee], ">=",
this.myScheduleParameters.minWorkingPeriodsOfPartTimeEmployeesPerSchedule));
chocoModelInitialSchedules.arithm(this.workingPeriodsPerPartTimeEmployees[employee], "<=",
this.myScheduleParameters.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule).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.workPeriodsPerSchedule; 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();
chocoModelInitialSchedules.arithm(this.partTimeEmployeesPerWorkPeriods[workPeriod], "+",
this.fullTimeEmployeesPerWorkPeriods[workPeriod], "=",
this.employeesPerWorkPeriods[workPeriod]).post();
}
}
private void createModelObjectiveFunction() {
// this.scheduleProfit = chocoModelInitialSchedules.intVar("TOTAL_COST", 0, 20 * N * p, true);
// chocoModelInitialSchedules.scalar(perte , coeffs , "=", this.scheduleProfit).post();
}
}

View file

@ -0,0 +1,211 @@
package InitialSchedules;
import org.chocosolver.solver.constraints.extension.Tuples;
public class ParametersInitialSchedules {
int workPeriodsPerDay;
int shiftWorkPerDay;
int daysPerSchedule;
int workPeriodsPerSchedule;
int totalWorkedPeriodsInSchedule;
double hoursPerWorkPeriod;
double fixedCostOfPartTimeEmployeesPerSchedule;
double hourlyRateOfPartTimeEmployees;
double minWorkingHoursOfPartTimeEmployeesPerSchedule;
double maxWorkingHoursOfPartTimeEmployeesPerSchedule;
int minWorkingPeriodsOfPartTimeEmployeesPerSchedule;
int maxWorkingPeriodsOfPartTimeEmployeesPerSchedule;
double fixedCostOfFullTimeEmployeesPerSchedule;
double regularHourlyRateOfFullTimeEmployees;
double overtimeHourlyRateOfFullTimeEmployees;
double workingHoursOfFullTimeEmployeesPerSchedule;
double maxWorkingHoursOfFullTimeEmployeesPerSchedule;
int workingPeriodsOfFullTimeEmployeesPerSchedule;
int maxWorkingPeriodsOfFullTimeEmployeesPerSchedule;
double workingHoursPaidAtRegularHourlyRatePerSchedule;
public int[] requiredWorkforce;
Tuples enumerationWorkPeriodsSchedulesOfFullTimeEmployees;
public ParametersInitialSchedules() {
this.setGeneralParameters();
this.setPartTimeEmployeesParameters();
this.setFullTimeEmployeesParameters();
this.setRequiredWorkforce();
this.setWorkPeriodsSchedulesOfFullTimeEmployees();
}
private void setGeneralParameters() {
this.workPeriodsPerDay = 6;
this.shiftWorkPerDay = 3;
this.daysPerSchedule = 14;
this.hoursPerWorkPeriod = 4;
this.workPeriodsPerSchedule = this.workPeriodsPerDay * this.daysPerSchedule;
}
private void setPartTimeEmployeesParameters() {
this.fixedCostOfPartTimeEmployeesPerSchedule = 50;
this.hourlyRateOfPartTimeEmployees = 12; // To simulate lower productivity
this.minWorkingHoursOfPartTimeEmployeesPerSchedule = 32;
this.maxWorkingHoursOfPartTimeEmployeesPerSchedule = 64;
this.minWorkingPeriodsOfPartTimeEmployeesPerSchedule
= (int) (this.minWorkingHoursOfPartTimeEmployeesPerSchedule / this.hoursPerWorkPeriod);
this.maxWorkingPeriodsOfPartTimeEmployeesPerSchedule
= (int) (this.maxWorkingHoursOfPartTimeEmployeesPerSchedule / this.hoursPerWorkPeriod);
}
private void setFullTimeEmployeesParameters() {
this.fixedCostOfFullTimeEmployeesPerSchedule = 50;
this.regularHourlyRateOfFullTimeEmployees = 10;
this.overtimeHourlyRateOfFullTimeEmployees = 15;
this.workingHoursOfFullTimeEmployeesPerSchedule = 80;
this.maxWorkingHoursOfFullTimeEmployeesPerSchedule = 120;
this.workingPeriodsOfFullTimeEmployeesPerSchedule
= (int) (this.workingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod);
this.maxWorkingPeriodsOfFullTimeEmployeesPerSchedule
= (int) (this.maxWorkingHoursOfFullTimeEmployeesPerSchedule / this.hoursPerWorkPeriod);
this.workingHoursPaidAtRegularHourlyRatePerSchedule = 80;
}
private void setRequiredWorkforce() {
this.requiredWorkforce = new int[this.daysPerSchedule * this.workPeriodsPerDay];
this.totalWorkedPeriodsInSchedule = 0;
for (int day = 0; day < this.daysPerSchedule; day++) {
// A ameliorer
this.requiredWorkforce[day * this.workPeriodsPerDay + 0] = 2;
this.requiredWorkforce[day * this.workPeriodsPerDay + 1] = 2;
this.requiredWorkforce[day * this.workPeriodsPerDay + 2] = 4;
this.requiredWorkforce[day * this.workPeriodsPerDay + 3] = 4;
this.requiredWorkforce[day * this.workPeriodsPerDay + 4] = 3;
this.requiredWorkforce[day * this.workPeriodsPerDay + 5] = 3;
this.totalWorkedPeriodsInSchedule += (2 * 2 + 2 * 4 + 2 * 3);
}
}
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},};
int possibleDailyScheduleOfFullTimeEmployees = dailySchedulesOfFullTimeEmployees.length;
int[][] workPeriodsSchedulesOfFullTimeEmployees
= new int[possibleDailyScheduleOfFullTimeEmployees * 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 day = 0; day < this.daysPerSchedule; day++) {
for (int shiftNumber = 0; shiftNumber < this.shiftWorkPerDay; shiftNumber++) {
if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 0) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
} else if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 1) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
} else if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 1 && shiftNumber == 2) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 1;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 1;
} else if (dailySchedulesOfFullTimeEmployees[scheduleNumber][day] == 0) {
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 0] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 1] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 2] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 3] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 4] = 0;
workPeriodsSchedulesOfFullTimeEmployees[scheduleNumber * this.shiftWorkPerDay + shiftNumber][day * this.workPeriodsPerDay + 5] = 0;
}
}
}
}
// Creation des tuples a partir du tableau pour creer les 3 types de quart de travail (nuit, jour soir).
this.enumerationWorkPeriodsSchedulesOfFullTimeEmployees
= new Tuples(workPeriodsSchedulesOfFullTimeEmployees, true);
}
// A implementer plus tard si l'on veut travailler avec des fichiers texte
public ParametersInitialSchedules(String fileName) {
// String line = null;
// try {
// FileReader fileReader =
// new FileReader(fileName);
//
// BufferedReader bufferedReader =
// new BufferedReader(fileReader);
//
// if((line = bufferedReader.readLine()) != null) {
// String[] arrayLine= line.split("\\s+");
// PARAMETRES_HORAIRE[0] = Integer.parseInt(arrayLine[0]);
// PARAMETRES_HORAIRE[1] = Integer.parseInt(arrayLine[1]);
// PARAMETRES_HORAIRE[2] = Integer.parseInt(arrayLine[2]);
// PARAMETRES_HORAIRE[3] = Integer.parseInt(arrayLine[3]);
// }
// if((line = bufferedReader.readLine()) != null) {
// String[] arrayLine= line.split("\\s+");
// for (int i = 0 ; i < p ; i++) {
// NBR_EMPLOYES_REQUIS[i] = Integer.parseInt(arrayLine[i]);
// }
// }
// if((line = bufferedReader.readLine()) != null) {
// String[] arrayLine= line.split("\\s+");
// for (int i = 0 ; i < p ; i++) {
// NBR_EMPLOYES_SOUHAITES[i] = Integer.parseInt(arrayLine[i]);
// }
// }
// bufferedReader.close();
// }
// catch(FileNotFoundException ex) {
// System.out.println(
// "Unable to open file '" +
// fileName + "'");
// }
// catch(IOException ex) {
// System.out.println(
// "Error reading file '"
// + fileName + "'");
// }
}
}

View file

@ -0,0 +1,97 @@
package InitialSchedules;
// classe statique pour mettre fonction utilitaire
public class UtilInitialSchedules {
private UtilInitialSchedules() {
}
public static void refineInitialSchedules() {
// A implementer si on veut rafiner la banque d'horaires initiales
}
public static void printSolutionResults(ModelInitialSchedules myModelInitialSchedules, ParametersInitialSchedules myScheduleParameters) {
// Cette fonction sera a ameliorer avec des sous-fonctions, car elle n'est pas tres explicite.
System.out.print("Schedule Day ");
for (int day = 1; day <= myScheduleParameters.daysPerSchedule; day++) {
System.out.print(day);
System.out.print(" ");
if (day < 10) {
System.out.print(" ");
}
System.out.print("|");
}
System.out.print("Worked Periods");
System.out.println("");
System.out.println("Part-Time Employees");
int partTimeemployeeNo = 1;
for (int employee = 0; employee < myModelInitialSchedules.maxPartTimeEmployee; employee++) {
if (myModelInitialSchedules.workingPeriodsPerPartTimeEmployees[employee].getValue() != 0) {
System.out.print("Employee ");
System.out.print(partTimeemployeeNo);
System.out.print(" ");
if (partTimeemployeeNo < 10) {
System.out.print(" ");
}
for (int workPeriod = 0; workPeriod < myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
if (myModelInitialSchedules.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod].getValue() == 1) {
System.out.print("1");
} else {
System.out.print("0");
}
if (workPeriod % 6 == 5 && workPeriod != 0) {
System.out.print("|");
}
}
System.out.print(myModelInitialSchedules.workingPeriodsPerPartTimeEmployees[employee].getValue());
System.out.println("");
partTimeemployeeNo++;
}
}
int fullTimeemployeeNo = 1;
System.out.println("Full-Time Employees");
for (int employee = 0; employee < myModelInitialSchedules.maxFullTimeEmployee; employee++) {
if (myModelInitialSchedules.workingPeriodsPerFullTimeEmployees[employee].getValue() != 0) {
System.out.print("Employee ");
System.out.print(fullTimeemployeeNo);
System.out.print(" ");
if (fullTimeemployeeNo < 10) {
System.out.print(" ");
}
for (int workPeriod = 0; workPeriod < myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
if (myModelInitialSchedules.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod].getValue() == 1) {
System.out.print("1");
} else {
System.out.print("0");
}
if (workPeriod % 6 == 5 && workPeriod != 0) {
System.out.print("|");
}
}
System.out.print(myModelInitialSchedules.workingPeriodsPerFullTimeEmployees[employee].getValue());
System.out.println("");
fullTimeemployeeNo++;
}
}
System.out.print("Working Employees ");
for (int workPeriod = 0; workPeriod < myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
System.out.print(myModelInitialSchedules.employeesPerWorkPeriods[workPeriod].getValue());
if (workPeriod % 6 == 5 && workPeriod != 0) {
System.out.print("|");
}
}
System.out.println("");
System.out.print("Required Workforce ");
for (int workPeriod = 0; workPeriod < myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
System.out.print(myScheduleParameters.requiredWorkforce[workPeriod]);
if (workPeriod % 6 == 5 && workPeriod != 0) {
System.out.print("|");
}
}
System.out.println("");
}
}

View file

@ -0,0 +1,37 @@
import org.chocosolver.solver.Solver;
public class MainClass {
public static void main(String[] args) {
// Le main ne devrait contenir que les 5 fonctions correspondantes aux etapes du pipeline
generateInitialSchedule();
// Creer les simulation avec une autre classe. Faire un nouveau package de fonctions.
// Algo de recouvrement d'absences. Faire un nouveau package de fonctions.
// Trouver meilleure solution et l'afficher.
}
private static void generateInitialSchedule() {
InitialSchedules.ParametersInitialSchedules myScheduleParameters
= new InitialSchedules.ParametersInitialSchedules();
InitialSchedules.ModelInitialSchedules myModelInitialSchedules
= new InitialSchedules.ModelInitialSchedules(myScheduleParameters);
Solver solverInitialSchedules = myModelInitialSchedules.chocoModelInitialSchedules.getSolver();
solverInitialSchedules.findSolution();
// Solution bestInitialSchedules = solverInitialSchedules.findOptimalSolution
// (myModelInitialSchedules.scheduleProfit, Model.MINIMIZE);
// fonction pour reduire le nombre d'horaire dans la banque d'horaire.
// InitialSchedules.UtilInitialSchedules.refineInitialSchedules(bestInitialSchedules);
// On pourrait creer un petit interface pour afficher les horaires optimales et les statistiques.
InitialSchedules.UtilInitialSchedules.printSolutionResults(myModelInitialSchedules, myScheduleParameters);
solverInitialSchedules.printStatistics();
//TODO Creer objet banque horaire
}
}

View file

@ -20,10 +20,12 @@ public class ModelInitialSchedules {
public int maxPartTimeEmployee;
public int maxFullTimeEmployee;
public IntVar workPeriodsSchedulesOfPartTimeEmployees[][];
private IntVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][];
public IntVar workPeriodsSchedulesOfFullTimeEmployees[][];
private IntVar transposeWorkPeriodsSchedulesOfFullTimeEmployees[][];
public BoolVar workPeriodsSchedulesOfPartTimeEmployees[][];
private BoolVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][];
public BoolVar workPeriodsSchedulesOfFullTimeEmployees[][];
private BoolVar transposeWorkPeriodsSchedulesOfFullTimeEmployees[][];
public BoolVar allWorkPeriods[];
public IntVar workingPeriodsPerPartTimeEmployees[];
public IntVar partTimeEmployeesPerWorkPeriods[];
@ -61,22 +63,39 @@ public class ModelInitialSchedules {
private void createScheduleVariables() {
// Variable pour l'horaire des employes
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule, 0, 1);
this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.maxFullTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule, 0, 1);
this.workPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.maxPartTimeEmployee, this.myScheduleParameters.workPeriodsPerSchedule);
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);
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];
}
}
// Variable pour faire le compte du nombre d'heures des employes
this.workingPeriodsPerPartTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxPartTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true);
this.workingPeriodsPerFullTimeEmployees = chocoModelInitialSchedules.intVarArray(this.maxFullTimeEmployee, 0, this.myScheduleParameters.workPeriodsPerSchedule, true);
// Creer la transpose des horaires pour compter les elements des colonnes
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxPartTimeEmployee, 0, 1);
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxPartTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
for (int employee = 0; employee < this.maxPartTimeEmployee; employee++) {
this.transposeWorkPeriodsSchedulesOfPartTimeEmployees[workPeriod][employee]
= this.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod];
}
}
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.intVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxFullTimeEmployee, 0, 1);
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.workPeriodsPerSchedule, this.maxFullTimeEmployee);
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.workPeriodsPerSchedule; workPeriod++) {
for (int employee = 0; employee < this.maxFullTimeEmployee; employee++) {
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod][employee]
@ -141,6 +160,20 @@ public class ModelInitialSchedules {
this.employeesPerWorkPeriods[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() {

View file

@ -79,17 +79,13 @@ public class ParametersInitialSchedules {
this.requiredWorkforce = new int[this.daysPerSchedule * this.workPeriodsPerDay];
this.totalWorkedPeriodsInSchedule = 0;
int[] dailyRequiredWorkforce = new int[]{4,4,5,5,3,3};
for (int day = 0; day < this.daysPerSchedule; day++) {
// A ameliorer
this.requiredWorkforce[day * this.workPeriodsPerDay + 0] = 2;
this.requiredWorkforce[day * this.workPeriodsPerDay + 1] = 2;
this.requiredWorkforce[day * this.workPeriodsPerDay + 2] = 4;
this.requiredWorkforce[day * this.workPeriodsPerDay + 3] = 4;
this.requiredWorkforce[day * this.workPeriodsPerDay + 4] = 3;
this.requiredWorkforce[day * this.workPeriodsPerDay + 5] = 3;
this.totalWorkedPeriodsInSchedule += (2 * 2 + 2 * 4 + 2 * 3);
for(int shift = 0; shift < this.workPeriodsPerDay; shift++) {
this.requiredWorkforce[day * this.workPeriodsPerDay + shift] = dailyRequiredWorkforce[shift];
this.totalWorkedPeriodsInSchedule += dailyRequiredWorkforce[shift];
}
}
}
private void setWorkPeriodsSchedulesOfFullTimeEmployees() {

View file

@ -26,7 +26,7 @@ public class UtilInitialSchedules {
System.out.println("Part-Time Employees");
int partTimeemployeeNo = 1;
for (int employee = 0; employee < myModelInitialSchedules.maxPartTimeEmployee; employee++) {
if (myModelInitialSchedules.workingPeriodsPerPartTimeEmployees[employee].getValue() != 0) {
if (myModelInitialSchedules.workingPeriodsPerPartTimeEmployees[employee].getValue() >= 0) {
System.out.print("Employee ");
System.out.print(partTimeemployeeNo);
System.out.print(" ");
@ -40,7 +40,7 @@ public class UtilInitialSchedules {
System.out.print("0");
}
if (workPeriod % 6 == 5 && workPeriod != 0) {
if (workPeriod % myScheduleParameters.workPeriodsPerDay == 5 && workPeriod != 0) {
System.out.print("|");
}
}
@ -52,7 +52,7 @@ public class UtilInitialSchedules {
int fullTimeemployeeNo = 1;
System.out.println("Full-Time Employees");
for (int employee = 0; employee < myModelInitialSchedules.maxFullTimeEmployee; employee++) {
if (myModelInitialSchedules.workingPeriodsPerFullTimeEmployees[employee].getValue() != 0) {
if (myModelInitialSchedules.workingPeriodsPerFullTimeEmployees[employee].getValue() >= 0) {
System.out.print("Employee ");
System.out.print(fullTimeemployeeNo);
System.out.print(" ");

View file

@ -1,5 +1,6 @@
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.search.strategy.Search;
public class MainClass {
@ -22,7 +23,9 @@ public class MainClass {
= new InitialSchedules.ModelInitialSchedules(myScheduleParameters);
Solver solverInitialSchedules = myModelInitialSchedules.chocoModelInitialSchedules.getSolver();
solverInitialSchedules.findSolution();
solverInitialSchedules.setSearch(Search.domOverWDegSearch(myModelInitialSchedules.allWorkPeriods));
solverInitialSchedules.limitSolution(10);
solverInitialSchedules.findAllSolutions();
// Solution bestInitialSchedules = solverInitialSchedules.findOptimalSolution
// (myModelInitialSchedules.scheduleProfit, Model.MINIMIZE);