TITRE DESSUS Mardi 1er décembre 2015 14h00 – 17h00 TITRE DESSOUS Contrôle Final IS1210 Algorithmes. Tous documents autorisés. Calculatrice autorisée. Cet examen comprend 21 pages et son barème est sur 100 points. Nom : Prénom : Avant Propos Il est conseillé de lire l’examen en entier avant de commencer (les exercices sont indépendants les uns des autres). Par défaut, vous êtes invités à répondre directement sur le sujet, dans l’espace prévu entre deux questions. Exceptionnellement, si l’espace manque, utilisez les dernières pages blanches de l’énoncé en reportant soigneusement le numéro de la question. Les pages supplémentaires sont numérotées de 1 à 4 : veuillez, le cas échéant, indiquer soigneusement à l’emplacement initial de la question vers quelle page le correcteur doit se reporter (par exemple, à la Question 1.1, écrire «voir solution page sup. n˚1») Il sera tenu compte du soin de la présentation, et tout particulièrement de la qualité de la description des algorithmes. TITRE DESSUS TITRE DESSOUS TITRE DESSUS Pseudocode et Python Vous pouvez exprimer les algorithmes en pseudocode avec les conventions rappelées ci-dessous. Vous pouvez également utiliser les constructions similaires de Python, à l’exclusion de toute bibliothèque nonstandard. — l’indentation est utilisée pour indiquer la structure de bloc (comme en Python, pas de begin..end ou autres marqueurs), — les types connus sont les booléens, les nombres entiers, les nombres flottants et les caractères — les expressions admises sont composées de : — and, or, not pour les booléens — +, -, *, /, « et » (décalage à droite et à gauche) pour les entiers — +, -, *, / pour les flottants — les variables admises sont de 3 natures différentes : — scalaires : elles sont d’un type de base connu — vectorielles : ce sont des vecteurs d’éléments qui sont tous du même type connu et indicés sur un intervalle [0.. n-1]. On utilisera la notation A[p..q] pour désigner le sous-ensemble du tableau A qui commence à l’indice p et se termine à l’indice q compris. — composées : dans ce cas la variable possède plusieurs propriétés qui sont elles-mêmes d’un type connu. On utilisera A.length pour se référer à la propriété d’un objet. Exemple : — une variable p de type personne peut posséder une propriété age de type entier que l’on notera p.age. — une variable n de type noeud peut posséder deux propriétés de type noeud que l’on notera n.filsGauche et n.filsDroit qui désigneront d’autres noeuds. — la conditionnelle if boolExpr then expr1 else expr2 — l’instruction de boucle définie for i ← depart to arrivee (to ou downto si arrivee est inférieure à départ) — l’instruction de boucle définie for e in collection (collection pouvant être toute collection finie de données : tableau, liste, clés d’un dictionnaire, ensemble) — l’instruction de boucle indéfinie while — l’appel de fonction — les paramètres sont passés par valeur pour les types scalaires, tous les autres sont passés par référence. Une référence qui ne réfère à aucun objet prend la valeur NIL (équivalent à None en Python), — les commentaires sont introduits par #c, — les opérateurs booléens and et or sont court-circuitants. Vous avez le droit d’utiliser les structures de données : tableau (liste en Python), liste chaînée, pile, file, file de priorité, dictionnaire, ensemble sans les redéfinir et en vous appuyant sur la signature des opérations données dans le cours. –2– Complexité Pour chacun des algorithmes suivants, déterminer sa complexité asymptotique. Pour le quatrième algorithme, vous devez de plus indiquer ce qu’il produit en sortie. Les données en entrée sont : — n un entier naturel pour A1(), A2() et A3() — n un entier naturel et A[0..m-1] avec 𝑚 ≥ 𝑛 pour A4() On rappelle que l’opérateur n % m calcule le reste de la division de n par m. Question 1 (2 points) Algorithme A1 : function A1(n) c ← 0 i ← 1 while i < n j ← n while j c ← j ← i ← i * return c Question 2 > 0 c + 1 j - 10 2 (2 points) Algorithme A2 : function A2(n): if n > 2 return 1 + A2(n-3) return 1 –3– Question 3 (2 points) Algorithme A3 : function A3(n) if n > 1 return 1 + A3(n-2)*A3(n-2) return 0 Question 4 (4 points) Algorithme A4 : function A4(A, n) if n = 1 print(A) else for i ← 0 to n - 1 do A4(A, n-1) if n % 2 = 1 permuter A[0] et A[n-1] else permuter A[i] et A[n-1] –4– Arbres de Huffman La chaîne binaire ci-dessous encode le titre d’une chanson en utilisant les codes de Huffman : 0101010001111100100110011010101010001111100100111 Question 1 (6 points) Étant donné la table ci-dessous des fréquences des lettres, construire l’arbre de Huffman. lettre : fréquence : ’-’ 4 ’a’ 3 ’o’ 2 ’l’ 2 ’d’ 2 ’b’ 2 ’ ’ 1 ’i’ 1 Le symbole désigne un espace. En cas d’égalité des priorités, les noeuds sont pris dans l’ordre où ils sont fournis dans le tableau. Les noeuds que vous ajoutez sont insérés après les noeuds de priorité identique. Donnez les étapes de construction des codes de Huffman. –5– Question 2 (2 points) Utiliser cet arbre pour décoder le titre de la chanson. Plus longue suite de valeurs constantes On cherche à écrire une fonction LongestConstantSubarray qui renvoie les bornes d’une plus longue suite de valeurs constantes dans un tableau 𝐴[0..𝑛 − 1]. Si (𝑖, 𝑗) = LongestConstantSubarray(𝐴), alors 𝐴[𝑖..𝑗] est une suite de longueur maximale de valeurs constantes de A : 𝐴[𝑖] = 𝐴[𝑖 + 1] = … = 𝐴[𝑗]. Question 1 (4 points) Donnez un algorithme utilisant une approche force brute pour résoudre ce problème et donnez sa complexité. –6– Question 2 (6 points) Donnez un algorithme de type diviser-pour-régner pour résoudre ce problème et calculez sa complexité. Question 3 (6 points) Donnez un algorithme par programmation dynamique pour résoudre ce problème et calculez sa complexité. –7– Skyline Un immeuble 𝐵 est représenté par un triplet (𝐿 , 𝐻 , 𝑅 ) où 𝐿 et 𝑅 dénotent les abscisses gauche et droite de l’immeuble, et 𝐻 dénote sa hauteur (remarque : les abscisses sont représentées en gras). La ligne d’horizon (skyline) d’un ensemble de 𝑛 immeubles est une liste d’abscisses et des hauteurs qui les relient ordonnées de gauche à droite. Exemple : la ligne d’horizon des immeubles {(3, 13, 9), (1, 11, 5), (12, 7, 16), (14, 3, 25), (19, 18, 22), (2, 6, 7), (23, 13, 29), (23, 4, 28)} est {1, 11, 3, 13, 9, 0, 12, 7, 16, 3, 19, 18, 22, 3, 23, 13, 29, 0}. 𝑦 𝑥 Notez que les abscisses dans une ligne d’horizon sont classées par valeur croissante. –8– Question 1 (6 points) Appelons taille d’une ligne d’horizon, le nombre total d’éléments (abscisses et hauteurs) qui la composent. Décrivez un algorithme pour combiner une ligne d’horizon 𝐴 de taille 𝑛 avec une ligne 𝐵 de taille 𝑛 en une ligne d’horizon 𝐶 de taille 𝑂(𝑛 + 𝑛 ). Votre algorithme doit s’exécuter en temps 𝑂(𝑛 + 𝑛 ). Question 2 (4 points) Décrivez un algorithme qui s’exécute en 𝑂(𝑛 log 𝑛) pour trouver la ligne d’horizon de 𝑛 immeubles. Quelle méthode utilisez-vous ? –9– Articulation On rappelle ici l’algorithme de parcours en profondeur d’un graphe. function DepthFirstSearch(G) for u in V(G) u.color ← WHITE u.parent ← NIL time ← 0 for node u in V(G) if u.color = WHITE DFS-VISIT(G, u) function DFS-VISIT(G, u) time ← time + 1 u.start ← time u.color ← RED for v in Adj[u] if v.color = WHITE v.parent ← u DFS-VISIT(G, v) u.color ← GREEN time ← time + 1 u.finish ← time On définit le graphe 𝐺 = (𝑉, 𝐸 ) où 𝐸 = {(u.parent, 𝑢) ∣ 𝑢 ∈ 𝑉 et u.parent ≠ NIL}. Soit 𝐺 = (𝑉, 𝐸) un graphe non orienté connexe. Un noeud d’articulation est un noeud dont la suppression déconnecte le graphe 𝐺 : le graphe 𝐺 n’est plus connexe après la suppression de ce noeud. Un pont est une arête dont la suppression déconnecte 𝐺. b a e g d p i k lj f m c h – 10 – n o Question 1 (2 points) Montrer que si 𝐺 est un graphe non orienté connexe, alors 𝐺 est un arbre. Qu’en est-il dans le cas général ? Au moment où un noeud 𝑢 est visité (au moment de l’appel DFS-VISIT(u)) que peut on dire des noeuds qui ont une couleur rouge ? Et que peut-on dire des valeurs de l’attribut start pour ces noeuds ? Question 2 (2 points) Donner l’arbre 𝐺 correspondant au graphe ci-dessus. – 11 – Question 3 (2 points) Donner les noeuds d’articulation et les ponts du graphe représenté ci-dessus. Question 4 (4 points) Montrer que la racine de 𝐺 est un noeud d’articulation si et seulement si elle a au moins deux fils dans 𝐺 . – 12 – Question 5 (4 points) On dit qu’une arête (𝑢, 𝑤) est une arête en arrière si 𝑤 est un ancêtre de 𝑢 dans l’arbre 𝐺 . Montrer qu’un noeud 𝑣 de 𝐺 différent de la racine est un noeud d’articulation si et seulement si 𝑣 possède un fils 𝑤 tel qu’il n’existe pas d’arête en arrière de 𝑤 ou de tout descendant de 𝑤 vers un ancêtre propre de 𝑣. Question 6 (6 points) Soit : 𝑓[𝑣] = min({𝑣. start}∪{𝑤. start ∣ (𝑢, 𝑤) est une arête en arrière telle que 𝑢 est un descendant de 𝑣}). Donner un algorithme en 𝑂(|𝐸|) qui calcule 𝑓[𝑣] pour tout noeud 𝑣 ∈ 𝑉. Justifier la complexité. – 13 – Question 7 (6 points) Donner un algorithme en 𝑂(|𝐸|) qui calcule tous les noeuds d’articulation de 𝐺. Justifier la complexité. – 14 – Autoroutes Une société gère un réseau autoroutier qui relie 8 villes que l’on notera A, B, C, E, F, G et H. ce réseau est donné par la matrice suivante : A B C D E F G H A 0 8 6 5 ∞ ∞ 6 15 B 8 0 ∞ 10 14 8 10 ∞ C 6 ∞ 0 5 ∞ ∞ ∞ 8 D 5 10 5 0 6 ∞ ∞ ∞ E ∞ 14 ∞ 6 0 10 ∞ ∞ F ∞ 8 ∞ ∞ 10 0 12 ∞ G 6 10 ∞ ∞ ∞ 12 0 12 H 15 ∞ 8 ∞ ∞ ∞ 12 0 Dans cette matrice 𝑀, le coût 𝑀[𝑖][𝑗] rerpésente le coût en euros du péage de l’autoroute reliant la ville 𝑖 à la ville 𝑗. Bien sûr, 𝑀[𝑖][𝑖] = 0 et 𝑀[𝑖][𝑗] = ∞ si il n’y a pas d’autoroute reliant 𝑖 à 𝑗. Question 1 (1 point) Représenter le graphe de façon planaire, i.e. sans intersection des arêtes. – 15 – Question 2 (5 points) Une agence de tourisme située en 𝐴 veut déterminer les itinéraires les plus économiques vers chacune des autres villes. Comment s’y prend-elle ? Détailler le déroulement des opérations. – 16 – Question 3 (6 points) En raison de problèmes économiques, la société gérant le réseau envisage de fermer momentanément certaines autoroutes. Il faut que le nouveau réseau , extrait du réseau existant, permette d’aller de toute ville à toute autre ville, et soit à la fois minimal en nombre de liaisons et maximal en terme de rentabilité pour la société d’autoroutes. Modéliser le problème. Modifier un algorithme vu en cours pour résoudre le problème. Justifier votre modification. Détailler le déroulement pas à pas sur le graphe proposé ici. – 17 – Navigation Google Maps vous demande d’implémenter un algorithme de navigation dans les conditions suivantes. On vous donne un graphe 𝐺 = (𝑉, 𝐸) où les noeuds sont des intersections et les arêtes sont des routes. La carte est limitée à une grande ville nord américaine et toutes les routes sont orientées nord-sud ou est-ouest. À chaque arête est associée un coût 𝑤(𝑢, 𝑣) qui indique le temps nécessaire pour parcourir la route entre les noeuds 𝑢 et 𝑣. De plus, à chaque arête (𝑢, 𝑣) est associée son orientation 𝑜(𝑢, 𝑣) qui peut être soit NS, soit EO. Chaque fois qu’un conducteur doit tourner à gauche ou à droite, il y a une pénalité supplémentaire 𝑃 qui n’existe pas pour rouler en ligne droite bien sûr. 3 4 3 s 5 13 6 6 4 10 6 11 8 12 9 14 7 1 3 5 t 3 4 s 19 13 6 4 10 +3 6 6 11 19 8 12 9 7 14 +3 1 t La seconde figure illustre le trajet de coût minimal dans le cas où 𝑃 = 3. le coût du trajet est de 5 + 6 + 10 + 𝑃 + 6 + 14 + 𝑃 + 1 = 48. – 18 – Question 1 (6 points) Donner un algorithme efficace qui prend en entrée un tel graphe 𝐺, un noeud origine 𝑠, un noeud destination 𝑡 et la pénalité 𝑃 et qui calcule le coût d’un chemin de coût minimal entre 𝑠 et 𝑡. (Il n’est pas nécessaire de déterminer le chemin, seulement son coût.) Quelle est la complexité de votre solution ? Indice : il est possible d’atteindre la même complexité que celle de l’agorithme de Dijkstra. – 19 – Branch and Bound Une entreprise doit définir une équipe pour prendre en charge une série d’opérations. L’équipe est composée de quatre personnes A, B, C et D. Il y a quatre opérations à entreprendre. Chaque membre de l’équipe prend en charge exactement une opération. Les quatre opérations doivent être réalisées avec succès pour que le projet réussisse. La probabilité qu’un membre donné réussisse une opération donnée est variable, comme le montre la table ci-dessous. A B C D 1 0.9 0.7 0.85 0.75 2 0.8 0.6 0.7 0.7 3 0.9 0.8 0.85 0.75 4 0.85 0.7 0.8 0.7 Si l’assignation choisie était 𝐴 ↔ 1, 𝐵 ↔ 2, 𝐶 ↔ 3 et 𝐷 ↔ 4, alors la probabilité de succès du projet serait de 0.9 × 0.6 × 0.85 × 0.7 = 0.3213. Le manager approuvera le projet si il existe une assignation des opérations aux membres avec une probabilité de succès qui excède 40% 1 . Question 1 (8 points) Donner un algorithme par backtracking pour trouver une telle assignation. Combien de noeuds votre algorithme va-t-il développer ? 1. Originellement, un faute de typographie stipulait 45%. – 20 – Question 2 (8 points) Donner un algorithme par branch-and-bound (séparation-évaluation) pour résoudre ce problème. Expliquer vos stratégies pour : — le choix du prochain noeud, — la séparation des noeuds. Expliquer par quelle méthode vous évaluez les noeuds. Montrez le développement de l’arbre d’exploration. Combien de noeuds votre algorithme va-t-il développer ? – 21 – – Page sup. n°1 – – Page sup. n°2 – – Page sup. n°3 – – Page sup. n°4 –