Changement de stratégie du solveur en 2 phases. Fonctionne bien pour trouver des horaires différents.
This commit is contained in:
parent
04f26c69fc
commit
f618018f9a
9 changed files with 485 additions and 41 deletions
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* 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 org.chocosolver.solver.Model;
|
||||
import org.chocosolver.solver.variables.BoolVar;
|
||||
import org.chocosolver.solver.variables.IntVar;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author frabe
|
||||
*/
|
||||
public class ModelFullTimeEmployeesInitialSchedules {
|
||||
public ParametersInitialSchedules myScheduleParameters;
|
||||
|
||||
// public int maxFullTimeEmployee;
|
||||
public int numberOfFullTimeEmployees;
|
||||
|
||||
public BoolVar workPeriodsSchedulesOfFullTimeEmployees[][];
|
||||
private BoolVar transposeWorkPeriodsSchedulesOfFullTimeEmployees[][];
|
||||
|
||||
private IntVar fullTimeEmployeesPerWorkPeriods[];
|
||||
|
||||
public Model chocoModelInitialSchedules;
|
||||
|
||||
public ModelFullTimeEmployeesInitialSchedules(ParametersInitialSchedules myScheduleParameters, int numberOfFullTimeEmployees) {
|
||||
|
||||
this.myScheduleParameters = myScheduleParameters;
|
||||
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
|
||||
this.workPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.numberOfFullTimeEmployees, this.myScheduleParameters.getWorkPeriodsPerSchedule());
|
||||
|
||||
// Creer la transpose des horaires pour compter les elements des colonnes
|
||||
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees = chocoModelInitialSchedules.boolVarMatrix(this.myScheduleParameters.getWorkPeriodsPerSchedule(), this.numberOfFullTimeEmployees);
|
||||
for (int workPeriod = 0; workPeriod < this.myScheduleParameters.getWorkPeriodsPerSchedule(); workPeriod++) {
|
||||
for (int employee = 0; employee < this.numberOfFullTimeEmployees; employee++) {
|
||||
this.transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod][employee]
|
||||
= this.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod];
|
||||
}
|
||||
}
|
||||
|
||||
// Variable pour faire le compte du nombre d'employes par periode de travail
|
||||
this.fullTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.numberOfFullTimeEmployees, true);
|
||||
|
||||
}
|
||||
|
||||
private void createModelConstraints() {
|
||||
|
||||
// Constraintes tableau pour choisir un type d'horaire dans les horaires possibles
|
||||
for (int employee = 0; employee < this.numberOfFullTimeEmployees; employee++) {
|
||||
chocoModelInitialSchedules.table(this.workPeriodsSchedulesOfFullTimeEmployees[employee],
|
||||
this.myScheduleParameters.enumerationWorkPeriodsSchedulesOfFullTimeEmployees).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),
|
||||
transposeWorkPeriodsSchedulesOfFullTimeEmployees[workPeriod],
|
||||
this.fullTimeEmployeesPerWorkPeriods[workPeriod]).post();
|
||||
chocoModelInitialSchedules.arithm(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.numberOfFullTimeEmployees-1); employee++){
|
||||
chocoModelInitialSchedules.lexLessEq(this.workPeriodsSchedulesOfFullTimeEmployees[employee],
|
||||
this.workPeriodsSchedulesOfFullTimeEmployees[employee+1]).post();
|
||||
}
|
||||
|
||||
IntVar[] workingPeriodsPerFullTimeEmployees =
|
||||
chocoModelInitialSchedules.intVarArray(this.numberOfFullTimeEmployees,0,this.myScheduleParameters.getWorkPeriodsPerSchedule(), true);
|
||||
for (int employee = 0; employee < this.numberOfFullTimeEmployees; employee++) {
|
||||
chocoModelInitialSchedules.sum(workPeriodsSchedulesOfFullTimeEmployees[employee],
|
||||
"=", workingPeriodsPerFullTimeEmployees[employee]).post();
|
||||
chocoModelInitialSchedules.arithm(workingPeriodsPerFullTimeEmployees[employee], ">", 0).post();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
package InitialSchedules;
|
||||
|
||||
import org.chocosolver.solver.Model;
|
||||
import org.chocosolver.solver.variables.BoolVar;
|
||||
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 BoolVar workPeriodsSchedulesOfPartTimeEmployees[][];
|
||||
private BoolVar transposeWorkPeriodsSchedulesOfPartTimeEmployees[][];
|
||||
|
||||
private IntVar partTimeEmployeesPerWorkPeriods[];
|
||||
|
||||
public Model chocoModelInitialSchedules;
|
||||
|
||||
public ModelPartTimeEmployeesInitialSchedules(ParametersInitialSchedules myScheduleParameters) {
|
||||
|
||||
this.myScheduleParameters = myScheduleParameters;
|
||||
|
||||
this.chocoModelInitialSchedules = new Model("Model Part Time Employees Initial Schedules");
|
||||
|
||||
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());
|
||||
|
||||
// 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];
|
||||
}
|
||||
}
|
||||
|
||||
// Variable pour faire le compte du nombre d'employes par periode de travail
|
||||
this.partTimeEmployeesPerWorkPeriods = chocoModelInitialSchedules.intVarArray(this.myScheduleParameters.getWorkPeriodsPerSchedule(), 0, this.maxPartTimeEmployee, true);
|
||||
|
||||
}
|
||||
|
||||
private void createModelConstraints() {
|
||||
|
||||
// Constraintes tableau pour choisir un type d'horaire dans les horaires possibles
|
||||
for (int employee = 0; employee < this.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.arithm(this.partTimeEmployeesPerWorkPeriods[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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package InitialSchedules;
|
||||
|
||||
import ScheduleUtil.FullTimeEmployeeScheduleArray;
|
||||
import org.chocosolver.solver.constraints.extension.Tuples;
|
||||
|
||||
public class ParametersInitialSchedules {
|
||||
|
@ -88,6 +89,14 @@ public class ParametersInitialSchedules {
|
|||
}
|
||||
}
|
||||
|
||||
public void adjustRequiredWorkforce( FullTimeEmployeeScheduleArray fullTimeSchedule) {
|
||||
|
||||
for (int workPeriod = 0 ; workPeriod < this.getWorkPeriodsPerSchedule() ; workPeriod++) {
|
||||
this.requiredWorkforce[workPeriod] -= fullTimeSchedule.getEmployeesWorkingPerWorkPeriod(workPeriod);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int getTotalWorkedPeriodsInSchedule() {
|
||||
int totalWorkedPeriodsInSchedule = 0;
|
||||
for (int workPeriod = 0 ; workPeriod < this.getWorkPeriodsPerSchedule() ; workPeriod++) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
//import AbsenceSchedules.AbsenceSchedulesArray;
|
||||
|
||||
import AbsenceSchedules.*;
|
||||
import InitialSchedules.ModelPartTimeEmployeesInitialSchedules;
|
||||
import ScheduleUtil.*;
|
||||
import SchedulesRecovery.*;
|
||||
import jdistlib.rng.MersenneTwister;
|
||||
|
@ -12,7 +13,6 @@ import org.chocosolver.solver.exception.ContradictionException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class MainClass {
|
||||
|
||||
|
@ -32,50 +32,90 @@ public class MainClass {
|
|||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static List<SchedulesArray> generateInitialSchedules() {
|
||||
|
||||
// Trouver les horaires des employes a temps plein possibles pour different ratio templein/temps partiel
|
||||
// Cleaner ce code avec des sous-foncitons. Creer une classe Solver.
|
||||
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 maxFullTimeEmployee = (int) Math.ceil((double) myScheduleParameters.getTotalWorkedPeriodsInSchedule()
|
||||
/ myScheduleParameters.getWorkingPeriodsOfFullTimeEmployeesPerSchedule());
|
||||
|
||||
int simulationNumber = 1;
|
||||
for (Solution CurrentSolution : myInitialSchedulesSolutions) {
|
||||
SchedulesArray isa = new SchedulesArray(myModelInitialSchedules, CurrentSolution, simulationNumber);
|
||||
initialSchedulesArrayList.add(isa);
|
||||
simulationNumber++;
|
||||
|
||||
for (int numberFullTimeEmployees = 4 ; 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();
|
||||
|
||||
System.out.println("numberFullTimeEmployeesScheduleFound: " + 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);
|
||||
|
||||
InitialSchedules.ParametersInitialSchedules myPartTimeScheduleParameters
|
||||
= new InitialSchedules.ParametersInitialSchedules();
|
||||
myPartTimeScheduleParameters.adjustRequiredWorkforce(fteisa);
|
||||
|
||||
// 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);
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
System.out.println("totalNumberScheduleFound: " + initialSchedulesArrayList.size());
|
||||
|
||||
// Pour afficher les horaires initiales
|
||||
SchedulesWindows.ShowSchedulesFrame intialSchedulesViewer = new SchedulesWindows.ShowSchedulesFrame(initialSchedulesArrayList, "Initial Schedules"); // to be removed
|
||||
|
||||
|
@ -83,6 +123,58 @@ 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);
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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 ScheduleUtil;
|
||||
|
||||
import InitialSchedules.*;
|
||||
import org.chocosolver.solver.Solution;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author frabe
|
||||
*/
|
||||
public class FullTimeEmployeeScheduleArray {
|
||||
public int initialScheduleSolutionNumber;
|
||||
public boolean[][] fullTimeSchedules;
|
||||
protected ParametersInitialSchedules myParametersInitialSchedules;
|
||||
|
||||
public FullTimeEmployeeScheduleArray(ModelFullTimeEmployeesInitialSchedules m, Solution s) {
|
||||
this.myParametersInitialSchedules = m.myScheduleParameters;
|
||||
Solution mySolution = s;
|
||||
|
||||
this.fullTimeSchedules = new boolean[getNumberOfFullTimeEmployees(s, m)][myParametersInitialSchedules.getWorkPeriodsPerSchedule()];
|
||||
|
||||
int fullTimeEmployee = 0;
|
||||
for (int i = 0; i < m.numberOfFullTimeEmployees; 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++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getNumberOfFullTimeEmployees( Solution s, ModelFullTimeEmployeesInitialSchedules m ) {
|
||||
int numberFullTimeEmployee = 0;
|
||||
for (int employee = 0; employee < m.numberOfFullTimeEmployees; employee++) {
|
||||
if (isFullTimeEmployeeActive (employee, s, m)) {
|
||||
numberFullTimeEmployee++;
|
||||
}
|
||||
}
|
||||
return numberFullTimeEmployee;
|
||||
}
|
||||
|
||||
private boolean isFullTimeEmployeeActive ( int employee, Solution s, ModelFullTimeEmployeesInitialSchedules m ) {
|
||||
int workPeriod = 0;
|
||||
while (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
|
||||
if (s.getIntVal(m.workPeriodsSchedulesOfFullTimeEmployees[employee][workPeriod]) == 1){
|
||||
return true;
|
||||
}
|
||||
workPeriod++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getEmployeesWorkingPerWorkPeriod(int workPeriod) {
|
||||
int employeesWorking = 0;
|
||||
for (int employee = 0; employee < this.getNumberFullTimeEmployee(); employee++) {
|
||||
if (this.fullTimeSchedules[employee][workPeriod]) {employeesWorking += 1;}
|
||||
}
|
||||
return employeesWorking;
|
||||
}
|
||||
|
||||
public int getNumberFullTimeEmployee() {
|
||||
return this.fullTimeSchedules.length;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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 ScheduleUtil;
|
||||
|
||||
import InitialSchedules.*;
|
||||
import InitialSchedules.ParametersInitialSchedules;
|
||||
import org.chocosolver.solver.Solution;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author frabe
|
||||
*/
|
||||
public class PartTimeEmployeeScheduleArray {
|
||||
public int initialScheduleSolutionNumber;
|
||||
public boolean[][] partTimeSchedules;
|
||||
protected ParametersInitialSchedules myParametersInitialSchedules;
|
||||
|
||||
public PartTimeEmployeeScheduleArray(ModelPartTimeEmployeesInitialSchedules m, Solution s) {
|
||||
this.myParametersInitialSchedules = m.myScheduleParameters;
|
||||
Solution mySolution = s;
|
||||
|
||||
this.partTimeSchedules = 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++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int getNumberOfFullTimeEmployees( Solution s, ModelPartTimeEmployeesInitialSchedules m ) {
|
||||
int numberPartTimeEmployee = 0;
|
||||
for (int employee = 0; employee < m.maxPartTimeEmployee; employee++) {
|
||||
if (isPartTimeEmployeeActive (employee, s, m)) {
|
||||
numberPartTimeEmployee++;
|
||||
}
|
||||
}
|
||||
return numberPartTimeEmployee;
|
||||
}
|
||||
|
||||
private boolean isPartTimeEmployeeActive ( int employee, Solution s, ModelPartTimeEmployeesInitialSchedules m ) {
|
||||
int workPeriod = 0;
|
||||
while (workPeriod < myParametersInitialSchedules.getWorkPeriodsPerSchedule()) {
|
||||
if (s.getIntVal(m.workPeriodsSchedulesOfPartTimeEmployees[employee][workPeriod]) == 1){
|
||||
return true;
|
||||
}
|
||||
workPeriod++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getNumberPartTimeEmployee() {
|
||||
return this.partTimeSchedules.length;
|
||||
}
|
||||
}
|
|
@ -27,7 +27,17 @@ public class SchedulesArray {
|
|||
this.partTimeSchedules = getDeepCopyEmployeesSchedules(myScheduleArray.partTimeSchedules);
|
||||
this.fullTimeSchedules = getDeepCopyEmployeesSchedules(myScheduleArray.fullTimeSchedules);
|
||||
this.initialScheduleSolutionNumber = myScheduleArray.initialScheduleSolutionNumber;
|
||||
this.totalScheduleCost = myScheduleArray.totalScheduleCost;
|
||||
}
|
||||
|
||||
public SchedulesArray( FullTimeEmployeeScheduleArray fteisa, PartTimeEmployeeScheduleArray pteisa, int scheduleNumber){
|
||||
this.initialScheduleSolutionNumber = scheduleNumber;
|
||||
this.myParametersInitialSchedules = fteisa.myParametersInitialSchedules;
|
||||
|
||||
this.partTimeSchedules = pteisa.partTimeSchedules;
|
||||
this.fullTimeSchedules = fteisa.fullTimeSchedules;
|
||||
|
||||
this.totalScheduleCost = EmployeeCostCalculator.getFullScheduleCost(this, myParametersInitialSchedules);
|
||||
}
|
||||
|
||||
public SchedulesArray(ModelInitialSchedules m, Solution s, int scheduleNumber) {
|
||||
|
|
|
@ -16,9 +16,10 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
|
|||
private List<ScheduleUtil.SchedulesArray> schedulesArrayList;
|
||||
private String title;
|
||||
/**
|
||||
* Creates new form ShowSchedulesFrame
|
||||
*/
|
||||
* Creates new form ShowSchedulesFrame
|
||||
**/
|
||||
public ShowSchedulesFrame(List<ScheduleUtil.SchedulesArray> schedulesArrayList, String title) {
|
||||
System.out.println("totalNumberScheduleFound: " + schedulesArrayList.size());
|
||||
this.schedulesArrayList = schedulesArrayList;
|
||||
this.title = title;
|
||||
initComponents();
|
||||
|
@ -29,10 +30,11 @@ public class ShowSchedulesFrame extends javax.swing.JFrame {
|
|||
setTitle(title);
|
||||
setVisible(true);
|
||||
changeScheduleNumberScrollBar.setMinimum(1);
|
||||
System.out.println("totalNumberScheduleFound: " + this.schedulesArrayList.size());
|
||||
int numberOfSchedules = this.schedulesArrayList.size();
|
||||
changeScheduleNumberScrollBar.setMaximum(numberOfSchedules);
|
||||
changeScheduleNumberScrollBar.setBlockIncrement(numberOfSchedules/10);
|
||||
changeScheduleNumberScrollBar.setVisibleAmount(numberOfSchedules/10);
|
||||
changeScheduleNumberScrollBar.setBlockIncrement(1);
|
||||
changeScheduleNumberScrollBar.setVisibleAmount(0);
|
||||
changeScheduleNumberScrollBar.setUnitIncrement(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,6 @@ public class ShowSolutionResultsFrame extends javax.swing.JFrame {
|
|||
|
||||
private void refreshScheduleText(int scrollBarValue) {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
|
||||
String formattedInitialScedulesArray = ScheduleUtil.PrintSchedules.getFormattedSchedule(bankRecoveredSchedulesOrderedByMeanCost.get(scrollBarValue-1).initialSchedulesArray);
|
||||
sbuf.append(formattedInitialScedulesArray);
|
||||
sbuf.append(String.format("%s" + "%.2f","Mean Cost of Recovered Schedules : $", bankRecoveredSchedulesOrderedByMeanCost.get(scrollBarValue-1).meanCostRecoveredSimulations));
|
||||
|
|
Loading…
Reference in a new issue