• Aucun résultat trouvé

Grammaires de descriptions d’objets Florent Hivert

N/A
N/A
Protected

Academic year: 2022

Partager "Grammaires de descriptions d’objets Florent Hivert"

Copied!
46
0
0

Texte intégral

(1)

Grammaires de descriptions d’objets

Florent Hivert

Mél : Florent.Hivert@lri.fr

Adresse universelle :http://www.lri.fr/˜hivert

(2)

Résumé des épisodes précédents

On a vu sur des exemples (mots binaires, permutations) plusieurs technique pour résoudre les questions classiques de la génération combinatoire :

Énumération lexicographique ; Décomposition récursive ;

itération vs listage pour gagner en complexité.

Solution ad hoc = ⇒ solution générique

(3)

Résumé des épisodes précédents

On a vu sur des exemples (mots binaires, permutations) plusieurs technique pour résoudre les questions classiques de la génération combinatoire :

Énumération lexicographique ; Décomposition récursive ;

itération vs listage pour gagner en complexité.

Solution ad hoc = ⇒ solution générique

(4)

Objectifs : algorithmes génériques

Identifier les composants de base :

=⇒ Singleton, union, produit cartésien, ensemble et multiensemble. . .

Comprendre comment composer les briques de base :

=⇒ grammaire de description, classe combinatoire

=⇒ Algorithmes génériques!

(5)

Objectifs : algorithmes génériques

Identifier les composants de base :

=⇒ Singleton, union, produit cartésien, ensemble et multiensemble. . .

Comprendre comment composer les briques de base :

=⇒ grammaire de description, classe combinatoire

=⇒ Algorithmes génériques!

(6)

Union disjointe

Definition

On écritC =AtB et on dit que C est l’union disjointedeA et B si C =AtB etA∩B =∅.

Alors :

count(C) = count(A) + count(B)

On peut prendre :list(C) = concat(list(A),list(B))

(7)

Union disjointe

Definition

On écritC =AtB et on dit que C est l’union disjointedeA et B si C =AtB etA∩B =∅.

Alors :

count(C) = count(A) + count(B)

On peut prendre :list(C) = concat(list(A),list(B))

(8)

Itération sur une union disjointe

On fixe l’ordre d’énumération tel que

list(AtB) := concat(list(A),list(B))

Itération en Python :

1 def iterunion(A, B):

2 for a in A:

3 yield a

4 for b in B:

5 yield b

(9)

first, next sur une union disjointe

list(AtB) := concat(list(A),list(B)) 1 def first_union(A, B):

2 return A.first() 3

4 def next_union(A, B, x):

5 if x in A:

6 try:

7 return A.next(x)

8 except StopIteration:

9 return B.first()

10 else:

11 return B.next(x)

(10)

rank sur une union disjointe

list(AtB) := concat(list(A),list(B)) 1 def rank_union(A, B, x):

2 if x in A:

3 return A.rank(x)

4 else:

5 return A.count() + B.rank(x) 6

7 def unrank_union(A, B, i):

8 if i < A.count():

9 return A.unrank(i)

10 else:

11 return B.unrank(i - A.count())

(11)

Le principe de l’idée récursive

Quand on a un’bonne idée, on l’appliqu’récursivement : on obtient le plus souvent une bien meilleure idée !

Unions disjointes récursives

(12)

Le principe de l’idée récursive

Quand on a un’bonne idée, on l’appliqu’récursivement : on obtient le plus souvent une bien meilleure idée !

Unions disjointes récursives

(13)

Les chaînes de n-bits ayant k -bits à 1

Une chaîne de bit non vide commence soit par un 0, soit par un 1 : BitString(n,k) =0·BitString(n−1,k) t 1·BitString(n−1,k−1) Idem triangle de pascal :

n k

=

n−1 k

+

n−1 k−1

BitString(n,k).count() = nk

(14)

rank, unrank pour les chaînes de n-bits ayant k -bits à 1

1 def rank_BSnk(x):

2 if not x: # liste vide

3 return 0

4 if x[0] == 0:

5 return rank_BSnk(x[1:])

6 else:

7 return binom(len(x)-1, sum(x)-1) + rank_BSnk(x[1:]) 8

9 def unrank_BSnk(n, k, i):

10 if n == 0:

11 return []

12 bn1k = binom(n-1, k) 13 if i < bn1k:

14 return [0]+unrank_BSnk(n-1, k, i)

15 else:

16 return [1]+unrank_BSnk(n-1, k-1, i-bn1k)

(15)

Le problème du calcul de la cardinalité

Problème

Le calcul récursif des coefficients binomiaux nk

n’est pas efficace car on recalcule plusieurs fois la même chose.

Plus généralement, le calcul récursif des cardinalités sera très inefficace pour la même raison.

(16)

Parenthèse : mémoization et programmation dynamique

Retenir

Mémoisation : on mémorise tous les calculs pendant la récursion au momment où on les fait

Programmation Dynamique : résoud les sous-problèmes, des plus petits aux plus grands en stockant les résultats intermédiaires.

En général, la programmation dynamique est plus efficace mais plus longue à mettre en oeuvre : il faut avoir planifié l’utilisation de la mémoire.

(17)

Parenthèse : mémoization et programmation dynamique

Retenir

Mémoisation : on mémorise tous les calculs pendant la récursion au momment où on les fait

Programmation Dynamique : résoud les sous-problèmes, des plus petits aux plus grands en stockant les résultats intermédiaires.

En général, la programmation dynamique est plus efficace mais plus longue à mettre en oeuvre : il faut avoir planifié l’utilisation de la mémoire.

(18)

Parenthèse : mémoization et programmation dynamique

Retenir

Mémoisation : on mémorise tous les calculs pendant la récursion au momment où on les fait

Programmation Dynamique : résoud les sous-problèmes, des plus petits aux plus grands en stockant les résultats intermédiaires.

En général, la programmation dynamique est plus efficace mais plus longue à mettre en oeuvre : il faut avoir planifié l’utilisation de la mémoire.

(19)

Autre exemple : les permutations

Les permutés d’un ensembleX :={x1,x2, . . . ,xn} :

Perm{1,2,3}=1·Perm{2,3} t 2·Perm{1,3} t 3·Perm{1,2}

Plus généralement : Retenir

Énumération lexicographique des permutations :

Perm(X) =

n

G

i=1

xi ·Perm(X/{xi})

Perm(X).count() =|X|!

(20)

Généralisation : permuté d’un multiensemble

Perm{1,1,2,3}=1·Perm{1,2,3} t2·Perm{1,1,3} t3·Perm{1,1,2}

Notation :{1,1,2,3}=122131

Perm(122331) =1·Perm(112331)t2·Perm(122231)t3·Perm(1223) Retenir

Énumération lexicographique des multi-permutations :

Perm(X) =

n

G

i=1

xi ·Perm(X/{xi})

(21)

Coefficient multinomiaux :

L’union disjointe précédente nous donne l’égalité de cardinaux : |I|

i1,i2, . . . ,ik

=

|I| −1 i1−1,i2, . . . ,ik

+

|I| −1 i1,i2−1, . . . ,ik

+

· · ·+

|I| −1 i1,i2, . . . ,ik−1

On montre alors :

Perm(x1i1. . .xkik).count() = (i1+i2+· · ·+ik)!

i1!i2!. . .ik! =

|I| i1,i2, . . . ,ik

(22)

Coefficient multinomiaux :

L’union disjointe précédente nous donne l’égalité de cardinaux : |I|

i1,i2, . . . ,ik

=

|I| −1 i1−1,i2, . . . ,ik

+

|I| −1 i1,i2−1, . . . ,ik

+

· · ·+

|I| −1 i1,i2, . . . ,ik−1

On montre alors :

Perm(x1i1. . .xkik).count() = (i1+i2+· · ·+ik)!

i1!i2!. . .ik! =

|I| i1,i2, . . . ,ik

(23)

Autre application : transmission en codage NRZ

Non Return to Zero, Manière très élémentaire pour transmettre de l’information sur un ligne : 0 : -V, 1 : +V

Source :https://fr.wikipedia.org/wiki/Non_Return_to_Zero

(24)

Perte de synchronisation en codage NRZ

Si on envoie une suite trop longue de bits identiques, le récepteur ne voit un signal constant. Il ne peut plus se baser sur les

transitions pour se synchroniser et risque de perdre la synchronisation avec l’émetteur.

Definition

Une séquence de longueurn est ditenon-repétitive d’ordrek (abréviationNRk(n)) si elle ne contient pas se séquence de plus de k bits identiques consécutifs.

On noteNRk(n,c,i) les suites qui commencent par au plusc i : NRk(n,0,0) =1·NRk(n−1,k−1,1)

NRk(n,c,0) =0·NRk(n−1,c−1,0) t 1·NRk(n−1,k−1,1) Idem en échangeant les rôles de 0 et 1.

(25)

C’est un automate fini !

I start

A0 B0 C0 D0

A1 B1 C1 D1

0

1

0

1

0 1

0

1 1

0

1 0

1 0

1 0

Tous les états sont acceptants.

(26)

Union récursive et automates finis

Retenir

La méthode précédente fonctionne pour touts lesautomates finis déterministes. SoitLangn(E)l’ensemble des mots de longueur n acceptés à partir de l’étatE, alors on a la définition récursive :

Cas de base, pour un étatE :

Lang0(E) =

({ε} si E est terminal

∅ sinon

Étape de la récursion :

Langn(E) = G

E→aE0

a·Langn−1(E0)

(27)

Le produit cartésien

Definition

On appelleproduit cartesiendeA etB l’ensembleC noté C :=A×B défini par

C :={(a,b) | a∈A,b∈B)}.

count(C) = count(A)·count(B) =k·`

On peut prendre la liste dans l’ordre lexicographique :

list(C) = [ (a0,b0) (a0,b1) (a0,b2) · · · (a0,b`−1) (a1,b0) (a1,b1) (a1,b2) · · · (a1,b`−1) (a2,b0) (a2,b1) (a2,b2) · · · (a2,b`−1)

... ... ... . .. ... ]

(28)

Le produit cartésien

Definition

On appelleproduit cartesiendeA etB l’ensembleC noté C :=A×B défini par

C :={(a,b) | a∈A,b∈B)}.

count(C) = count(A)·count(B) =k·`

On peut prendre la liste dans l’ordre lexicographique : list(C) = [ (a0,b0) (a0,b1) (a0,b2) · · · (a0,b`−1)

(a1,b0) (a1,b1) (a1,b2) · · · (a1,b`−1) (a2,b0) (a2,b1) (a2,b2) · · · (a2,b`−1)

... ... ... . .. ... ]

(29)

Itération sur un produit cartésien

Ordre lexicographique :

(a0,b0) (a0,b1) (a0,b2) · · · (a0,b`−1) (a1,b0) (a1,b1) (a1,b2) · · · (a1,b`−1) (a2,b0) (a2,b1) (a2,b2) · · · (a2,b`−1)

... ... ... . .. ...

(ak−1,b0) (ak−1,b1) (ak−1,b2) · · · (ak−1,b`−1) Itération en Python :

1 def iter_cartprod(A, B):

2 for a in A:

3 for b in B:

4 yield (a, b)

(30)

first, next sur un produit cartésien

1 def first_cartprod(A, B):

2 return (A.first(), B.first()) 3

4 def next_cartprod(A, B, x):

5 (a , b) = x # pattern matching

6 try:

7 return (a, B.next(b))

8 except StopIteration:

9 return (A.next(a), B.first())

(31)

rank sur un produit cartésien

1 def rank_cartprod(A, B, x):

2 (a , b) = x # pattern matching 3 A.rank(a)*B.count() + B.rank(b) 4

5 def unrank_cartprod(A, B, i):

6 c = B.count()

7 return (A.unrank(i // c), B.unrank(i % c))

(32)

Notion de classe combinatoire

Définition (Classe combinatoire)

On appelleclasse combinatoireun ensemble C dont les éléments e ont une taille (nommée aussi degrée) noté |e|et tels que

l’ensembleCn des éléments de taillen est fini : count({e ∈ C | |e|=n})<∞

Exemple :

Les mots sur un alphabet où la taille est la longueur Les permutations de{1, . . .n} (taille =n)

Les arbres binaires où la taille est le nombre de noeuds

(33)

L’union disjointe graduée

SiC=A t B, les élements deAet Bgardent leur taille dans l’union disjointe graduée :

Cn:=Ant Bn Alors :

C.count(n) =A.count(n) +B.count(n)

On peut prendre :C.list(n) = concat(A.list(n),B.list(n))

=⇒ On peut réutiliser tout ce que l’on a vu sur les unions disjointes.

(34)

L’union disjointe graduée

SiC=A t B, les élements deAet Bgardent leur taille dans l’union disjointe graduée :

Cn:=Ant Bn Alors :

C.count(n) =A.count(n) +B.count(n)

On peut prendre :C.list(n) = concat(A.list(n),B.list(n))

=⇒ On peut réutiliser tout ce que l’on a vu sur les unions disjointes.

(35)

Le produit cartesien gradué

Idée : les tailles (complexité, coût, nbr d’emplacements mémoires) s’ajoutent.

Definition

La taille de la paire(a,b)∈ A × B est la somme des tailles :

|(a,b)|A×B :=|a|A+|b|B

(36)

Le produit cartesien gradué

Retenir

SiC=A × B alors

Cn = G

i+j=n

Ai × Bj

Calcul de la cardinalité :

|Cn|= X

i+j=n

|Ai| × |Bj|=

n

X

i=0

|Ai| × |Bn−i|

On peut alors prendre l’ordre union/lexicographique suivant :

A0× Bn A1× Bn−1 A2× Bn−2 . . . An× B0

(37)

Le produit cartesien gradué

Retenir

SiC=A × B alors

Cn = G

i+j=n

Ai × Bj

Calcul de la cardinalité :

|Cn|= X

i+j=n

|Ai| × |Bj|=

n

X

i=0

|Ai| × |Bn−i|

On peut alors prendre l’ordre union/lexicographique suivant :

A0× Bn A1× Bn−1 A2× Bn−2 . . . An× B0

(38)

Application les arbres binaires

Spécification récursive :

BinTree = Leaf t Node(BinTree× BinTree)

Deux manières de compter les tailles :

1 Nombre de feuille :

BinTree = Leaf1 t BinTree× BinTree

2 Nombre de Noeuds :

BinTree = Leaf0 t Node1× BinTree× BinTree

(39)

Application les arbres binaires

Spécification récursive :

BinTree = Leaf t Node(BinTree× BinTree)

Deux manières de compter les tailles :

1 Nombre de feuille :

BinTree = Leaf1 t BinTree× BinTree

2 Nombre de Noeuds :

BinTree = Leaf0 t Node1× BinTree× BinTree

(40)

Liste de tous les arbres à n Nœuds

Algorithme

Entrée : un entier positif ou nuln Sortie :une liste d’arbres

if n == 0:

yield arbreVide() else:

for i in range(n):

for g in BinTree(i):

for d in BinTree(n-1-i):

yield Noeud(g, d)

(41)

Nombre de Catalan

Proposition

Le nombre d’arbres binaires àn nœuds est appelé n-ième nombre de Catalan notéCn. Les nombre de Catalan vérifient la récurrence :

C0 =1 Cn=

n−1

X

i=0

CiCn−1−i.

On peut trouver une formule close : Cn= (2n)!

n!(n+1)!. Voici les premières valeurs :

C0 =1, C1 =1, C2 =2, C3=5, C4=14, C5 =42, c6 =132.

(42)

Specification d’une classe combinatoire

But : on veut décrire uneclasse combinatoirede manière à pouvoir appliquer automatiquement les algorithmes de comptage, itération, génération,. . ..

Pour ceci, on va utiliser unegrammaire qui code comment appliquer récursivement les constructions précédentes.

(43)

Specification d’une classe combinatoire

Retenir (Grammaire de description d’objets) Constructeurs terminaux :

E(o) : la classe qui contient un seul objeto de taille 0 Z(o) : la classe qui contient un seul objet o de taille 1 Constructeurs binaires :

C= Union(A,B) : union disjointe graduée :

|a|C =|a|A si a∈ A |a|C=|b|B si b∈ B C= Prod(A,B) : produit cartésien graduée :

|(a,b)|C=|a|A+|b|B sia∈ Aetb ∈ B

(44)

Exemples :

Les arbres binaires, la taille est le nombres de Noeuds

BinTree = Union(E(⊥),Prod(Z(◦),Prod(BinTree,BinTree)) Les arbres binaires, la taille est le nombres de Feuilles

BinTree = Union(Z(⊥),Prod(BinTree,BinTree))

(45)

Exemples : Codage d’un automate fini

I start

A0 B0

A1 B1 0

1

0

1 0

1 1 0

Les mots binaires qui n’ont pas plus de deux lettres identiques consécutives :

I=E(ε) t (Z(”0”)× A0) t (Z(”1”)× A1) A0=E(ε) t (Z(”0”)× B0) t (Z(”1”)× A1)

B0=E(ε) t (Z(”1”)× A1)

A1=E(ε) t (Z(”0”)× A0) t (Z(”1”)× B1) B1=E(ε) t (Z(”0”)× A0)

(46)

Exemples : Codage d’un automate fini

I start

A0 B0

A1 B1 0

1

0

1 0

1 1 0

Dans cet exemple : plus simple, on inclut la lettre dans l’état : I =E(ε) t A0 t A1

A0 =Z(”0”)×(E(ε) t B0t A1) B0 =Z(”0”)×(E(ε) t A1) A1 =Z(”1”)×(E(ε) t B1t A0)

B1 =Z(”1”)×(E(ε) t A0)

Références

Documents relatifs

L’enseignement traditionnel, qui n’a jamais été des cours ex cathedra à l’école primaire, donne aussi de meilleurs résultats que toutes les pédagogies ouvertes et

Ensuite , chacun propose une idée en rapport avec l’univers réunionnais , pour remplacer les phrases du texte de base ( certains oublient même le texte initial et propose une

Alors, clairement cette application est bien dé- finie, car (?) et (??) impliquent que pour tout a : A, il existe un et un seul élément qui est en f - relation avec a, c’est

Pour arriver à démontrer ce fait, il faut donc intro- duire un nouvel axiome, l’axiome du choix qui, en gros, dit que si vous avez une quantité infinie d’en- sembles non vides

Encercle les objets que tu utiliseras pour faire tes

Les algorithmes d’itérations vue en cours sont pour la plupart en temps constant amorti (CAT)!. On peut trouver des algoritmes réellement en

Dans un triangle non isocèle, la hauteur, la bissectrice intérieure et la médiane issues d’un même sommet se classent dans cet ordre par longueur croissante?. Q₁ Existe-t-il

La modélisation réalisée par l’ONUSIDA indique qu’un doublement des investissements annuels consacrés au sida en Ukraine et une amélioration de la couverture des programmes