Corrigés TD Algorithmique Avancée
Corrigés TD Algorithmique Avancée
Avancée
Question 1 Pour montrer qu’un algorithme est correct, il faut montrer qu’il ter-
mine et qu’il renvoie le résultat attendu.
— Terminaison :
— Avant et après la boucle “tant que” il y a un nombre constant d’opé-
rations.
— Dans la boucle “tant que” il y a un nombre constant d’opérations.
— La boucle “tant que” s’exécute au plus n fois (si t = 1 alors m mod t =
n mod t = 0)
1
— L’algorithme renvoie le résultat attendu pour n’importe quelle donnée :
— Le premier “si” est correct (si n = 0 alors le PGCD est 0).
— Invariant de boucle : t ≥ P GCD(m, n)
1. Initialisation : le PGCD est plus petit que n, donc correct.
2. Conservation : On suppose que l’invariant est vrai au début d’une
itération, on montre qu’il est vrai au début de l’opération suivante.
Puisque t ≥ P GCD(m, n), si m mod t ̸= 0 et n mod t ̸= 0 alors
t > P GCD(m, n) et donc l’invariant est vrai au début de l’itération
suivante.
3. Terminaison : La boucle termine si t est un diviseur de m et de n,
puisque t ≥ P GCD(m, n), alors t = P GCD(m, n) d’où le résultat.
Question 3 Le pire des cas est lorsque m n’a pas de diviseur commun avec n, par
exemple quand m est un nombre premier. Dans ce cas PGCD_brute-force
passe n fois dans la boucle, et donc le nombre d’opérations est cn où c est
une constante.
2
Par conséquence, p divise r car m n ′
p ∈ N et p ∈ N . Et donc p ≤ p puisque
p divise n et r. D’autre part, m n r ′ n
p′ = k p′ + p′ implique p divise m car p′ ∈ N
et pr′ ∈ N. Donc p′ ≤ p car p = P GCD(m, n). D’où p = p′ .
Question 6 Non : m mod n est toujours plus petit que n, donc le nombre d’itéra-
tions ne peut pas être supérieur à n.
Question 8 Le pire des cas est le même : lorsque m et n n’ont aucun commun
diviseur. Dans ce cas là on s’arrête lorsque n = 0. Considérons les valeurs
successive de n à chaque début itération dans l’ordre inverse. La première
valeur est positive, et après 2 itérations, par le résultat de la question précé-
dentes, la valeur de n est au moins doublée. Donc si on a k itération, alors
k
n ≥ 2 2 . Autrement dit le nombre d’itérations k est tel que k ≤ 2 log2 n.
3
2 Analyse asymptotique et complexité d’algorithmes itératifs
Exercice 1 Utiliser la complexité algorithmique.
Question 1
√
— 1.C : Pour l’algorithme en O(n2 ), on a 100n20 = n21 , et donc n1 = 100×n0
Question 2
4
1. 1000 ∈ O(1) 16. (n + 1) ∗ ( n2 − 1) ∈ Θ(n2 )
2. n2 ∈ Ω(n3 ) (f) 17. n3 + 3n2 + n + 2017 ∈ O(n3 )
3. n3 ∈ Ω(n2 ) 18. n2 ∗ n3 ∈ O(n3 ) (f)
1 2
4. 2n+1 ∈ O(2n ) 19. 2n − 3n ∈ Θ(n2 )
1 2
5. (n + 1)2 ∈ Θ(n2 ) 20. 4n ∗ Ω(n) ∈ Ω(n3 )
6. n3 + 12 ∈ O(2n ) 21. log2 (2n) ∈ Θ(log n)
√
7. n ∈ Θ(n) (f) 22. log2 (n2 ) ∈ Θ(log n)
8. π 32 ∈ O(1) 23. (log2 (n))2 ∈ Θ(log n) (f)
9. (n − 3)(n + 1) ∈ O(n3 ) 24. 3n ∈ O(2n ) (f)
10. n3 m2 ∈ O(m6 ) (f) 25. 2n+3 ∈ O(2n )
11. 2(n−12) ∈ Ω(2n ) 26. 23n ∈ O(2n ) (f)
12. 3n ∈ O(2n ) (f) 27. Si g(n) ∈ O(f (n)) alors 2g(n) ∈ O(2f (n) ) (f)
13. n3.14 ∈ Θ(n3 ) (f) 28. Si g(n) ∈ Θ(f (n)) alors |g(n) − f (n)| ∈ Θ(1) (f)
g(n)
14. n3.14 ∈ O(n3 ) (f) 29. Si g(n) ∈ Θ(f (n)) alors f (n) ∈ Θ(1)
15. n3.14 ∈ Ω(n3 ) 30. Θ(f (n)) ⊆ O(f (n))
Question 5 Est-ce que les propositions suivantes sont vraies pour tout f, g ? Pour
chacune, prouvez-le ou trouvez un contre-exemple (si un contre-exemple est
nécessaire, un schéma sans analyse numérique sera suffisant).
(5.a) f (n) ∈ Ω(g(n)) alors g(n) ∈ O(f (n))
(5.b) f (n) ∈ O(g(n)) ou g(n) ∈ O(f (n))
Equivalent à prouver que h(n) ∈ O(max(f (n), g(n))) ⇔ h(n) ∈ O(f (n) + g(n))
— ⇒ : h(n) ∈ O(max(f (n), g(n))) ⇒ ∃c∃n0 ∀n ≥ n0 h(n) ≤ c max(f (n), g(n)),
donc h(n) ≤ c(f (n) + g(n)) et donc h(n) ∈ O(f (n) + g(n))
5
— ⇐ : h(n) ∈ O(f (n) + g(n)) ⇒ ∃c∃n0 ∀n ≥ n0 h(n) ≤ c(f (n) + g(n)), donc
h(n) ≤ 2c(max(f (n), g(n))) et donc h(n) ∈ O(max(f (n), g(n)))
Question 7
Question 8 Dans les deux cas, on peut remarquer que l’instruction la plus souvent
exécutée (terme dominant) est “r ← r + 1” avec r initialisé à 0 et retourné
par l’algorithme. Donc la complexité de ces algorithmes est du même ordre
de grandeur que la valeur retournée.
— L’algorithme f1 retourne ni=1 nj=i+1 1 = ni=1 (n − i) = n2 − ni=1 i =
P P P P
6
7
3 Complexité d’algorithmes récursifs
Exercice 1 Algorithmes recursifs
Question 1 Pour les deux fonctions rec1 et rec2, nous allons utiliser T1 (x) (res-
pectivement T2 (x)) pour représenter la complexité de rec1(x) (respectivement
rec2(x))
(1.a) rec1 (
Θ(1) si n = 1
T1 (x) =
T1 (x − 1) + Θ(1) sinon
Pour appliquer la méthode par substitution, il faut avoir une intuition
sur la forme de récurrence. Une façon simple de travailler l’intuition est
de construire T(x) de manière ascendante (en supposant que Θ(1) = 1 ).
C’est à dire :
— T1 (1) = Θ(1) = 1
— T1 (2) = T1 (1) + Θ(1) = 1 + 1 = 2
— T1 (3) = T1 (2) + Θ(1) = 2 + 1 = 3
— T1 (4) = T1 (3) + Θ(1) = 3 + 1 = 4
— ...
— T1 (x) = x
Donc à priori T1 (x) ∈ Θ(x). On va démontrer ce résultat. On prouve
T1 (x) ∈ Ω(x) (puis de manière similaire T1 (x) ∈ O(x))
On utilise le principe de récurrence (induction) pour montrer qu’il existe
c > 0 tel que ∀x ≥ 1, T1 (x) ≥ cx. On vérifie pour x = 1 en posant
T1 (1) = c1 :
T1 (1) = c1 ≥ c × 1
c1 ≥ c
T1 (x) = T (x − 1) + c2
≥ c(x − 1) + c2
= cx − c + c2
≥ cx
8
À la dernière étape nous avons supposé que c ≤ c2
Donc par récurrence on a ∃c ∈ [c1 , c2 ], tel que T1 (x) ≥ cx. Donc T1 (x) ∈
Ω(x). De la même façon on montre que T1 (x) ∈ O(x). Par conséquent,
T1 (x) ∈ Θ(x).
(1.b) rec2 (
Θ(1) si x = 1
T2 (x) =
2T2 (x − 1) + Θ(1) sinon
Pour trouver une intuition sur la forme de T2 (x), on peut appliquer une
approche ascendante en supposant que Θ(1) = 1 :
— T2 (1) = 1
— T2 (2) = 2T2 (1) + 1 = 2 × 1 + 1 = 2 + 1 = 21 + 20
— T2 (3) = 2T2 (2) + 1 = 2 × (21 + 20 ) + 1 = 22 + 21 + 20
— T2 (4) = 2T2 (2) + 1 = 2 × (22 + 21 + 20 ) + 1 = 23 + 22 + 21 + 20
— ...
— T2 (x) = 2x−1 + 2x−2 . . . + 20
Donc à priori T2 (x) appartient à Θ(2x ). Pour montrer le résultat, on
prouve que T2 (x) ∈ Ω(2x ) (et T2 (x) ∈ O(2x )). On utilise le raisonnement
par récurrence pour montrer qu’il existe un c > 0 tel que T2 (x) ≥ c2x .
On vérifie pour x = 1 en posant Θ(1) = 1 :
T2 (1) = 1 ≥ c21
1
≥ c
2
Donc la constante c doit satisfaire 12 ≥ c.
On suppose T2 (i) ≥ c2i vrai pour 1 ≤ i ≤ x − 1 et on substitue :
T2 (x) = 2T2 (x − 1) + 1
≥ 2c2x−1 + 1
≥ (2c2x )/2 + 1
≥ c2x + 1
≥ c2x
9
Question 2
T (x/2) + 1 = 2 ≤ c log 2
2 ≤ c
T (x) = T (x/2) + 1
≤ c log(x/2) + 1
≤ c log(x/2) + log(2)
≤ c log(x/2) + c log(2)
≤ c log(2x/2)
≤ c log(x)
Question 3
(3.a) — expo2 :
T (x) = T (x/2) + x0
On a a = 1, b = 2, d = 0 et donc logb (a) = d : expo2 ∈ Θ(log x)
10
— expo3 :
T (x) = 2T (x/2) + x0
On a a = 2, b = 2, d = 0 et donc logb (a) > d : expo2 ∈ Θ(x)
(3.b) Logiquement équivalents, mais expo2 est plus efficace
Question 4
(4.a) y ∗ expo4(y, x − 1)
(4.b) Il faut remarquer que si x est impair, alors cette ligne coûte Θ(1) et expo4
est appelé avec x pair, donc :
Θ(1)
si x = 1
T (x) = T (x/2) + Θ(1) si x est pair
T ((x − 1)/2) + Θ(1)
sinon
Le troisième cas est donc asymptotiquement équivalent au deuxième cas,
donc la démonstration utilisée pour expo2 fonctionne.
Question 6
11
— Supposons que Ci croise la diagonale sur la grille (1, 0) − (i + 1, i), c’est
à dire atteind la coordonnée j, j pour 1 ≤ j ≤ i. Alors le ‘↑’ qui atteind
(j, j) est précédé par j ‘→’ et j − 1 ‘↑’. Mais dans ce cas, i n’est pas le
plus petit entier tel que la proposition est vraie.
n−1
X
Cn = Ci Cn−i−1
i=0
(8.e) ...
Question 9 √
n3/2 π
lim Cn =1
n→∞ 4n
12
Donc pour tout ϵ > 0 il existe nϵ tel que
3/2 √
nϵ π
Cnϵ n
≤1+ϵ
4 ϵ
1 + ϵ 4nϵ
Cnϵ ≤ √
π nϵ3/2
(1+ϵ)
Choisissons n’importe quelle valeur pour ϵ > 0 et posons c = √
π
et n0 = nϵ ,
on a n
4
Cn ∈ O
n3/2
Pour tout ϵ > 0 il existe nϵ tel que
3/2 √
nϵ π
Cnϵ ≥1−ϵ
4nϵ
1 − ϵ 4nϵ
Cnϵ ≥ √
π nϵ3/2
(1−ϵ)
Choisissons n’importe quelle valeur pour 1 > ϵ > 0 et posons c = √
π
et
n0 = nϵ , on a n
4
Cn ∈ Ω
n3/2
4n
|x| ∈ Θ(log2 )
n3/2
On a :
4n 3
log2 = 2n − log2 n
n3/2 2
et donc :
|x| ∈ Θ(n)
13
4 Programmation Dynamique
Exercice 1 Suite de Fibonacci
Question 1
(1.a) Il y a des redondances dans les appels récursifs comme le montre l’arbre
suivant (par exemple F(n-2) est appelé plusieurs fois) :
F(n)
F(n-1) F(n-2)
14
Exercice 2 Sacs à dos
Question 2
F (n − 1, W ) F (n − 1, W − wn )
F (n − 2, W ) F (n − 2, W − wn−1 ) F (n − 2, W − wn ) F (n − 2, W − wn − wn−1 )
15
1 Algorithme : Knapsack(n, W, w1 , . . . , wn , v1 , . . . , vn ))
Données : n, W, w1 , . . . , wn , v1 , . . . , vn )
Résultat : F(n,W)
2 début
3 F : matrice de taille n + 1 × W + 1 ;
4 pour j ∈ [0 . . . W ] faire
5 F [0][j] ← 0
6 pour i ∈ [1 . . . n] faire
7 pour j ∈ [0 . . . W ] faire
8 si j − wi < 0 alors
9 F [i][j] ← F [i − 1][j]
10 sinon
11 F [i][j] ← max(F [i − 1][j], F [i − 1][j − wi ] + vi )
12 retourner F [n][W ];
16
5 Algorithmes gloutons et matroïdes
Exercice 1 Problème de bipartition
Question 1
17
1 Algorithme : ClusteringGlouton (E = {x1 , x2 , . . . xn }, d
Données : E = {x1 , x2 , . . . xn }, d
Résultat : (A, B) : 2-Partition
2 A←∅;
3 B←∅;
4 F ← T rier{(xi , xj ) | 1 ≤ i < j ≤ n} par ordre décroissant sur la distance d(xi , xj );
5 i←1;
6 tant que |A ∪ B| ̸= n faire
7 (x, y) = F [i] ;
8 i←i+1 ;
9 si x ∈ A alors
10 si y ∈
/ A alors
11 B ← B ∪ {y}
12 sinon
13 si x ∈ B alors
14 si y ∈
/ B alors
15 A ← A ∪ {y}
16 sinon
17 si y ∈ A alors
18 si x ∈
/ A alors
19 B ← B ∪ {x}
20 sinon
21 si y ∈ B alors
22 si x ∈
/ B alors
23 A ← A ∪ {x}
24 sinon
25 % On va séparer x et y. Il y a deux choix possibles : ajouter x à A et y à B ou
ajouter x à B et y à A. On évalue d’abord le cout de chaque choix et on évite le
pire. ;
26 coutxA ← max(d(a, b) | (a, b) ∈ A ∪ {x} × A ∪ {x}) ;
27 coutxB ← max(d(a, b) | (a, b) ∈ B ∪ {x} × B ∪ {x}) ;
28 coutyA ← max(d(a, b) | (a, b) ∈ A ∪ {y} × A ∪ {y}) ;
29 coutyB ← max(d(a, b) | (a, b) ∈ B ∪ {y} × B ∪ {y}) ;
30 % on calcule le cout quand on ajoute x à A et y à B
cout1 ← max{coutxA, coutyB}
31 % on calcule le cout quand on ajoute x à B et y à A
cout2 ← max{coutxB, coutyA}
32 si cout1 > cout2 alors
33 A ← A ∪ {y} ;
34 B ← B ∪ {x}
35 sinon
36 A ← A ∪ {x} ;
37 B ← B ∪ {y}
38 retourner (A,B) ;
18
O(n) car A et B contiennent au plus n éléments.
Question 2(2.a) Par exemple : Organisation des séances de TDs à l’INSA pour
une seule salle. La salle est la ressource. Une séance de TD est une tâche
(qui dure une unité de temps 1h15). Chaque séance peut avoir une date
d’échéance (par exemple un tel TD doit être effectué avant 12h15). On
cherche à maximiser le nombre de séances effectuées dans une salle tout
en respectant les échéances.
Autre exemple similaire : la réservation de salle à la bibliothèque de
l’INSA. Une salle est une ressource. Une demande de réservation est une
tache qui est associé à une date d’échéance. Pour une salle, on veut maxi-
miser le nombre de demandes satisfaites.
Autre exemple est le cas d’ordonnancement de tâches unitaires pour un
processeur.
(2.b) Pour la première instance :
F ←∅
L ← [a1, a4, a3, a2]
F ← {a1}
–> valide
F ← {a1, a4}
–> valide
F ← {a1, a4, a3}
–> valide
{a1, a4, a4}
–> n’est pas valide
Retourner F ← {a1, a4, a3}
(2.c) Oui par exemple quand deux taches ont la même priorité et la même date
d’échéance.
(2.d) Il faut montrer que :
— Si un exemple de taches est valide alors en supprimant une tache il
reste valide (héréditaire)
19
— Si A et B sont deux ensembles de taches valides tel que |A| < |B| alors
il existe une tache t dans B \ A tel que A ∪ {t} est valide (échange)
(2.e) — La fonction du poids sur le matroïde est la fonction de priorité.
— E est héréditaire –> évident
— Échange : Soit A et B deux exemples de taches valides tel que A =
{a1 , . . . an }, B = {b1 , . . . bm } et n < m. Prenons la tache bk de B qui
n’appartient pas à A avec la plus grande date d’échéance. Ajouter bk
à A donne un ensemble valide.
(2.f) Il suffit de faire le tri des éléments de F à chaque fois par ordre croissant
sur les dates d’échéance (Θ(nlog(n))). Ceci donne une complexité totale
de O(n2 log(n)) de l’algorithme.
On peut améliorer cette méthode en gardant les taches de F dans une liste
ordonnée par ordre croissant par rapport aux dates d’échéances. Pour
chaque élément à tester, construire la nouvelle liste ordonnée est linéaire
car il suffit de faire un parcours à partir de la fin de la liste jusqu’à la
position du nouvel élément. Une fois l’insertion est faite, il suffit de faire
le test de validité en O(n) et donc la complexité de l’algorithme est O(n2 ).
20
6 Structures de données
Exercice 1 Structure de données
Question 2 On peut utiliser une table de hâchage pour les paires (x, y) (la clé est
la concaténation de x et y) ; un ABR pour lister les émetteurs et un autre
pour lister les récepteurs.
21
7 Classes de complexité
Pas au programme (sauf montrer qu’un problème est dans P ou dans NP)
Exercice 1 P et NP
Question 1 QCM :
— P ⊆ NP ? : Oui
— P ⊊ NP ? : On ne sait pas
— Si P = NP alors P = NP = NP-Complet ? : Oui
— P ⊊ NP alors NP \ NP-Complet = P ? : Oui
— P ⊊ NP alors NP \ P = NP-Complet ? : Oui
— P ⊊ NP alors P ⊊ NP-Complet ? : Non
— P ⊊ EXP ? : Oui
— NP ⊊ EXP ? : Oui
— NP ⊊ NP-Complet ? : On ne sait pas
— Si P = NP alors P = NP = NP-Complet ? : Oui
— Si P = NP alors NP-Complet \ P = ∅ ? : Oui
— NP = EXP ? : Non
— Si A ∈ Θ(2n ) est un algorithme pour un problème Pb alors Pb ∈ EXP ? :
Oui
— Si A ∈ Θ(2n ) est un algorithme pour un problème Pb alors Pb ∈ NP ? :
on ne sait pas
— Si A ∈ Θ(2n ) est un algorithme pour un problème Pb alors Pb ∈ P ? : on
ne sait pas
Question 2
— Sac-à-Dos ∈ NP :
— Certificat : le sous-ensemble S d’objets (espace mémoire en Θ(n) en
utilisant un tableau de booléens)
— Vérification en O(n log W ) : il faut calculer la somme des vi et la
somme des wi , la taille de la donnée est en Θ(n log W ), l’algorithme
est donc linéaire dans la taille de la donnée
22
Question 3 ProgDyn ∈ Θ(nW ). Ce n’est pas une preuve que Sac-à-Dos ∈ P
puisque qu’il faut un algorithme polynômial dans la taille de la donnée. Ici la
donnée x est telle que |x| ∈ Θ(n log W ). Supposons que n ≃ log W , alors on
a |x| ∈ Θ(log W ) et ProgDyn ∈ Θ(W log W ), donc on a ProgDyn ∈ Ω(|x|2|x| )
23
8 Recherche Arborescente
Exercice 1 Recherche arborescente
Question 1 ...
Question 2 ...
24
On veut concevoir un algorithme pour la coloration de graphe basé sur la récurrence
de Zykov.
Question 7 Montrez que l’équation suivante est correcte pour tout graphe G =
(S, A), et toute paire de sommets distincts v, w ∈ S tels que (v, w) ̸∈ A :
Solution : pour un graphe G pouvant être coloré avec χ(G) couleurs et conte-
nant 2 sommets u et v non reliés par une arête. Il y a deux possibilités de
couleur pour ces sommets :
— soit u et v sont de la même couleur : ces deux sommets peuvent être
fusionnés et produire le graphe G/(v, w)
— soit u et v sont de couleurs différentes : ces deux sommets peuvent être
séparés par une arête et produire le graphe G + (v, w)
Donc χ(G) correspond au minimum de couleurs permettant de colorer ces
deux graphes.
Dégénérescence
Question 9 Soit un graphe G, et un sommet k-dégénéré v de ce graphe. Montrez
que G est k + 1-colorable si et seulement si G \ v est k + 1-colorable.
Solution :
— G est k + 1-colorable → G \ v est k + 1-colorable : (trivial) : si le graphe
initial est k + 1-colorable il reste k + 1-colorable quand on lui retire un
sommet
— G \ v est k + 1-colorable → G est k + 1-colorable : le graphe G \ v est
k +1-colorable et on lui ajoute un sommet v ayant au plus k voisin, il faut
au pire k + 1 couleurs pour ce sommet v et ses voisins. Donc le graphe
avec v est k + 1-colorable.
25
Question 10 Supprimer les sommets 3-dégénérés du graphe de la figure ?? (3a),
continuer jusqu’à ce que ce ne soit plus possible.
Solution : on peut retirer tous les sommets et obtenir un graphe vide.
Que peut-on en déduire sur la colorabilité du graphe de la figure ?? (3a) ?
Solution : on a obtenu une borne (supérieure) sur le nombre de couleurs
possibles pour ce graphe
Question 11 Quelle est la règle d’élagage induite par la borne supérieure calculée
dans la question précédente et la borne inférieure définie dans la question 8 ?
Solution : si taille clique max = valeur dégénéresence + 1 alors stopper la
recherche arborescence.
26
9 Annales
Exercice 1 Sous-séquence maximale
Question 1 Θ(n)
Question 2
1 Algorithme : MaxSousSéquenceq ((L))
Données : un tableau L avec éléments Pedans {−1, 1}
Résultat : les entiers s et e tels que i=s
L[i] est maximal
2 s ← 1;
3 e ← 1;
4 m ← L[1];
5 pour chaque x allant de 1 à n faire
6 z ← 0;
7 pour chaque y allant de x à n faire
8 z ← z + L[y];
9 si z > m alors
10 s ← x;
11 e ← y;
12 m ← z;
Question 3
(3.a) (
O(1) si n ≤ 1
T (n) =
2T (n/2) + Θ(n) sinon
T (n) = cn log n
T (n) ≤ cn log n
27
— pour n = 3, on a T (3) = T (⌈3/2⌉) + 1 = 3 ≤ c3 log 3 pour c ≥
3/(log 3) ;
On montre que si l’hypothèse est vraie pour n−k pour tout 1 ≤ k ≤ (n−2)
alors elle reste vraie pour n
Puisque T (n−k) ≤ c(n−k) log(n−k), alors T (⌈n/2⌉) ≤ c(⌈n/2⌉) log(⌈n/2⌉)
T (n) = T (⌈n/2⌉) + n
≤ c(⌈n/2⌉) log(⌈n/2⌉) + n
c
= n(log(n) − log(2)) + n
2
c
= n log(n)
2
Question 4
(4.a) Θ(n)
(4.b) Oui
(4.c) MaxSousSéquenceq :70 heures ; MaxSousSéquencer :10 secondes ; MaxSousSéquencel :
0,5 secondes
28
Exercice 2 Plus courts chemins
Soit V = {1, . . . , n}. L’algorithme suivant calcule tous les plus courts chemins
depuis un sommet s ∈ V vers chaque sommet v ∈ V dans le graphe non-orienté
G = (V, E) où E est un ensemble de m arêtes, c’est à dire de m paires distinctes
de sommets de V . Le graphe est représenté par des listes de voisins : la liste N (v)
contient tous les voisins du sommet v, c’est à dire l’ensemble des sommets u tels
que {u, v} 1 ∈ E. Les arêtes sont valuées, et la “longueur” d’une arête L[{u, v}] est
accessible en temps constant.
Dans cet algorithme, toutes les opérations d’ajout, de suppression, d’affectation et
les additions seront considérées en temps constant (O(1)).
Les réponses des six premières questions sont à donner en ordre de grandeur
(Θ) en fonction de n et/ou de m. Si vous avez un doute, une réponse moins
précise utilisant Ω et/ou O rapportera plus de points qu’une réponse erronée en
Θ.
Notez que comprendre le fonctionnement de l’algorithme n’est pas absolument
nécessaire pour répondre aux questions.
1 Algorithme : PlusCourtChemin
Données : Un ensemble de sommets V , des listes de voisinage N , une table de
distance L et un sommet s ∈ V
Résultat : un tableau dist, où ∀v ∈ {1, . . . , n}, dist[v] est la distance du plus court
chemin entre s et v dans le graphe
2 Q ← ∅;
3 pour chaque v ∈ V faire
4 dist[v] ← ∞;
5 ajouter v à Q;
6 dist[s] ← 0;
7 tant que Q n’est pas vide faire
8 u ← sommet de Q tel que dist[u] est minimal;
9 retirer u de Q;
10 pour chaque v dans la liste N (u) faire
11 l ← dist[u] + L[{u, v}];
12 si l < dist[v] alors
13 dist[v] ← l;
14 retourner dist;
Question 5 Θ(n).
29
Question 6 Θ(n) fois (le sommet u est supprimé).
Question 7 l’arête u, v peut être lue O(2) fois : pour v ∈ N (u) et pour u ∈ N (v).
Question 10 Θ(m log n) (on considère que le graphe est connexe et donc n ≤
m + 1).
Question 11 Oui.
Question 12 n!
30
Exercice 3 Recherche arborescente
Question 13 ...
Question 14 ...
31
Exercice 4 Vote à la majorité absolue
Question 16
Question 17 Θ(n2 ).
Question 18
Question 19
(19.a) Le seul élément non trivial de la preuve est que lorsqu’on sépare les vo-
tants en deux groupes, l’élément majoritaire doit forcément être majo-
ritaire dans au moins un des deux groupes. Donc on n’a pas besoin de
compter le nombre de voix des autres candidats.
(19.b)
Θ(1) si n ≤ 1
T (n) =
2T ( n2 ) + Θ(n) sinon
Question 20
32
(20.b) l’algorithme Dépouillement est en Ω(n + m) et la taille |x| de la donnée
est en O(n log m). Soit m ≫ 2n . Dans ce cas, Dépouillement requiert
Ω(m) operations et |x| ∈ O(log m), donc Dépouillement requiert Ω(2|x| )
operations.
Donc il existe au moins un cas où la complexité de Dépouillement n’est
pas en O(|x|c ) (pour |x| la taille de la donnée et c une constante). Par
conséquence, Dépouillement ne peut pas être utilisé pour prouver que
ce problème est dans P.
Tous les autres algorithmes constituent des preuves valides que ce pro-
blème est dans P.
(20.c) Il suffit de vérifier que le candidat renvoyé par Boyer-Moore est bien
majoritaire, en comptant combien de votes il a reçu. Il est évident que
c’est possible en O(n) temps.
Question 21
33
— Invariant b(i) : x ̸= candidati =⇒ marge(x, i) ≤ −comptei
34