Vous êtes sur la page 1sur 7

Fiche de TP INF311

Cette fiche de TP contient 9 travaux pratiques. Les étudiants seront divisés en 9 groupes équitablement
repartis. Chaque groupe aura en charge la réalisation d’un travail pratique. La restitution des travaux
pratique se fera à partir du lundi 06 Décembre 2021. Chaque groupe dans l’ordre présentera son travail.
La note de TP comptera pour 30% de la note finale de CC.

Travail pratique 1 : Flocon de Von Koch

L’objectif de ce TP est de créer une frise de flocon de Von Koch, comme l’exemple de l’image ci-
dessous .

Pour ce faire, la première étape est le dessin du Flocon de Von Koch. Le flocon de Von Koch est une
fractale dont des approximations arbitrairement proches peuvent être obtenues de la manière récurrente
par l’algorithme suivant :

1. Commencer à partir d’une ligne polygonale quelconque du plan. (Le flocon canonique de Von
Koch se construit à partir d’un triangle équilatéral ayant une base parallèle à l’axe des abscisses.)

2. Pour chaque segment de la ligne on divise le segment en trois segments de longueurs égales, on
construit un triangle équilatéral ayant pour base le segment médian et on supprime le segment
qui était la base du triangle.

3. Recommencer à la deuxième étape avec la nouvelle ligne polygonale obtenue.

Pour programmer le dessin du flocon de Von Koch, l’étudiant réalisera les fonctions suivantes en
étudiant la complexité théorique.

Page 1 sur 7
Fiche de TP INF311

a) Programmer une fonction


construire_chapeau(extremites)
qui prend en argument un tableau
extrémités de taille 2 × 2 contenant
les coordonnées des extrémités
d’un segment et qui renvoie un
tableau points de taille 2 × 5
contenant les coordonnées des
sommets de la ligne polygonale (« le chapeau de sorcière ») construite à partir de ce segment à
l’étape 2 de l’algorithme.

b) Programmer une fonction von_koch(sommets, n) qui


construit la n-ième approximation du flocon de von
Koch. La fonction von_koch prend en argument un
tableau sommets à deux lignes contenant les
coordonnées des sommets de la ligne polygonale de
départ et un entier n. Elle renvoie un tableau points_renv à deux lignes contenant les
coordonnées des sommets de la n-ième approximation du flocon de von Koch. On définira la
fonction
von_koch de manière récursive. Pour n = 1 la fonction von_koch construit un « chapeau de
sorcière » sur chaque segment de la ligne définie par sommets et renvoi les sommets de la ligne
obtenue. La figure ci-contre donne un exemple pour n=2.

c) Tracez les flocons de von Koch construits à partir d’un segment de droite et d’un triangle
équilatéral.

d) Faites une étude expérimentale de la complexité du tracé du flocon de Von Koch, tracer le
fonction de complexité par rapport à n et comparer à la complexité théorique calculée dans la
question précédente.

Un fois la fonction de tracé de Von Koch implémenté, l’objectif est maintenant de dessinez la frise de n
flocons de Von Koch. Pour ce faire suivez les étapes suivantes :

e) Calculer les coordonnées les centres de gravité des n triangles équilatéraux avec la condition
que deux triangles équilatéraux successifs ont un sommet en commun. La figure ci-dessous
donne l’exemple pour n=5

f) En fonction des coordonnées du point de gravité, calculez les coordonnées des sommets pour
tous le triangles. Calculez la complexité théorique pour le calcul de ces coordonnées.

g) Utilisez ces coordonnées et la fonction de tracé du flocon de Von Koch pour tracer la frise de
flocon de Von Koch pour n.

Travail pratique 2 : Crible d’Erathosthène

On se propose de calculer tous les nombres premiers plus petits qu’un entier 𝑛 > 1 donné. La
méthode consiste à calculer pas à pas ces nombres en utilisant la règle suivante :

Page 2 sur 7
Fiche de TP INF311

• si un entier 𝑘 n’est divisible par aucun nombre premier plus petit que 𝑘 alors il est lui-
même premier.

1. Quelles sont les structures de données qu’on peut utiliser pour résoudre ce problème ?
Quelle est la plus efficace ?

2. Ecrire la fonction Eratosthène qui calcule les nombres premiers plus petits que 𝑛 passé
en paramètre.

Travail pratique 3 : Les Tour de Hanoï

Les tours de Hanoï sont un jeu inventé par le mathématicien Édouard Lucas. Le jeu est constitué
de trois emplacements sur lesquels on peut empiler des disques de tailles différentes. Au départ
on commence avec tous les disques empilés sur le premier emplacement du plus grand (en
dessous) au plus petit. Le but du jeu est de déplacer toute la tour sur un des deux autres
emplacements, en ne déplaçant qu’un seul disque à la fois, sans jamais poser un disque sur un
disque plus petit que lui (si vous ne connaissez pas le jeu et que vous n’avez rien compris à
l’explication, allez voir sur la page wikipedia, il y a des photos et une animation expliquant le
fonctionnement). On va écrire une fonction qui décrit les coups à jouer pour déplacer une tour
de taille n sur un autre emplacement. On représente les n disques par des entiers de 1 à n (n
étant le plus grand disque) et les piles qui se trouvent sur chacun des emplacements par une liste
Python (le fond de la pile au début de la liste).

La résolution du problème des tours de Hanoï est extrêmement récursive. Si l’on sait déplacer
les (n−1) premiers disques d’un emplacement à un autre, pour déplacer les n disques de
l’emplacement 0 à l’emplacement 1, on va déplacer les (n − 1) premiers disques de
l’emplacement 0 à l’emplacement 2, puis déplacer le disque n sur l’emplacement 1 et
redéplacer les (n − 1) disques de l’emplacement 2 à l’emplacement 1. Bien évidemment, le
déplacement des (n − 1) disques se fait récursivement en supposant qu’on sait déplacer (n − 2)
disques...

1. Écrivez la fonction récursive hanoi (n, i, j, k, t) qui déplace les disques de 1 à n de


l’emplacement i à l’emplacement j en utilisant l’emplacement k comme stockage
temporaire (t désigne la liste de listes qui représente l’état des tours au départ). Après
chaque déplacement d’un disque (en utilisant la fonction saut (i, j, t)), appelez la
fonction affiche(t) pour afficher à l’écran chaque étape de la résolution.
Remarque : Le fait de donner le troisième emplacement (k) en argument à la fonction peut
paraître inutile puisqu’il ne sert pas directement, mais ça simplifie grandement l’écriture de la
fonction car ce troisième emplacement va être un argument important pour les appels
récursifs.
2. Réalisez l’étude de la complexité de cet algorithme. Réalisez une étude théorique et
une étude expérimentale restituée à l’aide d’un diagramme en bande.

Travail pratique 4 : Evaluation d’un polynôme (Polynôme de Horner)

Un polynôme est une expression de la forme 𝑃(𝑥) = ∑𝑑𝑖=0 𝑐𝑖 𝑥 𝑖

On suppose de plus que 𝑐𝑑 ≠ 0 (c’est-à-dire que d est le degré de P ). On stocke un polynôme sous la
forme d’une structure contenant deux variables : le degré d et un tableaux C[0..d] contenant les
coefficients. On veut calculer la valeur de P(x) pour une valeur de x donnée.

Page 3 sur 7
Fiche de TP INF311

1. En utilisant la fonction puissance précédente écrire un programme qui répond au problème.


(Utilisez les différentes approches de calcul de 𝑥 𝑖 )

2. Pour chaque approche, quels sont les nombres d’opérations (additions, multiplications)
effectués dans le calcul précédent ? Quel est sa complexité théorique ?

3. Réalisez une étude expérimentale de la complexité pour chaque approche, comparez les.

Une première amélioration consiste à accumuler en même temps la valeur de P(x) et les valeurs des
puissances de x.

4. Écrire le programme correspondant. Quels sont les nombres d’opérations effectués dans cette
méthode ? Quel est sa complexité théorique ?

En fait, on peut faire encore mieux en utilisant la méthode de Hörner. Elle provient de l’écriture
suivante du polynôme :

𝑃𝑛 (𝑥) = (… ((𝑎𝑛 𝑥 + 𝑎𝑛−1 )𝑥 + 𝑎𝑛−2 )𝑥 + ⋯ + 𝑎1 )𝑥 + 𝑎0


5. Écrire le programme correspondant. Quels sont les nombres d’opérations effectués dans cette
méthode ? Quel est sa complexité théorique ?

6. Réalisez une étude expérimentale de la complexité des deux derniers programmes et comparez
les à la première étude expérimentale.

Travail pratique 5 : Multiplication de deux polynômes (Algorithme de Karatsuba)

1. Montrez comment multiplier deux polynômes linéaires 𝑎𝑥 + 𝑏 et 𝑐𝑥 + 𝑑 à l’aide de trois


multiplications seulement. (Indication : l’une des multiplications est (a + b)(c + d).)
2. Programmez deux algorithmes « diviser pour régner » permettant de multiplier deux
polynômes de degré au plus n et s’exécutant en 𝜃(𝑛𝑙𝑜𝑔23 ).

a) Le premier algorithme devra couper les coefficients du polynôme d’entrée en deux


moitiés, l’une supérieure et l’autre inférieure.
b) Le second algorithme devra séparer les coefficients du polynôme d’entrée selon
la partie de leur indice.

3. Montrez que deux entiers à n bits peuvent être multipliés en 𝜃(𝑛𝑙𝑜𝑔23 ) étapes.
4. En examinant la croissance des temps de calcul, essayez de voir si la multiplication
de grands entiers est programmée de manière naïve ou avec Karatsuba.

Travail pratique 6 : Algorithme de Vigenère

Considérons l’algorithme de chiffrement de chaînes de caractères dit « de Vigenère ». Il consiste à «


additionner » les caractères du texte à chiffrer avec ceux d’une clé de chiffrement. Par exemple, le
chiffrement de la chaîne « Cherchez au pied de l’arbre » avec la clé « indice » peut s’illustrer ainsi :

• on place la clé en regard du texte à chiffrer, en répétant la clé autant de fois que nécessaire pour
couvrir le texte, et en ignorant les caractères qui ne sont pas des lettres (ils seront laissés
inchangés par l’algorithme de chiffrement) :
C h e r c h e z a u p i e d d e l ‘ a r b r e
i n d i c e i n d i c e i n d i c ‘ e i n d i

Page 4 sur 7
Fiche de TP INF311

• on remplace chaque lettre de la clé par sa position dans l’alphabet (0 pour ‘a’, 1 pour ‘b’…),
C h e r c h e z a u p i e d d e l ‘ a r b r e
8 13 3 8 2 4 8 13 3 8 2 4 8 13 3 8 2 ‘ 4 8 13 3 8

• on remplace chaque lettre du texte à chiffrer par la lettre située d positions plus loin dans
l’alphabet, où d est le nombre indiqué par la clé (si on dépasse z, on reboucle sur a, b etc.) :
C h e r c h e z a u p i e d d e l ‘ a r b r e
K u h z e l m m d c r m m q g m n ‘ e z o u m

Notez qu’une lettre identique dans le texte à chiffrer ne produit pas forcément le même code (ex. le
premier et deuxième e de Cherchez donnent respectivement un h et un m). Et notez qu’un même code
n’est pas forcément issu d’une même lettre (ex. les deux m successifs du troisième mot sont issus d’un
i et d’un e). Cela rend le processus de décryptage très difficile sans la clé.

1. Si x est le code ASCII d’une lettre à chiffrer et y le code ASCII de la lettre de la clé située en
regard, quelle formule permet de calculer le code ASCII résultant ? On supposera pour cette
question que les deux lettres sont des minuscules.

2. Ecrire la fonction chiffer (texte, clé) : code, qui prend en entrée un texte et une clé et produit
en sortie un texte correspondant au texte chiffré. On considèrera que texte contient un ou
plusieurs caractères suivis d’un caractère de terminaison ‘\n’. clé
contient une ou plusieurs lettres minuscules suivie de ‘\n’. code contient la version cryptée de
texte. Seules les lettres (majuscules ou minuscules) non accentuées sont cryptées, les autres
caractères sont recopiés tels quels, incluant la place pour le caractère de terminaison

3. Supposons que l’on veuille chiffrer, avec une clé de longueur k, une chaîne constituée
exclusivement de n minuscules, avec n > k.

• Comptez le nombre d’opérations de chaque type (affectations d’entiers, comparaison


de caractères, etc.) pour évaluer la complexité en temps de cet algorithme de
chiffrement. Déterminez la complexité théorique.

• Proposez une étude expérimentale de la complexité suivant les paramètre n et k.


Proposez un diagramme de surface (fonction de deux variables).

• Qui de n ou de k influence le plus le temps d’exécution ? Ce temps sera-t-il plus long


ou plus court avec une plus longue clé ?

4. Donner un invariant de la boucle introduite dans la procédure chiffrer


5. Fait de même pour la fonction chiffer (code, clé) : texte

Travail pratique 7 : La plus longue sous séquence communes

Une séquence est une suite finie de symboles pris dans un ensemble fini. Si 𝑢 = (𝑎1 , 𝑎2 , … , 𝑎𝑛 ) est une
séquence, où 𝑎1 , 𝑎2 , … , 𝑎𝑛 sont des lettres, l’entier n est la longueur de u. Une séquence 𝑣 =
(𝑏1 , 𝑏2 , … , 𝑏𝑚 )est une sous-séquence de 𝑢 = (𝑎1 , 𝑎2 , … , 𝑎𝑛 ) s’il existe des entiers 𝑖1 , 𝑖2 , … , 𝑖𝑚 avec
(1 ≤ 𝑖1 ≤ 𝑖2 ≤ ⋯ ≤ 𝑖𝑚 ≤ 𝑛) tels que 𝑏𝑘 = 𝑎𝑖𝑘 pour 𝑘 ∈ [1. . 𝑚]. Par exemple, 𝑣 = (𝐵, 𝐶, 𝐷, 𝐵) est une
sous-séquence de 𝑢 = (𝐴, 𝐵, 𝐶, 𝐷, 𝐵, 𝐴, 𝐵) correspondant à la suite d’indice (2; 3; 5; 7).

Une séquence w est une sous-séquence commune aux séquences u et v si w est une sous-séquence de u
et de v. Une sous-séquence commune est maximale ou est une plus longue sous-séquence si elle est de

Page 5 sur 7
Fiche de TP INF311

longueur maximale. Par exemple : les séquences (𝐵, 𝐶, 𝐵, 𝐴) et (𝐵, 𝐷, 𝐴, 𝐵) sont les plus longues sous-
séquences communes de (𝐴, 𝐵, 𝐶, 𝐵, 𝐷, 𝐴, 𝐵) et de (𝐵, 𝐷, 𝐶, 𝐴, 𝐵, 𝐴).

Résolution par programmation dynamique

1. On cherche à déterminer la longueur d’une sous-séquence commune maximale à 𝑢 =


(𝑎1 , 𝑎2 , … , 𝑎𝑛 ) et 𝑣 = (𝑏1 , 𝑏2 , … , 𝑏𝑚 ) . On note 𝐿(𝑖, 𝑗) la longueur d’une sous-séquence
commune maximale à u et v avec 0 ≤ 𝑖 ≤ 𝑛 𝑒𝑡 0 ≤ 𝑗 ≤ 𝑚). Donnez une récurrence définissant
𝐿(𝑖, 𝑗). Indication : on pourra distinguer les cas 𝑎𝑖 = 𝑏𝑗 𝑒𝑡 𝑎𝑖 ≠ 𝑏𝑗 .
2. Ecrivez alors une fonction récursive calculant la longueur de la plus longue sous-séquence
commune de deux séquences.

3. Montrez que cet algorithme est de complexité au moins exponentielle dans le cas où les deux
séquences n’ont pas d’éléments en commun.

4. Ecrivez alors une fonction suivant le paradigme de la programmation dynamique et calculant la


longueur de la plus longue sous-séquence commune de deux séquences.

5. Quelle est la complexité de cet algorithme ?

6. Modifiez l’algorithme précédent pour que l’on puisse en plus construire une plus longue sous-
séquence commune et affichez une telle sous-séquence.

Travail pratique 8 : Primalité

On appelle nombres de Carmichael les entiers 𝑛 non premiers vérifiant l’égalité de Fermat :
∀ 𝑎 ∈ ℵ, 𝑎𝑛 ≡ 𝑎 𝑚𝑜𝑑 𝑛.

1. Déterminer le plus petit nombre de Carmichael.

On donne le critère suivant (Korselt, 1899) : 𝑛 est un nombre de Carmichael si et seulement si :


aucun carré de nombre premier ne divise n (on dit que n est sans facteur carré) et pour chaque diviseur
premier p de n, le nombre p − 1 divise n − 1. De plus, un tel n divise tous les an – a (même pour a non
premier à n).
2. Ecrire une fonction qui retourne les nombres de Carmichael inférieur à une valeur seuil donnée.
3. Déterminé la complexité théorique et expérimentale de cette fonction

Soit 𝑛 un entier impair, on pose 𝑛 − 1 = 2𝑘 𝑚 avec 𝑚 impair. Si 𝑛 est premier, alors pour tout
entier 𝑎 < 𝑛 on a :
𝑜𝑢 𝑏𝑖𝑒𝑛 𝑎𝑚 ≡ 1 𝑚𝑜𝑑 𝑛
{ 𝑖
𝑜𝑢 𝑏𝑖𝑒𝑛 ∃ 𝑖 ∈ [0 . . 𝑘 − 1], 𝑎2 𝑚 ≡ −1 𝑚𝑜𝑑 𝑛

4. Écrire une fonction miller(n,a) qui vérifie que 𝑛 passe le test de Miller pour l’entier 𝑎. On ne
factorisera pas 𝑛 − 1.
5. Ecrire une fonction qui donne le nombre d’entiers 𝑎 permettant de prouver la non primalité de
𝑛. Testez la fonction pour n = 1729.
6. Calculez la complexité théorique et étudiez la complexité expérimentale de la fonction de test .

Travail pratique 9 : Recherche simultanée du maximum et du minimum

Nous supposerons ici que l’ensemble considéré ne contient pas deux fois la même valeur.

Page 6 sur 7
Fiche de TP INF311

1. Proposez un algorithme naïf de recherche du maximum et du minimum d’un ensemble


de n éléments.
2. Quelle est sa complexité en nombre de comparaisons ?
3. Proposez un algorithme plus efficace.
4. Quelle est sa complexité en nombre de comparaisons ?
5. Montrez que cet algorithme est optimal.
Indication : on appelle unité d’information :
• l’information « l’élément x ne peut pas être le plus grand élément » ;
• l’information « l’élément x ne peut pas être le plus petit élément » ;

a) Quel est le nombre minimal d’unités d’information qu’un algorithme de recherche du


maximum et du minimum doit produire pour nous garantir la validité de son résultat ?
b) Combien d’unités d’information sont produites par la comparaison de deux éléments
(distinguez des cas, suivant que l’on a ou non des unités d’informations sur ces valeurs).
c) Concluez.

Page 7 sur 7

Vous aimerez peut-être aussi