Projet NSI : Simulation d’attente au restaurant

Le problème

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.

Illustration du restaurant
Image d'iullustration du restaurant vide (© La Table Du 2)

Structures de données utilisées

Algorithme

Code Python


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)