1 ©Arnaud de Saint Julien -Informatique- MPSI Lycée La Merci 2015-2016 Feuille d’exercices n°4 : Complexité et preuves d’algorithmes Exercice 1 Dans cet exercice truc et bidule désignent deux instructions et n un entier naturel. Déterminer en fonction de n pour chaque script le nombre de fois où les instructions truc et bidule sont exécutées. # script 1 for i in range(n): truc for j in range(n): bidule # script 2 for i in range(n): truc for j in range(n): bidule # script 3 for i in range(n): truc for j in range(i,n): bidule Exercice 2 Déterminer pour chacun des scripts le nombre d’opérations significatives effectuées, en déduire leur complexité en fonction de n. # script 1 n = 100 p = 0 for i in range(n): for j in range(n): for k in range(n): s = 2 * s # script 2 n = 100 p = 0 for i in range(n): s = s + 3 for j in range(n): s = s + 3 # script 3 n = 20 s = 0 for i in range(n): for j in range(i,n): s = s + j**2 # script 4 n = 100 p = 1 for i in range(n): for j in range(i-5,i+5): p = 2*p # script 5 n = 100 s = 0 for i in range(n): a = n while a > 1: a = a/2 s += 1 # script 6 n = 20 i = n s = 0 while i > 1: for j in range(i): s = s + 1 i = i/2 Exercice 3 (Terminaison et complexité) Étudier la terminaison des scripts suivants et déterminer le cas échéant le nombre d’itérations. # script 1 n = 100 a = 1 while a < n: a = a + 5 # script 2 n = 10**8 a = 1 while a < n: a = 2 * a a = 100 while a >= 0: a = a//2 Exercice 4 (Invariant de boucle) Justifier la terminaison puis démontrer que la fonction suivante renvoie le produit de a par b en utilisant l’invariant de boucle p = i × b. def multiplication(a,b): p = 0 i = 0 while i < a: p = p + b i = i + 1 return p Exercice 5 (Invariant de boucle) Démontrer que : «à l’entrée de la boucle i, la variable maximum est égale à max{t[0], t[1], . . . , t[i − 1]}». C’est un invariant de boucle. En déduire que maxi(t) renvoie bien le maximum des éléments de t. def maxi(t): """Données: t un tableau d’entiers Résultat: le maximum des éléments de t""" 2 ©Arnaud de Saint Julien -Informatique- MPSI Lycée La Merci 2015-2016 n =len(t) if n == 0: return None # cas où le tableau est vide maximum = t[0] for k in range(1,n): if t[k] > maximum: maximum = t[k] return maximum Exercice 6 (Liste de nombres premiers) On considère la fonction suivante est_premier qui teste la primalité d’un entier. def est_premier(n): if n < 2: return False d = 2 while d**2 <= n: if n % d == 0: return False d = d + 1 return True 1. Tracer la fonction avec n = 35 et n = 31. 2. Si k > 1, on note dk la valeur de la variable d à la fin de la k-ième itération de la boucle while. On convient que d0 = 2. Déterminer dk , en déduire que l’algorithme se termine. 3. Combien de divisions sont nécessaires au pire pour tester la primalité d’un entier naturel n ? 4. Peut-on remplacer la boucle while par une boucle for ? Si, oui quel peut-être l’inconvénient ? 5. Écrire une fonction liste_premiers qui prend en argument un entier n et renvoie la liste des nombres premiers inférieurs ou égaux à n. 6. Déterminer une majoration du nombre de divisions effectuées lorsque l’on exécute liste_premiers(n). En déduire, pour déterminer la liste des nombres premiers inférieurs ou égaux à n si l’on utilise est_premier. 7. En déduire la complexité de liste_premiers. On pourra utliser librement que si f : [1, +∞[→ R+ est P une fonction continue et croissante telle que la série f (n) diverge, alors : N X k=1 f (k) ∼N →+∞ Z N f (t) dt. 1 Remarque : cet algorithme n’est pas très performant, on préfèrera utiliser l’algorithme du crible d’Eratosthène bien plus efficace, dont la complexité temporelle est quasi-linéaire en O(n ln n). Exercice 7 (Une suite récurrente) Soit u la suite définie par u0 = 1 et pour n ∈ N, un+1 = sin(un ). 1. Écrire une fonction nommée suite prenant n ∈ N en argument et renvoyant un . 2. Que calcule la fonction suivante : def mystere(n): s = 0 for k in range(n+1): s = s + suite(k) return s 3. Déterminer en fonction de n le nombre d’additions et de calculs de sinus nécessaires pour calculer mystere(n). 3 ©Arnaud de Saint Julien -Informatique- MPSI Lycée La Merci 2015-2016 4. Écrire une autre fonction qui renvoie les mêmes valeurs que mystere mais avec une meilleure complexité. Exercice 8 (Une suite récurrente d’ordre 3) Soit u la suite définie par u0 = 1, u1 = −2, u3 = 5 et ∀n ∈ N, un+3 = −2un+2 + un+1 − un . On veut calculer u50 . On propose deux méthodes : 1. Première méthode : créer un tableau d’entiers de longueur 51 dont les trois premiers élements sont u0 , u1 , u2 . Compléter ensuite ce tableau de sorte que ses éléments soient u0 , u1 , . . . , u49 , u50 . 2. Déterminer les complexités temporelles et spatiales de votre programme. 3. Deuxième méthode : proposer une autre méthode plus économique du point de vue de la mémoire. Exercice 9 (Nombres de Bell) Les nombres de Bell Bn sont définies par B0 = 1 et ∀n ∈ N, Bn+1 = n X n k=0 k Bk 1. Écrire une fonction prenant en argument un entier naturel n et renvoyant la valeur de Bn . On pourra réutiliser une fonction binomial créée précédemment. 2. Déterminer la complexité de votre programme. Exercice 10 (Dichotomie et juste prix) On veut écrire un script qui demande à l’utilisateur de deviner un nombre entre 1 et 100 qui a été choisi aléatoirement. Si la réponse de l’utilisateur est fausse, le programme indique si sa réponse est trop grande ou trop petite et l’utilisateur peut à nouveau faire une proposition. Le programme ne doit se terminer que si la bonne réponse est donnée. On utilisera une technique de dichotomie