diff --git a/Rapport_de_session/bibliographie.bib b/Rapport_de_session/bibliographie.bib new file mode 100644 index 0000000..0327306 --- /dev/null +++ b/Rapport_de_session/bibliographie.bib @@ -0,0 +1,60 @@ + +@inproceedings{walsh_stochastic_2002, + address = {Amsterdam, The Netherlands, The Netherlands}, + series = {{ECAI}'02}, + title = {Stochastic {Constraint} {Programming}}, + isbn = {978-1-58603-257-9}, + url = {http://dl.acm.org/citation.cfm?id=3000905.3000930}, + abstract = {To model combinatorial decision problems involving uncertainty and probability, we introduce stochastic constraint programming. Stochastic constraint programs contain both decision variables (which we can set) and stochastic variables (which follow a probability distribution). They combine together the best features of traditional constraint satisfaction, stochastic integer programming, and stochastic satisfiability. We give a semantics for stochastic constraint programs, and propose a number of complete algorithms and approximation procedures. Finally, we discuss a number of extensions of stochastic constraint programming to relax various assumptions like the independence between stochastic variables, and compare with other approaches for decision making under uncertainty.}, + urldate = {2018-02-25}, + booktitle = {Proceedings of the 15th {European} {Conference} on {Artificial} {Intelligence}}, + publisher = {IOS Press}, + author = {Walsh, Toby}, + year = {2002}, + pages = {111--115}, + file = {FS01-04-020.pdf:/home/francois/Zotero/storage/Y6SRJRY9/FS01-04-020.pdf:application/pdf} +} + +@article{chapados_retail_2014, + title = {Retail store scheduling for profit}, + volume = {239}, + issn = {0377-2217}, + url = {http://www.sciencedirect.com/science/article/pii/S0377221714004561}, + doi = {10.1016/j.ejor.2014.05.033}, + abstract = {In spite of its tremendous economic significance, the problem of sales staff schedule optimization for retail stores has received relatively scant attention. Current approaches typically attempt to minimize payroll costs by closely fitting a staffing curve derived from exogenous sales forecasts, oblivious to the ability of additional staff to (sometimes) positively impact sales. In contrast, this paper frames the retail scheduling problem in terms of operating profit maximization, explicitly recognizing the dual role of sales employees as sources of revenues as well as generators of operating costs. We introduce a flexible stochastic model of retail store sales, estimated from store-specific historical data, that can account for the impact of all known sales drivers, including the number of scheduled staff, and provide an accurate sales forecast at a high intra-day resolution. We also present solution techniques based on mixed-integer (MIP) and constraint programming (CP) to efficiently solve the complex mixed integer non-linear scheduling (MINLP) problem with a profit-maximization objective. The proposed approach allows solving full weekly schedules to optimality, or near-optimality with a very small gap. On a case-study with a medium-sized retail chain, this integrated forecasting–scheduling methodology yields significant projected net profit increases on the order of 2–3\% compared to baseline schedules.}, + number = {3}, + urldate = {2018-02-25}, + journal = {European Journal of Operational Research}, + author = {Chapados, Nicolas and Joliveau, Marc and L’Ecuyer, Pierre and Rousseau, Louis-Martin}, + month = dec, + year = {2014}, + keywords = {Constraint programming, Mixed integer programming, Retail, Shift scheduling, Statistical forecasting}, + pages = {609--624}, + file = {1-s2.0-S0377221714004561-main.pdf:/home/francois/Zotero/storage/6NFQP2JJ/1-s2.0-S0377221714004561-main.pdf:application/pdf} +} + +@article{parisio_two-stage_2015, + title = {A two-stage stochastic programming approach to employee scheduling in retail outlets with uncertain demand}, + volume = {53}, + issn = {0305-0483}, + url = {http://www.sciencedirect.com/science/article/pii/S0305048315000055}, + doi = {10.1016/j.omega.2015.01.003}, + abstract = {This paper describes an employee scheduling system for retail outlets; it is a constraint-based system that exploits forecasts and stochastic techniques to generate schedules meeting the demand for sales personnel. Uncertain scenarios due to fluctuating demand are taken into account to develop a stochastic operational optimization of staffing levels. Mathematically, the problem is stated as a mixed-integer linear programming problem. Simulations with store data belonging to a major Swiss retailer show the effective performance of the proposed approach. The schedule quality is assessed through comparison with a deterministic scheduling package, which has been used at several outlets in Switzerland.}, + urldate = {2018-02-24}, + journal = {Omega}, + author = {Parisio, Alessandra and Neil Jones, Colin}, + month = jun, + year = {2015}, + keywords = {Stochastic programming, Decision making/process, Decision support systems, Integer programming, Operational/OR, Optimization, Resource management, Scheduling}, + pages = {97--103}, + file = {parisio2015.pdf:/home/francois/Zotero/storage/K8B6NYRM/parisio2015.pdf:application/pdf} +} + +@manual{choco, + author = {Charles Prud'homme and Jean-Guillaume Fages and Xavier Lorca}, + title = {Choco Documentation}, + year = {2017}, + organization = {TASC - LS2N CNRS UMR 6241, COSLING S.A.S.}, + timestamp = {Thu, 23 November 2017}, + url = {http://www.choco-solver.org }, +} diff --git a/Rapport_de_session/conclusion.tex b/Rapport_de_session/conclusion.tex new file mode 100644 index 0000000..cf49ee1 --- /dev/null +++ b/Rapport_de_session/conclusion.tex @@ -0,0 +1,6 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: + diff --git a/Rapport_de_session/experimentation.tex b/Rapport_de_session/experimentation.tex new file mode 100644 index 0000000..cf49ee1 --- /dev/null +++ b/Rapport_de_session/experimentation.tex @@ -0,0 +1,6 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: + diff --git a/Rapport_de_session/generationabsences.tex b/Rapport_de_session/generationabsences.tex new file mode 100644 index 0000000..cf49ee1 --- /dev/null +++ b/Rapport_de_session/generationabsences.tex @@ -0,0 +1,6 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: + diff --git a/Rapport_de_session/introduction.tex b/Rapport_de_session/introduction.tex new file mode 100644 index 0000000..0d1f17b --- /dev/null +++ b/Rapport_de_session/introduction.tex @@ -0,0 +1,5 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: diff --git a/Rapport_de_session/logo.png b/Rapport_de_session/logo.png new file mode 100755 index 0000000..df2c3d8 Binary files /dev/null and b/Rapport_de_session/logo.png differ diff --git a/Rapport_de_session/makefile b/Rapport_de_session/makefile new file mode 100644 index 0000000..0994487 --- /dev/null +++ b/Rapport_de_session/makefile @@ -0,0 +1,24 @@ +build: rapport_de_recherche.pdf + +maxconsecutif.svg: + dot -Tpdf maxconsecutif.dot -o maxconsecutif.pdf + +rapport_de_recherche.pdf: rapport_de_recherche.bbl + pdflatex rapport_de_recherche.tex + pdflatex rapport_de_recherche.tex + +rapport_de_recherche.bbl: rapport_de_recherche.tex maxconsecutif.svg + pdflatex rapport_de_recherche.tex + bibtex rapport_de_recherche.aux + +run: rapport_de_recherche.pdf + -evince rapport_de_recherche.pdf & + +clean: + -rm *.aux + -rm *.bbl + -rm *.blg + -rm *.lof + -rm *.log + -rm *.out + -rm *.toc diff --git a/Rapport_de_session/maxconsecutif.dot b/Rapport_de_session/maxconsecutif.dot new file mode 100644 index 0000000..a933a86 --- /dev/null +++ b/Rapport_de_session/maxconsecutif.dot @@ -0,0 +1,22 @@ +digraph Automaton { + rankdir = LR; + 0 [shape=circle]; + 0 -> 5 [label="{0}"] + 0 -> 3 [label="{1}"] + 1 [shape=circle]; + 1 -> 5 [label="{0}"] + 1 -> 2 [label="{1}"] + 2 [shape=doublecircle]; + 2 -> 2 [label="{0,1}"] + 3 [shape=circle]; + 3 -> 5 [label="{0}"] + 3 -> 1 [label="{1}"] + 4 [shape=circle]; + 4 -> 5 [label="{0}"] + 4 -> 0 [label="{1}"] + 5 [shape=circle]; + initial [shape=plaintext,label=""]; + initial -> 5 + 5 -> 5 [label="{0}"] + 5 -> 4 [label="{1}"] +} diff --git a/Rapport_de_session/maxconsecutif.pdf b/Rapport_de_session/maxconsecutif.pdf new file mode 100644 index 0000000..0dd9520 Binary files /dev/null and b/Rapport_de_session/maxconsecutif.pdf differ diff --git a/Rapport_de_session/modelisation.tex b/Rapport_de_session/modelisation.tex new file mode 100644 index 0000000..7df4ac7 --- /dev/null +++ b/Rapport_de_session/modelisation.tex @@ -0,0 +1,103 @@ + +\section{Modélisation} +\label{sec:modelisation} + +%% TODO INTRODUIRE LA SECTION + +\subsection{Paramètres} +\label{sec:parametres} + +\subsubsection{Horaire de travail et demande} +\label{sec:horairedemande} + +Nous considérons un horaire de travail d'une durée de $J$ jours. Chaque journée est composée de $P$ périodes de travail, d'une durée de $\frac{24}{P}$ heures chacunes. La demande de travail pour la période $p$ de la journée $j$ est définie par $d_{p,j}$. La demande totale pour la durée de l'horaire de travail est définie par l'équation \eqref{eq:dtot}. + +\begin{align} + \label{eq:dtot} + D^{TOT} = \sum_{p=1}^{P} \sum_{j=1}^{J} d_{p,j} +\end{align} + +\subsubsection{Employés} +\label{sec:modeleemployes} + +Notre modèle considère deux types $A$ d'employés: les employés à temps plein et les employés à temps partiel \eqref{typeemployes}. + +\begin{align} + \label{typeemployes} + A \in {FT,PT} +\end{align} + +Ils travaillent des périodes consécutives d'une durée $i^{A}$ heures. L'intervalle de travail des employés à temps plein doit cependant débuter à la première, troisième ou cinquième période. On définit aussi un nombre d'heures de repos minimal $r_{min}^{A}$ entre les périodes travaillées. Les employés à temps plein travaillent $h_{reg}^{FT}$ heures par période de deux semaines et les employés à temps partiel travaillent entre $h_{min}^{PT}$ et $h_{max}^{PT}$ heures durant cette même période. Les employés ne travaillent pas plus que $j_{max}^{A}$ journées consécutives. Le nombre d'employés $E$ de chaque type est variable et sera déterminé par les ratios \eqref{eq:eftept}: + +\begin{align} + \label{eq:eftept} + E^{A} &= \frac{D^{TOT}}{h_{reg}^{A}}, &\forall A +\end{align} + +Les employés ont respectivement un salaire horaire de $S^{A}$ et encourent un frais fixe de $F^{A}$. Afin de représenter une plus faible productivité des employés à temps partiel, on pourra majorer artificiellement leur salaire horaire. + +\subsection{Variables} +\label{sec:variables} + +On représente les horaires de travail par deux tableaux de variables booliennes $X^{FT}$ et $X^{PT}$ \eqref{tableauxvariables}. + +\begin{align} + \label{tableauxvariables} + X^{A} &= \left( x_{e,j,p}^{A} \right) \in \N^{E^{A} \times J \times P} &\forall A\\ + dom(x_{e,j,p}^{A}) &= \lbrace 0,1 \rbrace &\forall 1 \leq e \leq E^{A}, 1 \leq j \leq J, 1 \leq p \leq P\nonumber +\end{align} + +\subsection{Énumération des horaires valides} +\label{sec:horairesvalides} + +Afin de réduire la taille du problème, la liste des horaires quotidiens valides pour un employé est générée, pour chaque type d'employés. Il s'agit de deux sous-problèmes de satisfaction pouvant aussi être résolus avec le solveur Choco \cite{choco}. L'énumération de toutes les solutions obtenues sera ensuite utilisée pour générer l'ensemble des tuples d'une contrainte \textsc{Tableau}. + +\subsubsection{Paramètres} +\label{sec:horairesparametres} + +\subsubsection{Variables} +\label{sec:horairesvariables} + +On définit $H^{A} \in \mathcal{N}^{J}$, un vecteur de variables booléennes $h_{j}$ formant un horaire d'une durée de $J$ journées pour un employé de type $A \in \lbrace FT, PT \rbrace$. + +\subsubsection{Contraintes} +\label{sec:horairescontraintes} + +L'horaire doit respecter le nombre de périodes travaillées sur la durée totale de l'horaire. + +\begin{align} + \frac{h_{min}^{A}}{i^{A}} \leq \sum_{j=1}^{J} h_{j} \leq \frac{h_{max}^{A}}{i^{A}} +\end{align} + +L'horaire de l'employé à temps partiel doit contenir un même nombre de jours dans les deux sous-périodes $j \in [p1_{min},p1_{max}]=[1,5]$ et $j \in [p2_{min},p2_{max}]=[8,12]$ du lundi au vendredi. + +\begin{align} + \sum_{j=p1_{min}}^{p1_{max}} h_{j} = \sum_{j=p2_{min}}^{p2_{max}} h_{j} +\end{align} + +L'horaire doit inclure le travail durant une fin de semaine sur deux. + +\begin{align} + h_{6} &= h_{7} \wedge h_{13} = h_{14} \wedge h_{6} \neq h_{13} +\end{align} + +L'horaire doit respecter le nombre maximum de jours consécutifs travaillés autorisés. On utilise une contrainte \textsc{Regular} \guillemotleft réifiée \guillemotright pour représenter le non-respect de cette contrainte, c'est-à-dire lorsque qu'on retrouve une séquence de jours consécutifs dont la longueur est supérieure à $j_{max}^{A}$. L'automate fini pour cette contrainte lorsque $j_{max}^{A}=4$ est représenté à la figure \ref{fig:automatemaxconsecutif}. L'expression régulière représentant cet automate prend la forme \texttt{[01]*1\{5,\}[01]*}. + +\begin{figure}[ht] + \centering + \includegraphics[width=15cm]{maxconsecutif} + \caption{Automate fini d'un horaire où $j_{max}^{A} \leq 4$ n'est pas respecté} + \label{fig:automatemaxconsecutif} +\end{figure} + +\subsection{Contraintes} +\label{sec:contraintes} + + + + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: + diff --git a/Rapport_de_session/pagetitre.tex b/Rapport_de_session/pagetitre.tex new file mode 100755 index 0000000..148577d --- /dev/null +++ b/Rapport_de_session/pagetitre.tex @@ -0,0 +1,13 @@ +\thispagestyle{empty} % Pour éviter d'avoir un en-tête et un pied de page sur la page couverture +\includegraphics[width=5cm]{logo.png} % Pour inclure le logo (on précise la largeur de l'image) +\vspace{4cm} % Espacement vertical +\begin{center} % On centre le texte +{\huge \bf \titre}\\ % \huge fait que le texte est gros, \bf fait que le texte est gras +\vspace{4cm} +\large Travail présenté à \destinataire \\ \cours\\ +\vspace{4cm} +Réalisé par \\ \auteurs ;\\ \matricules +\vfill % On va jusqu'au bas de la page avant de mettre le texte ci-dessous +Dernière version produite le~\today~à~\currenttime +\pagebreak +\end{center} diff --git a/Rapport_de_session/rapport_de_recherche.pdf b/Rapport_de_session/rapport_de_recherche.pdf new file mode 100644 index 0000000..23a0529 Binary files /dev/null and b/Rapport_de_session/rapport_de_recherche.pdf differ diff --git a/Rapport_de_session/rapport_de_recherche.tex b/Rapport_de_session/rapport_de_recherche.tex new file mode 100644 index 0000000..39ccdef --- /dev/null +++ b/Rapport_de_session/rapport_de_recherche.tex @@ -0,0 +1,78 @@ +\documentclass[12pt]{article} % Précise le type de document, et la taille de la police de caractère +\usepackage[square,sort,numbers]{natbib}% Pour pouvoir utiliser une bibliographie externe +\usepackage[french]{babel} % Pour préciser la langue du document +\usepackage[utf8]{inputenc} % Précise comment le texte est saisi : cela permet de tapper directement les accents +\usepackage[T1]{fontenc} % Précise la façon dont le document actuel est encodé +\usepackage{setspace} +\usepackage{datetime} +\usepackage[margin=2.5cm]{geometry} % Précise les marges du document +\title{IFT-7020 Optimisation combinatoire - Rapport de recherche\\Session d'hiver 2018}% N'affecte pas la page titre, mais défini le nom de votre projet +\author{François Bérubé et François Pelletier} % N'affecte pas la page titre, mais défini le nom de l'auteur(e) du projet + +%Bibliographie +%---------------------------------------------------------------- +\bibliographystyle{plainnat} % Pour changer le style de bibliographie +\addto{\captionsfrench}{\renewcommand{\refname}{Bibliographie}} % Comme le langage défini est le français, "Références" aurait été le titre par défaut pour la bibliographie +\usepackage[nottoc]{tocbibind} % Ajoute la bibliographie dans la table des matières +%---------------------------------------------------------------- + +%Sections +%---------------------------------------------------------------- +%\usepackage{newclude} % Pour pouvoir utiliser l'étoile après \inculde pour éviter les sauts de page. Ce package a des problême de compatibilité avec la package natbib +%\renewcommand\thesection{} % Pour éviter la numérotation des sections +%---------------------------------------------------------------- + +%Informations destinées à la page de présentation +%---------------------------------------------------------------- +\newcommand{\titre}{Rapport de recherche} +\newcommand{\auteurs}{François Bérubé et François Pelletier} +\newcommand{\matricules}{900226407, 908144032} +\newcommand{\destinataire}{Claude-Guy Quimper} +\newcommand{\cours}{IFT-7020 Optimisation combinatoire\\Session d'hiver 2018} +%---------------------------------------------------------------- + +%Autres packages et commandes utiles +%---------------------------------------------------------------- +\usepackage{amsmath,amsthm,amssymb,amsfonts,calc} % Pour pouvoir inclure certains symboles et environnements mathématiques +\usepackage[ + left = \flqq,% + right = \frqq,% + leftsub = \flqq,% + rightsub = \frqq% +]{dirtytalk} +\newtheorem{definition}{Définition} +\usepackage{array} +\usepackage{float} +\usepackage{lscape} +\usepackage{enumerate} % Pour mieux gérer la commande enumerate dans les sections +\usepackage{graphicx} % Pour inclure des images +\usepackage{color} % Pour inclure du texte en couleur +\usepackage{units} % Pour pouvoir tapper les unités correctement +\usepackage{pgf,tikz} % Utilisation du module tikz, qui permet de tracer des belles images +\usetikzlibrary{shapes.geometric, arrows} % Quand on exporte une image GeoGebra, on a besoin de préciser cela +\usepackage{hyperref} % Pour include des liens dans le document +\newcommand{\N}{\mathbb{N}} % Commande personnelle, plus rapide pour tapper les ensembles +\newcommand{\Z}{\mathbb{Z}} % Commande personnelle, plus rapide pour tapper les ensembles +\newcommand{\R}{\mathbb{R}} % Commande personnelle, plus rapide pour tapper les ensembles +\usepackage{cprotect} % Pour pouvoir personaliser la légende des figures +%---------------------------------------------------------------- + +\begin{document} +\input{pagetitre} % Inclut le code contenu dans un fichier comme s'il était entré ici +\tableofcontents +%\listoffigures +% Le package newclude mis en commentaire permet d'introduire une * pour éviter le saut de page entre les section +\include{introduction} +\include{modelisation} +\include{generationabsences} +\include{recouvrement} +\include{experimentation} +\include{resultats} +\include{conclusion} +\bibliography{bibliographie} +\end{document} + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: t +%%% End: diff --git a/Rapport_de_session/recouvrement.tex b/Rapport_de_session/recouvrement.tex new file mode 100644 index 0000000..cf49ee1 --- /dev/null +++ b/Rapport_de_session/recouvrement.tex @@ -0,0 +1,6 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: + diff --git a/Rapport_de_session/resultats.tex b/Rapport_de_session/resultats.tex new file mode 100644 index 0000000..cf49ee1 --- /dev/null +++ b/Rapport_de_session/resultats.tex @@ -0,0 +1,6 @@ + +%%% Local Variables: +%%% mode: latex +%%% TeX-master: "rapport_de_recherche" +%%% End: + diff --git a/Travail_de_session/InitialSchedules/ValidDailySchedules.java b/Travail_de_session/InitialSchedules/ValidDailySchedules.java index 006c8ca..d94c36d 100644 --- a/Travail_de_session/InitialSchedules/ValidDailySchedules.java +++ b/Travail_de_session/InitialSchedules/ValidDailySchedules.java @@ -3,9 +3,9 @@ package InitialSchedules; import org.chocosolver.solver.Model; import org.chocosolver.solver.Solution; import org.chocosolver.solver.constraints.nary.automata.FA.FiniteAutomaton; -import org.chocosolver.solver.constraints.nary.automata.FA.IAutomaton; import org.chocosolver.solver.variables.BoolVar; import org.chocosolver.solver.variables.IntVar; + import java.util.List; public class ValidDailySchedules { @@ -45,10 +45,12 @@ public class ValidDailySchedules { model.arithm(horaire[5], "!=", horaire[12]).post(); /*Respect du maximum consecutif*/ - IAutomaton automatonConsecutif = new FiniteAutomaton("[01]*1{" + (nbMaxConsecutif + 1) + "," + nbPeriodes + "}[01]*"); + FiniteAutomaton automatonConsecutif = new FiniteAutomaton("[01]*1{" + (nbMaxConsecutif + 1) + "," + nbPeriodes + "}[01]*"); BoolVar respecteMaxConsecutif = model.regular(horaire, automatonConsecutif).reify(); model.arithm(respecteMaxConsecutif, "=", 0).post(); + //System.out.println(automatonConsecutif.toDot()); + /* Trouver les solutions*/ List solutions = model.getSolver().findAllSolutions();