Master 2 Année 2014/2015 Analyse d’Algorithmes et Génération Aléatoire Examen Réparti 1 Appareils électroniques interdits. Seuls documents autorisés : Notes de cours et de TD/TME. Le sujet comporte 4 exercices indépendants et le barème est indicatif. Exercice 1 : Générateur linéaire congruentiel (4 points) Un générateur linéaire congruentiel est basé sur l’équation suivante : Xn+1 = (aXn + c) mod m X0 fixé, appelé graine. 1. a, c, m et X0 étant fixés, quel est le plus grand ensemble d’entiers qui peut être généré ? 2. a, c et m étant fixés, quelque soit X0 , la suite d’entiers générés est périodique : le justifier. On fixe pour la fin de l’exercice a = 6, c = 9 et m = 15. 6 × 5 = 30 6 × 6 = 36 Nous rappelons une partie de la table de 6 : 6 × 7 = 42 6 × 8 = 48 6 × 9 = 54 6 × 10 = 60 6 × 11 = 66 6 × 12 = 72 6 × 13 = 78 6 × 14 = 84 3. Pour la graine X0 = 0, quelle est la suite infinie générée ? Puisqu’on ne peut pas écrire en 2h une suite infinie, expliquer son contenu (tout en le justifiant). 4. Pour la graine X0 = 1, quelle est la suite infinie générée ? On rappelle que la période d’un générateur est la période la plus petite d’une suite d’entiers générés, quelque soit la graine utilisée. 5. Quelle est la période de ce générateur ? Justifier la réponse. Exercice 2 : Générateur non uniforme d’entiers (8 points) On a à notre disposition un générateur pseudo aléatoire de bits. Les bits générés sont indépendant les uns des autres et suivent la distribution uniforme. La fonction BitSuivant() renvoie un bit uniformément. Génération uniforme Soit n un entier supérieur à 1, et ` = dlog2 ne. On souhaite générer uniformément un entier entre 0 et n − 1 inclus. Pour ce faire, on génère ` bits et suivant l’entier qu’ils représentent, soit on renvoie cet entier, soit on recommence. 1. Donner le pseudo-code de la fonction RandUnif qui prend un argument entier n et qui renvoie un entier uniformément entre 0 et n − 1 inclus. On fera appel à la fonction BitSuivant(). 2. Justifier la correction de l’algorithme, c’est-à-dire le fait que que l’entier renvoyé par RandUnif(n) est choisi uniformément au hasard, quelque soit la valeur de n. 1 3. Peut-on prouver la terminaison de l’algorithme ? Quel est le problème de la fonction RandUnif lorsqu’elle est appelée sur certains n ? Quelles sont ces valeurs problématiques ? Pour les questions 4 à 9 (incluses), supposons n = 5, et donc ` = 3. 4. Quelle est la probabilité d’avoir exactement 0 rejet et donc d’utiliser 3 bits pour générer un entier ? (à justifier) 5. Quelle est la probabilité d’avoir exactement un rejet et donc d’utiliser 6 bits pour générer un entier ? (à justifier) 6. Quelle est la probabilité d’avoir exactement deux rejets pour générer un entier ? (à justifier) 7. Soit r un entier positif ou nul. Quelle est la probabilité d’avoir exactement r rejets pour générer un entier ? (à justifier) 8. Prouver que l’appel à la fonction RandUnif(5) termine presque sûrement, c’est-à-dire que la probabilité que la fonction termine tend vers 1. 9. Quel est le nombre moyen de rejets nécessaires à l’appel à la fonction RandUnif(5) ? Génération non uniforme Soit n un entier supérieur à 1, on a à notre disposition une fonction RandUnif qui, pour le paramètre n, renvoie uniformément un entier entre 0 et n − 1. On souhaite faire de la génération dans un multi-ensemble. On a r entiers (de 0 à r − 1), chacun associé à un poids (entier positif ). Par exemple aux entiers entre 0 et 3, on associe les poids respectifs 1, 2, 3, 1. C’est-à-dire que l’entier 0 a chance d’apparaître, l’entier 1 a 2/7 chance d’apparaître, l’entier 2 a 3/7 chance d’apparaître et l’entier 3 1 a /7 chance d’apparaître. 1/7 On souhaite générer successivement (et indépendamment) k entiers dans {0, 1, . . . , r − 1} suivant la distribution D fixée. 10. Proposer une structure de données permettant d’encoder les différentes données et un algorithme permettant de générer ces k entiers. On s’autorise une complexité temporelle en O(k) recherches dans la structure de données, et une complexité spatiale en O(n), où n est la somme des poids des entiers entre 0 et r − 1. 11. Justifier les complexités. Exercice 3 : Arbre binaire croissant (4 points) Un arbre binaire croissant est un arbre binaire, dont les nœuds internes sont d’arité 2 (un fils gauche et un fils droit) et les feuilles (nœuds externes) sont d’arité 0. On appelle taille de l’arbre son nombre de nœuds internes. De plus, chaque nœud interne porte une étiquette qui est un entier entre 1 et la taille de l’arbre. Toutes les étiquettes sont distinctes et enfin, les suites d étiquettes de chaque branche, en partant de la racine de l’arbre vers une feuille, sont croissantes. Voilà un exemple d’arbre binaire croissant de taille 4. Les feuilles sont représentées par des •. 1 2 • • 4 • 3 • 2 • 1. Dessiner tous les arbres binaires croissants de taille 0 à taille 4. Pour générer uniformément un arbre de taille n on itère n fois l’étape suivante (en partant de l’arbre de taille 0). A l’étape i (pour i de 1 à n), on choisit une feuille uniformément parmi les i feuilles de l’arbre déjà construit. Puis on la remplace par un nœud interne étiqueté par i dont chacun des deux fils est une feuille. 2. Dessiner les 4 étapes permettant de générer un arbre de taille 4. Mettre en évidence les feuilles choisies lors de chacune des étapes. 3. Donner une structure de données permettant d’encoder un arbre. On a à notre disposition rand prenant un entier i en argument et renvoyant un entier uniformément entre 0 et i − 1. 4. Donner le pseudo-code d’un générateur d’arbres binaires croissants. Les complexités spatiale et temporelles doivent être en O(n). Justifier que l’algorithme vérifie les complexités annoncées. Exercice 4 : Arbre binaire (4 points) Un arbre binaire est un arbre binaire, dont les nœuds internes sont d’arité 2 (un fils gauche et un fils droit) et les feuilles (nœuds externes) sont d’arité 0. On appelle taille de l’arbre son nombre de nœuds internes. On dispose d’un tableau C, tel que la case C[n] contient le nombre d’arbres binaires de taille n. On rappelle la formule de récurrence : C[n] = n−1 X C[i] × C[n − 1 − i]. i=0 On a à notre disposition rand prenant un entier i en argument et renvoyant un entier uniformément entre 0 et i − 1. 1. Donner le pseudo-code d’un générateur d’arbres binaires de taille n, sachant que C est rempli pour les case de 0 à n inclus. 2. Donner les complexités spatiale et temporelle de l’algorithme. 3