Vous êtes sur la page 1sur 47

Polycopie de cours d'Algorithmique avancée

Hadda Cherroun

27 novembre 2011
2
Table des matières

1 Introduction 5

2 Structure B-arbres 7
2.1 Introduction & motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Rappels arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 Rappels complexité et Ordre de grandeur asymptotique : O, o, Θ et Ω . . . . . . . . . . . 8
2.4 B-arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.4.1 Dénition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.4.2 Hauteur d'un B-arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5 Opérations de base sur les B-arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.5.1 Création dans un B-arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.5.2 Insertion d'une clé dans un B-arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.5.3 Suppression d'une clé dans un B-arbre . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6 Variantes des B-arbres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.7 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3 Arbre, tas binomial et tas de Fibonacci 17


3.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.2 Arbre binomial . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3 Tas binomiaux (Binomial Heaps) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3.1 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.2 Représentation d'un noeud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.3.3 Opérations sur les Tas Binomiaux . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4 Tas de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.4.1 Opérations sur les Tas de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.4.1.1 Création d'un tas de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . 26
3.4.1.2 Insertion d'un n÷ud . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.4.1.3 Trouver la clé minimale . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4.1.4 Union de de tas de Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4.1.5 Extraction du n÷ud de clé minimale d'un TF . . . . . . . . . . . . . . . 27

4 Chemins minimaux et Graphes avancés 29


4.1 Introduction & motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.2 Parcours en profondeur et ses propriétés . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.3 Parcours en Largeur et ses propriétés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.4 Chemins de poids maximal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.4.1 Chemin de poids maximal à partir d'une source donnée . . . . . . . . . . . . . . . 31
4.4.1.1 Technique de relaxation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.4.1.2 Algorithme de Dijkstra . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.4.1.3 Algorithme de Bellman-Ford . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.4.2 Chemin de poids maximal pour tous les couples de sommets . . . . . . . . . . . . . 32
4.4.2.1 Algorithme de Floyd-Warshall . . . . . . . . . . . . . . . . . . . . . . . . 33
4.4.2.2 Algorithme de Johnson . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.5 Algorithme de Roy-Warshall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

3
5 Introduction à la théorie de la N P -Complétude 37
5.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.2 Vocabulaire général . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.3 Classication de problèmes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
5.4 N P -complet ? . . . . . . .
Qu'est ce qu'un problème . . . . . . . . . . . . . . . . . . . . . 39
5.4.1 Problèmes connus N P -complets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.5 Comment prouver qu'un problème est N P -complet ? . . . . . . . . . . . . . . . . . . . . . 41
5.6 Processus de réduction polynomiale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.7 Exemple de réduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.8 La conjecture de l'informatique théorique P= N P ? . . . . . . . . . . . . . . . . . . . . . 43

6 Introduction à l'Algorithmique géometrique 45


6.1 Introduction & motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
6.2 Triangulation de Delaunay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

4
Chapitre 1

Introduction

Les structures de données constituent un concept vital dans la science des ordinateurs : quelque soit le
probléme que l'on veut automatiser, on se trouve toujours confronter du choix des structures de données
les mieux adaptées à l'implémentation de sa solution.
Inspiré principalement de [1], l'objectif de ce module est de donner un panorama des structures de
données avancées et de méthodes phares dans divers domaines d'applications algorithmiques : codage,
géométrie, réseaux, compilation. On insiste sur l'importance d'analyser et de comparer les performances
de diérentes solutions algorithmiques. Les thèmes traités sont les suivants : Organisation de l'informa-
tion : Arbres-B versus Hachage extensible. Représentation de les de priorités : des tas aux les de Fi-
bonacci. Gémétrie algorithmique : enveloppe convexe triangulation de Delaunay. Graphes : composantes
connexes et fortement connexes. Chemins minimaux et ots maximaux dans les graphes. NP-complétude
et réduction entre problèmes.

Connaissances préalables recommandées


 Connaissances algorithmiques
 Connaissances sur les structures algorithmique de bases (tableau, structures séquentielles, struc-
tures arborescentes

Contenu de la matière
1. Représentation de les de priorités : des tas aux les de Fibonacci.

2. Arbres-B versus Hachage extensible.

3. Graphes : composantes connexes et fortement connexes.

4. Chemins minimaux et ots maximaux dans les graphes.

5. NP-complétude et réduction entre problèmes.

6. Géométrie algorithmique : enveloppe convexe triangulation de Delaunay.

5
6
Chapitre 2

Structure B-arbres

2.1 Introduction & motivation


Les B-arbres ou arbres B sont des arbres de recherche équilibrés (Balancés) qui sont conçus pour bien
fonctionner sur les disques magnétiques ou autre périphérique de stockage d'accés direct.

En eet, pour optimiser l'exécution des requétes, on a besoin d'information sur la façon dont les
données sont stockées car sans aucune information sur le stockage des informations on est obligé de les
1
parcourir tous pour trouver celui ou ceux qui satisfont la requéte. Si on suppose qu'ils sont indéxés
suivant un ordre particulier (croissant, décroissant), la recherche peut devenir plus aisée. Les structures
les plus répandues d'indexation sont les B-arbres.

Ce sont des arbres n-aire qui peuvent avoir beaucoup de ls allant d'une simple poigné à des milliers.
Ce facteur de branchement dépend des caractéristiques de l'unité disque utilisée.

Quoique les disques sont pas chéres, ils sont longs voir trés longs comparées avec la mémoire centrale
et ceci est due à la mécanique des mouvements des plateaux autour de l'axe (compris 5400-54 000 tours
par minute RPM ce qui fait 3 à 9 millisecondes) et des bras des têtes de lecture.

Pour amortir ce temps, attente des mouvements, les données sont stockées dans des blocks et chaque
accès disque aectera le temps d'exécurion de l`application. Pour celà l'indexation et la structure des
indexes deviennent des facteurs très importants.

1. Index : toute structure de données qui prend en entrée une propriété des records (ex. la valeur d'un ou plusieurs
champs) et renvoie rapidement les reccords satisfaisant cette propriété.

Axe Secteur

Plateau Tete de Lecture/Ecriture

Figure 2.1  Structure d'un disque


7
2.2 Rappels arbres
Arbre binaire de recherche
Un ABR est un arbre binaire construit par des éléments ayant une clé d'identication et tel que pour
tout noeud sa clé est supérieure à toutes celles de ses descendants de gauche et inférieure à toutes celles
de ses descendants de droite.

Arbre équilibré
un arbre équilibré est un arbre qui posséde un critére d'équilibre par rapport au nombre de noeuds
de ses ls et dont les arbres ls sont eux-mêmes équilibrés. Toutes les feuilles sont au même niveau.
Le but est d'éviter de construire des arbres dégénérés (arbres peignes). Cela peut étre trés avantageux
lors de son utilisation. En eet, utiliser un arbre équilibré permet d'avoir une recherche de complexité
logarithmique dans le pire des cas au lieu d'une complexité linéaire, comme c'est parfois le cas pour des
arbres dégénérés.

2.3 Rappels complexité et Ordre de grandeur asymptotique :


O, o, Θ et Ω
Souvent l'étude de la performance des algorithmes est rangée sous le nom d'étude de complexité. On
distingue deux types de complexité :

1. complexité théorique : vise à donner une idée du comportement générale d'un algorithme. On
dit que l'algorithme a un comportement de l'ordre d'une certaine fonction mathématique dont on
connait les variations. Les cas de comportements les plus fréquents sont reportés dans le tableau
TAB 2.1.

2. complexité pratique : qui vise au contraire à une analyse ne des algorithmes au niveau de
chaque instruction. Il s'agit d'une estimation grossière du temps.

On peut s'intéresser également à 3 types de comportements :


 le comportement dans le cas moyen ;
 le cas le plus favorable ;
 le cas le plus defavorable.
Dans certaines applications la complexité dépendera de la distribution des données.

la notation O
On dit que deux fonctions f et g sont de même ordre, noté f = O(g) et se lit f est en grand O de g
ssi

∃c, d ∈ R∗+ et n0 / ∀n > n0 ⇒ c.f (n) ≤ g(n) ≤ d.f (n)


.
Utilité : Le temps d'exécution est borné
Signication : Pour toutes les grandes entrées (i.e., n > n0 ), on est assuré que l'algorithme ne prend
pas plus de d.f (n) étapes. On parle alors d'une Borne supérieure.
Les comportements les plus fréquents sont reportés dans la table TAB 2.1 :

La notation Ω -Equivalent-
Lorsque f = O(g) et g = O(f ) on dira que f = Ω(g)
c'est-à-dire

c ∈ R∗+ , d ∈ R∗+ , n0 tq n > n0 , dg(n) ≤ f (n) ≤ cg(n)


Ex. : 2n = Ω(n) mais 2n n'est pas en Ω(n2 )
Deux règles de simplication :

8
Ordre de grandeur Appelation
O(1) constant
O(log n) logarithmique
O(n) linéaire
O(n ln n) n ln n
O(n2 ) quadratique
O(n3 ) cubique
O(nk ) polynomial avec k constante
O(2n ) exponentiel

Table 2.1  Les comportements algorithmiques les plus fréquents

 Les constantes et les coecients n'ont pas d'importance


T (n), si T (n) est O(d.f (n)) (d > 0) alors T (n) est O(f (n)) Ex. T (n) = 2000n2 > T (n) est en
O(n2 )
 Les termes d'ordre inférieur n'ont pas d'importance
Si ∀T (n) = ak n + ak−1 n
k k−1
+ . . . + a1 n + a0 alors T (n) est O(nk )
Ex. T (n) = 2n + n − 100 > O(2n)

La notation Θ
le symbole Θ est reservé pour exprimer la complexité lorsque la complexité en O et Ω sont égaux.

Complexité en temps amorti


L'analyse amortie consiste à estimer une borne supérieure sur le coût total T (n) requis par une
séquence de n opérations. Quelques opérations, parmi cette séquence, peuvent avoir un coût énorme et
d'autres, un coût moindre. L'algorithme génère un coût T (n) pour les n opérations. Le coût amorti
pour chaque opération est T (n)/n.
Il existe 3 méthodes pour déterminer la complexité amortie d'un algorithme. La diérence réside
dans la manière dont le coût est assigné aux diérentes opérations : Méthode par aggrégation, Méthode
comptable et Méthode du potentiel (plus de détail en chapitre suivant).
L'analyse amortie est diérente de l'analyse en moyenne :
 dans l'analyse en moyenne, on cherche à exploiter le fait que le pire cas est peu probable en faisant
des hypothèses sur la distribution des entrées ou sur les choix aléatoires eectués dans l'algorithme ;
 dans l'analyse amortie, on cherche à exploiter le fait que le pire cas de l'algorithme ne peut pas se
produire plusieurs fois consécutivement, ou de manière trop rapprochée, quelle que soit l'entrée.

2.4 B-arbre
Un arbre B (appelé aussi B-arbre par analogie au terme anglais à B-tree) est un arbre équilibré qui
est principalement mis en oeuvre dans les mécanismes de gestion de bases de données et de systémes de
chiers. Il stocke les données sous une forme triée et permet une exécution des opérations d'insertion et
de suppression en temps amorti logarithmique.
Le principe général est de permettre aux noeuds de posséder plus d'une clé ; cela minimise la taille
de l'arbre et réduit le nombre d'opérations d'équilibrage.

Origine de l'appélation
Le créateur des arbres B, Rudolf Bayer [?], n'a pas explicité la signication du "B". L'explication la
plus fréquente est que ce "B" correspond au terme anglais "Balanced" (en français : équilibré). Cependant,
il pourrait aussi découler de "Bayer", du nom du créateur, ou de "Boeing", du nom de la rme pour
laquelle le créateur travaillait (Boeing Scientic Research Labs) !
Les deux avantages des arbres B sont donc leur bon comportement pour des chiers dynamiques
et le stockage ordonné des articles qui permet deux types d'accés, sélectif et séquentiel. Par contre,

9
l'utilisation d'une structure de données volumineuse qui nécessite plusieurs accés disque (typiquement
3 à 5 E/S pour l'accés à un article) rend les B-Trees peu attrayants lorsqu'accéder à des performances
élevées sont recherchées.

2.4.1 Dénition
Un B-arbre est un arbre de recherche équilibré ayant les proprietés suivantes :

1. Chaque noeud x est décrit par les champs suivants :


 n[x] est le nombre des clés enregistrés dans ce noeud ;
 les n[x] clés eux même sont enregistrés dans l'ordre croissant :

key1 [x] ≤ key2 [x] ≤ key3 [x] . . . ≤ keyn[x]

 leaf[x] un boolean valant vrai si x est une feuille.

2. Chaque noeud interne x contient,n[x] +1 pointeurs c1 [x], c2 [x], . . . , cn[x]+1 vers ses ls. Pour les
noeuds feuilles les ci sont indénis.

3. Les clés keyi [x] séparent les rangés de clés contenus dans chaque sous-arbre. Si ki est n'importe
quelle clé emagaziné dans un sousarbre de racine ci [x]. alors

k1 ≤ key1 [x] ≤ k2 ≤ key2 [x] ≤ k3 ≤ key3 [x] . . . ≤ kn[x] ≤ keyn[x] ≤ kn[x]+1

4. Toutes les feuilles sont au même niveau qui est la hauteur de l'arbre h;
5. Il y a une borne inférieure et une borne supérieure sur le nombre des clés qu'un noeud peut contenir.
Ces bornes peuvent être exprimés moyenant un nombre t ≥ 2 appelé le degré minimum du b-arbre ;
 Tout noeud, diérent de la racine doit avoir au moins (t − 1) clés, donc il peut avoir au moins t
ls. Si l'arbre est non vide, la racine doit avoir au moins une clé ;
 Chaque noeud peut contenir au plus (2t − 1) clés. Parcon3séquent, un noeud interne peut avoir
au plus 2t ls. On dit qu'un noeud est plein s'il contient exactement (2t − 1) clés.

Exemple
Le plus simple b-arbre exige t = 2, chaque noeud peut avoir 2, 3 ou 4 ls, on appelle cet arbre 2−3−4
arbre.

Racine Niveau Nombre


de noeuds

1 0 1

t−1 t−1 1 2

t t

. . . . . . 2 2t
t−1 t−1 t−1 t−1

t t t t

t − 1 ... t−1 t − 1 ... t−1 t − 1 ... t−1 t − 1 ... t−1 3 2t2

Figure 2.2  Un B-arbre de profondeur 3 contenant un minimum de clés.


L'utilisation d'une telle structure, a évidemment pour but d'obtenir le plus petit nombre possible de
lectures de pages disque. Chaque noeud de l'arbre est stocké dans une page disque. Le nombre de niveaux
de l'arbre constitue ainsi la borne maximum du nombre d'accés disque nécessaire pour un enregistrement
quelconque.

10
2.4.2 Hauteur d'un B-arbre
le nombre d'accès disque nécessaire pour la plus part des opérations sur les B-arbres est proportionnel
à sa hauteur.

Théorème 2.1. Soit T un b-arbre de hauteur h et de degré minimum t≥2 si n≥1 alors

n+1
h ≤ lnt ( )
2
Démonstration. Si le B-arbre T a une hauteur h et si la racine contenant au moins 1 clé et les autres
noeuds (t − 1) donc le nombre de clés n est borné par :
Ph
n ≥ 1 + (t − 1) i=1 2t(i−1)
Ph
= 1 + 2(t − 1) i=1 t(i−1)
 
th − 1
= 1 + 2(t − 1)
t−1

= 2th − 1

th ≤ (n + 1)/2

lnt (t) ≤ lnt ((n + 1)/2)

2.5 Opérations de base sur les B-arbres


Principalement, on adopte deux conventions pour ecrire et analyser les primitives sur les B-arbres :
 La racine du B-arbre est toujours en mémoire (pas de lecture disque)
 Tous noeud passé comme paramêtre doit avoir été lu par une opération Decture − Disque

Recherche d'une clé dans un B-arbre

La recherche dans un B-arbre ne diére pas trop d'une recherche dans un arbre binaire de recherche
sauf qu'au lieu de faire que deux décisions de branchement on fait plusieurs selon le nombre de ls c.à.d
on fait n[x] + 1 appels éventuels. Cette fonction prend en entrée un pointeur vers le noeud racine x d'un
sous arbre et une clé k à rechercher dans cet sous-arbre.
Le premier appel est de la forme B − arbre − crer(racine(T , k ). Si k est dans le B-arbre T alors elle
retourne la paire (y ,i) où y est le noeud et i est l'indice telque Keyi [y] = k sinon elle retourne nil.

Function(B _arbre_rechercher x k )())


( ,

i ←− 1;
tant que ( i ≤ n[x]) et ( k ≥ Keyi [x]) faire
n
i ←− i + 1;
si i ≤ n[x] et k = Keyi [x] alors
retourner(x,k )
n
si leaf [x] alors
retourner(nil)
sinon
lecture-disque(ci [x]);
retourner(B _arbre_rechercher (ci [x],k )
n

Analyse : Comme pour un A.B.R les noeuds parcourus durant la recursion ne peuvent etre plusque la
hauteur du B-arbre.

11
]

yi x]

x]
ke 1 [x

k e −1 [

1[
]

ke [x]
[x

+
yi

yi

yi

yi
x x

ke

ke
...N W... ..N S W...

y = ci [x] y = ci [x] z = ci+1 [x]


PQRSTYUV PQR TYUV

(a) (b)

Figure 2.3  Exemple d'insertion d'une clé dans un B-arbre

2.5.1 Création dans un B-arbre


Pour construire un B-arbre, on commence par créer un B-arbre vide, ceci est réalisé par la création
d'un noeud rcine vide, puis appeler la primitive B-arbre-inserer. Ces deux opérations l'allocation d'un
noeud, on suppose aussi que cette allocation se fait en O(1) donc pas nécessaire de faire de lecture disque.

Function B − arbre − créer


x ←− allouer-noeud() ;
leaf [x] ←− vrai ;
n[x] ←− 0 ;
Ecriture-disk(x) ;
racine[T] ←− x ;

2.5.2 Insertion d'une clé dans un B-arbre


Il est plus complexe d'insérer une clé dans un B-arbre par simple ajout d'une feuille comme pour le
cas des arbres bina B − arbre − scinder − f ils(s,1,r)ires car ça peut engendrer un B-arbre non valide.
En fait, on l'insert dans une feuille existante. Cependant on ne peut le faire sur une feuille pleine. Pour
éviter de rencontrer de tel type de feuilles, par prévision, on introduit une opération supplémentaire qui
scinder un noeud plein y c.à.d ayant (2t − 1) clés  en deux noeuds ayant (t − 1) clés chacun. Cette
division de y se fera autour de la clé médiane Keyt [y].
Cette clé médiane sera déplacer (remonter ) vers le noeud père de y pour bien identier le point de
division entre les deux sous arbres. Cependant le noeud père peut etre à son tour un noeud plein et doit
a son tour subir une opération scinder avant l'insertion de la nouvelle clé. Pour éviter de tomber dans
ce besoin instantané de scinder un noeud plein et qui peut nous mener jusqu'à la racine de l'arbre, nous
proterons durant la descente de la recherche de la position que doit occuper la nouvelle clé et on scinde
tous les noeuds pleins durant ce parcours toute en incluant la feuille aussi. Ainsi on a la garantie de ne
pas tomber dans le cas d'un noeud parent plein. voir Fig. 2.3

12
Function B − arbre − scinder − f ils(x, i, y )
z ←− allouer-noeud();
leaf [z] ←− leaf [y];
n[z] ←− t − 1;
pour j := 1 à t − 1 faire keyj [z] ←− keyj+t [y] ;
si non leaf [y] alors
pour j := 1 à t faire cj [z] ←− cj+t [y] ;
n
n[y] ←− t − 1 ;
pour j := n[x] + 1 à i + 1 pas -1 faire cj+1 [x] ←− cj [x] ;
ci+1 [x] ←− z ;
pour j := n[x] à i pas -1 faire keyj+1 [x] ←− keyj [x] ;
keyi [x] ←− keyt [y] ;
n[x] ←− n[x] + 1 ;
Ecriture-disk(x);
Ecriture-disk(y );
Ecriture-disk(z );

Function B -arbre-insert(T , k )
r ←− racine[T];
si n[r] = 2t − 1 alors
s ←− allouer-noeud() ;
root[T ] ←− s;
leaf [s] ←−False;
n[s] ←−0;
c1 [s] ←− r;
B -arbre-scinder-f ils(s, 1, r);
B -arbre-insert-nonplein(s, k );
sinon
B -arbre-insert-nonplein(r, k )
n

13
Function B -arbre-insert-nonplein(x, k )
i ←− n[x] ;
si leaf [x] alors
tant que (i ≥ 1) et (k < Keyi [x]) faire
Keyi+1 [x] ←− Keyi [x];
i ←− i − 1 ;
n
Keyi+1 [x] ←− k ;
n[x] ←− n[x] + 1;
Ecriture-disk(x);
sinon
tant que (i ≥ 1) et ( k < Keyi [x]) faire
i ←− i − 1
n
i ←− i + 1;
Lecture-disk(ci [x]);
si n[ci [x]] = 2t − 1 alors
B -arbre-scinder-f ils(x, i, ci [x]);
si k > Keyi [x] alors
i ←− i + 1;
n
n
B -arbre-insert-nonplein(ci [x], k )
n

2.5.3 Suppression d'une clé dans un B-arbre


La suppression ressemble à l'insertion mais un peu plus compliquée pour deux raisons :a/ la clé à
supprimer peut être à n'importe quel n÷ud (pas seulement en feuille) et b/ la suppression d'un n÷ud
interne peut entrainer un réarrangement d'un n÷ud ls.
Principe : la primitive B − arbre − supprimer(x, k ) supprime la clé k du sous arbre de racine x ,
on suppose que n[x] ≥ t.
1. si la clé k est dans le n÷ud x et x est une feuille alors supprimer k de x.
2. si la clé k est dans le n÷ud x et x est un n÷ud interne alors

0
(a) si le ls y qui précède k dans le n÷ud x a au moins t clés alors trouver le prédécesseur k de
k dans le sous arbre de racine y . Récursivement supprimer k 0 et remplacer k par k 0 dans x.
0
Trouver k et l'eacer peut se faire en une passe.

(b) de la même façon symétrique si le ls z qui suit k dans le n÷ud x a au moins t clés alors
0 0
trouver le successeur k de k dans le sous arbre de racine z . Récursivement supprimer k et
0 0
remplacer k par k dans x. Trouver k et l'eacer peut se faire en une passe.

(c) Autrement, si y et z ont seulement (t−1) clés fusionner k et tout les éléments de y et z de telle
sorte que x perd k et le pointeur vers z . y va contenir (2t − 1) clés, libérer z et récursivement
eacer k de y.
3. si la clé k n'est pas présente dans la racine x , déterminer ci [x] qui doit contenir k. Si ci [x] possède
seulement (t − 1) clés faire se qui suit autant de fois que c'est nécessaire pour garantir que l'on
descend vers un n÷ud qui a au moins t clés puis terminer par une récursion sur le ls approprié
dans x.
(a) si ci [x] a seulement (t − 1) clés mais que l'un de ses frère direct (sibling) a au moins t clés
alors donner à ci [x] une clé en déplaçant une clé de x (faire descendre ) et faire remonter une
clé de l'un des frères y ou z vers x et déplacer le pointeur ls approprié du sibling vers ci [x].
(b) sinon c.à.d si ni ci [x] ni l'un de ces sibling ne possède plus de t clé alors fusionner ci [x] avec
l'un de ses sibling et déplacer une clé de x dans le nouveau n÷ud pour devenir clé médiane

14
2.6 Variantes des B-arbres
local ou distribué ?,
unidimensionnel ou multidimensionnel ?

2.7 Conclusion
 Utilisation d'un arbre B pour le stockage des données
 un n÷ud de l'arbre est alors un bloc sur le disque.
 A un moment donné seule une page est ramenée en mémoire.
 nécessite des buers de taille très grande (ordre de 200).
 Deux façons de ranger les articles :

1. dans les n÷uds avec les clés, ( Fichier = B-arbre )

2. séparément, donc pointeur additionnel vers l'information. ( B-arbre = Index)

Si le chier est grand on préféré de loin utiliser la façon 2).

15
16
Chapitre 3

Arbre, tas binomial et tas de Fibonacci

3.1 Introduction
Les tas connus sous le nom de Tas fusionnables [Anglais : Mergeable Heaps] ce sont des structures
de données qui s'apprètant à des opérations non trop coûteuses en temps. Les tas les plus étudiés sont
les tas binomiaux et les tas de Fibonacci qui supportent principalement les cinq opérations suivantes :
 CREER − T AS crée et retourne un nouveau tas sans élément.
 IN SERER(T, x) insère dans le tas T un noeud x, dont le champ clé a déjà été rempli.
 M IN IM U M (T ) retourne un pointeur sur le noeud dont la clé est minimum dans le tas T .
 EXT RAIRE − M IN (T ) supprime du tas T le noeud dont la clé est minimum, est retourne un
pointeur sur ce noeud.
 U N ION (T1 T2 ) crée et retourne un nouveau tas qui contient tous les noeuds des tas T1 et T2 . Les
tas T1 et T2 sont détruits" par cette opération.
Les tas binomiaux et les tas de Fibonacci supportent aussi les deux opérations suivantes.
 DIM IN U ER − CLE(T ; x; k) aecte au noeud x du tas T la nouvelle valeur de clé k, dont on
suppose qu'elle est inférieure à sa valeur de clé courante.
 SU P P RIM ER(T ; x) supprime le noeud x du tas T.
La force de ces structures réside dans le fait, comme le montre le Tableau 3.1, * que la plus part des
algorithmes sont rapides, souvent de l'ordre de lg(n) spécialement l'action de l'U nion qui prend seulement
ln(n) (ou O(1) pour le cas des Tas de Fibonacci) pour fusionner des tas dont le nombre total des éléments
est n. En eet, les algorithmes les plus rapides asymptotiquement pour des problèmes comme la recherche
plus courts chemins à partir d'une source unique et le calcul des arbres couvrants de coût minimal font
essentiellement recours aux tas et spécialement ceux de Fibonacci.
Cependant, d'un point de vue pratique, toutefois, les facteurs constants et la programmation complexe
des tas de Fibonacci les rendent moins interessants que les tas binaires ordinaires et les tas binomiaux,
pour la plupart des applications.
Remarque : Attention !, Les tas binaires, les tas binomiaux et les tas de Fibonacci sont tous ine-
caces pour l'opération RECHERCHER ; trouver un noeud contenant une clé peut perdre beaucoup de
temps. Heureusement, cette contrainte ne pose aucun problème pour la plupart des applications dédiés.

Action Tas binaire Tas binomial Tas Fibonacci


CREER − T AS O(1) O(1) O(1)
IN SERER O(lg n) O(lg n) O(1)
M IN IM U M O(1) O(lg n) O(1)
EXT RAIREM IN O(lg n) O(lg n) O(lg n)
U N ION O(n) O(lg n) O(1)
DIM IN U ER − CLE O(lg n) O(lg n) O(1)
SU P P RIM ER O(lg n) O(lg n) O(lg n)

Table 3.1  Complexité des actions sur les trois implémentations des tas fusionnables. n représente le
nombre d'éléments dans le tas.

17
B0 B1 B2 B3 B4

Figure 3.1  Structure d'un Tas

3.2 Arbre binomial


Dénition : Un arbre binomial est un arbre enraciné dans lequel les ls de chaque noeud sont
ordonnés. Autrement dit, si un noeud a k ls, alors il existe un premier, un deuxiéme etc. Un arbre
binomial est déni récursivement comme suit :

1. B0 est constitué d'un noeud unique,

2. Bk est constitué de deux arbres binomiaux Bk−1 reliés entre eux de la maniére suivante : La racine
de l'un est le ls le plus à gauche de la racine de l'autre.

L'illustration est comme suit :


Propriétés des arbres binomiaux
Soit Bk un arbre binomial.

1. Le nombre de noeuds de Bk est 2k ,


2. La hauteur de l'arbre Bk est k,
i
3. Il existe exactement Ck noeuds à la profondeur i, i = 1, 2, . . . , k ,
4. La racine a un degré k (supérieur au degré de tout autre noeud) qui est plus grand que celui de
n'importe quel autre noeud. Les clés de la racine sont les racines des sous- arbres B0 ; B1 ; :::; Bk−1
dans un certain ordre,

5. Si les ls de la racine sont numérotés de la gauche vers la droite par k − 1, . . . ,1,0, alors le ls i est
la racine de l'arbre Bi ,
6. Le degré maximum d'un noeud quelconque dans un arbre binomial à n noeuds est ln n
Preuve (par récurrence sur k ) : Pour chaque propriété, la base est l'arbre binaire B0 Vérier que
chaque propriété est valide pour B0 est trivial.
Supposons que ce résultat soit vrai pour Bk−1 Maintenant : l'arbre Bk est constitué de deux copies
de Bk−1 , par conséquent, l'arbre Bk contient 2k−1 + 2k−1 = 2k noeuds.

Origine de l'appélation
L'appélation vient de la propriété 3, car les termes Cki sont appelés dans la littérature les coecients
binomiaux.

3.3 Tas binomiaux (Binomial Heaps)


Dénition
Un tas binomial TB est une collection (ensemble) d'arbres binomiaux.

1. chaque AB dans TB vérie la propriété du tas, c'est à dire la clé d'un noeud est inférieure ou égale
aux clés de ses ls.

18
B0
B1
Bk−2
Bk−1

BK

Figure 3.2  Structure récursive d'un arbre binomial


10 1 7

12 24 80 14 30

18 11 16 39

26

Figure 3.3  Exemple de B-arbre

2. un tas contenant n noeuds contient au plus log(n) + 1 arbre binomial.

3. dans un TB, un AB d'un degré donné apparait au plus une fois

4. les racines binomiales sont reliées en liste (appelée liste de racines), selon l'ordre croissant des
degrés.

3.3.1 Exemple
La représentation de 13 et 1101 le Tas H alors consiste en 3 arbres binomiaux B3 , B2 et B0 ayant 8,
4, 1 noeud respectivement

3.3.2 Représentation d'un noeud


Chaque arbre binomial dans un TB est emagaziné sous la représentation ls-gauchefrère-droit.
Chaque noeud possède 3 pointeurs (plus n'importe quelle information nécessaire à l'application) :

1. p[x] un pointeur vers son parent


2. f ils[x] un pointeur vers son ls le plus à gauche

3. f rredroit[x] un pointeur vers son frère immédiat à droite

degré[x] → le nbre de ses ls

19
Tete[H]
10 1 7
0 2 3

12 24 8 14 30
1 0 2 1 0

18 11 16 39
0 1 0 0

26
0

Figure 3.4  Exemple de B-arbre

Liste des racines

Les racines binomiales sont chainées en liste apppelés "liste des racines" et organisé selon l'ordre
croissant des degrés. Le frère immédiat a dierents sens qu'il soit dans un noeud dans la liste des racines
ou noeud non racine.

3.3.3 Opérations sur les Tas Binomiaux

Création d'un tas binomial

creer-tas
allocate(H)
Head[H] := Nil

20
Trouver la clé minimale

Fonction MINIMUM-Tas-binomial(H) : noeud


y ← Nil ;
x ← head(H) ;
min ← ∞;
Tant que (x 6= Nil) faire
Si (clé(x) < min) Alors
min = clé(x) ;
y ← x;
Fin Si
x ← frère-droit(x) ;
Fait
Retourner y ;
Fin

Opération d'union

Cette opération fait souvent recours à unir deux arbres binaires de même degré

Procédure Lien-binomial(y,z)
p[y] ← z;
frere-immediat[y] ← ls(z) ;
ls(z) ← y;
degree[z] ← degree[z] + 1;
Fin

Cette procédure rend le noeud y la nouvelle tête de la liste des ls de z.


Cette procédure marche toujours et donne un arbre binomial d'ordre (degré + 1) et çàepouse bien la
dénition récursive d'un arbre binomial.
On utilisera aussi fusion-tas-binomial(H1 et H2 ) qui fusionne les listes des racines de H1 et H2 dans une
seule liste chainé trié dans l'ordre croissant monotone.

21
Action Union-Tas-binomiaux(H1 ,H2 )
H ← creer-tas-binomial() ;
head[H] ← fusion-tas-binomiaux(H1 ,H2 ) ;
Liberer les noeuds H1 et H2 mais pas les listes
Si (tête[x] = Nil) Alors
Retourner H ;
prec-x = nil ;
x ← tête[x] ;
suiv-x ← sibling[x] ;
Fin Si
Tant que (suiv-x 6= Nil) faire
Si (degree[x] 6= degree[next-x] OU frère-droit[suiv-x] 6= Nil ET degree[sibling[next-x]]
= degree[x]) Alors
prec-x ← x;
x ← next-x ;
Sinon
Si (clé(x) ≤ clé[suiv-x]) Alors
sibling[x] ← sibling[next-x] ;
lien-binomial(next-x,x) ;
Sinon
Si (prec-x = nil) Alors
head[H] ← next-x ;
Sinon
sibling[prev-x] ← suiv-x ;
Fin Si
Fin Si
lien-binomial(suivant-x) ;
x ← suivant-x ;
Fin Si
next-x ← sibling(x) ;
Fait
Retourner H ;
Fin Action

22
puc
puc−x x suiv−x sibling[suiv−x] x suiv−x

a b c d a b c d
Cas 1

Bk BL

prev x
puc−x x suiv−x sibling[suiv−x] suiv
a b c d avancer
Cas 2
Bk Bk Bk

prev
x next−x sibling[suiv−x]
a b c d a b d

Cas 3 c
Bk Bk BL

prec x suiv sibling[suiv−x] puc−x


x suiv−x
a b c d a c

Cas 4
Bk Bk BL BL
b

Figure 3.5  Exemple de B-arbre

Insertion d'un noeud

/* Soit H un tas binomial


/* x un noeud à inserer

Action Insert-Tas-binomial(H,x)
Hx ← creer-tas-binomial() ;
p[x] ← Nil ;
ls[x] ← Nil ;
sibling[x] ← Nil ;
degree[x] ← 0 ;
tête[Hx] ← x ;
H ← Union-tas-binomial(H,Hx) ;
Fin Action

23
Analyse O(Log(n))

La complexité de cette procédure est en O(Log(n))

Extraction du noeud de clé minimale

1. Trouver la racine x dont Key[x] est minimum. Enlever x de la liste des racines

2. Construire un Hx ← Créer-Tas-binomial

3. Inverser l'ordre de la liste chainée des ls de x et initialiser tête[Hx] pour pointer la tête de cette
liste

4. H ← Union-Tas-binomial(H,Hx)

5. Retour x

Diminuer une clé

Action Diminuer-Tas-binomial(H,x,k)
H : Le Tas ;
x : L'adresse du noeud ;
k : la nouvelle valeur Key[x] ;
Si (k > Key[x]) Alors
write("la nouvelle clé est supérieur à la clé courante") ;
Sinon
Tant que (Z 6= nil et Key[y] < Key[z]) faire
permuter Key[y] ←→ Key[z] ;
y ←− z ;
z ←− P[y] ;
Fait
Fin Si
Fin Action

Supprimer une clé

Action Supprimer-tas-bino(H,x)
Diminuer-tas-binomial(H,x,-∞) ;
Extraire-min-tas(H) ;
Fin Action

3.4 Tas de Fibonacci


Dénition
Un tas de Fibonacci TF (en Anglais : Fibonacci Heap) est une collection d'arbres dotés de la
propriété de tas ; ces arbres ne sont pas obligatoirement binomiaux. Ci dessus un exemple d'un TF avec
5 tas et 14 noeuds.

24
min[H]

37 8 2 18 26

81 53 38 34 88 46

91 42 40

Structure d'un noeud


x

left

key

right

degree

child

mark

 Les racines des arbres sont connectées en liste circulaire doublement chaînée.
 L'ordre des arbres est arbitraire
 Le FH est accessible par le pointeur min(H)
 On stocke le nombre de noeuds courants de T dans n[T ].
1. L'ordre dans lequel apparait la liste des ls est arbitraire

2. Interet de 2 listes circulaires doublement chainées

(a) On peut extraire un élément en O(1)

(b) On peut les caractériser en O(1)

25
3. Un TF donné est accessible via son pointeur min[H] à la liste des arbres

4. L'ordre des arbres dans la liste des racines est aussi arbitraire

5. Un autre attribut est attribué à un TB est son nombre n[H]

En rapport avec le temps amortie et l'analyse


Fonction potentielle

Soit F un TF, on désigne par t(F) le nombre d'arbre de F, m(F) le nombre de noeud marqué
Φ(F) = t(F) + 2m(F)

Degrée maximum

Degré maximum d'un noeud dans le tas Fibonacci D(n) ≤ lg(n)

3.4.1 Opérations sur les Tas de Fibonacci


Dénition

Un arbre binomial non-ordonné est déni récursivement exactement comme un arbre binomial à la
diérence que l'ordre des arbres B0 , B1 , B2 , B3 , . . . , Bk−10 dans Bk n'est pas gé
Avec cette construction nous évitons les traitements :
 consolidation des arbres dans un TF
 et le lien des tas binomiaux
On eectue ces opérations que lorsqu'on aura besoin et après avoir avoir amorti plus d'autres opérations

3.4.1.1 Création d'un tas de Fibonacci

Action allouer-objet(H)
n[H] = 0
min[H] = Nil
t[H] = 0
potentiel de TF =⇒ Φ(H) = 0 donc O(1)
m[H] = 0
Fin Action

3.4.1.2 Insertion d'un n÷ud

Action Insert-Tas-Fibo(H,x)
degree[x] = 0;
p[x] ← nil ;
child[x] ← nil ;
left[x]← x;
right[x] ← x ;
mark[x] ← false ;
Concaténer la liste des racines contenant x avec la liste des racines de H
Si (min[H] = Nil OU key[x] < key[min[H]]) Alors
min[H] ← x;
n[H] ← ++ ;
Fin Si
Fin Action

26
3.4.1.3 Trouver la clé minimale

Facile et instantané

3.4.1.4 Union de de tas de Fibonacci

Action Union-tas-Fibo(H1 ,H2 )


H ← creer-tas-Fibo ;
min[H] ← min[H1 ] ;
concaténer les 2 listes des racines de H et H2
Si ((min[H1 ] = nil) OU (min[H2 ] 6= nil) ET (keymin[H2 ] < keymin[H1 ])) Alors
min[H] ← min[H2 ]
Fin Si
n[H] ← n[H1 ] + n[H2 ] ;
libéré H1 et H2 ;
Retourner H ;
Fin Action

Analyse

Chargement dans le potentiel

Φ(H) = (Φ(H1 ) + Φ(H2 ))


= t(H) + 2m(H) . . .

3.4.1.5 Extraction du n÷ud de clé minimale d'un TF

C'est le processus le plus complexe car c'est ici que les opérations de consolidation des arbres la liste
des racines sont eectués.

Action Extract-Min(H)
Z ← min[H] ;
Si (Z 6= nil) Alors
Tant que ((chaque ls de x) ∈ Z) faire
rajouter x à la liste des racines ;
P[x] ← nil ;
Fait
éliminer Z de la liste des racines ;
Fin Si
Si (Z = right[Z]) Alors
min[H] ← Nil ;
Sinon
min[H] ← right[Z] ;
Consolider(H) ;
Fin Si
n[H] ← n[H] - 1 ;
Retourner Z ;
Fin Action

La procédure consolider sert à réduire le nombre d'arbre de H, elle consiste à itérer sur les étapes
suivantes :

1. Trouver 2 racines x et y ayant le mêle degré et tel que Key(x) ≤ Key(y)

27
2. Lier y à x ; enlever y de la liste des racines puis faire de y un ls de x. Le champs degree[x] est
incrémenté et le lsy est marqué
Cette procédure utilise un tableau auxiliaire A[0. . .D(N[H])] ; si A[i] = y alors la racine ayant degree[y]
= i

Action Consolider(H)
Tant que ((chaque n÷ud w) ∈ (la liste de H)) faire
x ← w;
d ← degre[w] ;
Tant que (A[d] 6= nil) faire
y ← A[d] ;
Si (Key(x) > Key[y]) Alors
echanger x ←→ y;
Fin Si
Tas-Fib-lier(H,y,x) ;
A[d] ← nil ;
d ← d + 1;
Fait
Fait
min[H] ← nil ;
Pour i de 0 à D(n[H]) faire
Si (A[i] 6= nil) Alors
ajouter A[i] à la liste des racines de H;
Si (min[H] = nil OU Key[A[i]] < Key[min[H]]) Alors
min[H] ← A[i] ;
Fin Si
Fin Si
Fin Pour
Fin Action

Action Tas-Fib-lier(H,y,x)
remove y from the root list H ;
make y a child of x, increment degree(x) ;
mark[y] ← faux ;
Fin Action

Diminuer une clé

Supprimer une clé

28
Chapitre 4

Chemins minimaux et Graphes avancés

4.1 Introduction & motivation


Les graphes modélisent de nombreuses situations concrètes où
interviennent des objets en interaction.
 Les interconnexions routières, ferrovières ou aériennes entre diérentes agglomérations,
 Les liens entre les composants d'un circuit électronique,
 Le plan d'une ville et de ses rues en sens unique,...

4.2 Parcours en profondeur et ses propriétés


Soit G = (V, E) un graphe quelconque, où V est un ensemble de n sommets et E un ensemble de m
d'arcs. Dans la suite de ce chapitre, les termes arc (resp. arrète ) et cycle (resp. circuit) seront réservés
lorsque l'on traite un graphe orienté (resp. non orienté).
Dans un parcours (ou exploration) en profondeur, les arcs sont explorés hors du sommet v le plus
récemment découvert qui a toujours des arcs sortants non explorés. Lorsque tous les arcs sortants sont
explorés, le parcours fait un retour arrière pour explorer les arcs sortants du sommet à partir duquel v
a été découvert. Le processus continu jusqu'à ce que tous les sommets qui sont atteignables à partir d'un
sommet source, soient découverts . Dans le cas où il reste encore des sommets non découverts, l'un d'eux
est choisi comme une nouvelle source et l'exploration est répétée à partir de cette source. Le processus
en entier est répété jusqu'à ce que tous sommets soient découverts.
Le parcours en profondeur fournit plusieurs informations sur la structure du graphe et posséde
plusieurs propriétés parmi elles :
1. Un parcours en profondeur construit un sous graphe des prédécesseurs Gπ = (V, Eπ ), où : Eπ =
{(π(v), v) : v ∈ V et π(v) 6= N IL}. Gπ forme la forét du parcours en profondeur. Les arrètes
(resp. arcs) de Eπ sont appelés les arrètes (arcs) de l'arbre.

2. En outre créer la forêt du parcours, le parcours en profondeur, aecte chaque sommet v de deux
estampilles temporelles : la premiére estampille temporelle d[v] enregistre le moment où v est
découvert pour la premiére fois, et la seconde f [v] indique quant le parcours a examiné toute
la liste d'adjacence de v . Ainsi un sommet v est un descendant propre d'un sommet u, dans la
foret du parcours en profondeur pour un graphe G (orienté ou non orienté), si et seulement si
d[u] < d[v] < f [v] < f [u].
3. l'algorithme de parcours en profondeur classie les arcs du graphe comme suit :
 arcs de l'arbre : sont les arcs qui sont dans la forét du parcours en profondeur Gπ .
 arcs de retour (R) : sont les arcs (u, v) qui ne sont pas dans Gπ . et qui relie le sommet u à
son ancétre v dans la forét du parcours en profondeur Gπ .
 arcs avant (A) : sont les arcs (u, v) qui ne sont pas dans Gπ . et qui relie le sommet u à son
descendant v dans la forét du parcours en profondeur Gπ .
 arcs traversant (T) : tous les arcs restants. Ils peuvent étre entres les sommets d'un méme
arbre, tant-que l'un des sommets n'est pas l'ancétre de l'autre. où ils peuvent étre entre les
sommets de deux arbres diérents.

29
Algorithm 6: L'algorithme de parcours en profondeur
début
pour chaque sommet u ∈ V [G] faire
couleur[u] ← blanc;
π[u] ← NIL;
n
time ← 0;
pour chaque sommet u ∈ V [G] faire
si couleur[u] = Blanc alors
PP-Visit (u);
n
n
n
PP-Visit(u)
début
couleur[u] ← Gray;
/** u vient d'être découvert
time ← time + 1 ;
d[u] ← time ;
pour chaque sommet v ∈ Adj[u] faire
/* explorer l'arc (u, v)
si couleur[u] = Blanc alors
π[v] ← u;
PP-Visit(v )
n
n
couleur[u] = Black;
/** exploration de u est terminé
time ← time + 1 ;
f [u] ← time ;
n

Remarque : Il est à noter que lorsque le graphe n'est pas orienté on ne distingue que deux types
d'arrètes : les arrètes de l'arbre et les arrèts n'appartenant pas à l'arbre. la Fig. 4.1 indique en
(a) les étapes du parcours en profondeur où chaque sommet u est étiqueté par son d[u]/f [u]. (b)
représente la forét du parcours (éches en gras) ainsi que la classication des arcs.

La complexité de l'algorithme 6 est en O(n + m). Cette algorithme peut servir à énumérer une base de
cycle, des chemins. On exploitant les valeurs f , on peut determiner le tri topologique d'un graphe s'il
est sans cycle où detecter l'existance de cycle. Il peut servir aussi de base pour calculer les composantes
fortement connexes d'un graphe etc.

4.3 Parcours en Largeur et ses propriétés


Par analogie essayez de voir que vaut les estampilles temporelles d[u]/f [u] pour chaque sommet u ∈ V
pour un parcours en largeur.

4.4 Chemins de poids maximal


1
Dans un problème de calcul de chemins de poids maximal , on se donne un graphe orienté G =
(V, E, w), où V est un ensemble de n sommets et E un ensemble d'arcs avec une fonction de poids
w : E → Z aectant chaque arc (i, j) par une valeur poids w(i, j). Le poids d'un chemin P =
1. Dans la littérature, ces algorithmes sont connus comme étant des algorithmes de recherche de chemins de poids
minimal, le problème est similaire, on a juste à changer le signe des poids des arcs.

30
t
S

T R

3/6 2/9 1/10 11/16


z t z A v u
y S T

T
R
x w v u y w
4/5 7/8 12/13 14/15

(a) (b)
x

Figure 4.1  Propriétés du parcours en profondeur


Pk
(v0 , v1 , . . . , vk ) est la somme des poids des arcs le constituants : w(P ) = i=1 w(vi−1 , vi ). On dénit le
chemin de poids maximal de u vers v par :
 p
maxp w(p) : u v s'il y a des chemins de u à v
∆(u, v) =
∞ sinon
Les algorithmes de résolution de ce problème seront diérenciés selon le problème considéré : recherche
du chemin de poids maximal d'un sommet s à tous les autres, ou recherche de chemin de poids maximal
pour tout couple de sommets.

4.4.1 Chemin de poids maximal à partir d'une source donnée


Les deux algorithmes, de recherche du chemin de poids maximal d'un sommet s à tous les autres,
décrit ci-dessous, reposent une technique dite la technique de relaxation d'arcs.

4.4.1.1 Technique de relaxation

Dans cette technique, pour tous sommet v ∈ V , on maintient un attribut d[v], qui représente une
borne inférieure au chemin de poids maximal de s à v . On appelle d[v] le chemin de poids maximal
estimé. On initialise les chemins de poids maximal estimé à d[v] = −∞ pour tous v , à l'exception du
sommet source s pour lequel d[v] = 0. On dénit π(v) le prédécesseur du sommet v pour le quel d[v] à
été mis à jour pour la dernière fois.
La technique de relaxation d'un arc (u, v, w) consiste à tester si l'on peut améliorer l'estimation du
chemin de poids maximal de v, trouver un prédécesseur, en allant à travers u. Si c'est le cas mettre à
jour d[v] et π(v).

RELAXER (u, v, w)
si d[v] < d[u] + w(u, v) alors
d[v] ← d[u] + w(u, v);
π(v) ← u;
n

4.4.1.2 Algorithme de Dijkstra

L'algorithme d'Edgser Wybe Dijkstra (1930-2002), proposé en 1959, résout le problème de calcul de
chemin de poids maximal d'un sommet à tous les autres. On suppose que w(u, v) ≤ 0 pour tous arc
(u, v) ∈ E . S de sommets dont les chemins de poids
L'algorithme de Dijkstra maintient un ensemble
maximal dont déjà déterminés : tel que pour tous sommet v ∈ S on a d[u] = ∆(u, v). A chaque étape
l'algorithme choisi un sommet u ∈ V − S dont le chemin de poids maximal estimé d[u] est maximal,
insert u dans S et relaxe tous les arcs sortants de u.

31
Algorithm 8: L'algorithme de Dijkstra
début
Initialise-source(G, s);
S ← ∅;
Q←V;
tant que Q 6= ∅ faire
u ← Extraire-Max(Q);
S ← S ∪ {u};
pour chaque v ∈ Adj[u] faire
RELAXER(u, v, w )
n
n
n

Dans l'algorithme 8, la structure Q représente une tas à priorité, qui contient tous les sommets dans
V − S, indexés par la valeur de leur d. Q est implémenté avec un
Dans le cas où la tas de priorité
simple tableau alors la procédure Extraire-Max
O(n). Dans l'algorithme de Dijkstra la boucle
sera en
Tantque est itéré n fois. La boucle Pour est itérée au total |E| fois soit m fois, , le nombre total d'arcs,
donc pour chaque itération elle prend O(1). Par conséquent, le temps d'exécution total de l'algorithme
est en O(n + m) ≡ O(n ). .
2 2 2

Toutes fois, si le graphe est peu dense, il est plus conseillé d'implémenter la tas à priorité avec
un tas binaire
3
Avec cette implémentation, la procédure Extraire-Maxsera en O(lg n) et l'aectation
d[v] ← d[u] + w(u, v) sera réalisée par la primitive Augmenter-clé (Q, v, d[u] + w(u, v)) en O(lg n), dans
quel cas le temps d'exécution de l'algorithme 8 sera en O((n + m) lg n).
Une structure de donnée encore plus adéquate pour accélérer cet algorithme est le tas de Fi-
bonacci [2]. Avec cette structure, chacun des n appels à la primitive Extraire-Max a un cout amorti 4
enO(lg n), et chacun des |E| appels à la primitive Augmenter-clé prend seulement un temps amorti en
O(1). Par conséquent, l'algorithme de Dijkstra peut étre exécuté en O(n lg n + m).

4.4.1.3 Algorithme de Bellman-Ford

L'algorithme de Bellman-Ford résout le problème de calcul de chemin de poids maximal d'un sommet
à tous les autres, dans le cas le plus général aucune restriction sur le poids des arcs. Pour un graphe orienté
G = (V, E, w) et un sommet source s, l'algorithme de Bellman-Ford retourne un bouleen indiquant si un
cycle de poids positif, atteignable à partir de s, existe ou non. Si un tel cycle existe, l'algorithme indique
qu'aucune solution n'existe. Dans le cas contraire, l'algorithme calcule pour chaque sommet v le chemin
3
de poids maximal allant de s vers v ainsi que son poids. L'algorithme 9 s'exécute en O(n ).

4.4.2 Chemin de poids maximal pour tous les couples de sommets


Dans un problème de calcul de chemins de poids maximal pour tous couple de sommets en se donne
graphe orienté G = (V, E, w), où V est un ensemble de n sommets et E un ensemble d'arcs avec une
fonction de poids dans l'ensemble des nombres réels.
Ce problème peut étre résolu en appliquant n fois l'un des deux algorithmes précédents : (1) lorsque
tous les arcs sont de poids non positif, les n appels à Dijkstra, selon son implémentation donne le résultat
3 2 2
en O(n ) (avec tableau), en (n + n.m) lg n) avec un tas binaire et en O(n lg n + n.m)) avec un tas de
4
Fibonacci, (2) Dans le cas général, n appels à l'algorithme de Bellman-Ford donne le résultat en O(n ).
Dans ce qui suit on donne deux algorithmes de calcul de chemins de poids maximal pour tous couple
de sommets

2. Dans la suite, souvent la complexité en O(|E|) est majorée par O(n2 )


3. Un tas binaire est une structure de donnée qui peut étre vue comme un arbre de recherche binaire complet, disposant
de primitives de manipulation spéciales tels que : Augmenter-clé (Q, v, k) qui incrémente la clé d'un élément v en O(lgn)
toute en préservant la tas ordonnée.
4. un cout amorti est le temps requis pour eectuer une séquence d'opérations sur une structure de données, il s'agit
d'une moyenne sur toutes les oprérations eectuées. L'analyse amortie diére de l'analyse dans le cas moyen, l'analyse
amortie garantie la performance moyenne de chaque opération dans le pire des cas.

32
Algorithm 9: L'algorithme de Bellman-Ford
début
Initialise-source(G, s);
pour i ← 1to|V | − 1 faire
pour chaque arc (u, v) ∈ E faire
RELAXER(u, v, w );
n
n
pour chaque arc (u, v) ∈ E faire
si d[v] < d[u] + w(u, v) alors
return FALSE ;
n
n
return TRUE ;
n

All intermediate vertices of p1 are in {1, 2, . . . , k − 1} All intermediate vertices of p2 are in {1, 2, . . . , k − 1}

k
$p_1$ $p_2$

i j

All intermediate vertices of p are in {1, 2, . . . , k}

4.4.2.1 Algorithme de Floyd-Warshall

L'algorithme de Floyd-Warshall, suppose que tous les cycles dans G, s'il en existe, sont de poids
négatifs. Cet algorithme utilise une formulation de programmation dynamique pour résoudre le problème
de chemins de poids maximal pour tous couple de couples de sommets. rappelons briévement que dans
une telle formulation on doit : (1) caractériser la structure de la solution optimal, (2) dénir récursivement
la valeur de la solution optimale et (3) calculer la valeur de la cette solution. En eet, dans algorithme
de Floyd-Warshall utilise la structure du chemin de poids maximal suivante : on dénit les sommets
intermédiaires d'un chemin de poids maximal, où un sommet intermédiaire d'un chemin p = (v1 , . . . , vk )
est un sommet dans l'ensemble (v2 , . . . , vk−1 ).
L'algorithme se base sur l'observation suivante. Soit V = {1, 2, . . . , n} l'ensemble de tous les sommets
de G, et pour un k ∈ V , considérons le sous ensemble {1, 2, . . . , k} pour chaque pair i, j ∈ V , considérons
tous les chemins de i vers j dont les sommet intermédiaires sont dans {1, 2, . . . , k}, et soit p le chemin de
poids maximal parmi eux. (p est un chemin élémentaire du fait que G ne contient pas de cycle positif ).
L'algorithme exploite la relation entre le chemin p et tous les chemins de poids maximal de i à j
dont les sommets intermédiaires sont dans l'ensemble {1, 2, . . . , k − 1} : (1) si k n'est pas un sommet
intermédiaire dans le chemin p, donc tous les sommets intermédiaires de p sont dans {1, 2, . . . , k − 1},
ainsi un chemin de poids maximal de i à j dont les sommets intermédiaires sont dans {1, 2, . . . , k − 1} est
aussi un chemin de poids maximal de i à j dont les sommets intermédiaires sont l'ensemble {1, 2, . . . , k}.
p1 p2
(2) si k est un sommet intermédiaire dans p alors on coupe le chemin en deux sous chemin i k j
comme l'indique la gure 4.4.2.1. p1 (resp. p2 ) est un chemin de poids maximal de i à k dont les sommets
intermédiaires sont dans {1, 2, . . . , k − 1}, en eet, k n'est pas un sommet intermédiaire dans p1 (resp.
p2 ). ceci est induit directement du fait que les sous chemins d'un chemin de poids maximal sont des
chemins de poids maximal.
Partant d'un graphe où tout circuit a une valeur négative ou nulle, l'algorithme de Floyd-Warshall,
(k)
basé sur la structure de chemin décrite ci-dessus, dénit aij comme étant la valeur du chemin de poids
(k)
maximal de i à j dont l'intérieur est inclus {1, 2, . . . , k} Lorsque k = 0, aij = wij , ainsi la dénition

33
Algorithm 10: Algorithme de Floyd-Warshall
début
pour i de 1 à n faire
pour j de 1 à n faire
aij ← wij ;
n
aii ← 0 ;
n
pour k de 1 à n faire
pour i de 1 à n faire
pour j de 1 à n faire
(k) (k−1) (k−1) (k−1)
aij ← max{aij , aik + akj } ;
n
n
n
n

récursive du chemin de poids maximal :

(
(k) wij si k=0
aij = (k−1) (k−1) (k−1)
max{aij , aik + akj } si k > 0.

3 2
L'algorithme 10 s'exécute en O(n ) et nécessite une matrice de travail de taille n . Dans cette algo-
(k)
rithme, l'exposant k dans a est juste mis pour indiquer l'itération, il est d'aucune importance lors de
l'implémentation.

4.4.2.2 Algorithme de Johnson

L'algorithmeé 11 trouve les chemins de poids maximal pour tous couple de sommets avec une com-
plexité enO(n2 lgn + m). Cette complexité est meilleure que celle de Floyd-Warshall O(n3 ) lorsque le
graphe est peu dense. L'algorithme s'applique pour un graphe quelconque, et rapporte si le graphe con-
tient des cycles de poids positifs. L'algorithme de Johnson utilise comme procédures à la fois l'algorithme
de Dijkstra et Bellman-Ford.
Pour pouvoir utilisé l'algorithme de Dijkstra dans le cas d'un graphe ayant des arcs de poids négatif,
l'algorithme de Johnson utilise la technique de repondération. Cette technique, dénit une nouvelle
fonction de pondération d'arc w qui doit vérier deux proprietés : (1) Pour tous couple i, j ∈ V si l'on
r
r
connait le chemin de poids maximal pour la fonction de poids w il est facile de retrouver le chemin de
poids maximal de i vers j
en utilsant la fonction de poids w , on parle de conservation de chemin de poids
maximal, (2) pour tous couple(i, j), le nouveau poids wr (i, j) est positif (négatif !) ou nulle.
Pour mettre au point une nouvelle fonction de pondération w , on dénit une fonction h : V → R
r

associant à chaque sommet un nombre réel. Pour chaque arc (u, v) ∈ E , on dénit w (i, j) = w(u, v) +
r

h(v) − h(u).
Dans l'algorithme 11, l'algorithme de Bellman-Ford est utilisé pour tester l'existance de cycle de poids
postif au quel cas il y a pas de solution. Dans le cas contraire, les chemins de poids maximal à partir de
la source ctive s vers tous sommet v ∈ V , ∆(s, v) servent à dénir la fonction de repondération h.
La Fig. 4.1 résume pour chacun des algorithmes, décrits ci-dessus, leurs complexités respectives ainsi
que les conditions sur la structure du graphe au quel il s'applique.

4.5 Algorithme de Roy-Warshall


L'algorithme de Roy-Warshall calcule pour un graphe orienté G, la relation d'accessibilité pour tous
couple de sommets ; il retourne un boolean à VRAI, pour chaque couple i, j de sommets, si il existe un
chemin de i à j , FAUX sinon. C'est un algorithme de programmation dynamique qui ressemble dans son

34
Algorithm 11: L'algorithme de Johnson
début
Construire G0 , Où V [G0 ] = V [G] ∪ {s} et
0
E[G ] = E[G] ∪ {(s, v); v ∈ V [G]};
si Bellman-Ford (G0 , w, s) = Faux alors
 G contient des cycles de poids positive
n
pour chaque sommet v ∈ V [G0 ] faire
h(v) ← −∆(s, v)
/* Oé ∆(s, v) est calculé par Bellman-Ford */
n
pour (u, v) ∈ E[G0 ] faire
chaque arc
w (u, v) ← w(u, v) + h(v) − h(u)
r

n
pour u ∈ V [G] faire
chaque sommet
∆r (u, v) ← r
Dijkstra(G, w
, u);
pour chaque sommet v ∈ V [G] faire
au,v ← ∆r (u, v) + h(u) − h(v)
n
n
Retourner D ;
n

Algorithme Type du problème Propriétés du Complexité temporelle Complexité spatiale


graphe
Recherche du chemin poids des arcs implémenté Queue binaire Queue de O(n)
Dijkstra
de poids maximal d'un négatifs avec tableau Fibonacci
sommet à tous les (Graphe peu
autres dense )
2
O(n ) O((n + m) lg n) O(n lg n + m)
Bellman-Ford // quelconque O(n3 ) O(n)
Floyd-Warshall Recherche du pas de cycle de O(n3 ) O(n2 )
chemin de poids poids positif
maximal pour tous
couple de sommets
Johnson // Graphe peu O(n2 lg n + n.m) O(n)
dense

Table 4.1  Tableau récapitulatif des algorithmes de recherche de chemins de poids maximal

5 (k)
principe à l'algorithme de Floyd-Warchall . En eet, on dénit Accij
le booléen qui atteste si j est
accessible à partir de i par un chemin dont les sommets intermédiaires sont dans l'ensemble {1, 2, . . . , k}.
ainsi on dénit récursivement Accij comme :


 V RAI s'il existe un arc de i à j et k = 0
(k)
Accij = F AU X si pas d'arc de i à j et k = 0
 (k−1) (k−1) (k−1)
Accij or (Accik and Acckj ) si k > 0.
L'algorithme 12 s'exécute en (n3 ), avec une matrice de travail de taille n2 .

5. Historiquement c'est l'algorithme de Floyd-Warchall qui est inspiré de l'algorithme de Roy-Warshall faisant la sub-
stitution suivante : or = max, and = + et

35
Algorithm 12: Algorithme de Roy-Warshall
début
pour chaque couple (i, j) ∈ (V XV )E faire
si l'arc(i, j) alors
Accij ← V RAI ;
sinon
Accij ← F AU X ;
n
n
pour k de 1 à n faire
pour i de 1 à n faire
pour j de 1 à n faire
Accij ← Accij or (Accik and Acckj ) ;
n
n
n
n

36
Chapitre 5

Introduction à la théorie de la
N P -Complétude

5.1 Introduction
Dans l'étude de la complexité des problèmes, le point important qui concerne aussi bien le théoricien
que le praticien est de savoir si, pour un problème donné, il existe un algorithme de complexité polyno-
k
miale  de complexité de l'ordre de O(n avec k une constante pour le résoudre.
Dans ce chapitre, nous allons, dans un premier temps, passer en revue les diérentes classes de
complexité des problèmes. Ensuite, nous allons nous concentrer sur les techniques de réduction pour
montrer l'improbabilité d'existence d'algorithmes ecaces pour résoudre tel ou tel problème.
Le praticien va trouver cette notion de ne prouver rien du tout quelque peu bizard : on investit son
temps pour prouver que quelque chose n'existe pas ! Pourquoi donc seriez-nous mieux en sachant que
quelque chose qu'on ne sait pas faire n'existe pas ?

En réalité, la théorie de la N P -complétude est utile pour le concepteur d'algorithmes, même si elle
ne produit que des résultats négatifs :  Quand l'impossible est éliminé, ce qui reste, même improbable,
doit être la vérité . La théorie de la N P -complétude permet de concentrer les eorts d'une manière pro-
ductive en révélant qu'il y a peu de chance que la recherche, pour une solution ecace pour un problème,
soit un succès. Autrement dit, quand on échoue de montrer que tel problème est dicile à résoudre, alors
on a plus de chance de lui en trouver un algorithme ecace.

Par ailleurs, la théorie de la N P -complétude nous permet d'identier les propriétés qui font qu'un
problème soit dicile. Cela devrait nous aider à mieux cerner les diérentes directions de modélisation
et de résolution.

5.2 Vocabulaire général


Problème : Question comportant un ou plusieurs paramètres ; par exemple, quel est le plus court chemin
entre deux sommets données d'un graphe ?

Instance d'un problème : soit X le problème caractérisé par l'ensemble E de ses données, E =
e1 , . . . , en , une instance de X serait alors caractérisée par un ensemble concret E 0 = e01 , . . . , e0n
00 00 00
, une deuxième instance serait caractérisée par un deuxième ensemble concret E = e1 , . . . , en et
ainsi de suite.

L'invariant suivant est toujours vérié : |E| = |E 0 | = |E 00 |.


Problème abstrait : relation binaire entre un ensemble d'instances d'un problème et un ensemble de
solutions à ce problème.

Problème de décision (ou décisionnel) : il possède pour solution oui ou non. On en déduit qu'un
problème décisionnel abstrait fait correspondre à toute instance l'ensemble des solutions {vrai,
f aux}.

37
On représente fréquemment un problème de décision par un ensemble X qui est un sous-ensemble
général Y. Alors, pour chaque instance y∈Y , le problème consiste à décider si oui ou non y ∈ X.
Problème de calcul : calculer la solution d'un problème. (ex. : Calculer le plus court chemin entre
deux sommets donnés d'un graphe).

Résoluble en un temps polynomial : il existe un algorithme permettant la résolution en O(nk ) pour


une constante k.
Problème d'optimisation : quadruplet < I, S, f, mode > où I représente les donnés du problème,
S est le type de collection/ensemble ou le type d'élément qu'on attend comme résultat, f est la
fonction qui mesure la qualité du résultat et mode (min ou max) indique s'il faut minimiser ou
maximiser la taille de ce résultat.
0
Réductibilité : un problème X peut être ramené (réduit) à un autre problème X si une instance
0
quelconque de X peut être facilement reformulée comme une instance de X dont la solution sera
aussi solution pour X.
Réductibilité en temps polynomial : La fonction qui réduit le problème X en X0 peut être obtenue
en temps polynomial.

Machine non-deterministe est un Concept abstrait / modèle mathématique d'un ordinateur mini-
maliste, mais particulièrement performant ; où

1. À chaque étape d'un processus décisionnel séquentiel, il prend la bonne décision instantané-
ment ;

2. Aucun besoin d'explorer les diérentes alternatives !

5.3 Classication de problèmes


Pour des raisons de simplicité et techniques aussi, la théorie de la complexité se limite juste à l'étude
des problèmes de décision. En eet, un problème de décision (ou décisionnel) est un problème qui pos-
sède pour solution oui/non. On en déduit qu'un problème décisionnel abstrait fait correspondre à toute
instance du problème l'ensemble des solutions {vrai, f aux}.
Exemple 1 : Étant donné un graphe G = (X, E), existe t-il un chemin de longueur ≤ L ?
Exemple 2 : Étant donné un graphe G = (X, E), les sommets de X peuvent-ils être colorés par au
plus m couleurs de telle manière que les sommets adjacents soient de couleurs diérentes.
De cette dénition, ce qui importe c'est juste l'existence de la solution. Cette restriction aux problèmes
de décision est justiée par le fait que les autres problèmes qui ne sont pas de décision, comme les
problèmes d'optimisation, peuvent être facilement transformés en un problème de décision équivalent.
Le but de la théorie de la complexité est la classication des problèmes de décision suivant leur degré de
diculté de résolution.
Dans la littérature, il y a un grand panorama de diérents classements de problèmes informatiques.
Les problèmes décisionnels sont tous eectivement rangés dans des collections de complexité comparable :
les Classes de complexité. La liste qui suit ne veut pas être exhaustive, mais elle montre une très grosse
partie de ce classement :

Cependant, celle qui sont les plus connues et qui méritent plus d'attention sont :

La classe P C'est la classe des problèmes dits faciles.

Il s'agit de la classe de complexité contenant les problèmes décisionnels pouvant être résolus par
une machine de Turing déterministe pendant un temps de calcul polynomial. La complexité du
temps de calcul pour un problème X exprime un rapport entre la taille de ses données et le temps
utilisé pour le résoudre. Pour cette raison on indique souvent les problèmes appartenant à cette
classe comme étant ecients ou tractables : bien qu'il soit naturel et raisonnable de considérer
200
comme intraitable dans la pratique un problème qui demande un temps de l'ordre de n , il ex-
iste eectivement très peu de problèmes qui requièrent un temps d'un ordre de grandeur aussi élevé.

1. un système de preuve interactif où les jets de la pièce du véricateur sont connus par le testeur.
2. une machine abstraite où les deux parties, le testeur et le véricateur, interagissent activement entre eux
3. une machine abstraite pour l'étude de problèmes décisionnels : elle possède une boite noire (l'oracle) capable de
décider sur certains problèmes décisionnels avec une seule étape.

38
Classe Description (des problèmes)
AM Peuvent être résolus en temps polynomiale par un protocole Arthur-Merlin 1 .
BPP Peuvent être résolus en temps polynomiale par un algorithme aléatoire (la réponse est correcte la plus part du
temps)
BQP Peuvent être résolus en temps polynomiale par un ordinateur quantique
Co-N P Réponse négative vériable en temps polynomial.
Co-N P -complete Les problèmes les plus diciles dans Co-N P
DSPACE(f (n)) Résolubles avec une machine déterministe et avec un espace en O(f (n))
DTIME(f (n)) Résolubles avec une machine déterministe et avec un temps en O(f (n))
E Résolubles en temps exponentiel avec un exposant lineaire
ELEMENTARY L'union des classes dans la hiérarchie exponentielle
ESPACE Résolubles en espace exponentiel avec un exposant lineaire
EXPSPACE Résolubles en espace exponentiel
EXPTIME Résolubles en temps exponentiel
FNP Le correspondant de N P pour les problèmes non décisionnels
FP Le correspondant de P pour les problèmes non décisionnels
FPN P Le correspondant de P N P pour les problèmes non décisionnels
FPT Fixed-parameter tractable : tractable avec un paramètre établi
IP Résolubles en temps polynomiale par un système de preuve interactif 2
L Peuvent être résolus en espace logarithmique (petit)
NC Résolubles ecacement (en temps poly-logarithmique) avec un ordinateur en parallèle (processeurs en parallèle)
NE Résolubles en temps exponentiel (avec un exposant lineaire) avec une machine non-déterministe
NESPACE Résolubles en espace exponentiel (avec un exposant lineaire) avec une machine non-déterministe
NEXPSPACE Résolubles en espace exponentiel avec une machine non-déterministe
NEXPTIME Résolubles en temps exponentiel avec une machine non-déterministe
NL Réponse armative vériable en espace logarithmique
NP Une réponse armative au problème peut être vériée en temps polynomiale
N P -complete Les problèmes les plus diciles (et intéressants) dans N P , ceux qui semblent vraiment ne pas faire partie de P
N P -easy Les problèmes les plus diciles dans FPN P
N P -hard Les problèmes N P -complets ou encore plus diciles
NSPACE(f (n)) Problèmes pouvant être résolus avec une machine non-déterministe en espace O(f (n))
NTIME(f (n)) Problèmes pouvant être résolus avec une machine non-déterministe en espace O(f (n))
P Résolubles en temps polynomial
P -complete Les problèmes les plus diciles dans P , à résoudre avec un ordinateur en parallèle (processeurs en parallèle)
PCP La preuve est vériable de façon probabiliste
PH L'union des classes dans la hiérarchie polynomiale
PN P Résolubles en temps polynomial avec un Oracle 3 pour un problème dans N P
PP Probabilistically Polynomial : la réponse est correcte avec une probabilité légèrement supérieure à 1/2
PSPACE Résolubles avec une mémoire polynomiale mais un temps illimité
PSPACE-complete Les problèmes les plus diciles dans PSPACE

P est réputé contenir de nombreux problèmes naturels, comme le calcul du plus grand commun
diviseur. On pourrait alors généraliser P avec l'inclusion de tout autre problème qui peut être
résolu en temps polynomiale par une machine de Turing non-déterministe. La classe qui en
résulte prend le nom de NP et elle implique une relation triviale : P⊆ N P .
La classe P -complète Un problème décisionnel appartient à ce classement s'il fait partie de la classe
P et si tout problème dans P peut s'y réduire en temps poly-logarithmique en utilisant un ordinateur
avec un nombre polynomial de processeurs. En pratique, si X est un problème dans P - complète
alors il appartient à P et pour tout problème Y dans P , il existe les constantes c et k telles que
Y puisse être réduit en X en O(c.(log(n))) avec un ordinateur qui possède O(nk ) processeurs en
parallèle.

La classe NP C'est l'abréviation pour "Nondeterministic Polynomial time". Il s'agit de l'ensemble


des problèmes décisionnels pouvant être résolus en temps polynomial avec une machine de Turing
non-déterministe. Ils peuvent également être validés par un algorithme polynomial. Autrement dit,
cette classe renferme tous les problèmes de décision dont les meilleurs algorithmes ne sont pas
polynômiaux mais dont on peut associer à chacun d'eux un ensemble de solutions potentielles (de
cardinal au pire exponentiel) tel qu'on puisse vérier en un temps polynomial si une solution poten-
tielle satisfait la question posée. Le terme nondeterministe désigne un pouvoir qu'on incorpore
à un algorithme pour qu'il puisse deviner la bonne solution.

Attention : erreur classique Confondre N P comme voulant dire temps Non-Polynomial ; le P indique
N une machine Non-déterministe ;
toujours un temps Polynomial et le

NP = Non deterministic Polynomial

5.4 Qu'est ce qu'un problème N P -complet ?


Le classement N P -complet contient les problèmes les plus diciles de N P. Ces problèmes semblent
vraiment ne pas faire partie de P (bien que à l'heure actuelle on ne possède pas une réponse dénitive,
voir la question irrésolue P= N P ?).
Si nous sommes capables de trouver un moyen de résoudre ecacement (algorithme polynomial) un
problème de N P -complet, nous pouvons alors utiliser cet algorithme pour résoudre tous les problèmes de
N P. En eet, comme pour P et P -complet, un problème X appartient à N P -complet s'il est dans N P
et si tout autre problème dans N P peut s'y réduire. On en déduit que une méthode assez facile pour

39
prouver que un nouveau problème appartient à N P -complet est de montrer d'abord qu'il est dans N P ,
ensuite le réduire en un problème connu dans N P -complet. Par conséquent, il est très utile de connaître
une variété de problèmes N P -complets : la liste qui suit en décrit brièvement certains parmi les plus
connus.

5.4.1 Problèmes connus N P -complets


Boolean Satisability problem (SAT) - satisabilité d'une formule booléenne (théorie de la com-
plexité) : Pour une expression booléenne donnée (contenant uniquement les opérations ET , OU ,
N ON , les variables et les parenthèses), existe-t-il une aectation (de VRAI ou FAUX) aux variables
qui rend vraie l'expression ? SAT est un des six principaux problèmes.

k -Conjunctive Normal Form Boolean Satisability problem (k -CNF SAT) - satisabilité d'une
formule booléenne en forme normal d'ordre k . (Rappel : Un littéral est une variable ou sa négation ;
une clause est une disjonction de littéraux. Une formule booléenne est en forme normale conjonc-
tive (CNF) si c'est une conjonction de clauses. Une aectation est une fonction v : X → {0, 1}. La
formule est dite satisable s'il existe une aectation rendant φ vraie et est non satisable s'il n'en
existe pas. Une formule est vraie si et seulement si toutes ses clauses sont vraies).

nQueens - nDames (Intelligence articielle, VLSI testing, circulation) Trouver toutes les combi-
naisons de n Dames sur un damier de taille n × n de telle sorte qu'aucune de dames ne puisse
être attaquée par les autres. Version décisionnelle : le damier possède-t-il au moins (ou plus que) k
combinaisons ?

Knapsack problem - problème du sac à dos (combinatoire, théorie de la complexité, cryptographie)


Pour un ensemble donné d'objets, chaque objet ayant un coût et une valeur, déterminer le nombre
de chaque objet à insérer dans une collection de telle sorte que le coût total soit inférieur à un coût
donné et que la valeur totale soit la plus grande possible. Le problème décisionnel correspondant
est peut-on réaliser une valeur V sans dépasser le coût C ?. (Une variante avec plus de sens est
de substituer le coût avec un poids maximal pour le sac à dos).

Hamiltonian Cycle problem - problème du cycle hamiltonien (théorie des graphes, mathématiques)
Pour un graphe donné, possède-t-il un cycle hamiltonien ?

Traveling Salesman problem (TSP) - problème du voyageur de commerce (optimisation discrète et


combinatoire) : Pour un ensemble de villes données et un prix de voyage entre toute couple de
villes, quelle est la route la plus économique qui permet de visiter une fois chaque ville et puis de se
retrouver à celle de départ ? Version décisionnelle : existe-t-il une route plus économique que celle
donnée, dont le prix est x?
Subgraph Isomorphism problem - problème du sous-graphe isomorphe (théorie des graphes) Pour
deux graphes donnés, le premier est-il isomorphe à un sous-graphe du deuxième ?

Subset Sum problem - problème de la somme d'un sous-ensemble (théorie de la complexité, cryptogra-
phie) Pour un ensemble d'entiers donné, existe-t-il un sous-ensemble dont la somme des éléments
est zéro ?

Clique problem - problème de la clique (dans un graphe) (théorie des graphes) Trou- ver la clique de
taille maximale dans un graphe donné. La variante décisionnelle  k -clique est : le graphe contient-il
une clique de taille k?
Vertex Cover problem - problème de la couverture de sommets (théorie de la complexité, théorie des
graphes) Le graphe donné possède-t-il une couverture de sommets d'une taille k donnée ?

Independent Set problem - problème de l'ensemble indépendant (de sommets dans un graphe) (théorie
des graphes, combinatoire) Le graphe donné possède-t-il un ensemble indépendant (de sommets)
de taille minimale k?
Graph Coloring problem - problème du coloriage du graphe (théorie des graphes, application dans
l'emploi du temps, allocation de registres dans le microprocesseurs, reconnaissance d'un motif )
Il regroupe plusieurs types de problèmes de coloriage des éléments du graphe : vertex coloring
(coloriage des sommets), edge coloring (coloriage des arêtes), list coloring (chaque sommet choisit
dans une liste de couleurs), total coloring, complete coloring, etc. Si on indique pas la méthodologie
de coloriage, on sous-entend généralement le problème de coloriage des sommets dans le graphe :
existe-t-il une coloration (des sommets) du graphe qui utilise au plus k couleurs ?

40
Circuit − SAT

SAT

3−CNF SAT

Clique Problem SubSet Problem

Vertex Cover Problem

Hamiltonian Cycle

Travelling Salesman

Figure 5.1  Struture des preuves de la N P -complétude

Dans la littérature, on distingue aussi entre les

Problème N P -Complet au sens faible Il est N P -Complet mais il existe un algorithme pseudo-
polynomial (peut s'exprimer comme un polynôme des paramètres du problème) pour le résoudre.

Problème N P -Complet au sens fort  Il appartient à la classe NP ;


 Il reste N P -Complet même si on limite la taille des paramètres du problème.

5.5 Comment prouver qu'un problème est N P -complet ?


On compte sur trois concepts clefs pour montrer qu'un problème est N P -complet.
1. Transformer le problème d'optimisation en un problème décisionnel.

2. Réductibilité : savoir réduire en un temps polynomiale un problème P en un autre dont la classe


est connu (voir la section suivante]

3. Avoir un premier problème N P -complet pour que le processus de réduction démarre. La section
précedente nous assure ce point.

Dans le diagramme 5.1, une èche indique le sens de réduction. Il faut se souvenir qu'il existe toujours
une réduction (en temps polynomial) entre deux problèmes dans N P -complet : ce schéma nous montre
où cette réduction a été facile.

5.6 Processus de réduction polynomiale


Soient deux problèmes P1 et P2 , réduire P1 en P2 signie transformer une instance quelconque de
P1 en une instance équivalent de P2 ; ainsi, P2 peut servir de sous-routine pour résoudre P1 . On note
P1 α P2 .
Principe : Le processus de réduction donne un moyen de résoudre un problème P1 en temps poly-
nomial de la façon suivante :

1. Etant donné une instance a de P 1, utiliser une réduction à temps polynomial pour la transformer
en une instance b d'un problème P 2,

41
Oui
Oui
α Algorithme de réduction β Algorithme de décision pour B
en temps polynomiale en temps polynomiale
Non
Non
Algorithme de décision pour A en temps polynomial

Figure 5.2  Schématisation du processus d'une réduction polynomiale

2. Exécuter l'algorithme de décision à temps polynomial de P2 sur l'instance b,


3. Utiliser la réponse pour b comme réponse pour a.
Dénition : Soient A et B, deux problèmes. On dit que A est polynomialement Turing réductible à
B (noté A <P
T B) s'il existe un algorithme pour résoudre A qui serait exécutable en temps polynomial
si on pouvait résoudre n'importe quelle instance de B en un temps unité.
Théorême : Si A <P T B et si B peut etre résolu en un temps polynomial, alors A est également
résoluble en temps polynomial.

5.7 Exemple de réduction

42
5.8 La conjecture de l'informatique théorique P = N P ?
Personne n'a trouvé d'algorithme polynomial pour un problème N P -Complet. En outre, personne
n'a pu prouver qu'il n'en existait pas !
On a clairement P ⊂ NP car un algorithme déterministe est un algorithme non déterministe partic-
ulier, ce qui, dit en mots plus simples, signie que si une solution peut être calculée en temps polynomial,
alors elle peut être vériée en temps polynomial. En revanche, la réciproque : N P⊂ P qui est la véritable
diculté de l'égalité P = N P est un problème ouvert central d'informatique théorique. Il a été posé en
1970 indépendamment par Stephen Cook et Leonid Levin. La plupart des spécialistes conjecturent que
les problèmes N P -complets ne sont pas solubles en un temps polynomial (donc, que P6= N P ). À partir
de là, plusieurs approches algorithmique ont été créer an d'approchr les solutions exactes.

Des algorithmes d'approximation (ou heuristiques) permettent de trouver des solutions approchées
de l'optimum en un temps raisonnable pour un certain nombre de programmes. Dans le cas d'un
problème d'optimisation on trouve généralement une réponse correcte, sans savoir s'il s'agit de la
meilleure solution.

Des algorithmes stochastiques en utilisant des nombres aléatoires on peut forcer un algorithme à
ne pas utiliser les cas les moins favorables, l'utilisateur devant préciser une probabilité maximale
admise que l'algorithme fournisse un résultat erroné.

Des algorithmes par séparation et évaluation permettent de trouver la ou les solutions exactes. Le
temps de calcul n'est bien sûr pas borné polynomialement mais, pour certaines classes de problèmes,
il peut rester modéré pour des instances relativement grandes.

L'approche de la complexité paramétrée consiste à identier un paramètre qui, dans le cas où il


reste petit, permet de résoudre rapidement le problème. En particulier les algorithmes FPT en un
paramètre k permettent de résoudre un problème en temps proportionnel au produit d'une fonction
quelconque de k et d'un polynôme en la taille de l'instance, ce qui fournit un algorithme polynomial
quand k est xé.

On peut restreindre la classe des problèmes considérés à une sous-classe susante, mais plus facile
à résoudre.

43
44
Chapitre 6

Introduction à l'Algorithmique
géometrique

6.1 Introduction & motivation


Algorithmique géometrique est le développement de méthodes informatiques pour résoudre des prob-
lèmes géométriques.

Domaines d'applications
 Informatique graphique,
 Robotique,
 Traitement d'image,
 Systèmes d'information géographique, bioinformatique...

Les classes principales d'algorithmes


Décomposition de polygone en triangles, trapèzes, polygones monotones, convexes,... plus faciles à
manipuler.

Enveloppe convexe déplacement, calcul de la + petite boite, analyse de forme...


Delaunay/Voronoi reconnaissance, allocation, interpolation, reconstruction de courbes ou de surfaces,
calcul de chemin minimal, graphe médian (déplacement), cristallographie.

Arrangements graphe de visibilité, face cachée, appariements.


Recherche spatiale intersection, localisation, points extrémaux

Outils disponibles
 Logiciels scientiques généralistes comme R, Matlab : enveloppe convexe, triangulation de Delau-
nay, diagramme de Voronoi, aire de polygone, test d'inclusion d'un point dans un polygone.
 Bibliothèques de programmation dédiés : LEDA (payant), CGAL (en partie sous GPL).

6.2 Triangulation de Delaunay

45
46
Bibliographie

[1] Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest. Introduction to Algorithms. The
MIT Press and McGraw-Hill Book Company, 1989.

[2] Thomas H. Cormen, Charles E. Leiserson, and Ronald L. Rivest. Introduction to Algorithms. The
MIT Press and McGraw-Hill Book Company, 1989.

47

Vous aimerez peut-être aussi