Centrale Option Informatique MP 2008Sujet, corrigé et rapport du jury
Mots de Lukasiewicz, recherche de motif
Pas encore noté
Téléchargements
Ces sujets peuvent vous intéresser
Lecture du sujet en ligne
L'énoncé complet, avec les formules et les figures, sans ouvrir le PDF.Afficher ou masquer la section
Lecture du sujet en ligne
L'énoncé complet, avec les formules et les figures, sans ouvrir le PDF.
Les deux parties sont indépendantes. Le candidat indiquera en tête de sa copie le langage choisi : Caml ou Pascal.
Partie I-Mots de Lukasiewicz
Dans cette partie, les mots considérés sont pris sur l'alphabet
{ − 1, + 1} .
On appelle mots de Lukasiewicz les motsu = (u_1, u_2, …, u_n) sur cet alphabet qui vérifient les deux propriétés suivantes :
On appelle mots de Lukasiewicz les mots
On note avec un point
⋅ la concaténation de deux mots, par exemple
a ⋅ b .
- En Caml, un mot de Lukasiewicz sera représenté par une liste d'entiers (int list).
- En Pascal, un mot de Lukasiewicz sera représenté par une chaîne de caractères (string) composée de symboles '+' (pour +1) et '-' (pour -1). On rappelle les opérations suivantes:
- accéder au caractère numéro
i de la chaînec : c [i] (la numérotation commence à 1); - obtenir la longueur d'une chaîne
c : length(c); - extraire une chaîne d'une sous-chaîne: copy(chaîne, position, longueur). Par exemple, copy('abcdef', 2, 3) retourne 'bcd';
- concaténer deux chaînes ou caractères
c_1 etc_2 pour obtenir une nouvelle chaîne :c1 + c2 .
On demande d'indiquer le type de toutes les fonctions écrites, que ce soit en Caml ou en Pascal.
I.A - Quelques propriétés
I.A.1) Donner tous les mots de Lukasiewicz de longueur 1, 2 et 3, puis tous ceux de longueur paire.
I.A.2) Écrire une fonction qui indique si un mot est de Lukasiewicz. Cette fonction renverra une valeur booléenne. La fonction proposée devra impérativement avoir une complexité (en termes d'opérations élémentaires) enO(n) , avec
n la longueur du mot d'entrée.
I.A.3) Montrer que siu et
v sont des mots de Lukasiewicz, alors
(+ 1) ⋅ u ⋅ v est un mot de Lukasiewicz.
I.A.4) Réciproquement, montrer que tout mot de Lukasiewicz de longueur supérieure ou égale à 3 admet une décomposition unique de la forme(+ 1) ⋅ u ⋅ v , où
u et
v sont des mots de Lukasiewicz.
I.A.5) Écrire une fonction décompose qui associe ce couple (u, v ) à un mot de Lukasiewicz de longueur supérieure ou égale à 3. En Pascal, on pourra écrire une procédure qui modifie deux de ses paramètres
u et
v passés par référence. On ne demande pas de traiter les cas où le mot fourni en entrée ne serait pas de Lukasiewicz.
I.A.6) On souhaite calculer tous les mots de Lukasiewicz d'une longueur donnée. Comparer les avantages d'une solution récursive appliquant le principe de la décomposition suggéré par la question A.4), et celle d'une solution appliquant le même principe, mais pour laquelle on tabulerait les résultats intermédiaires.
I.A.7) Écrire une fonction obtenirLukasiewicz qui calcule la liste des mots de Lukasiewicz de taille inférieure ou égale à un entier donné.
I.A.2) Écrire une fonction qui indique si un mot est de Lukasiewicz. Cette fonction renverra une valeur booléenne. La fonction proposée devra impérativement avoir une complexité (en termes d'opérations élémentaires) en
I.A.3) Montrer que si
I.A.4) Réciproquement, montrer que tout mot de Lukasiewicz de longueur supérieure ou égale à 3 admet une décomposition unique de la forme
I.A.5) Écrire une fonction décompose qui associe ce couple (
I.A.6) On souhaite calculer tous les mots de Lukasiewicz d'une longueur donnée. Comparer les avantages d'une solution récursive appliquant le principe de la décomposition suggéré par la question A.4), et celle d'une solution appliquant le même principe, mais pour laquelle on tabulerait les résultats intermédiaires.
I.A.7) Écrire une fonction obtenirLukasiewicz qui calcule la liste des mots de Lukasiewicz de taille inférieure ou égale à un entier donné.
En Pascal, on dispose des types et fonction :
type
ptliste=^liste;
liste=record
valeur : string;
suivant:ptliste
end;
function adjonction(x:string; pt:ptliste):ptliste;
Cette dernière fonction adjonction réalise l'adjonction d'une nouvelle cellule en tête de liste (et retournant un pointeur sur ladite cellule). On ne demande pas de l'écrire.
I.B - Dénombrement
I.B.1) Soitu = (u_1, …, u_n) un mot tel que
∑_(i = 1)^n u_i = − 1 . Démontrer qu'il existe un unique entier
i, 1 ⩽ i ⩽ n , tel que (
u_i, u_(i + 1), …, u_n, u_1, …, u_(i − 1) ) soit un mot de Lukasiewicz. Ce mot est appelé conjugué de
u .
I.B.2) Écrire une fonction conjugue qui calcule le conjugué d'un motu = (u_1, …u_n) vérifiant
∑_(i = 1)^n u_i = − 1 .
I.B.3) En utilisant les résultats précédents, déterminer le nombre de mots de Lukasiewicz de longueur2n + 1 .
On pourra utiliser ce résultat admis :≪Siu et
v sont deux mots non vides, les deux propositions suivantes sont équivalentes :
I.B - Dénombrement
I.B.1) Soit
I.B.2) Écrire une fonction conjugue qui calcule le conjugué d'un mot
I.B.3) En utilisant les résultats précédents, déterminer le nombre de mots de Lukasiewicz de longueur
On pourra utiliser ce résultat admis :
-
uv = vu - il existe un mot
w non vide et deux entiersk, ℓ ⩾ 1 tels queu = w^k etv = w^ℓ≫
I.C - Régularité
I.C.1) Montrer que le langageL = {(+ 1)^n(− 1)^(n + 1), n ∈ ℕ} n'est pas reconnaissable (implicitement dans la suite : «par un automate fini »).
I.C.2) Montrer que l'intersection de deux langages reconnaissables est un langage reconnaissable.
I.C.3) Prouver le caractère reconnaissable ou non du langage constitué des mots de Lukasiewicz.
I.D - Capsules
On appelle capsule d'un mot
u tout facteur de
u de la forme
(+ 1, − 1, − 1) . On définit sur
{ − 1, 1}^∗ une fonction
ρ dite de décapsulage :
I.D.1) Justifier le fait que la suite
(ρ^n(u))_(n ∈ ℕ) est constante au delà d'un certain rang. La valeur limite de la suite
(ρ^n(u))_(n ∈ ℕ) est notée
ρ^∗(u) .
I.D.2) Écrire une fonction rho qui calculeρ(u) .
I.D.3) Écrire une fonction rhoLim qui calculeρ^∗(u) .
I.D.4) Démontrer queu est un mot de Lukasiewicz si et seulement si
ρ^∗(u) = (− 1) .
I.D.2) Écrire une fonction rho qui calcule
I.D.3) Écrire une fonction rhoLim qui calcule
I.D.4) Démontrer que
Partie II-Recherche de motif
Dans ce problème, nous allons étudier deux algorithmes de recherche de motif (en général noté
p ) dans un mot (en général noté
m ). Par exemple, le motif
p0 = bra apparaît deux fois dans le mot m0=abracadabra. Les programmes de recherche de motif devront retourner la liste (éventuellement vide) des positions (au sens de Caml/Pascal) du motif dans le mot. Dans l'exemple précédent, les programmes devront retourner une liste contenant les positions 1 et 8 en Caml; 2 et 9 en Pascal. C'est la position de la première lettre qui est prise en compte. Plus formellement, si
m = m_1…m_n , on dit que
p apparaît en position
i dans
m lorsque
p = m_i…m_(i + |p| − 1) , avec
|p| la longueur de
p .
II.A - Algorithme naïf
II.A.1) Écrire une fonction coincide prenant en entrée deux chaînes de caractères p et
m , une position pos, et retournant true si
p apparait en position pos dans m (et false sinon). Cette fonction devra uniquement utiliser des comparaisons de caractères, sans utiliser sub_string (Caml) ou copy (Pascal). De plus, en cas de réponse false, elle devra arrêter les tests dès que possible.
II.A.2) Écrire une fonction recherche prenant en entrée deux chaînes de caractères p et m , et retournant la liste (dans n'importe quel ordre, et éventuellement vide) des positions de p dans m.
En Pascal, on dispose comme dans la première partie des types ptliste, liste et de la fonction adjonction, avec cette fois le champ valeur de type integer.
II.A.3) Évaluer la complexité (en termes de comparaisons de caractères, et en fonction de|p| et
|m|) de la fonction précédente dans le pire des cas. On exhibera un cas défavorable (en terme de complexité), avec
p et
m arbitrairement grands.
II.A.2) Écrire une fonction recherche prenant en entrée deux chaînes de caractères p et m , et retournant la liste (dans n'importe quel ordre, et éventuellement vide) des positions de p dans m.
En Pascal, on dispose comme dans la première partie des types ptliste, liste et de la fonction adjonction, avec cette fois le champ valeur de type integer.
II.A.3) Évaluer la complexité (en termes de comparaisons de caractères, et en fonction de
II.B - Algorithme de Rabin-Karp
La présentation de l'algorithme de Rabin-Karp est faite dans le cas de l'alphabet
A_0 = {0, 1, …, 9} .
Un motm ∈ A_0^∗ peut être vu naturellement comme un entier (
m = 366 est dans
A_0^∗… mais aussi dans
ℕ ).
II.B.1) La première idée de l'algorithme de Rabin-Karp est que si on cherchep = 366 dans
m = 97463667305 , on va regarder les lettres de
m par groupes de 3 , en initialisant un compteur à
c = 974 , et en «avançant» dans
m en ajoutant à chaque fois une nouvelle lettre, et en effaçant la première de
c . Dans notre exemple,
c passe d'abord à 746 puis 463 . Plus formellement, lire la lettre
ℓ = m_(i + |p|) dans
m en effaçant
m_i change
c en
10c + ℓ − 10^(|p|)m_i . Si
c = p , cela signifie que le motif
p est présent en position
i dans
m .
On suppose dans cette première version de l'algorithme de Rabin-Karp quep est de très petite longueur, de sorte que le compteur
c ne dépassera jamais la valeur du plus grand entier autorisé par Caml ou Pascal.
On considère définie une fonction appelée numeral prenant comme entrée un caractère de l'alphabetA_0 et retournant la valeur entière correspondante (par exemple on associe l'entier 0 au caractère ' 0 ') :
Un mot
II.B.1) La première idée de l'algorithme de Rabin-Karp est que si on cherche
On suppose dans cette première version de l'algorithme de Rabin-Karp que
On considère définie une fonction appelée numeral prenant comme entrée un caractère de l'alphabet
- En Caml, numeral : char -> int = <fun>
- En Pascal, function numeral(a : char) : integer ;
a) Écrire une fonction prenant en entrée un motm , une longueurℓ , et retournant la valeur initiale du compteur, calculée en lisant lesℓ = |p| premières lettres dem . Dans l'exemple donné plus haut, sur l'entrée (m, 3 ), la fonction doit retourner 974.
b) Écrire enfin une fonction prenant en entrée un motif, un mot (supposé de taille supérieure au motif), et calculant la liste des positions dansm où le motifp est présent.
II.B.2) L'hypothèse quant à la longueur << faible >> dep étant très restrictive, on modifie l'algorithme précédent en choisissant un entierq modulo lequel on calculera c. En lisant la lettreℓ = m_(i + |p|) et en effaçantm_i , le nouveau compteur devient doncc^′ ← (10c^′ + ℓ − 10^(|p|)m_i)[q] .
Lorsquec = p , on ac^′ ≡ p[q] . Mais réciproquement, lorsquec^′ ≡ p[q] , on n'est pas assuré d'avoirc = p . On regarde alors (avec l'algorithme naïf) si le facteur dem correspondant au compteurc calculé est égal àp . Sic^′ ≡ p[q] maisc ≠ p , on parle de << fausse-position >>.
a) Donner les valeurs successives dec^′ lors de la recherche dep = 366 dansm = 97463667305 , avecq = 9 .
b) Écrire une fonction recherchant les positions d'un motif dans un mot, en appliquant l'algorithme de Rabin-Karp, avec un entierq donné en paramètre.
c) Lors de la recherche dep = 0001000 dansm = 000000000 avecq = 1000 , combien de cas de fausse-position va-t-on rencontrer?
d) Majorer le temps de calcul de la liste des positions dep dansm , en fonction de|p| et|m| avec l'algorithme de Rabin-Karp.
q est supposé tel que les calculs arithmétiques moduloq sont d'un coût constant. Le temps de calcul pendra donc en compte ces opérations arithmétiques, et les comparaisons de caractères, du typem_i = p_j .
e) Comparer les complexités dans le pire des cas de l'algorithme de Rabin-Karp et de l'algorithme naïf.
f) En pratique, aura-t-on intérêt à prendreq plutôt petit ou plutôt grand? Que peut-on alors espérer pour le temps de calcul de la recherche des occurrences dep dansm ?
On demande une justification informelle, le choix de l'entier q et l'évaluation de temps moyen de calcul étant deux choses très délicates ...
Pas de description pour le moment
