Etude de cas simulation de banque UML/C++



Documents pareils
Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Le prototype de la fonction main()

Programme Compte bancaire (code)

INFO-F-105 Language de programmation I Séance VI

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

ETUDE DE CAS en UML : GESTION DES COMMANDES DE PIECES FABRIQUEES PAR LA SOCIETE C

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Java Licence Professionnelle CISII,

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Corrigés des premiers exercices sur les classes

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

et Programmation Objet

Introduction à l héritage en C++

Programmation système en C/C++

Programmation en Java IUT GEII (MC-II1) 1

3IS - Système d'exploitation linux - Programmation système

COMPARAISONDESLANGAGESC, C++, JAVA ET

Utilisation d objets : String et ArrayList

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Projet L1, S2, 2015: Simulation de fourmis, Soutenance la semaine du 4 mai.

Package Java.util Classe générique

Introduction à Java. Matthieu Herrb CNRS-LAAS. Mars

Mon premier rpm. 7 juin Avant de commencer RPM URPMI RPMBUILD... 2

Introduction à la programmation concurrente

Architecture des ordinateurs

OS Réseaux et Programmation Système - C5

Développement Logiciel

C++ Programmer. en langage. 8 e édition. Avec une intro aux design patterns et une annexe sur la norme C++11. Claude Delannoy

Introduction au langage C

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

TD3: tableaux avancées, première classe et chaînes

Exceptions. 1 Entrées/sorties. Objectif. Manipuler les exceptions ;

Quelques patterns pour la persistance des objets avec DAO DAO. Principe de base. Utilité des DTOs. Le modèle de conception DTO (Data Transfer Object)

Programmation C++ (débutant)/instructions for, while et do...while

Premiers Pas en Programmation Objet : les Classes et les Objets

Introduction à C++ et à wxwidgets

Une introduction à Java

Programmation avec des objets : Cours 7. Menu du jour

Tp 1 correction. Structures de données (IF2)

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

PROJET 1 : BASE DE DONNÉES REPARTIES

Corrigé des exercices sur les références

Projet de programmation (IK3) : TP n 1 Correction

Chapitre 10. Les interfaces Comparable et Comparator 1

Héritage presque multiple en Java (1/2)

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année


TP1 : Initiation à Java et Eclipse

2. Comprendre les définitions de classes

Informatique III: Programmation en C++

Claude Delannoy. 3 e édition C++

Programmation en C/C++

Le langage C. Séance n 4

Un ordonnanceur stupide

03/04/2007. Tâche 1 Tâche 2 Tâche 3. Système Unix. Time sharing

Cours d initiation à la programmation en C++ Johann Cuenin

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Introduction au pricing d option en finance

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

4. Outils pour la synchronisation F. Boyer, Laboratoire Lig

1. Structure d un programme C. 2. Commentaire: /*..texte */ On utilise aussi le commentaire du C++ qui est valable pour C: 3.

Bases de programmation. Cours 5. Structurer les données

1.6- Génération de nombres aléatoires

Programmer en JAVA. par Tama

Cours 1: Java et les objets

Bases Java - Eclipse / Netbeans

Programmation système I Les entrées/sorties

Département Automatisation et Informatisation Année Programmation en C++ Institut des Sciences et Techniques de l Ingénieur d Angers

Derrière toi Une machine virtuelle!

Algorithmique I. Algorithmique I p.1/??

Exercice sur les Dockers

Langage propre à Oracle basé sur ADA. Offre une extension procédurale à SQL

Java Licence Professionnelle Cours 7 : Classes et méthodes abstraites

Programmation C. Apprendre à développer des programmes simples dans le langage C

Encapsulation. L'encapsulation consiste à rendre les membres d'un objet plus ou moins visibles pour les autres objets.

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Programmation Par Objets

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

Les structures de données. Rajae El Ouazzani

Cours Programmation Système

EPREUVE OPTIONNELLE d INFORMATIQUE CORRIGE

Serveur d'application Client HTML/JS. Apache Thrift Bootcamp

Auto-évaluation Programmation en Java

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

Cours de Systèmes d Exploitation

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Convers3 Documentation version Par Eric DAVID : vtopo@free.fr

Les structures. Chapitre 3

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Durée estimée :1 journée Date de la réalisation : Description Fournisseur Référence Nombre PU HT LM35CZ, LM35AZ LM35DZ

Plan du cours. Historique du langage Nouveautés de Java 7

[APPLICATON REPARTIE DE VENTE AUX ENCHERES]

as Architecture des Systèmes d Information

TD/TP PAC - Programmation n 3

Synchro et Threads Java TM

Approche Contract First

SHERLOCK 7. Version du 01/09/09 JAVASCRIPT 1.5

Algorithmique et Programmation, IMA

Introduction à l algorithmique et à la programmation M1102 CM n 3

Transcription:

Etude de cas simulation de banque UML/C++ Philippe Laroque $Id: simubanque.lyx 1665 2009-03-05 16:02:45Z phil $ laroque@u-cergy.fr mars 2009 Abstract Ce petit document résume, à travers une étude de cas simple, le principe du passage d un modèle UML à un codage C++. L exemple utilise la STL. Il est donné comme corrigé indicatif lors de la formation continue SAGEM en avril 2009. 1 Rappel du sujet Il s agit de simuler le fonctionnement d une banque contenant un nombre fixé de caissiers, et recevant des clients qui arrivent de manière pseudo-aléatoire. Lorsqu un client arrive, si un caissier est libre il prend en charge le client, sinon le client prend place dans une file d attente (supposée commune à tous les caissiers, représentée par exemple par un système de tickets numérotés en ordre croissant). Le but de la simulation est de fournir des résultats statistiques sur les différents acteurs de la simulation. Pour cela, on donne en entrée de la simulation: La durée estimée de la simulation : c est la durée au bout de laquelle la banque n accepte plus de nouveaux clients. Bien entendu, ceux qui se trouvent déjà dans la file seront servis... Le nombre de caissiers. Le temps moyen de service de chaque caissier (on suppose donc qu ils ne sont pas tous également performants...). Le temps moyen entre deux arrivées successives de clients. On souhaite obtenir, à la fin de la simulation, les résultats suivants : La durée réelle de la simulation (c est-à-dire la durée au bout de laquelle tous les clients qui se trouvaient encore dans la file ont été servis). Les longueurs maximale et moyenne de la file d attente. Le nombre de clients servis (au total, et par caissier). Le taux d occupation de chque caissier. Le temps moyen d attente d un client dans la file. 1

Hypothèses de fonctionnement Pour réaliser cette simulation, on adopte un certain nombre d hypothèses simplificatrices : Les clients sont honnêtes (ils ne cherchent pas à passer devant ceux qui étaient là avant eux). Les clients sont patients (quelle que soit la longueur de la file, ils attendent leur tour et ne quittent pas la banque avant d avoir été servis). Les clients sont paresseux (si plusieurs caissiers sont libres lors de l arrivée d un client, ce dernier se fera servir par le caissier de plus faible numéro, celui situé le plus près de la porte d entrée). Les caissiers ne sont jamais fatigués : dès la fin de traitement d un client, le caissier en reprend un si la file n est pas vide. On dispose d un générateur aléatoire permettant de déterminer les arrivées de clients et les temps de service effectifs des caissiers. La simulation repose sur la succession d événements discrets: on suppose qu entre deux événements consécutifs il ne se passe rien de marquant dans le système, donc le temps varie de manière discrète. 2 Modèle UML initial Quelques remarques sur le modèle ci-dessous: les attributs ne figurent pas, ils sont à la charge du développeur de chaque classe; les passages d objets se font tous par adresse, même si le modèle UML ne permet pas de le représenter (même chose en ce qui concerne les objets retournés par une méthode); les associations sont traversables par une méthode (accesseur) du même nom que le rôle. Par exemple, pour accéder à la file d attente depuis la banque b, on écrit en C++ b->fileattente(); Ces méthodes ne sont pas représentées dans le modèle de conception ci-dessous (mais doivent bien sûr être définies!): 2

Poisson init() next(moy : double = 1) : double DiscreteSimulation DiscreteSimulation() add(e : Event) run() time() : double 0.. Event Event(h : double,s : DiscreteSimulation) time() : double fire( Client Client(ha : double) heurearrivee() : double 0.. Depart Depart(h : double,s : DiscreteSimulation,c : Caissier) fire( Arrivee Arrivee(h : double,s : DiscreteSimulation) fire( FileAttente FileAttente(bq : Banque) estvide() : bool longueurmax() : int longueurmoyenne() : double tempsmoyenattente() : double ajouter(c : Client) retirer() : Client Banque Banque() uncaissierlibre() : Caissier nbclientsservis() : int dureeprevue() : double dureereelle() : double tempsmoyenentrearrivees() : double N Caissier Caissier(tms : double,bq : Banque) nbclientsservis() : int estlibre() : bool liberer() tauxoccupation() : double servir(c : Client) Constructeur: les paramètres de la simulation (dureeprevue, nbcaissiers, tservice, tentrearriv ees) 3 Le code source de l application Il est à noter que la version de code source présentée ici ne gère pas proprement les problèmes de mémoire (les classes ne sont pas mises sous forme canonique, les variables allouées dynamiquement ne sont donc pas toutes récupérées). 3.1 Le pattern simulation discrete Les deux classes Event et DiscreteSimulation ont été définies de telle façon qu elles ne dépendent pas de l application, et sont donc entièrement réutilisables (notion de pattern ). 3.1.1 La classe Event / $Id: Event.h 1667 2009-03-10 14:09:08Z phil $ / #ifndef Event_h #define Event_h #include <iostream> #include <string> using namespace std; class DiscreteSimulation; / 3

Event is the abstract root for all event types. It only publishes the time at which it is to fired, and the fire() method (abstract). / class Event { protected: const double _time; DiscreteSimulation ds; public: Event(double h, DiscreteSimulation s) : _time(h) { ds = s; double time() { return _time; virtual void fire() = 0; virtual string type() = 0; friend ostream& operator << (ostream& o, Event& e) { return o << e.type() << "@" << e.time(); ; #endif // 3.1.2 La classe DiscreteSimulation L interface / $Id: DiscreteSimulation.C 1667 2009-03-10 14:09:08Z phil $ / static char rcsid[] = "@(#) $Id: DiscreteSimulation.C 1667 2009-03-10 14:09:08Z phil $"; #include "DiscreteSimulation.h" / Implementation of the DiscreteSimulation class. The insertion of an Event is extremely simple, since the map used to store the events is "naturally" sorted! The run() method iteratively removes the first (that is, "chronologically" next) event from the map, fires it and deletes it. It stops when the map is empty. / void DiscreteSimulation :: add (Event e) { events.insert(e); void DiscreteSimulation :: run() { while (events.size()) { 4

Event e = ((events.begin())); events.erase(events.begin()); _time = e->time(); e->fire(); // cout << e << endl; // uncomment to debug delete e; // L implémentation / $Id: DiscreteSimulation.C 1667 2009-03-10 14:09:08Z phil $ / static char rcsid[] = "@(#) $Id: DiscreteSimulation.C 1667 2009-03-10 14:09:08Z phil $"; #include "DiscreteSimulation.h" / Implementation of the DiscreteSimulation class. The insertion of an Event is extremely simple, since the map used to store the events is "naturally" sorted! The run() method iteratively removes the first (that is, "chronologically" next) event from the map, fires it and deletes it. It stops when the map is empty. / void DiscreteSimulation :: add (Event e) { events.insert(e); void DiscreteSimulation :: run() { while (events.size()) { Event e = ((events.begin())); events.erase(events.begin()); _time = e->time(); e->fire(); // cout << e << endl; // uncomment to debug delete e; // 5

3.2 La classe Arrivee L interface / $Id: Arrivee.C 1664 2009-03-05 14:52:22Z phil $ / static char rcsid[] = "@(#) $Id: Arrivee.C 1664 2009-03-05 14:52:22Z phil $"; #include <iostream> #include "Arrivee.h" #include "Client.h" #include "Caissier.h" #include "FileAttente.h" #include "Poisson.h" #include "Banque.h" using namespace std; / lors d une arrivee : - on cree le client - on calcule l heure de la prochaine arrivee - si cette heure est < duree prevue, on cree la prochaine arrivee et on l ajoute a l echeancier - si un caissier est libre, il sert le client - sinon, le client fait la queue dans la file d attente / void Arrivee :: fire() { // cerr << "Il est " << _time << " : arrivee\n"; Banque s = (Banque) ds; Client c = new Client(_time,s); double next = _time + Poisson::next(s->tempsMoyenEntreArrivees()); if (next < s->dureeprevue()) s->add(new Arrivee(next,s)); Caissier cs = s->uncaissierlibre(); if (cs) cs->servir(c); else s->fileattente()->ajouter(c); // L implémentation / $Id: Arrivee.C 1664 2009-03-05 14:52:22Z phil $ / 6

static char rcsid[] = "@(#) $Id: Arrivee.C 1664 2009-03-05 14:52:22Z phil $"; #include <iostream> #include "Arrivee.h" #include "Client.h" #include "Caissier.h" #include "FileAttente.h" #include "Poisson.h" #include "Banque.h" using namespace std; / lors d une arrivee : - on cree le client - on calcule l heure de la prochaine arrivee - si cette heure est < duree prevue, on cree la prochaine arrivee et on l ajoute a l echeancier - si un caissier est libre, il sert le client - sinon, le client fait la queue dans la file d attente / void Arrivee :: fire() { // cerr << "Il est " << _time << " : arrivee\n"; Banque s = (Banque) ds; Client c = new Client(_time,s); double next = _time + Poisson::next(s->tempsMoyenEntreArrivees()); if (next < s->dureeprevue()) s->add(new Arrivee(next,s)); Caissier cs = s->uncaissierlibre(); if (cs) cs->servir(c); else s->fileattente()->ajouter(c); // 3.3 La classe Banque L interface / $Id: Banque.C 1664 2009-03-05 14:52:22Z phil $ / static char rcsid[] = "@(#) $Id: Banque.C 1664 2009-03-05 14:52:22Z phil $"; #include "Banque.h" #include "FileAttente.h" #include "Caissier.h" #include "Poisson.h" #include "Arrivee.h" 7

/ La banque est responsable de la creation des caissiers et de la file. dans cette version, pas de mise sous forme canonique / Banque :: Banque(double dp, int nbc, double tms, double tma) { _file = new FileAttente(this); _caissiers = new Caissier[nbC]; _nbcaissiers = nbc; _dureeprevue = dp; _tempsmoyenentrearrivees = tma; add(new Arrivee(Poisson::next(tma),this)); Poisson::init(); // initialisation generateur aleatoire for (int i=0; i<nbc;i++) _caissiers[i] = new Caissier(tms[i],this); / retourne le premier caissier disponible, ou 0 si tous pris (implemente donc l hypothese du client paresseux) / Caissier Banque :: uncaissierlibre() { for (int i = 0; i < _nbcaissiers; i++) if (_caissiers[i]->estlibre()) return _caissiers[i]; return 0; / somme des clients servis par les differents caissiers / int Banque :: nbclientsservis() { int res = 0; for (int i = 0; i< _nbcaissiers; i++) { res += _caissiers[i]->nbclientsservis(); return res; // L implémentation / $Id: Banque.C 1664 2009-03-05 14:52:22Z phil $ / static char rcsid[] = "@(#) $Id: Banque.C 1664 2009-03-05 14:52:22Z phil $"; #include "Banque.h" #include "FileAttente.h" #include "Caissier.h" 8

#include "Poisson.h" #include "Arrivee.h" / La banque est responsable de la creation des caissiers et de la file. dans cette version, pas de mise sous forme canonique / Banque :: Banque(double dp, int nbc, double tms, double tma) { _file = new FileAttente(this); _caissiers = new Caissier[nbC]; _nbcaissiers = nbc; _dureeprevue = dp; _tempsmoyenentrearrivees = tma; add(new Arrivee(Poisson::next(tma),this)); Poisson::init(); // initialisation generateur aleatoire for (int i=0; i<nbc;i++) _caissiers[i] = new Caissier(tms[i],this); / retourne le premier caissier disponible, ou 0 si tous pris (implemente donc l hypothese du client paresseux) / Caissier Banque :: uncaissierlibre() { for (int i = 0; i < _nbcaissiers; i++) if (_caissiers[i]->estlibre()) return _caissiers[i]; return 0; / somme des clients servis par les differents caissiers / int Banque :: nbclientsservis() { int res = 0; for (int i = 0; i< _nbcaissiers; i++) { res += _caissiers[i]->nbclientsservis(); return res; // 3.4 La classe Depart L interface / $Id: Depart.C 1665 2009-03-05 16:02:45Z phil $ / static char rcsid[] = "@(#) $Id: Depart.C 1665 2009-03-05 16:02:45Z phil $"; 9

#include <iostream> #include "Depart.h" #include "Banque.h" #include "Client.h" #include "Caissier.h" #include "FileAttente.h" using namespace std; / lors de la fin du service d un caissier, - si la file est vide, le caissier attend - sinon, - le premier client quitte la file - le caissier le sert / void Depart :: fire() { // cerr << "Il est " << _time << " : depart\n"; Banque s = (Banque) ds; if (s->fileattente()->estvide()) _caissier->liberer(); else { Client c = s->fileattente()->retirer(); _caissier->servir(c); delete c; // L implémentation / $Id: Depart.C 1665 2009-03-05 16:02:45Z phil $ / static char rcsid[] = "@(#) $Id: Depart.C 1665 2009-03-05 16:02:45Z phil $"; #include <iostream> #include "Depart.h" #include "Banque.h" #include "Client.h" #include "Caissier.h" #include "FileAttente.h" using namespace std; / lors de la fin du service d un caissier, - si la file est vide, le caissier attend - sinon, - le premier client quitte la file - le caissier le sert 10

/ void Depart :: fire() { // cerr << "Il est " << _time << " : depart\n"; Banque s = (Banque) ds; if (s->fileattente()->estvide()) _caissier->liberer(); else { Client c = s->fileattente()->retirer(); _caissier->servir(c); delete c; // 3.5 La classe FileAttente L interface / $Id: FileAttente.C 1664 2009-03-05 14:52:22Z phil $ / static char rcsid[] = "@(#) $Id: FileAttente.C 1664 2009-03-05 14:52:22Z phil $"; #include "FileAttente.h" #include "Banque.h" #include "Client.h" #include "Caissier.h" / constructeur: mise a zero des parametres internes, memorisation du lien retour vers la banque / FileAttente :: FileAttente(Banque b) { _banque = b; _lmax = 0; _surface = _lmoy = _sommetempsattente = _precedent = 0.0; / valeur moyenne : l integrale temporelle de la longueur sur la duree reelle / double FileAttente :: longueurmoyenne() { return _surface / _banque->dureereelle(); / l ajout physique du client dans la file s accompagne: 11

- d une MAJ de la longueur max le cas echeant - de l ajout d une portion de surface a la valeur de l integrale / void FileAttente :: ajouter(client c) { int s = _clients.size(); double h = _banque->time(); _surface += s (h - _precedent); // valeur du rectangle a ajouter _precedent = h; // memorisation du dernier evt file _clients.push_back(c); if (s >= _lmax) _lmax++; / le retrait physique du client de tete s accompagne: - de l ajout d une portion de surface a la valeur de l integrale / Client FileAttente :: retirer() { int s = _clients.size(); double h = _banque->time(); Client res = _clients.front(); _surface += s (h - _precedent); // valeur du rectangle a ajouter _sommetempsattente += (h - res->heurearrivee()); _precedent = h; // memorisation du dernier evt file _clients.pop_front(); // N.B. : retourne void!! return res; / / double FileAttente :: tempsmoyenattente() { return _sommetempsattente / _banque->nbclientsservis(); // L implémentation / $Id: FileAttente.C 1664 2009-03-05 14:52:22Z phil $ / static char rcsid[] = "@(#) $Id: FileAttente.C 1664 2009-03-05 14:52:22Z phil $"; #include "FileAttente.h" #include "Banque.h" #include "Client.h" #include "Caissier.h" / constructeur: 12

mise a zero des parametres internes, memorisation du lien retour vers la banque / FileAttente :: FileAttente(Banque b) { _banque = b; _lmax = 0; _surface = _lmoy = _sommetempsattente = _precedent = 0.0; / valeur moyenne : l integrale temporelle de la longueur sur la duree reelle / double FileAttente :: longueurmoyenne() { return _surface / _banque->dureereelle(); / l ajout physique du client dans la file s accompagne: - d une MAJ de la longueur max le cas echeant - de l ajout d une portion de surface a la valeur de l integrale / void FileAttente :: ajouter(client c) { int s = _clients.size(); double h = _banque->time(); _surface += s (h - _precedent); // valeur du rectangle a ajouter _precedent = h; // memorisation du dernier evt file _clients.push_back(c); if (s >= _lmax) _lmax++; / le retrait physique du client de tete s accompagne: - de l ajout d une portion de surface a la valeur de l integrale / Client FileAttente :: retirer() { int s = _clients.size(); double h = _banque->time(); Client res = _clients.front(); _surface += s (h - _precedent); // valeur du rectangle a ajouter _sommetempsattente += (h - res->heurearrivee()); _precedent = h; // memorisation du dernier evt file _clients.pop_front(); // N.B. : retourne void!! return res; / / double FileAttente :: tempsmoyenattente() { return _sommetempsattente / _banque->nbclientsservis(); // 13

3.6 La classe Poisson / $Id: Poisson.h 975 2007-01-10 11:09:59Z phil $ / #ifndef Poisson_h #define Poisson_h / Generateur aleatoire de nombre reels positifs suivant une loi de Poisson. la loyenne est fixee par le parametre de la methode de classe next(). par defaut, la moyenne est 1.0 / #include <math.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> class Poisson { public: // permet d avoir des resultats differents a chaque fois // ou de forcer une meme serie aleatoire (param. seed) static void init(int seed = 0) { srandom(seed? seed : getpid()); static double next(double moy = 1.0) { return -log(((double)random()/rand_max))moy; ; #endif // 3.7 Le programme de test / $Id: tbanque.c 1664 2009-03-05 14:52:22Z phil $ / static char rcsid[] = "@(#) $Id: tbanque.c 1664 2009-03-05 14:52:22Z phil $"; #include <iostream> #include <stdio.h> #include "Banque.h" #include "Caissier.h" #include "FileAttente.h" 14

#include <string.h> #include <stdlib.h> using namespace std; / les valeurs par defaut de la simulation : - 2 caissiers (temps de service 1 et 1) - duree de 10 - les clients arrivent tous les 0.6 Ces valeurs peuvent etre modifiees sur la ligne de commande : $ banque [ -dp duree ] [[ -nc nbcaissiers ] -ts temps1...tempsn ] [ -ta tempsarrivees ] avec - -dp pour modifier la duree prevue - -nc pour modifier le nombre de caissiers (il faut alors donner les temps de service de tous les caissiers) - -ts pour modifier les temps moyens de service des caissiers - -ta pour modifier le temps moyen entre deux arrivees successives / int main(int argc, char argv) { // etablissement des valeurs par defaut de la simulation int nbcaissiers = 2; double temps = new double[2]; double tempsarrivees = 0.6; double duree = 10.0; // boucle de lecture des parametres de la ligne de commande int i = 1; temps[0] = temps[1] = 1.0; while (argv[i]) { if (!strcmp(argv[i], "-dp")) sscanf(argv[i+1],"%lf",&duree); else if (!strcmp(argv[i], "-nc")) { sscanf(argv[i+1],"%d",&nbcaissiers); delete [] temps; temps = new double[nbcaissiers]; for (int i = 0; i < nbcaissiers; i++) temps[i] = 1.0; else if (!strcmp(argv[i], "-ta")) sscanf(argv[i+1],"%lf",&tempsarrivees); else if (!strcmp(argv[i], "-ts")) { temps = new double[nbcaissiers]; for (int j =0; j < nbcaissiers; j++) sscanf(argv[i+1+j],"%lf",&temps[j]); i += nbcaissiers-1; else { cerr << "usage: banque [ -dp duree ] [[ -nc nbcaissiers ] -ts temps1...tempsn ] [ -ta tempsarr exit(1); i += 2; 15

// affichage des valeurs des parametres de la simulation cout << "duree : " << duree << "\nnbc : " << nbcaissiers << "\nta : " << tempsarrivees << "\ntps : "; for (int i = 0; i < nbcaissiers ; i++) cout << temps[i] << ; cout << endl; ////////////////////////////////////////////////////////////////////// // creation et lancement de la simulation Banque s(duree,nbcaissiers,temps,tempsarrivees); s.run(); // affichage des resultats FileAttente f = s.fileattente(); cout << "duree Reelle : " << s.dureereelle() << endl; cout << "nb clients : " << s.nbclientsservis() << endl; cout << "lg max file : " << f->longueurmax() << endl; cout << "lg moy file : " << f->longueurmoyenne() << endl; for (int i = 1; i <= nbcaissiers ; i++) { cout << "caissier " << i << " : "; Caissier c = s.caissiers(i); cout << c->tauxoccupation() << "%, " << c->nbclientsservis() << " clients\n"; return 0; // 3.8 Le makefile Seul le début est intéressant, les dépendances générées représentent 10 pages et ne sont pas reproduites: # Makefile pour l application simulation banque # $Id: simubanque.lyx 1665 2009-03-05 16:02:45Z phil $ # ############################################################.C.o : c++ -c $<.o: c++ -o $@ $< ALL = banque all : $(ALL) clean : touch clean simubanque 16

rm -f clean.o.aux.log.dvi.toc.tex.tmp ~ 2> /dev/null rm -rf $(ALL) simubanque 2>/dev/null OBJS = Arrivee.o Banque.o DiscreteSimulation.o Caissier.o \ Depart.o FileAttente.o tbanque.o banque : $(OBJS) c++ -o $@ $(OBJS) && clear &&./banque ############################################################ # gestion des dependances C++ ############################################################ depend: sed /^#DEP/q < Makefile > mk.tmp c++ -M.C >> mk.tmp mv mk.tmp Makefile #DEPENDANCES : NE PAS DETRUIRE Arrivee.o: Arrivee.C /usr/include/c++/4.3/iostream \ /usr/include/c++/4.3/i486-linux-gnu/bits/c++config.h \ /usr/include/c++/4.3/i486-linux-gnu/bits/os defines.h \ [...] 4 Une sortie du programme réalisé bash-2.04$ banque duree : 10 nbc : 2 ta : 0.6 tps : 1 1 duree Reelle : 11.2335 nb clients : 21 lg max file : 4 lg moy file : 1.12115 caissier 1 : 92.0221%, 11 clients caissier 2 : 83.6479%, 10 clients bash-2.04$ banque -dp 100 -nc 3 -ts 2 2 2 duree : 100 nbc : 3 ta : 0.6 tps : 2 2 2 duree Reelle : 113.113 nb clients : 184 lg max file : 25 lg moy file : 12.9794 caissier 1 : 99.0303%, 67 clients caissier 2 : 99.0375%, 62 clients caissier 3 : 98.1438%, 55 clients bash-2.04$ 17

Contents 1 Rappel du sujet 1 2 Modèle UML initial 2 3 Le code source de l application 3 3.1 Le pattern simulation discrete............................ 3 3.1.1 La classe Event.................................. 3 3.1.2 La classe DiscreteSimulation......................... 4 3.2 La classe Arrivee.................................... 6 3.3 La classe Banque..................................... 7 3.4 La classe Depart..................................... 9 3.5 La classe FileAttente.................................. 11 3.6 La classe Poisson.................................... 14 3.7 Le programme de test.................................. 14 3.8 Le makefile........................................ 16 4 Une sortie du programme réalisé 17 18