Un restaurant possède 50 tables de 2 places. Les clients arrivent en groupes de 2 à 6 personnes toutes les 1 à 3 minutes. Ils restent entre 60 et 120 minutes. Si les tables ne sont pas libres, les groupes attendent. On veut simuler le fonctionnement du restaurant pendant 4 heures.
import random
from filedyna import FileDyna
def tables_requises(nb_personnes):
"""
Calcule le nombre de tables nécessaires pour un groupe
Une table accueille 2 personnes.
"""
if nb_personnes % 2 == 0:
return int(nb_personnes / 2)
else:
return int(nb_personnes / 2) + 1
def simulation_restaurant():
"""
Simule le fonctionnement du restaurant pendant 240 minutes.
Retourne : clients servis, tables utilisées, moyenne de clients par table
"""
duree_service = 240
nombre_tables_total = 50
file_attente = FileDyna()
groupes_installes = []
total_clients_servis = 0
total_tables_utilisees = 0
tables_disponibles = nombre_tables_total
prochaine_arrivee = 0
for minute in range(duree_service):
# libération des tables
# On parcourt les groupes installés : si leur heure de départ est atteinte,
# leurs tables sont libérées et ajoutées au compteur. Sinon, ils restent installés
nouveaux_groupes = []
for groupe in groupes_installes:
if groupe["depart"] <= minute:
tables_disponibles = tables_disponibles + groupe["tables"]
else:
nouveaux_groupes.append(groupe)
groupes_installes = nouveaux_groupes
# Arrivée d’un groupe
# a la minute prévue, un nouveau groupe arrive. On calcule sa taille et le nombre
# de tables nécessaires. S’il y a assez de tables libres, on l’installe directement
# et on met à jour les compteurs. Sinon, on l’ajoute dans la file d’attente
if minute >= prochaine_arrivee:
taille = random.randint(2, 6)
tables = tables_requises(taille)
if tables_disponibles >= tables:
tables_disponibles = tables_disponibles - tables
total_clients_servis = total_clients_servis + taille
total_tables_utilisees = total_tables_utilisees + tables
duree = random.randint(60, 120)
depart = minute + duree
groupes_installes.append({"taille": taille, "tables": tables, "depart": depart})
else:
file_attente.enfiler([taille, tables])
prochaine_arrivee = minute + random.randint(1, 3)
# servir la file d’attente
# tant que la file n’est pas vide et qu’il y a assez de tables libres pour le premier groupe,
# on le retire de la file, on l’installe, et on met à jour les compteurs et son heure de départ
while not file_attente.est_vide() and tables_disponibles >= file_attente.file[0][1]:
groupe_attente = file_attente.defiler()
taille_attente = groupe_attente[0]
tables_attente = groupe_attente[1]
tables_disponibles = tables_disponibles - tables_attente
total_clients_servis = total_clients_servis + taille_attente
total_tables_utilisees = total_tables_utilisees + tables_attente
duree = random.randint(60, 120)
depart = minute + duree
groupes_installes.append({"taille": taille_attente, "tables": tables_attente, "depart": depart})
# calcul du nombre de clients assis
# on additionne la taille de tous les groupes actuellement installés
clients_assis = 0
for g in groupes_installes:
clients_assis = clients_assis + g["taille"]
# Calcul du nombre de clients en attente
# on additionne la taille de tous les groupes présents dans la file d’attente
clients_attente = 0
for g in file_attente.file:
clients_attente = clients_attente + g[0]
print("Minute", minute, "- Assis :", clients_assis, "- En attente :", clients_attente)
# moyenne finale
# a la fin du service, on calcule la moyenne de clients par table utilisée
if total_tables_utilisees > 0:
moyenne = total_clients_servis / total_tables_utilisees
else:
moyenne = 0
return {"clients_servis": total_clients_servis, "tables_utilisees": total_tables_utilisees, "moyenne_clients_par_table": round(moyenne, 2)}
resultats = simulation_restaurant()
print(resultats)