Ensimag 1A Apprentissage 2012-2013 Algorithmique & Programmation - Examen période 2 ALGORITHMIQUE ET PROGRAMMATION Examen de période 2, 14 mars 2013 Durée 3h, tous documents autorisés. Le barème est indicatif (total sur 22 points). La rédaction de vos réponses devra contenir des commentaires et des explications pertinentes. Sauf indication contraire, le code demandé sera rédigé en Java. Si vous ne connaissez pas la syntaxe d’une classe ou d’une méthode existante, décrivez précisement l’opération attendue. 1 Recherche de points dans un intervalle (17 points) Le but de ce problème est d’étudier une structure de données, nommée RangeTree, permettant de déterminer efficacement quels points, parmi un grand ensemble, se trouvent dans un intervalle donné (en général de petite taille). La première partie étudie le problème en dimension 1 et la seconde étend le problème à 2 dimensions (l’“intervalle“ considéré est alors un rectangle). 1.1 Recherche de points dans un intervalle 1D En 1D, on s’intéresse à un RangeTree contenant des valeur entières. La structure utilisée repose sur un arbre binaire de recherche avec les propriétés suivantes : • chaque noeud de l’arbre porte une étiquette entière v. Pour une feuille, v est une des valeurs stockées (les valeurs sont donc toutes contenues dans les feuilles). Pour un noeud interne, v est la plus grande valeur contenue dans son sous-arbre gauche. • pour tout noeud d’étiquette v, toutes les étiquettes vg dans le sous-arbre gauche vérifient vg ≤ v et toutes les étiquettes vd du sous-arbre droit vérifient vd ≥ v. Autrement dit, un autre noeud portant la même étiquette v peut être stocké soit à gauche soit à droite. • tout noeud interne est de plus étiquetté par un intervalle, qui représente l’intervalle des feuilles contenus dans ses sous-arbres, les bornes étant atteintes. Par exemple sur la figure 1, le noeud interne d’étiquette 14, dont les feuilles sont 10, 14 et 20, porte l’intervalle [10, 20]. • l’arbre est équilibré. Un noeud interne a toujours exactement deux fils, dont les nombres de valeurs portées diffèrent d’au plus 1. 1/8 Ensimag 1A Apprentissage 2012-2013 Algorithmique & Programmation - Examen période 2 [3,20] 6 [3,6] [6,20] 3 8 [3,3] [6,8] [3,6] 3 [10,20] 4 7 [3,4] [3,3] [6,7] [10,14] [3,3] 3 3 14 3 3 3 3 3 3 6 6 4 6 8 7 10 10 20 14 Figure 1: Exemple de RangeTree 1D contenant {3, 3, 3, 3, 3, 4, 6, 6, 7, 8, 10, 14, 20}. Question 1 : propriétés de l’arbre équilibré (1 point) 1. Soit n le nombre de valeurs stockées dans l’arbre, qui a donc n feuilles. Combien l’arbre contient-il de noeuds internes? (valeur exacte en fonction de n). Le démonstrer par récurrence. 2. Quelle est la hauteur de l’arbre en fonction de n? (par convention, la hauteur de l’arbre vide est -1). 1.1.1 Représentation de l’arbre, construction et affichage Un RangeTree 1D est un objet de la classe Arbre, qui contient comme seul attribut la racine de l’arbre de type Noeud : public class Arbre { private Noeud racine = null ; // precondition : le tableau valeurs est trie par ordre croissant public Arbre ( int [] valeurs ) { if ( valeurs . length > 0) { racine = construitArbre ( valeurs , 0 , valeurs . length - 1); } } // METHODES A COMPLETER DANS LES QUESTIONS SUIVANTES private Noeud construitArbre ( int [] valeurs , int indInf , int indSup ) { 2/8 Ensimag 1A Apprentissage 2012-2013 Algorithmique & Programmation - Examen période 2 ... } public String toString () { ... } public String toString ( int a , int b ) { ... } public Iterator < Integer > iterator ( int a , int b ) { ... } } La hiérarchie des noeuds est composée classiquement d’une classe Noeud abstraite, héritée par deux classes concrètes Interne et Feuille. Question 2 : classes de la hiérarchie des noeuds (1 point) D’après les propriétés décrites en section 1.1, écrire la structure des classes Noeud, Interne et représentant les différents noeuds d’un RangeTree. Dans cette question, préciser uniquement les attributs et constructeurs des classes. Feuille Question 3 : construction de l’arbre (3 points) L’arbre est construit directement à partir d’un tableau trié contenant l’ensemble des valeurs. 1. écrire la méthode de la classe Arbre : private Noeud construitArbre ( int [] valeurs , int indInf , int indSup ) En précondition, le tableau valeurs est supposé trié, et les indices vérifient 0 ≤ indInf ≤ indSup ≤ valeurs.length. La méthode retourne la racine de l’arbre binaire de recherche, équilibré, dont les feuilles sont tous les éléments du tableau valeurs compris entre les indices indInf et indSup. Tous les champs des noeuds de l’arbre doivent être renseignés (valeur v, et intervalle pour les noeuds internes). Indication : rien à ajouter a priori dans la hiérarchie des noeuds. 2. quel est son coût, pour un tableau de n valeurs? 3/8 Ensimag 1A Apprentissage 2012-2013 Algorithmique & Programmation - Examen période 2 Question 4 : affichage de toutes les valeurs (0,5 points) Ecrire la méthode de la classe Arbre qui retourne une chaı̂ne contenant toutes les valeurs d’un RangeTree : public String toString () Si nécessaire, écrire toute méthode supplémentaire à ajouter dans la hiérarchie des noeuds. 1.1.2 Recherche de valeurs dans un intervalle On s’intéresse désormais à la recherche de toutes les valeurs contenues dans un intervalle donné. Soit la méthode (déclarée abstraite) de la classe Noeud : abstract protected Noeud chercheValeurs ( int a , int b ); L’objectif est de retourner un nouvel arbre, utilisant des noeuds de type Interne ou Feuille, dont les feuilles sont le sous-ensemble des feuilles de l’arbre initial qui sont contenues dans l’intervalle considéré [a, b]. Cet arbre résultat ne sera utilisé que pour être parcouru en entier, par exemple pour l’affichage des valeurs dans l’intervalle. Ses propriétés sont donc : • il peut réutiliser des noeuds existants de l’arbre initial (sans les modifier) • il n’est pas forcément équilibré au sens de l’énoncé • il suffit que ses feuilles soient les bonnes et dans le bon ordre • les étiquettes des noeuds internes ne sont pas utilisées et n’ont pas à respecter les propriétés d’un RangeTree vues en section 1.1. Par exemple, la méthode invoquée sur l’arbre de la figure 1 pour l’intervalle [6, 9] pourrait retourner un noeud Interne ayant pour fils gauche la première feuille de valeur 6 et pour fils droit le noeud interne de valeur 7 et d’intervalle [6,8]. Question 5 : arbre contenant les valeurs d’un intervalle (2 points) Soit un noeud interne r portant la valeur v et d’intervalle [min, max]. On cherche toutes les feuilles de r dont les valeurs sont contenues dans un intervalle [a, b]. 1. En fonction de a, b, min, max et v, quel(s) sous-arbre(s) du noeud r doivent être explorés pendant la recherche? (justification avec un shéma et/ou des explications en français) 2. Ecrire l’implémentation de la méthode abstract public Noeud chercheValeurs ( int a , int b ); dans les classes Interne et Noeud. 4/8 Ensimag 1A Apprentissage 2012-2013 Algorithmique & Programmation - Examen période 2 Question 6 : affichage des valeurs dans un intervalle (1 point) 1. Ecrire la méthode public String toString ( int a , int b ); de la classe Arbre qui retourne une chaı̂ne contenant toutes les valeurs d’un arbre RangeTree dans l’intervalle [a, b]. (Vous pouvez bien sûr utiliser les méthodes des questions précédentes, même si elles n’ont pas été écrites...) 2. Quelle est la complexité de cette méthode pour un arbre à n noeuds dont m sont contenus dans l’intervalle recherché ? Question 7 : itérateur dans un intervalle (3 points) Ecrire maintenant tout le code nécessaire pour une méthode de la classe Arbre retournant un itérateur sur toutes les valeurs d’un arbre comprises dans un intervalle : public Iterator < Integer > iterator ( int a , int b ); Attention : il n’est pas autorisé d’utiliser l’opérateur instanceof ou toute autre méthode en simulant le comportement (genre boolean estFeuille() dans la classe Feuille...). Indication : ajouter une méthode dans la hirérarchie des noeuds! 5/8 Ensimag 1A Apprentissage 2012-2013 1.2 Algorithmique & Programmation - Examen période 2 Recherche de points dans un intervalle en 2D On s’intéresse maintenant au même problème mais en deux dimensions. On se limite à des données de type point du plan, munis de deux attributs entiers x et y. L’idée de la structure de donnée est de superposer l’ordre selon la première dimension et l’ordre selon la deuxième. L’arbre principal de la structure est un arbre binaire de recherche équilibré (mêmes propriétés qu’en dimension 1) ordonné selon la première dimension. A chaque nœud interne de cet arbre est en plus associé un arbre binaire de recherche équilibré qui porte exactement les mêmes feuilles, mais ordonné cette fois selon la dimension 2. ytree [1,4] (2,1) [1,3] [1,2] [3,4] (1,3) ytree (4,2) (3,3) [1,2] ytree [3,3] (2,1) (1,3) (2,1) (3,3) (4,2) [1,3] [2,3] (2,1) (2,1) (2,1) (3,3) (4,2) (3,3) (1,3) (4,2) (1,3) (4,2) (3,3) Figure 2: Example de RangeTree 2D représentant les points (1,3), (2,1), (3,3) et (4,2). L’arbre principal est ordonné suivant la 1ère dimension x. A chaque noeud interne est associé un arbre 1D contenant les mêmes feuilles mais ordonné selon la 2ème dimension y. Question 8 : coût mémoire (1 point) Quelle est la place occupée en mémoire par un RangeTree 2D stockant n points? Question 9 : représentation des classes 2D (1 point) Quelle serait la structure des classes pour représenter un arbre en 2D? Indiquer clairement tous les attributs de chaque classe. 6/8 Ensimag 1A Apprentissage 2012-2013 Algorithmique & Programmation - Examen période 2 Question 10 : construction de l’arbre 2D (2 points) 1. Ecrire un algorithme permettant de construire un RangeTree 2D à partir d’un tableau de n points (en fait l’équivalent de la méthode construitArbre(...) de la classe Arbre vue en section 1.1.1) . Vous pouvez écrire du peuso-code ou une méthode en Java, le but est de comprendre votre algorithme. Bien spécifier les rôles et entrées/sorties des fonctions/sousfonctions, le cas échéant. 2. Quel est son coût, pour un arbre à n points? Question 11 : recherche en 2D (1,5 points) 1. Quelle est le principe d’une méthode public String toString ( int xMin , int xMax , int yMin , yMax ); qui retourne une chaı̂ne contenant tous les points d’un arbre contenus dans un rectangle [xMin,xMax]×[yMin,yMax] ? 2. Quelle est le coût de la recherche en 2 dimensions, pour un arbre à n points dont m sont dans le rectangle considéré ? 7/8 Ensimag 1A Apprentissage 2012-2013 2 Algorithmique & Programmation - Examen période 2 Elément majoritaire (5 points) Un tableau possède un élément majoritaire si et seulement si plus de la moitié (strictement) de ses éléments sont identiques. Étant donné un tableau tab de taille n > 0, on s’intéresse à la méthode Java (et tout autre sous-méthode nécessaire le cas échéant) : static E elemMajo ( E [] tab ); qui retourne l’élément majoritaire trouvé dans le tableau tab s’il existe, null sinon. Les éléments sont d’un type générique E sur lequel il n’existe pas de relation d’ordre. Il n’est pas possible d’effectuer des comparaisons de la forme x < y, mais seulement de tester l’égalité de deux valeurs (en temps constant) : x.equals(b). Question 12 : algorithmes “simples” (2 points) 1. Proposer un algorithme simple mais qui n’utilise aucun coût mémoire supplémentaire (hors variables locales, en O(1)). Donner sa complexité temporelle en fonction de n. 2. Proposer une solution plus efficace en temps, si un coût mémoire plus élevé est accepté (indication : utiliser une structure de donnée intermédiaire). Donner les coûts en temps et mémoire correspondants. Question 13 : diviser pour régner (3 points) Une autre approche consiste à utiliser le paradigme “diviser pour régner” en divisant le tableau tab et deux moitiés tab1 et tab2. 1. Expliquer comment déduire le résultat sur tab des résultats sur tab1 et tab2 (expliciter les différents cas possibles). 2. Ecrire le code de elemMajo correspondant. 3. Indiquer le meilleur et le pire des cas possibles, et les côuts en temps associés. 8/8