Enseignant : Claude-Guy Quimper Date de remise : 26 février 2017, 23h59. IFT-3001 (Hiver 2017) Travail 1 Les travaux remis en retard ne seront pas corrigés et se verront attribuer la note de zéro. À moins de spécifications contraires, vous devez toujours pleinement justifier vos réponses. Il s agit d un travail individuel. Toute communication ou entraide avec une autre personne au sujet de ce travail est interdite. Le code de programmation doit pouvoir compiler avec g++ 4.9.2. À partir d une connexion VPN, vous pouvez compiler votre code sur cette page web : http://geyron.fsg.ulaval.ca. Format de remise : Vous devez remettre un fichier zip contenant un fichier PDF par question. La structure du fichier zip ne doit pas contenir de sous-répertoire et doit seulement contenir les fichiers : Question1.pdf, vecteur.cpp, Question2.pdf et Question3.pdf. Votre nom, prénom et matricule doivent apparaître dans l en-tête de chaque page. Question # 1: [25 points] Les fichiers vecteur.cpp et vecteur.hpp contiennent la définition d une classe Vecteur. Elle permet de créer un vecteur vide d entiers doté d une capacité. La méthode ajouteentier ajoute un entier à la fin du vecteur et la méthode supprimeentier supprime un entier à une position passée en paramètre. Ces deux méthodes font augmenter ou réduire de 1 la taille du vecteur, c est-à-dire le nombre d entiers dans le vecteur, que nous notons n. La taille du vecteur ne peut pas dépasser sa capacité. Le fichier main.cpp, quant à lui, contient une série de tests unitaires. a) Analysez en meilleur cas, en pire cas et en cas moyen l efficacité de la méthode supprimeentier. Votre analyse doit être faite en fonction de n, la taille du vecteur. Justifiez votre choix d instruction baromètre. Justifiez les instances choisies pour représenter le pire cas et le meilleur cas. Pour l analyse en cas moyen, les n instances possibles sont la suppression d un élément à un index entre 0 et n 1 et toutes ces instances sont équiprobables. Exprimez vos réponses à l aide de la notation asymptotique Θ. b) Vous devez écrire la méthode supprimeentiers qui prend en entrée un vecteur d index et qui supprime tous les entiers à ces positions. Vous devez analyser votre méthode en pire cas en fonction de la taille du vecteur avant la suppression des entiers. Pour obtenir tous les points à cette question, vous devez, sans utiliser de librairie de programmation externe, programmer une fonction dont l efficacité en pire cas est T W ORST (n) Θ(n) 1. Pour obtenir une partie des points, vous pouvez utiliser un algorithme de tri d une librairie externe en supposant que son efficacité 1. Ici, n est la taille du vecteur dont les éléments sont supprimés. Vous pouvez supposer que la taille du vecteur d index est inférieure, ou égale, à n. 1
est dans Θ(n log n) dans tous les cas. Finalement, aucun point ne sera accordé pour une solution dont l efficacité en pire cas est dans Ω(n 2 ). Votre code doit passer les tests unitaires du fichier main.cpp. Il pourrait être soumis à d autres tests unitaires qui ne vous sont pas donnés. Votre fichier vecteur.cpp doit compiler avec les fichiers vecteur.hpp et main.cpp originaux. Livrables : 1. Un fichier Question1.pdf contenant les analyses demandées en a) et en b). 2. Le fichier vecteur.cpp modifié. 2
Question # 2: [25 points] Analysez les algorithmes suivants. Si l efficacité de l algorithme ne dépend pas uniquement de la taille de l instance, procédez à une analyse en pire cas et en meilleur cas. Donnez l ordre de croissance de l efficacité de l algorithme en utilisant la notation asymptotique Θ. N utilisez que les relations de l aide-mémoire pour simplifier les sommations dans vos calculs. Algorithme 1 : PremierAlgorithme(n) c 0; for i = 1..n do for j = i 3..n 3 do c c + 1; for i = 1.. n do c c + 1; return c; Algorithme 2 : TriBizarre(A[l..r]) // Si le vecteur a deux éléments ou plus; if l < r then // Si le premier élément est plus grand que le dernier élément; if A[l] > A[r] then // Échange le premier élément avec le dernier élément; t A[l]; A[l] A[r]; A[r] t; // Si le vecteur a trois éléments ou plus; if l + 1 < r then k r l+1 3 ; TriBizarre(A[l..r k]) // Trie les deux premiers tiers du vecteur; TriBizarre(A[l + k..r]) // Trie les deux derniers tiers du vecteur; TriBizarre(A[l..r k]) // Trie, une seconde fois, les deux premiers tiers du vecteur; 3
Question # 3: [25 points] Résolvez la récurrence suivante avec la substitution à rebours. { 0 si n 1 C(n) = 2C( n 3 ) + n si n > 1 Vous devez faire au moins deux substitutions. Vous pouvez supposer que n est une puissance d un entier. Vous devez trouver la formule exacte de la récurrence et non pas son ordre de croissance. N utilisez que les sommations de l aide-mémoire pour simplifier votre résultat. Le résultat final doit être dans sa forme la plus simple possible, donc ne laissez pas de logarithmes dans les exposants. 4
Question # 4: [25 points] Une matrice triangulaire inférieure est une matrice carrée telle que toutes les entrées A[i, j], pour j > i, sont nulles. Nous pouvons décomposer une matrice triangulaire inférieure en quatre sous-matrices de la façon suivante. [ ] A1 0 A = (1) A 2 A 3 Si A est une matrice triangulaire inférieure de dimension n n, alors A 1 et A 3 sont des matrices triangulaires inférieures de dimensions n n, A 2 2 2 est une matrice de dimensions n n qui n est pas 2 2 nécessairement triangulaire et 0 est la matrice nulle de dimensions n n. En utilisant la relation 2 2 suivante, concevez et analysez un algorithme de type «diviser pour régner» qui calcule l inverse d une matrice triangulaire inférieure inversible de dimension n n où n est une puissance de 2. [ ] A 1 A 1 1 0 = A 1 3 A 2 A 1 1 A 1 (2) 3 Voici les étapes à suivre : 1. Téléchargez le code de programmation pour cette question ; 2. Parcourez les fichiers Strassen.hpp et Strassen.cpp et voyez comment l algorithme de Strassen a été programmé ; 3. Modifiez le fichier inverse.cpp (et uniquement ce fichier) pour y écrire votre algorithme qui inverse une matrice triangulaire inférieure. 4. Dans un fichier nommé Question4.pdf, présentez l analyse de votre algorithme. Attention, les opérateurs + et sur les matrices ne sont pas des opérations élémentaires. Si le temps d exécution de votre algorithme ne dépend pas uniquement de la taille de l instance, mais bien de l instance elle-même, alors faites une analyse en meilleur cas et en pire cas (mais pas en cas moyen). Si le temps d exécution de votre algorithme dépend uniquement de la taille de l instance, alors faites une analyse pour tous les cas. 5