Expert Python
Le monde réel regorge de systèmes, comme les aéroports et les autoroutes, qui connaissent fréquemment des encombrements et des retards. Lorsque ces systèmes ne sont pas optimisés, leur inefficacité peut conduire à d'innombrables clients mécontents et des heures de temps perdu. Dans ce didacticiel, vous allez apprendre à utiliser les simpy
cadre pour créer des simulations virtuelles qui vous aideront à résoudre des problèmes comme ceux-ci.
Dans ce didacticiel, vous allez apprendre à:
- Utilisation une simulation pour modéliser un processus réel
- Créer un algorithme pas à pas pour approximer un système complexe
- Conception et exécutez une simulation du monde réel en Python avec
simpy
Dans ce didacticiel, vous allez créer une simulation pour une salle de cinéma locale. Votre objectif est de fournir au gestionnaire un script pour aider à trouver le nombre optimal d'employés à avoir sur le personnel. Vous pouvez télécharger le code source de ce script en cliquant sur le lien ci-dessous:
Qu'est-ce que la simulation
UNE simulation est une représentation d'un système du monde réel. On peut utiliser des modèles mathématiques ou informatiques de ce système pour étudier son fonctionnement ou ce qui se passe lorsque des parties de celui-ci sont modifiées. Les simulations sont utilisées dans les aéroports, les restaurants, les mécaniciens, les agences gouvernementales et de nombreux autres systèmes où une mauvaise allocation des ressources peut entraîner des encombrements, l'insatisfaction des clients et des retards de transport critiques.
UNE système peut être n'importe quel environnement où les choses se produisent. Des exemples de systèmes réels incluent les lave-autos, les banques, les usines de fabrication, les aéroports, les bureaux de poste, les centres d'appels, etc. Ces systèmes ont agents qui subissent processus en eux. Par exemple:
- Un lave-auto fera passer les voitures par le processus de lavage.
- Un aéroport fera passer les passagers par le processus de contrôle de sécurité.
- Un centre d'appels permettra aux clients de passer par le processus de parler avec un télévendeur.
Cette relation est résumée dans le tableau ci-dessous:
Système | Agent | Processus |
---|---|---|
Lave-Auto | Voiture | Laver |
Aéroport | Passager | Vérification de sécurité |
Centre d'appel | Client | Parlez à un télévendeur |
Comprendre les processus que traversent les agents au sein d'un système est un élément important de la planification logistique, en particulier pour les grandes organisations. Par exemple, un aéroport peut voir les temps d'attente des passagers à un poste de contrôle de sécurité monter en flèche s'il n'y a pas assez de travailleurs ce jour-là. De même, le courrier sensible au facteur temps peut être retardé de plusieurs jours (voire plusieurs semaines) s'il n'est pas correctement acheminé.
Ces cas de congestion peuvent avoir conséquences réelles temps et argent, il est donc important de pouvoir modéliser ces processus au préalable. Cela vous donne une idée de l'endroit où le système peut rencontrer des problèmes et comment les ressources doivent être allouées à l'avance pour résoudre ces problèmes de la manière la plus efficace possible.
Fonctionnement de la simulation
En Python, vous pouvez utiliser le simpy
cadre pour la simulation d'événements. Tout d'abord, jetez un coup d'œil à la façon dont un processus simulé s'exécuterait en Python. Voici un extrait de code d'une simulation d'un système de points de contrôle de sécurité. Les trois lignes de code suivantes configurent l'environnement, transmettent toutes les fonctions nécessaires et exécutent la simulation:
# Configurer l'environnement
env = simpy.Environnement()
# Supposons que vous avez défini checkpoint_run () au préalable
env.processus(checkpoint_run(env, num_booths, check_time, passager_arrivée))
# Allons-y!
env.courir(jusqu'à=dix)
La première ligne de code ci-dessus établit le environnement. Pour ce faire, vous attribuez simpy.Environment ()
à la variable souhaitée. Ici, c'est simplement nommé env
. Cela raconte simpy
pour créer un objet d'environnement nommé env
qui va gérer le temps de simulation et déplacer la simulation à travers chaque pas de temps suivant.
Une fois votre environnement établi, vous passerez toutes les variables qui vous serviront de paramètres. Ce sont les choses que vous pouvez modifier pour voir comment le système réagira aux changements. Pour ce système de points de contrôle de sécurité, vous utilisez les paramètres suivants:
env
: l'objet environnement pour planifier et traiter des événementsnum_booths
: le nombre de cabines de contrôle d'identitécheck_time:
le temps qu'il faut pour vérifier l'identité d'un passagerpassager_arrivée
: la vitesse à laquelle les passagers arrivent à la file d'attente
Ensuite, il est temps de lancer la simulation! Vous pouvez le faire en appelant env.run ()
et en spécifiant la durée pendant laquelle la simulation doit s'exécuter. La simulation s'exécute en quelques minutes, donc cet exemple de code exécutera la simulation pendant 10 minutes en temps réel.
Remarque: Ne vous inquiétez pas! Vous n'aurez pas à attendre 10 minutes réelles pour que la simulation se termine. Parce que la simulation vous donne un aperçu virtuel d'un processus en temps réel, ces 10 minutes passeront en quelques secondes sur l'ordinateur.
Pour récapituler, voici les trois étapes pour exécuter une simulation en Python:
- Établir l'environnement.
- Passer dans les paramètres.
- Courir la simulation.
Mais il se passe beaucoup plus de choses sous le capot! Vous devrez comprendre comment choisir ces paramètres et définir toutes les fonctions qui seront appelées lors de l'exécution de la simulation.
Commençons!
Comment débuter avec simpy
Il y a quelques tâches à faire que vous devriez vérifier dans votre liste avant de créer des simulations en Python. La première chose que vous devez faire est de vous assurer que vous avez une bonne compréhension des bases de Python. En particulier, vous devrez avoir une bonne compréhension des classes et des générateurs.
La prochaine chose que vous voudrez faire est d'installer le package requis. Le cadre principal que vous utiliserez est simpy
. Il s'agit du package de base qui va créer, gérer et exécuter votre simulation. Vous pouvez l'installer avec pépin
:
$ python3 -m pip install simpy
Vous aurez également besoin de quelques modules Python intégrés. Vous utiliserez le statistiques
module pour calculer les temps d'attente moyens et la Aléatoire
module pour générer des nombres aléatoires. Celles-ci font partie de la bibliothèque standard Python, vous n'avez donc pas besoin d'installer quoi que ce soit de nouveau.
Enfin, vous devrez choisir la manière dont vous souhaitez exécuter votre simulation. En général, vous pouvez choisir l'une des deux options:
- Exécutez-le de manière interactive: Utilisez un bloc-notes Jupyter, où chaque bloc de code contiendra sa propre définition de classe ou de fonction. La sortie sera affichée en bas de l'ordinateur portable.
- Exécutez-le dans le shell: Enregistrez votre simulation en tant que
.py
fichier et dites à Python de l'exécuter dans votre terminal. La sortie sera imprimée directement sur la console.
Choisissez la méthode qui vous convient le mieux! Le résultat devrait être le même.
Tout au long de ce didacticiel, vous verrez des références à un fichier autonome nommé simulate.py
. Au fur et à mesure que vous parcourez ce didacticiel, les blocs de code feront référence simulate.py
pour vous aider à garder une trace de la façon dont toutes les pièces s'assemblent. Pour votre référence, vous pouvez accéder au code complet de simulate.py
sur le lien ci-dessous:
N'hésitez pas à enregistrer le fichier simulate.py
et suivez dans votre éditeur préféré!
Comment simuler avec le simpy
Paquet
La première étape pour exécuter une simulation dans simpy
est de choisir un processus à modéliser. La simulation consiste à créer un environnement virtuel pour refléter un système du monde réel. Dans le même esprit, vous "simulez" une situation pour votre simulation!
Imaginez que vous avez été embauché pour aider le directeur d’un petit cinéma local. Le théâtre a reçu de mauvaises critiques en raison de leur longs temps d'attente. Le manager, qui se préoccupe autant des coûts que de la satisfaction des clients, ne peut que se permettre de garder autant d'employés.
Le manager est particulièrement inquiet de ce que le chaos peut se dérouler une fois que ces superproductions commencent à sortir: des lignes qui tournent autour du théâtre, des employés tendus à leur limite, des cinéphiles en colère qui manquent les scènes d'ouverture… C'est définitivement une situation à éviter!
Après avoir vérifié les critiques, le directeur a pu déterminer qu'un cinéphile donné de son théâtre était prêt à passer au plus 10 minutes entre son arrivée et le moment où il mettait ses fesses dans un siège. En d'autres termes, le temps d'attente moyen pour une nuit au théâtre doit être de 10 minutes ou moins. Le gestionnaire a demandé votre aide pour trouver une solution pour réduire les temps d'attente des clients en vertu de cette exigence de 10 minutes.
Remue-méninges sur un algorithme de simulation
Avant d'écrire une seule ligne de code, il est important que vous commenciez par comprendre comment votre processus se déroulerait dans la vie réelle. Il s'agit de s'assurer que, lorsque vous le transmettez à la machine, le processus reflète fidèlement ce que les clients vont vraiment vivre. Voici comment vous pourriez réfléchir aux étapes qu'un cinéphile pourrait suivre pour écrire votre algorithme:
- Arrivée au théâtre, faites la queue et attendez pour acheter un billet.
- Acheter un ticket à la billetterie.
- Attendez en ligne pour faire vérifier le billet.
- Avoir le ticket vérifié par un huissier.
- Choisir l'opportunité ou non de se mettre en ligne pour le stand de concession:
- S'ils s'alignent, puis ils achètent de la nourriture.
- S'ils ne font pas la queue, puis ils passent à la dernière étape.
- Aller trouver leur siège.
Il s'agit d'une itération étape par étape pour un cinéphile qui achète son billet à la billetterie du théâtre. Vous pouvez déjà voir quelles parties de ce processus peuvent être contrôlées. Vous pouvez affecter la durée d'attente d'un client en ayant plus de caissiers disponibles à la billetterie.
Certaines parties du processus ne peuvent pas être contrôlées, comme la toute première étape. Vous ne pouvez pas contrôler le nombre de clients qui arriveront ni la vitesse à laquelle ils le feront. Vous pouvez faire une supposition, mais vous ne pouvez pas simplement choisir un nombre, car ce serait un mauvais reflet de la réalité. Pour ce paramètre, la meilleure chose à faire est de utiliser les données disponibles pour déterminer une heure d'arrivée appropriée.
Remarque: L'utilisation de données historiques garantit que la solution que vous trouverez reflétera avec précision ce que vous pouvez vous attendre à voir dans la vie réelle.
Avec ces choses à l'esprit, il est temps de construire votre simulation!
Configuration de l'environnement
Avant de commencer à créer votre simulation, vous devez vous assurer que votre environnement de développement est correctement configuré. La toute première chose que vous voudrez faire est d'importer les packages nécessaires. Vous pouvez le faire en déclarant importation
déclarations en haut de votre fichier:
importation simpy
importation Aléatoire
importation statistiques
Ce sont les principales bibliothèques que vous utiliserez pour créer un script pour le directeur du théâtre. N'oubliez pas que l'objectif est de trouver le nombre optimal d'employés qui donne un temps d'attente moyen de moins de 10 minutes. Pour ce faire, vous devez collecter le temps qu'il faut à chaque cinéphile pour se rendre à son siège. L'étape suivante consiste à déclarer une liste pour contenir ces heures:
Cette liste contiendra le temps total que chaque cinéphile passe à se déplacer dans le théâtre, de son arrivée à son siège. Vous déclarez cette liste tout en haut du fichier afin de pouvoir l'utiliser dans n'importe quelle fonction que vous définissez ultérieurement.
Création de l'environnement: définition de classe
La première partie de la simulation que vous souhaitez créer est le plan du système. Ce sera l'environnement global dans lequel les choses se produisent, et les personnes ou les objets se déplacent d'un endroit à un autre. Rappelez-vous, un environnement peut être l'un des nombreux systèmes différents, comme une banque, un lave-auto ou un point de contrôle de sécurité. Dans ce cas, l'environnement est une salle de cinéma, ce sera donc le nom de votre classe:
classe Théâtre(objet):
def __init__(soi):
# Plus à venir!
Il est maintenant temps de réfléchir aux parties d'un cinéma. Bien sûr, il y a le théâtre lui-même, ce que vous avez appelé votre environnement. Plus tard, vous déclarerez explicitement le théâtre comme un véritable environnement
en utilisant l'un des simpy
les fonctions. Pour l'instant, appelez-le env
pour faire court et l'ajouter à la définition de classe:
classe Théâtre(objet):
def __init__(soi, env):
soi.env = env
D'accord, quoi d'autre pourrait-il y avoir dans un théâtre? Vous pouvez le comprendre en réfléchissant à l'algorithme de simulation que vous avez planifié précédemment. Lorsqu'un cinéphile arrive, il devra faire la queue au box-office, où un caissier attendra pour l'aider. Vous venez de découvrir deux choses sur l'environnement du théâtre:
- Il y a caissiers.
- Les cinéphiles peuvent acheter des billets d'eux.
Les caissiers sont Ressource que le théâtre met à la disposition de ses clients, et ils aident les cinéphiles à travers le processus d'acheter un billet. Pour le moment, vous ne savez pas combien de caissiers sont disponibles dans le théâtre simulé. En fait, c'est le problème que vous essayez de résoudre. Comment les temps d'attente varient-ils en fonction du nombre de caissiers travaillant une nuit donnée?
Vous pouvez continuer et appeler cette variable inconnue num_cashiers
. La valeur exacte que prendra cette variable peut être triée ultérieurement. Pour l'instant, sachez simplement que c'est un élément indispensable de l'environnement théâtral. Ajoutez-le à la définition de classe:
classe Théâtre(objet):
def __init__(soi, env, num_cashiers):
soi.env = env
soi.la caissière = simpy.Ressource(env, num_cashiers)
Ici, vous ajoutez le nouveau paramètre num_cashiers
à ton __init __ ()
définition. Ensuite, vous créez une ressource self.cashier
et utilise simpy.Resource ()
pour déclarer combien il peut y avoir à tout moment dans cet environnement.
Remarque: Dans simpy
, les ressources sont les parties de l'environnement (env
) dont le nombre est limité. L'utilisation de l'un d'eux prend du temps, et seulement autant (num_cashiers
) peuvent être utilisés simultanément.
Il vous reste une étape à franchir. Un caissier ne va pas acheter un billet pour se, droite? Ils vont aider le cinéphile! Encore une fois, vous savez que ce processus d'achat d'un billet va prendre un certain temps. Mais combien de temps?
Supposons que vous ayez demandé au responsable des données historiques sur le théâtre, telles que les évaluations des performances des employés ou les reçus d'achat de billets. Sur la base de ces données, vous avez appris qu'il faut en moyenne entre 1 et 2 minutes pour émettre un ticket à la billetterie. Comment obtenez-vous simpy
imiter ce comportement? Il ne prend qu'une seule ligne de code:
rendement soi.env.temps libre(Aléatoire.randint(1, 3))
env.timeout ()
raconte simpy
pour déclencher un événement après un certain temps. Dans ce cas, l'événement est qu'un billet a été acheté.
Le temps que cela prend peut être une minute, deux minutes ou trois minutes. Vous voulez que chaque cinéphile passe un temps différent à la caisse. Pour ce faire, vous utilisez random.randint ()
pour choisir un nombre aléatoire entre les valeurs basses et hautes données. Ensuite, pour chaque cinéphile, la simulation attendra la durée choisie.
Terminons cela dans une fonction bien rangée et ajoutons-le à la définition de classe:
classe Théâtre(objet):
def __init__(soi, env, num_cashiers):
soi.env = env
soi.la caissière = simpy.Ressource(env, num_cashiers)
def ticket_achat(soi, amateur de cinéma):
rendement soi.env.temps libre(Aléatoire.randint(1, 3))
Celui qui a déclenché l'événement Purchase_ticket ()
est le amateur de cinéma
, ils doivent donc être passés comme argument requis.
Remarque: Vous verrez comment le cinéphile achète réellement le billet dans la section suivante!
C'est ça! Vous avez sélectionné une ressource limitée dans le temps, défini son processus associé et codifié cela dans votre définition de classe. Pour ce didacticiel, vous devez déclarer deux autres ressources:
- Huissiers pour vérifier les billets
- Les serveurs vendre de la nourriture
Après avoir vérifié les données envoyées par le gestionnaire, vous déterminez que les serveurs prennent entre 1 et 5 minutes pour terminer une commande. De plus, les huissiers sont remarquablement rapides à vérifier les billets, avec une vitesse moyenne de 3 secondes!
Vous devrez ajouter ces ressources à votre classe et définir les fonctions correspondantes check_ticket ()
et vendre de la nourriture()
. Pouvez-vous comprendre à quoi devrait ressembler le code? Lorsque vous avez une idée, vous pouvez développer le bloc de code ci-dessous pour vérifier votre compréhension:
classe Théâtre(objet):
def __init__(soi, env, num_cashiers, num_servers, num_ushers):
soi.env = env
soi.la caissière = simpy.Ressource(env, num_cashiers)
soi.serveur = simpy.Ressource(env, num_servers)
soi.huissier = simpy.Ressource(env, num_ushers)
def ticket_achat(soi, amateur de cinéma):
rendement soi.env.temps libre(Aléatoire.randint(1, 3))
def check_ticket(soi, amateur de cinéma):
rendement soi.env.temps libre(3 / 60)
def vendre de la nourriture(soi, amateur de cinéma):
rendement soi.env.temps libre(Aléatoire.randint(1, 5))
Examinez de près les nouvelles ressources et fonctions. Remarquez comment ils suivent le même format que celui décrit ci-dessus. vendre de la nourriture()
les usages random.randint ()
pour générer un nombre aléatoire entre 1 et 5 minutes, représentant le temps qu'il faudrait à un cinéphile pour passer une commande et recevoir sa nourriture.
Le délai pour check_ticket ()
est un peu différent car les huissiers ne prennent que 3 secondes. Puisque simpy
fonctionne en quelques minutes, cette valeur doit être transmise en fraction de minute, ou 3/60
.
Se déplacer dans l'environnement: définition de la fonction
D'accord, vous avez configuré l'environnement en définissant une classe. Vous avez des ressources et des processus. Maintenant, vous avez besoin d'un amateur de cinéma
pour les utiliser. Lorsqu'un amateur de cinéma
arrive au théâtre, ils vont demander une ressource, attendre la fin de son processus, puis partir. Vous allez créer une fonction, appelée aller au cinéma()
, pour garder une trace de ceci:
def aller au cinéma(env, amateur de cinéma, théâtre):
# Moviegoer arrive au théâtre
heure d'arrivée = env.maintenant
Trois arguments sont passés à cette fonction:
env
: leamateur de cinéma
sera contrôlé par l'environnement, vous passerez donc ceci comme premier argument.amateur de cinéma
: Cette variable suit chaque personne qui se déplace dans le système.théâtre
: Ce paramètre vous donne accès aux processus que vous avez définis dans la définition de classe globale.
Vous déclarez également une variable heure d'arrivée
de tenir l'heure à laquelle chaque amateur de cinéma
arrive au théâtre. Vous pouvez obtenir cette fois en utilisant le simpy
appeler pour env.now
.
Vous voudrez que chacun des processus de votre théâtre
avoir correspondant demandes dans aller au cinéma()
. Par exemple, le premier processus de la classe est Purchase_ticket ()
, qui utilise un la caissière
Ressource. le amateur de cinéma
devra faire une demande au la caissière
ressource pour les aider à travers le Purchase_ticket ()
processus. Voici un tableau pour résumer ceci:
Processus en théâtre |
Demande en aller au cinéma() |
---|---|
Purchase_ticket () |
Demandez un la caissière |
check_ticket () |
Demandez un huissier |
vendre de la nourriture() |
Demandez un serveur |
Le caissier est une ressource partagée, ce qui signifie que de nombreux cinéphiles utiliseront le même caissier. Cependant, un caissier ne peut aider qu'un seul cinéphile à la fois. Vous devrez donc inclure un comportement d'attente dans votre code. Voici comment cela fonctionne:
def aller au cinéma(env, amateur de cinéma, théâtre):
# Moviegoer arrive au théâtre
heure d'arrivée = env.maintenant
avec théâtre.la caissière.demande() comme demande:
rendement demande
rendement env.processus(théâtre.ticket_achat(amateur de cinéma))
Voici comment ce code fonctionne:
theatre.cashier.request ()
:amateur de cinéma
génère une demande d'utilisation d'unla caissière
.demande de rendement
:amateur de cinéma
attend unla caissière
devenir disponible si tous sont en cours d'utilisation. Pour en savoir plus sur lerendement
, consultez Comment utiliser les générateurs et le rendement en Python.yield env.process ()
:amateur de cinéma
utilise un disponiblela caissière
pour terminer le processus donné. Dans ce cas, c'est pour acheter un billet avec un appel àtheatre.purchase_ticket ()
.
Une fois qu'une ressource est utilisée, elle doit être libérée pour que le prochain agent puisse l'utiliser. Vous pouvez le faire explicitement avec Libération()
, mais dans le code ci-dessus, vous utilisez un avec
à la place. Ce raccourci indique à la simulation de libérer automatiquement la ressource une fois le processus terminé. En d'autres termes, une fois le billet acheté, le amateur de cinéma
partira et le caissier sera automatiquement prêt à prendre le prochain client.
Lorsqu'un caissier est libéré, le amateur de cinéma
passera un certain temps à acheter leur billet. env.process ()
indique à la simulation d’aller au Théâtre
par exemple et exécutez la Purchase_ticket ()
processus sur ce amateur de cinéma
. le amateur de cinéma
va répéter cela demande, utilisation, libération cycle pour faire vérifier son ticket:
def aller au cinéma(env, amateur de cinéma, théâtre):
# Moviegoer arrive au théâtre
heure d'arrivée = env.maintenant
avec théâtre.la caissière.demande() comme demande:
rendement demande
rendement env.processus(théâtre.ticket_achat(amateur de cinéma))
avec théâtre.huissier.demande() comme demande:
rendement demande
rendement env.processus(théâtre.check_ticket(amateur de cinéma))
Ici, la structure du code est la même.
Ensuite, il y a l'étape facultative d'acheter de la nourriture au stand de concession. Vous ne pouvez pas savoir si un cinéphile voudra acheter des collations et des boissons. Une façon de faire face à cette incertitude consiste à introduire un peu de hasard à la fonction.
Chaque amateur de cinéma
voudra ou ne voudra pas acheter de la nourriture, que vous pouvez stocker comme valeurs booléennes Vrai
ou Faux
. Ensuite, utilisez le Aléatoire
module pour que la simulation décide au hasard si oui ou non cette particulier amateur de cinéma
va se rendre au stand de concession:
def aller au cinéma(env, amateur de cinéma, théâtre):
# Moviegoer arrive au théâtre
heure d'arrivée = env.maintenant
avec théâtre.la caissière.demande() comme demande:
rendement demande
rendement env.processus(théâtre.ticket_achat(amateur de cinéma))
avec théâtre.huissier.demande() comme demande:
rendement demande
rendement env.processus(théâtre.check_ticket(amateur de cinéma))
si Aléatoire.choix([[[[Vrai, Faux]):
avec théâtre.serveur.demande() comme demande:
rendement demande
rendement env.processus(théâtre.vendre de la nourriture(amateur de cinéma))
Cette déclaration conditionnelle renverra l'un des deux résultats suivants:
Vrai
: leamateur de cinéma
demandera un serveur et commandera de la nourriture.Faux
: leamateur de cinéma
ira à la place pour trouver leurs sièges sans acheter de collations.
Maintenant, rappelez-vous que le but de cette simulation est de déterminer le nombre de caissiers, d'huissiers et de serveurs qui devraient être sur le personnel pour maintenir les temps d'attente sous 10 minutes. Pour ce faire, vous devez savoir combien de temps il a fallu amateur de cinéma
pour se rendre à leurs sièges. Tu utilises env.now
au début de la fonction pour suivre la heure d'arrivée
, et encore une fois à la fin de chaque amateur de cinéma
est terminé avec tous les processus et se dirige vers le théâtre:
def aller au cinéma(env, amateur de cinéma, théâtre):
# Moviegoer arrive au théâtre
heure d'arrivée = env.maintenant
avec théâtre.la caissière.demande() comme demande:
rendement demande
rendement env.processus(théâtre.ticket_achat(amateur de cinéma))
avec théâtre.huissier.demande() comme demande:
rendement demande
rendement env.processus(théâtre.check_ticket(amateur de cinéma))
si Aléatoire.choix([[[[Vrai, Faux]):
avec théâtre.serveur.demande() comme demande:
rendement demande
rendement env.processus(théâtre.vendre de la nourriture(amateur de cinéma))
# Moviegoer entre dans le théâtre
temps d'attente.ajouter(env.maintenant - heure d'arrivée)
Tu utilises env.now
pour obtenir l'heure à laquelle le amateur de cinéma
a terminé tous les processus et a atteint ses sièges. Vous soustrayez le cinéphile heure d'arrivée
à partir de cette heure de départ et ajouter le décalage horaire résultant à votre liste d'attente, temps d'attente
.
Remarque: Vous pouvez stocker l'heure de départ dans une variable distincte comme heure de départ
, mais cela rendrait votre code très répétitif, ce qui viole le D.R.Y. principe.
Cette amateur de cinéma
est prêt à regarder quelques aperçus!
Faire bouger les choses: définition de la fonction
Vous devez maintenant définir une fonction pour exécuter la simulation. run_theater ()
sera chargé de créer une instance de théâtre et de générer des cinéphiles jusqu'à la fin de la simulation. La première chose que cette fonction devrait faire est de créer une instance de théâtre:
def run_theater(env, num_cashiers, num_servers, num_ushers):
théâtre = Théâtre(env, num_cashiers, num_servers, num_ushers)
Comme il s'agit du processus principal, vous devrez passer toutes les inconnues que vous avez déclarées jusqu'à présent:
num_cashiers
num_servers
num_ushers
Ce sont toutes des variables dont la simulation a besoin pour créer et contrôler l'environnement, il est donc absolument vital de les transmettre toutes. Ensuite, vous définissez une variable théâtre
et dites à la simulation d'installer le théâtre avec un certain nombre de caissiers, de serveurs et d'huissiers.
Vous pouvez également commencer votre simulation avec quelques cinéphiles en attente au théâtre. Il y aura probablement quelques personnes prêtes à partir dès l'ouverture des portes! Le manager dit de s'attendre à environ 3 cinéphiles en ligne prêts à acheter des billets dès l'ouverture du box-office. Vous pouvez dire à la simulation d'avancer et de parcourir ce groupe initial comme suit:
def run_theater(env, num_cashiers, num_servers, num_ushers):
théâtre = Théâtre(env, num_cashiers, num_servers, num_ushers)
pour amateur de cinéma dans intervalle(3):
env.processus(aller au cinéma(env, amateur de cinéma, théâtre))
Tu utilises intervalle()
pour peupler le théâtre avec 3 cinéphiles. Ensuite, vous utilisez env.process ()
pour dire à la simulation de se préparer à les déplacer dans le théâtre. Les autres cinéphiles arriveront au théâtre à leur rythme. Ainsi, la fonction devrait continuer d'envoyer de nouveaux clients dans le théâtre tant que la simulation est en cours.
Vous ne savez pas combien de temps il faudra aux nouveaux cinéphiles pour arriver au cinéma, alors vous décidez de regarder les données passées. En utilisant des reçus horodatés du box-office, vous apprenez que les cinéphiles ont tendance à arriver au théâtre, en moyenne, toutes les 12 secondes. Maintenant, tout ce que vous avez à faire est de dire à la fonction d'attendre aussi longtemps avant de générer une nouvelle personne:
def run_theater(env, num_cashiers, num_servers, num_ushers):
théâtre = Théâtre(env, num_cashiers, num_servers, num_ushers)
pour amateur de cinéma dans intervalle(3):
env.processus(aller au cinéma(env, amateur de cinéma, théâtre))
tandis que Vrai:
rendement env.temps libre(0,20) # Attendez un peu avant de générer une nouvelle personne
# Presque fini!...
Notez que vous utilisez le nombre décimal 0,20
pour représenter 12 secondes. Pour obtenir ce nombre, vous divisez simplement 12 secondes par 60 secondes, ce qui correspond au nombre de secondes en une minute.
Après avoir attendu, la fonction doit incrémenter amateur de cinéma
par 1 et générer la personne suivante. La fonction de générateur est la même que celle utilisée pour initialiser les 3 premiers cinéphiles:
def run_theater(env, num_cashiers, num_servers, num_ushers):
théâtre = Théâtre(env, num_cashiers, num_servers, num_ushers)
pour amateur de cinéma dans intervalle(3):
env.processus(aller au cinéma(env, amateur de cinéma, théâtre))
tandis que Vrai:
rendement env.temps libre(0,20) # Attendez un peu avant de générer une nouvelle personne
amateur de cinéma + = 1
env.processus(aller au cinéma(env, amateur de cinéma, théâtre))
C'est ça! Lorsque vous appelez cette fonction, la simulation générera 3 cinéphiles pour commencer et commencer à les déplacer à travers le théâtre avec aller au cinéma()
. Après cela, les nouveaux cinéphiles arriveront au théâtre avec un intervalle de 12 secondes et se déplaceront dans le théâtre à leur rythme.
Calcul du temps d'attente: définition de la fonction
À ce stade, vous devriez avoir une liste temps d'attente
qui contient le temps total qu'il a fallu à chaque cinéphile pour se rendre à son siège. Vous allez maintenant vouloir définir une fonction pour aider à calculer le temps moyen amateur de cinéma
passe du moment où ils arrivent au moment où ils finissent de vérifier leur billet. get_average_wait_time ()
fait juste ceci:
def get_average_wait_time(temps d'attente):
attente moyenne = statistiques.signifier(temps d'attente)
Cette fonction prend votre temps d'attente
liste comme argument et utilise statistics.mean ()
pour calculer le temps d'attente moyen.
Étant donné que vous créez un script qui sera utilisé par le directeur de la salle de cinéma, vous devez vous assurer que la sortie peut être lue facilement par l'utilisateur. Vous pouvez ajouter une fonction appelée Calculate_wait_time ()
pour faire ça:
def Calculate_wait_time(heure_arrivée, heures de départ):
attente moyenne = statistiques.signifier(temps d'attente)
# Assez imprimé les résultats
minutes, frac_minutes = divmod(attente moyenne, 1)
secondes = frac_minutes * 60
revenir rond(minutes), rond(secondes)
La dernière partie de la fonction utilise divmod ()
pour renvoyer les résultats en minutes et secondes, afin que le gestionnaire puisse facilement comprendre la sortie du programme.
Choix des paramètres: définition de la fonction d'entrée utilisateur
Au fur et à mesure que vous avez construit ces fonctions, vous avez rencontré quelques variables qui n'ont pas été clairement définies:
num_cashiers
num_servers
num_ushers
Ces variables sont les paramètres que vous pouvez changement pour voir comment la simulation change. Si un film à succès a des clients alignés autour du bloc, combien de caissiers devraient travailler? Et si les gens volaient au box-office mais restaient coincés dans les concessions? Quelle valeur de num_servers
aidera à faciliter le flux?
Remarque: C’est la beauté de la simulation. Il vous permet d'essayer ces choses afin que vous puissiez déterminer la meilleure décision possible dans la vie réelle.
Celui qui utilise votre simulation doit pouvoir modifier les valeurs de ces paramètres pour essayer différents scénarios. À cette fin, vous allez créer une fonction d'aide pour obtenir ces valeurs de l'utilisateur:
def get_user_input():
num_cashiers = contribution("Nombre de caisses travaillant:")
num_servers = contribution("# D'entrée de serveurs fonctionnant:")
num_ushers = contribution("Nombre d'huissiers travaillant:")
params = [[[[num_cashiers, num_servers, num_ushers]
si tout(str(je).isdigit() pour je dans params): # Vérifier que l'entrée est valide
params = [[[[int(X) pour X dans params]
autre:
impression(
"Impossible d'analyser l'entrée. La simulation utilisera les valeurs par défaut:",
" n1 caissier, 1 serveur, 1 huissier. ",
)
params = [[[[1, 1, 1]
revenir params
Cette fonction appelle simplement Python contribution()
pour récupérer les données de l'utilisateur. Étant donné que la saisie par l'utilisateur risque d'être désordonnée, vous pouvez inclure un sinon
pour attraper tout ce qui n'est pas valide. Si l'utilisateur entre de mauvaises données, la simulation s'exécutera avec des valeurs par défaut.
Finalisation de la configuration: définition de la fonction principale
La dernière fonction que vous voudrez créer est principale()
. Cela garantira que votre script s'exécute dans le bon ordre lorsque vous l'exécutez sur la ligne de commande. Vous pouvez en savoir plus sur principale()
dans Définition des fonctions principales en Python. Voici ce que votre principale()
devrait ressembler à:
def principale():
# Installer
Aléatoire.la graine(42)
num_cashiers, num_servers, num_ushers = get_user_input()
# Exécutez la simulation
env = simpy.Environnement()
env.processus(run_theater(env, num_cashiers, num_servers, num_ushers))
env.courir(jusqu'à=90)
# Voir les résultats
min, secondes = get_average_wait_time(temps d'attente)
impression(
"Exécution de la simulation ...",
F" nLe temps d'attente moyen est mins minutes et secs secondes. ",
)
Voici comment principale()
travaux:
- Installer votre environnement en déclarant une graine aléatoire. Cela garantit que votre sortie ressemblera à ce que vous voyez dans ce tutoriel.
- Requete l'utilisateur de votre programme pour une entrée.
- Créer l'environnement et l'enregistrer comme variable
env
, qui déplacera la simulation à chaque pas de temps. - Dire
simpy
pour exécuter le processusrun_theater ()
, qui crée l'environnement du théâtre et incite les cinéphiles à s'y déplacer. - Déterminer combien de temps vous souhaitez que la simulation s'exécute. Par défaut, la simulation est configurée pour s'exécuter pendant 90 minutes.
- Boutique la sortie de
get_average_wait_time ()
en deux variables,min
etsecondes
. - Utilisation
impression()
pour montrer les résultats à l'utilisateur.
Avec cela, la configuration est terminée!
Comment exécuter la simulation
Avec seulement quelques lignes de code supplémentaires, vous pourrez voir votre simulation prendre vie. Mais d'abord, voici un aperçu des fonctions et classes que vous avez définies jusqu'à présent:
-
Théâtre
: Cette définition de classe sert de modèle pour l'environnement que vous souhaitez simuler. Il détermine certaines informations sur cet environnement, comme les types de ressources disponibles et les processus qui leur sont associés. -
aller au cinéma()
: Cette fonction fait des demandes explicites pour utiliser une ressource, passe par le processus associé, puis la libère au cinéphile suivant. -
run_theater ()
: Cette fonction contrôle la simulation. Il utilise leThéâtre
plan de classe pour créer une instance d'un théâtre, puis appellealler au cinéma()
pour générer et déplacer les gens à travers le théâtre. -
get_average_wait_time ()
: Cette fonction trouve le temps moyen nécessaire pouramateur de cinéma
pour traverser le théâtre. -
Calculate_wait_time ()
: Cette fonction garantit que la sortie finale est facile à lire pour l'utilisateur. -
get_user_input ()
: Cette fonction permet à l'utilisateur de définir certains paramètres, comme le nombre de caissiers disponibles. -
principale()
: Cette fonction garantit que votre script s'exécute correctement dans la ligne de commande.
Maintenant, il vous suffit de deux lignes de code supplémentaires pour appeler votre fonction principale:
si __Nom__ == '__principale__':
principale()
Avec cela, votre script est prêt à fonctionner! Ouvrez votre terminal, accédez à l'endroit où vous avez stocké simulate.py
et exécutez la commande suivante:
$ python simulate.py
Nombre de caisses travaillant:
Vous serez invité à sélectionner les paramètres souhaités pour votre simulation. Voici à quoi ressemble la sortie avec les paramètres par défaut:
$ python simulate.py
Nombre de caisses travaillant: 1
Nombre de serveurs fonctionnant: 1
Nombre d'huissiers travaillant: 1
Exécution de la simulation ...
Le temps d'attente moyen est de 42 minutes et 53 secondes.
Whoa! C’est long à attendre!
Quand changer les choses
N'oubliez pas que votre objectif est d'approcher le responsable avec une solution pour le nombre d'employés dont il aura besoin pour limiter les temps d'attente à moins de 10 minutes. À cette fin, vous voudrez jouer avec vos paramètres pour voir quels nombres offrent une solution optimale.
Tout d'abord, essayez quelque chose de complètement fou et maximisez les ressources! Disons qu'il y avait 100 caissiers, 100 serveurs et 100 huissiers travaillant dans ce théâtre. Bien sûr, cela est impossible, mais l'utilisation de chiffres incroyablement élevés vous indiquera rapidement quelle est la limite du système. Essayez-le maintenant:
$ python simulate.py
Nombre de caisses travaillant: 100
Nombre de serveurs en entrée: 100
Nombre d'huissiers travaillant: 100
Exécution de la simulation ...
Le temps d'attente moyen est de 3 minutes et 29 secondes.
Même si vous maximisez les ressources, vous n'obtiendrez que des temps d'attente de 3 minutes et demie. Maintenant, essayez de changer les chiffres pour voir si vous pouvez réduire les temps d'attente à 10 minutes, comme le gestionnaire l'a demandé. Quelle solution avez-vous trouvée? Vous pouvez développer le bloc de code ci-dessous pour voir une solution possible:
$ python simulate.py
Nombre de caisses travaillant: 9
Nombre de serveurs en entrée: 6
Nombre d'huissiers travaillant: 1
Exécution de la simulation ...
Le temps d'attente moyen est de 9 minutes et 60 secondes.
À ce stade, vous présenteriez vos résultats au directeur et feriez une suggestion pour aider à améliorer le théâtre. For instance, to cut down on costs, he might want to install 10 ticket kiosks at the front of the theater instead of keeping 10 cashiers on hand each night.
Conclusion
In this tutorial, you’ve learned how to build and run a simulation in Python using the simpy
framework. You’ve come to understand how systems have agents undergo processes, and how you can create virtual representations of those systems to fortify them against congestion and delay. While the type of simulation can vary, the overall execution is the same! You’ll be able to apply what you’ve learned here to a variety of different scenarios.
Now you can:
- Brainstorm a simulation algorithm step by step
- Créer a virtual environment in Python with
simpy
- Define functions that represent agents and processes
- Changement parameters of your simulation to find the optimal solution
There’s so much you can do with simpy
, so don’t let your exploration stop here. Take what you’ve learned and apply it to new scenarios. Your solutions could help save people valuable time and money, so dive in and see what other processes you can optimize! You can download the source code for the script you built in this tutorial by clicking on the link below:
[ad_2]