Download Algorithmique 1 - Ensiwiki
Transcript
Ensimag 1ère année — Algorithmique 1 Examen 1ère session — Janvier 2009 Algorithmique 1 Durée : 3h Machines électroniques interdites Tous documents papiers autorisés Les deux parties du sujet sont indépendantes. Veuillez rendre ces deux parties sur des feuilles séparées. Veuillez respecter les notations introduites dans l’énoncé. Il est inutile de paraphraser l’énoncé dans vos réponses, mais des explications avec dessins sur votre code sont les bienvenues. Dans l’ensemble de cet examen, on travaille avec le type Liste des listes simplement chaı̂nées, introduit par les définitions suivantes : type Cellule ; type Liste i s a c c e s s Cellule ; type Cellule i s record Val : Integer ; Suiv : Liste ; end record ; procedure Liberer i s new Ada . U n c h e c k e d _ D e a l l o c a t i o n ( Cellule , Liste ); Figure 1 – Définition du type Liste 2008-2009 page : 1/5 Ensimag 1ère année — Algorithmique 1 Examen 1ère session — Janvier 2009 package FilePrio i s subtype Elt i s Integer range ...; f u n c t i o n EstVide return Boolean ; -- retourne True ssi la file ne contient aucun élément . procedure Vider ; -- garantit EstVide = True procedure Inserer ( X : i n Elt ); -- garantit une nouvelle occurrence de X est insérée dans la file . procedure DetruireMax ( Max : out Elt ); -- requiert EstVide = False -- garantit une occurrence de Max est retirée de la file , -et Max est >= à tous les éléments restants dans la file . end FilePrio ; Figure 2 – Interface de FilePrio En supposant Elt’First<=3 et 10<=Elt’Last, on considère la séquence ci-contre. A l’issue de cette séquence, la variable X vaut 10. La file de priorités contient ici les éléments suivants : “3” en deux exemplaires, “5” en quatre exemplaires, et “10” en un exemplaire. Si on fait ensuite un nouvel appel à DetruireMax (X), la variable X vaut encore 10, mais la file ne contient plus l’élément 10. Le maximum de la file est donc 5 (en quatre exemplaires). X : Elt ; begin ... Vider ; Inserer (3); Inserer (10); Inserer (5); Inserer (5); Inserer (10); Inserer (5); Inserer (3); Inserer (5); DetruireMax ( X ); Figure 3 – Exemple d’utilisation de FilePrio L’implémentation par tableau utilise les deux variables globales : NbOcc : array ( Elt ) o f Natural ; MaxFile : Elt ; L’invariant satisfait par ces deux variables du paquetage est la conjonction des deux propriétés : 1. si NbOcc = (others => 0) alors MaxFile = Elt’First ; 2. si NbOcc /= (others => 0) alors NbOcc (MaxFile) /= 0 et pour tout I : Elt tel que NbOcc (I) /= 0, on a I <= MaxFile. Figure 4 – Variables globales de FilePrio dans implém. par tableau 2008-2009 page : 2/5 Ensimag 1ère année — Algorithmique 1 Examen 1ère session — Janvier 2009 I - Files de priorités (12 points) L’objectif de cet exercice est d’étudier différentes implémentations d’une structure de données appelée file de priorités. Les implémentations abordées ici sont relativement naı̈ves. Des implémentations plus efficaces seront traitées au deuxième semestre. On travaille ici avec un paquetage FilePrio dont l’interface est donnée figure 2 page 2. L’état interne de ce paquetage représente une suite ordonnée d’éléments, appelée file de priorités. Ces éléments sont du type Elt, un sous-type intervalle de Integer. L’ordre sur les éléments est donc l’ordre par défaut sur Integer. Le mode d’emploi du paquetage précise que l’état initial (au chargement du programme) n’est pas défini. Il faut donc commencer par appeler Vider avant d’utiliser le reste du paquetage. La figure 3 page 2 donne un exemple d’utilisation du paquetage. Dans la suite, on note N le cardinal de Elt (le nombre d’éléments de l’intervalle Elt’Range). ⊲ Question 1 (1 point) : Utiliser ce paquetage pour définir une procédure Tri qui ordonne les éléments d’un tableau T suivant l’ordre décroissant. type Tab i s array ( Integer range < >) o f Elt ; procedure Tri ( T : i n out Tab ); 1 Implémentation par un tableau Dans un premier temps, on suppose que N est relativement petit. On représente la file par un tableau NbOcc qui associe à chaque élément son nombre d’occurrences (ou d’exemplaires) dans la suite. Voir figure 4 page 2. Par exemple, à l’issue de la suite d’instructions donnée à la figure 3, on a : NbOcc = (3 => 2, 5 => 4, 10 => 1, others => 0) Pour rendre DetruireMax plus efficace, on calcule à l’avance le maximum courant de la file dans une variable globale appelée MaxFile. Typiquement pour le NbOcc de l’exemple précédent, MaxFile=10. Plus précisément, ces 2 variables doivent satisfaire l’invariant du paquetage donné figure 4 page 2 : si la file est vide, MaxFile vaut Elt’First, sinon il vaut l’élément maximum de la file. ⊲ Question 2 (4 points) : Implémenter les sous-programmes du paquetage en optimisant les temps de calculs autant que possible. 1. Écrire Vider (0,5 point) : cette procédure doit établir l’invariant. 2. Écrire EstVide (0,5 point) en utilisant l’invariant : le coût en temps de cette fonction est constant en fonction de N . 3. Écrire Inserer (1 point) : cette procédure doit préserver l’invariant. 4. Écrire DetruireMax (1,5 points) : cette procédure doit préserver l’invariant. 2008-2009 page : 3/5 Ensimag 1ère année — Algorithmique 1 2 Examen 1ère session — Janvier 2009 Deux implémentations par une liste chaı̂née Maintenant, on étudie deux autres implémentations du paquetage, qui peuvent être intéressantes par rapport à l’implémentation précédente lorsque N est grand et que le nombre d’occurrences de chaque éléments de la file reste faible. Dans ces deux implémentations, le paquetage n’a qu’une seule variable globale interne qui est une liste simplement chaı̂née de type Liste (défini figure 1 page 1). Cette liste a une sentinelle de tête pour rendre les algorithmes réguliers. Dans votre code, vous devez utiliser cette sentinelle, et éviter des analyses par cas inutiles. Cette sentinelle est allouée à l’initialisation du paquetage et elle n’est jamais libérée. Cette variable est donc simplement appelée Senti et déclarée comme ci-dessous dans le paquetage : Senti : Liste := new Cellule ; Dans les deux implémentations, l’invariant du paquetage garantit que Senti est une liste simplement chaı̂née non vide et bien formée (sans cycle et sans pointeur pendant), et que les éléments de la file sont ceux accessibles depuis la liste de tête Senti.Suiv. Par exemple, les deux listes chaı̂nées dessinées ci-dessous peuvent représenter la file obtenue à l’issue de la séquence donnée figure 3. Dans cette figure le champ Val de la cellule pointée par Senti est laissée vide pour signifier que sa valeur n’est jamais utilisée. 2008-2009 Senti Senti Val Suiv Val Suiv Val Suiv 5 Val Suiv 10 Val Suiv 3 Val Suiv 5 Val Suiv 5 Val Suiv 5 Val Suiv 5 Val Suiv 5 Val Suiv 5 Val Suiv 5 Val Suiv 10 Val Suiv 3 Val Suiv 3 null Val Suiv 3 null page : 4/5 Ensimag 1ère année — Algorithmique 1 Examen 1ère session — Janvier 2009 ⊲ Question 3 (1 point) : Programmer EstVide et Vider en respectant le fait que Senti est une sentinelle de tête. la procédure Vider doit libérer les éventuelles cellules devenant inutilisées. 2.1 Première implémentation Dans la première des 2 implémentations utilisant Senti, on ne contraint pas davantage l’invariant sur Senti. ⊲ Question 4 (1 point) : Écrire la procédure Inserer de sorte qu’elle place la nouvelle occurrence de X en tête de liste (dans le suivant de la sentinelle). ⊲ Question 5 (1 point) : Écrire une fonction interne au paquetage, appelée CherchePredMax qui a la spécification suivante : f u n c t i o n CherchePredMax return Liste i s -- requiert la file contient au moins un élément . -- retourne un pointeur P non nul accessible depuis Senti -tel que le suivant de P est non nul -et la valeur de la cellule suivant P -est le max des éléments de la file . ⊲ Question 6 (1 point) : Utiliser CherchePredMax pour écrire DetruireMax. La procédure DetruireMax doit libérer la cellule qui n’est plus utilisée. 2.2 Deuxième implémentation Dans cette dernière implémentation, on contraint maintenant l’invariant sur Senti à garantir que la liste dont la tête est Senti.Suiv est triée par ordre décroissant sur les éléments (comme sur le dessin de droite, page 4). ⊲ Question 7 (2 points) : Reprogrammer Inserer et DetruireMax pour respecter ce nouvel invariant. La procédure DetruireMax doit libérer la cellule qui n’est plus utilisée. 2008-2009 page : 5/5