La force brute
Après avoir introduit le cadre et les méthodes d’analyse des algorithmes au chapitre précédent, nous
sommes maintenant prêts pour entamer la discussion sur les techniques de conception des
algorithmes. Chacun des neuf chapitres suivants est consacré à une stratégie particulière de
conception. Le thème de ce chapitre est la force brute, la plus simple des stratégies. Elle peut être
décrite de la façon suivante :
La force brute est une approche directe pour résoudre un problème, habituellement basée
directement sur l’expression du problème et la définition des concepts impliqués.
La force impliquée par la définition de la stratégie est celle d’un ordinateur et non celle de
l’intelligence. « Fait le juste ! » serait une autre façon de décrire la prescription de l’approche par la
force brutale. Et très souvent, la stratégie de la force brutale est en effet celle qui est la plus simple à
appliquer.
On commence le tri par sélection en parcourant la liste entière pour trouver le plus petit élément et
permuter celui-ci avec le premier élément de la liste, plaçant ainsi le plus élément dans sa position
finale dans la liste triée. On parcourt ensuite la liste en commençant par le deuxième élément, pour
trouver le plus petit parmi les n – 1 derniers éléments et permuter celui-ci avec le deuxième
élément, plaçant ainsi le deuxième plus petit élément dans sa position finale. Généralement, au ième
parcours de la liste, l’algorithme cherche le plus petit parmi les n – i derniers éléments pour le
permuter avec le ième élément :
A A1 A i 1 A i , , A min , , A n 1
0
dans leur position finale les n 1 derniers éléments
Voici un pseudocode de cet algorithme, pour plus de simplicité nous supposons que la liste est
implémentée sous forme de vecteur.
89 45 68 90 29 34 17
17 45 68 90 29 34 89
17 29 68 90 45 34 89
17 29 34 90 45 68 89
1 29 34 45 90 68 89
17 29 34 45 68 90 89
17 29 34 45 68 89 90
FIGURE 1.3 – Exemple de tri avec le tri par sélection. Chaque ligne correspond à une itération de
l’algorithme. Les éléments à gauche de la barre verticale sont dans leurs positions finales et ne sont
pas considérés dans cette itération les suivantes.
61
L’analyse du tri par sélection est évidente. La taille de l’input est donnée par le nombre d’éléments
n de la liste ; l’opération de base est la comparaison A[j] A[min]. Le nombre de fois que cette
comparaison est exécutée dépend de la taille de la liste et est donné par la somme :
n2 n 1 n2 n2
C (n) 1 ( n 1) ( i 1) 1 ( n 1 i ).
i 0 j i 1 i0 i0
Donc le tri par sélection est un algorithme n 2 pour toutes les entrées. Noter cependant que le
nombre de permutations clés est seulement n ou, plus précisément n 1 (une pour chaque
itération de la boucle sur i). Cette propriété distingue positivement le tri par sélection de plusieurs
autres algorithmes de tri.
L’action de l’algorithme sur la liste 89, 45, 68, 90, 29, 34, 17 est illustrée comme exemple dans la
Figure 3.1. Le nombre de comparaisons clés correspondant à la version du tri par échanges ci-
dessus est le même pour toutes les listes de taille n ; il est obtenu par une somme presque identique
à la somme associée au tri par sélection :
n 2 n 2i n2
C (n) 1 ( n 2 i ) 0 1
i0 j0 i0
n2
( n 1) n
(n 1 i) n . 2
i0 2
62
Le nombre de permutations clés dépend cependant de l’entée. Pour le pire cas des vecteurs
décroissants, il est identique au nombre de comparaisons clés :
( n 1) n
C w (n) C (n)
n .
2
?
89 45 68 90 29 34 17
?
45 89 68 90 29 34 17
? ?
45 68 89 90 29 34 17
?
45 68 89 29 90 34 17
?
45 68 89 29 34 90 17
45 68 89 29 34 17 | 90
? ? ?
45 68 89 29 34 17 | 90
?
45 68 29 89 34 17 | 90
?
45 68 29 34 89 17 | 90
45 68 29 34 17 | 89 90
etc.
FIGURE 3.2 – Les deux premières étapes du tri par échange sur la liste 89, 45, 68, 90, 29, 34, 17.
Une nouvelle ligne est montrée après le swap de deux éléments. Les éléments à droite de la barre
verticale sont dans leurs positions finales et ne sont pas considérés dans l’étape et les suivantes.
Comme cela est souvent le cas avec une application de la stratégie de la force brute, la première
version d’un algorithme obtenue peut souvent être améliorée avec un effort modeste. Spécialement,
nous pouvons améliore la version primaire du tri par échanges présentée ci-dessus en exploitant
l’observation suivante : si un passage à travers la liste n’effectue aucun échange, alors la liste est
triée et nous pouvons déjà arrêter l’algorithme. Bien que la nouvelle version s’exécute plus
rapidement pour certaines entrées, elle est toujours dans n 2 dans les pire et moyen cas. En
réalité, même parmi les méthodes de tri élémentaires, le tri par échanges est un choix inférieur, et ce
n’état pas à cause de son nom plaisant, vous n’aurez probablement pas entendu parlé de lui.
Toutefois, la leçon générale que vous avez juste apprise est importante et bonne à répéter : Une
première application de l’approche de la force brutale résulte souvent en un algorithme qui peut
être amélioré avec une quantité infime d’effort.
Exercices 3.1
Problème 1. a) Donnez un exemple d’algorithme qui ne sera pas considéré comme une application
de l’approche de la force brute.
b) Donnez un exemple de problème qui ne peut pas être résolu par un algorithme de la force brute.
Problème 2. a) Quelle est l’efficacité de l’algorithme de la force brute pour le calcul de a n comme
une fonction de n ? Comme une fonction du nombre des bits de la représentation binaire de n ?
b) Si vous devez calculer a n mod m , où a 1 et n est un grand entier positif, comment pouvez-
vous contourner le problème d’une très magnitude de a n ?
Problème 4. Est-il possible d’implémenter le tri par échanges pour les listes chaînées avec la même
efficacité n 2 comme pour la version vecteur ?
Problème 5. Le tri par sélection est-il stable ? Le tri par échanges est-il stable ?
Problème 6. a) Montrer que si le tri par échanges n’effectue aucun échange au cours d’un parcours
de la liste, alors la liste est triée et l’algorithme peut être stoppé.
b) Ecrire un pseudocode pour la méthode qui intègre cette amélioration.
c) Montrer que l’efficacité au pire de la version améliorée est quadratique.
Problème 7. Alterner des disques. Vous avez une rangée de 2n disques de deux couleurs, n noirs et
n blancs. Elles alternent : noir, blanc, noir, blanc, et ainsi de suite. Vous voulez avoir tous les
disques noirs à l’extrémité droite et toutes les boules blanches à l’extrémité gauche. Les seuls
mouvements que vous êtes autorisés de faire sont ceux qui inter-changent les positions de deux
disques voisins.
Nous avons vu dans la section précédente deux applications de l’approche de la force brute au
problème de tri. Nous présentons ici deux applications de cette stratégie au problème de recherche.
Le premier traite du problème classique de la recherche associative dans une liste donnée. Le
deuxième est différent parce qu’il traite du problème de la reconnaissance des chaînes.
64
while A[i] K do
ii+1
if i n return i
else return –1
Une autre amélioration évidente peut être incorporée dans la recherche séquentielle si le vecteur est
trié : la recherche dans une telle liste peut être arrêtée dès qu’un élément supérieur ou égal à la clé
de recherche est trouvé.
La recherche séquentielle offre une excellente illustration de l’approche de la force brute : sa force
caractéristique (simplicité) et sa faiblesse (efficacité inférieure). Le résultat d’efficacité obtenu à la
section 2.1 pour la version standard ne change que très peu pour la solution améliorée, de sorte que
l’algorithme reste linéaire au pire et en moyenne. Nous étudierons dans la suite du cours plusieurs
autres algorithmes de recherche ayant une meilleure efficacité temporelle.
t0 ti ti j t i m 1 t n 1 Texte T
↕ ↕ ↕
p0 pj p m 1 Forme P
65
Une application de cet algorithme est illustrée à la Figure 3.3.
N O B O D Y _ N O T I C E D _ H I M
N O T
N O T
N O T
N O T
N O T
N O T
N O T
N O T
FIGURE 3.3 Exemple de reconnaissance de forme par la force brute. (Les caractères de la
forme qui sont comparés avec leurs homologues du texte sont en gras)
Noter que pour et exemple, l’algorithme décale la forme presque toujours après une seule
comparaison de caractère. Cependant, le pire cas est plus pire : l’algorithme peut effectuer toutes les
m comparaisons avant de décaler la forme et ce peut arriver pour toutes les n m 1 tentatives.
Donc dans le pire cas, l’algorithme est dans (nm ) . Pour une recherche typique d’un mot dans un
texte en langage naturel, nous pouvons espérer que la plupart des décalages arriveront après très peu
de comparaisons. Par conséquent, l’efficacité moyenne sera considérablement meilleure que
l’efficacité au pire. Il a en effet montré que l’efficacité de la recherche dans un texte aléatoire est
linéaire, c’est-à-dire ( n m ) ( n ) . Il existe plusieurs algorithmes plus sophistiqués et plus
efficaces pour la recherche des chaînes. Le plus connu parmi eux est celui de R. Boyer and J.
Moore.
Exercices 3.2
Problème 1. Trouver le nombre de comparaisons effectuées par la version avec sentinelle de la
recherché séquentielle.
a) dans le pire cas
b) en moyenne si la probabilité d’une recherche positive est p 0 p 1
Problème 2. Comme cela a été montré à la Section 2.1, le nombre moyen de comparaisons clés
effectuées par la recherche séquentielle (avec sentinelle, sous les hypothèses standard concernant
son entrée) est donné par la formule
p ( n 1)
C avg ( n ) n (1 p )
2
où p est la probabilité d’une recherche positive. Déterminer, pour un n fixé, les valeurs de
p 0 p 1 pour lesquelles cette formule produit la plus grande valeur de C avg ( n ) et la plus petite
valeur de C avg ( n ) .
66
Problème 4. Combien de comparaisons (à la fois pour les recherches positives et négatives) seront
effectuées par l’algorithme de la force brute en cherchant chacune des formes suivantes dans une
chaîne binaire de mille zéros ?
a) 00001 b) 10000 c) 01010
Problème 5. En résolvant le problème de la reconnaissance des formes, y aura-t-il un avantage à
comparer la forme et le texte de la droite vers la gauche plutôt que de la gauche vers la droite ?
L’approche de la force brute pour résoudre ce problème conduit à l’algorithme évident suivant :
calculer la distance entre chaque paire de points distincts et trouver la paire qui a la plus petite
distance. Naturellement, nous n’avons pas besoin de calculer deux fois la distance associée à la
même paire de points. Pour éviter de le faire, nous considérons uniquement les paires de points
( Pi , P j ) pour lesquels i j.
ALGORITHME BruteForceClosestPoints(P)
//Trouve les points les plus proches dans le plan par la force brute
//Input : Une liste P de n points P1 ( x1 , y 1 ), , Pn ( x n , y n )
//Output : Les indices index1 et index2 des points les plus proches
dmin
for i 1 to n – 1 do
for j i + 1 to n do
d sqrt ( x i x j ) 2 ( y i y j ) 2
if d dmim
dmin d ; index1 i; index2 j
return index1, index2
L’opération de base de cet algorithme est le calcul de la distance euclidienne entre deux points.
Pour éviter le calcul de la racine carrée qui est encore aujourd’hui problématique, l’astuce consiste
tout simplement à ignorer la racine carrée et à comparer les valeurs ( x i x j ) 2 ( y i y j ) 2 elles-
mêmes. Ainsi, si nous remplaçons
d sqrt ( x i x j ) ( y i y j )
2 2
par
dsqr ( x i x j ) ( y i y j ) , l’opération de base de l’algorithme sera l’élévation au carré d’un
2 2
nombre. Le nombre de fois que cette opération sera exécutée sera calculé de la manière suivante :
67
n 1 n n 1
C (n) 2 2 ( n i ) 2 ( n 1) ( n 2 ) 1 ( n 1) n ( n ) .
2
i 1 j i 1 i 1
DEFINITION. Un ensemble de points du plan est dit convexe si pour deux points quelconque P et
Q de l’ensemble, le segment de droite d’extrémités P et Q est contenu dans l’ensemble.
(a) (b)
FIGURE 3.4 – (a) Ensembles convexes. (b) Ensembles qui ne sont pas convexes.
Tous les ensembles présentés à la Figure 3.4a sont convexes, et tel est le cas pour une droite, un
triangle, un rectangle et plus généralement tout polygone convexe, un cercle et le plan tout entier.
Par contre, les ensembles présentés à la Figure 3.4b, tout ensemble fini de deux ou plusieurs points,
la frontière d’un polygone convexe et une circonférence sont des exemples d’ensembles qui sont
non convexes.
68
votre enthousiasme, considérez le problème en tant celui qui consiste à barricader n tigres endormis
par une barrière ayant la plus courte longueur. Cette interprétation est due à D. Harel [Har92]; elle
est cependant quelque peu effrayante parce que les poteaux de la barrière doivent être érigés juste à
côté de la barrière où certains des tigres dorment! Il y a une autre interprétation beaucoup plus
commode de cette notion. Imaginez que les points en question soient représentés par des onglets
dressés sur une grande feuille de contre-plaqué représentant le plan. Prenez une bande élastique et
étirez-la pour inclure tous les onglets, puis laissez-la revenir à sa place. La couverture convexe est le
domaine délimité par la bande élastique cassée.
Une définition formelle de la couverture convexe qui est applicable à un ensemble arbitraire,
incluant les ensembles de points pouvant être situés sur la même droite est la suivante.
DEFINITION. La couverture convexe d’un ensemble de points est le plus petit ensemble convexe
qui contient S. (La condition de plus petit signifie que la couverture convexe de S doit être un sous-
ensemble de tout ensemble convexe contenant S).
Si S est convexe, sa couverture convexe est évidemment S lui-même. Si S est un ensemble de deux
points sa couverture convexe est le segment de droite reliant ces deux points. Si S est un ensemble
de trois points non alignés, sa couverture convexe est le triangle dont les sommets sont les points
donnés ; si les trois points sont alignés, la couverture convexe est le segment de droite dont les
extrémités sont les deux points les plus éloignés. Comme exemple de couverture convexe d’un
ensemble plus grand, voir la Figure 3.6. Une étude de ces exemples rend le théorème suivant un
résultat attendu.
THEOREME. La couverture convexe de tout ensemble de n 2 points (non tous situés sur la
même droite) est un polygone convexe dont les sommets correspondent à certains points de S. (Si
tous les points sont alignés, le polygone dégénère en un segment de droite mais encore avec les
extrémités situées à deux points de S.)
P6
P7
P2
P8
P3 P4 P5
P1
FIGURE 3.6 – La couverture convexe de cet ensemble de huit points est le polygone convexe dont
les sommets sont P1, P5, P6, P7 et P3.
Le problème de la couverture convexe est le problème de la construction de la couverture convexe
d’un ensemble donné de n points. Pour le résoudre, nous devons trouver les points qui serviront
comme les sommets du polygone en question. Les mathématiciens appellent les sommets d’un tel
polygone les « points extrêmes ». Par définition, un point extrême d’un ensemble convexe est un
point de cet ensemble qui n’est pas un point intérieur d’un segment de droite dont les extrémités
sont dans S. Par exemple, les points extrêmes d’un triangle sont ses trois sommets, les points
extrêmes d’un cercle sont tous les points de sa circonférence et les points extrêmes de la couverture
convexe de l’ensemble de huit points de la Figure 3.6 sont P1, P5, P6, P7 et P3.
69
Les points extrêmes ont plusieurs propriétés particulières que d’autres points de la couverture
convexe n’ont pas. Une de ces propriétés est exploitée par un algorithme très important appelé la
méthode de simplex. Cet algorithme résout les problèmes de programmation linéaire, problèmes
de détermination du minimum ou du maximum d’une fonction linéaire de n variables sujettes à des
contraintes linéaires. Ici cependant, nous sommes intéressés aux points extrêmes car leur
identification résout le problème de la couverture convexe. Dans la pratique, pour résoudre ce
problème complètement, nous devons savoir un peu plus que de savoir lesquels des n points d’un
ensemble donné sont les points extrêmes de la couverture convexe de l’ensemble : nous devons
connaître quelles paires de points doivent être reliés pour former la frontière de la couverture
convexe. Noter que ce sujet peut aussi être abordé en listant les points extrêmes dans l’ordre des
aiguilles d’une montre ou inversement.
Ainsi comment pouvons nous résoudre le problème de la couverture convexe en utilisant la force
brute ? Si vous ne trouvez pas un plan intermédiaire pour une attaque frontale, ne soyez pas
consterné : le problème de la couverture convexe est un des problèmes qui n’ont pas de solution
algorithmique évidente. Néanmoins, il existe un algorithme simple mais inefficace basé sur
l'observation suivante au sujet des segments de droite qui constituent la frontière de la couverture
convexe : un segment reliant deux points Pi et Pj d'un ensemble de n points est une partie de la
frontière de sa couverture convexe si et seulement si tous les autres points de l'ensemble se trouvent
du même côté de la droite passant par ces deux points. La répétition de ce test pour chaque paire de
points produit une liste de segments de droite qui composent la frontière de la couverture convexe.
Quelques notions élémentaires de la géométrique analytique sont nécessaires pour implémenter cet
algorithme. D’abord, la ligne droite passant par deux points ( x1 , y 1 ) et ( x 2 , y 2 ) du plan peut être
défini par l’équation
ax by c
où a y 2 y 1 , b x1 x 2 , c x1 y 2 y 1 x 2 .
Deuxièmement, une telle droite divise le plan en deux demi-plans : pour tous les points qui se
trouvent dans un d’entre eux, ax by c , tandis que pour tous les points de l’autre, ax by c .
Donc pour déterminer si certains points se situent du même côté de la droite, on peut simplement
vérifier si l’expression ax by c a le même signe en chacun de ces points.
Quelle est l’efficacité temporelle de cet algorithme ? Elle est dans n 3 : pour chacune des
n ( n 1) / 2 paires de points distincts, nous avons besoin de trouver le signe de ax by c pour
chacun des autres n – 2 points. Il existe des algorithmes plus efficaces pour cet important problème,
nous discuterons un d’entre eux plus tard dans la suite du cours.
Exercices 3.3
Problème 1. Pouvez-vous concevoir un algorithme plus rapide que celui basé sur la stratégie de la
force brute pour résoudre le problème de la paire la plus proche pour n points x1 , , x n de la droite
réelle ?
Problème 2. Soient x1 x 2 x n des nombres réels représentant les coordonnées de n villages
situés le long d’une route droite. Un poste de police doit être construit dans l’un de ces villages.
a) Concevoir un algorithme efficace pour déterminer la position du poste de police qui
minimise la distance moyenne entre les villages et le poste de police.
b) Concevoir un algorithme efficace pour déterminer la position du poste de police qui
minimise la distance maximum d’un village au poste de police.
Problème 3. Le problème de la paire la plus proche peut être posé dans un espace k-dimensionnel
dans lequel la distance euclidienne entre deux points x ( x1 , , x s ) et y ( y 1 , , y s ) est définie par
70
k
x ys .
2
d ( x, y ) s
s 1
Quelle sera la classe d’efficacité de l’algorithme de la force brute pour le problème k-dimensionnel
de la paire la plus proche ?
Problème 4. Trouver la couverture convexe des ensembles suivants et identifier leurs points
extrêmes (s’ils existent)
a) un segment de droite
b) un carré
c) la frontière d’un carré
d) une ligne droite
Problème 6. Quelle modification doit être apportée à l’algorithme de la force brute pour le
problème de la couverture convexe pour traiter plus de deux points situés sur la même ligne droite.
Maximiser 3x + 5y
Sujet à x+y4
x + 3y 6
x 0, y 0
a) Dessiner dans un plan cartésien, la région définie comme l’ensemble des points satisfaisant
les contraintes du problème.
b) Identifier les points extrêmes de la région.
c) Résoudre le problème donné en utilisant le théorème suivant : un problème de
programmation linéaire avec une région de faisabilité non vide bornée a toujours une
solution, qui peut être trouvée a un des points extrêmes de la région de faisabilité.
Plusieurs problèmes importants demandent de trouver un élément ayant une propriété particulière
dans un domaine qui croit exponentiellement (ou rapidement) avec la taille du problème.
Typiquement, de tels problèmes arrivent dans des situations qui impliquent, explicitement ou
implicitement, des objets combinatoires tels que les permutations, les combinaisons et des sous-
ensembles d’un ensemble donné. Plusieurs problèmes de ce genre sont des problèmes
d’optimisation : ils demandent de trouver un élément qui maximise ou minimise certaines
caractéristiques désirées telles que la longueur du chemin ou une affectation de coût.
La recherche exhaustive est simplement une approche de la force brute pour des problèmes
combinatoires. Elle suggère de générer chacun des éléments du domaine du problème, de choisir
ceux d’entre eux qui satisfont toutes les contraintes et trouver ensuite l’élément désiré (ex : celui qui
optimise une certaine fonction objectif). Noter que même si l’idée de la recherche exhaustive est
assez évidente, ses implémentations nécessitent typiquement un algorithme pour générer certains
objets combinatoires. Nous allons illustrer la recherche exhaustive en l’appliquant à trois problèmes
importants : le problème du voyageur de commerce, le problème du sac à dos et le problème
d’affectation.
71
3.4.1 Le problème du voyageur de commerce
Le problème du voyageur de commerce a intrigué les chercheurs au cours des 150 dernières années
à cause de sa formulation apparemment simple, ses applications importantes et ses liens intéressants
avec d’autres problèmes combinatoires. En termes simples, ce problème demande de trouver le plus
court chemin passant par n cités qui visite chaque cité exactement une fois avant de revenir à la cité
de départ. Ce problème peut convenablement être modélisé par un graphe pondéré dans lequel les
sommets représentent les cités et les poids des arcs représentent les distances. Le problème peut
alors être posé comme le problème de la recherche du plus court chemin Hamiltonien d’un graphe.
A 2 B
5 3
8 7
C D
1
Tour Longueur
A B C A L = 2 + 8 + 1 + 7 = 18
A B D A L = 2 + 3 + 1 + 5 = 11 Optimal
A C B A L = 5 + 8 + 3 + 7 = 23
A C D A L = 5 + 1 + 3 + 2 = 11 Optimal
A D B A L = 7 + 3 + 8 + 5 = 23
A D C A L = 7 + 1 + 8 + 2 = 18
FIGURE 3.7 – Résolution d’un petit problème du voyageur de commerce par recherche exhaustive
Il est facile de voir qu’un circuit Hamiltonien peut aussi être défini comme une suite de n + 1
sommets adjacents v i , v i , , v i , v i , où le premier sommet de la suite est le même que le dernier
0 1 n 1 0
tandis que tous les autres n – 1 sommets sont distincts. Par ailleurs, nous pouvons supposer sans
perdre la généralité que tous les circuits commencent et se terminent par un sommet particulier.
Ainsi, on peut obtenir tous les tours en générant toutes les permutations de n – 1 cités
intermédiaires, calculer la longueur des tours et déterminer le plus court parmi eux. La figure 3.7
montre un petit exemple du problème et sa solution par cette méthode.
Une inspection de la Figure 3.7 révèle trois paires de tours qui diffèrent seulement par leur
direction. Donc, nous pouvons réduire le nombre de permutations des sommets de moitié. Nous
pouvons par exemple choisir deux sommets intermédiaires quelconques, par exemple A et B, et
considérer ensuite uniquement les permutations dans lesquelles B précède C. (Cette restriction
définit implicitement une direction pour un tour).
Cette amélioration ne peut cependant pas mettre assez en évidence l’idée d’efficacité. Le nombre
total de permutations nécessaires sera encore (n – 1)!/2, ce qui rend la recherche exhaustive
impraticable même pour des petites valeurs de n. D’un autre côté, si vous voyez toujours votre verre
comme moitié-plein, vous pouvez réclamer que la réduction du travail de moitié n’a rien de notable,
même si vous résolvez une petite instance du problème, particulièrement à la main. Noter également
72
que nous n’avons pas limité notre investigation aux circuits commençant par le même sommet, le
nombre de permutations aurait été plus grand, par un facteur de n.
3.4.2 Le problème du sac à dos
Voici un autre problème bien connu en algorithmique. Etant donné n objets de poids connus
w1 , , w n et des valeurs v 1 , , v n et un sac à dos de capacité W, trouver le sous-ensemble d’objets le
plus valuable qui s’ajuste dans le sac. Si vous n’aimez pas l’idée de vous mettre dans les chaussures
d’un chef qui voudrait attacher le lot le plus valuable qui s’ajuste à son sac à dos, penser à un avion
de transport qui doit délivrer l’ensemble le plus valuable d’objets dans une réservation à distance
sans dépasser la capacité de l’avion. La Figure 3.8a présente un petit exemple du problème du sac à
dos.
10
w3 = 4 w4 = 5
w1 = 7 w2 = 3 v4 = 25F
v1 = 42F v2 = 12F v3 = 40F
(b)
FIGURE 3.8 – (a) Une instance du problème du sac à dos. (b) Sa solution par recherche exhaustive.
La solution optimale est en gras.
73
L’approche par recherche exhaustive de ce problème consiste à générer tous les sous ensembles de
l’ensemble des n objets donnés, calculer le poids total de chacun des sous-ensembles pour identifier
les sous-ensembles acceptables, et trouver un sous-ensemble ayant la plus grande valeur parmi ces
sous-ensembles. Comme exemple, la solution de l’exemple de la Figure 3.8a est donnée à la Figure
3.8b. Comme le nombre de sous-ensembles d’un ensemble de n objets est égal à 2 n , la recherche
exhaustive conduit à un algorithme 2 n indépendamment de l’efficacité avec laquelle les sous-
ensembles individuels sont générés.
Donc, pour les deux problèmes du voyageur de commerce et du sac à dos, la recherche exhaustive
conduit à des algorithmes extrêmement inefficaces pour toutes les entrées. En effet, ces deux
algorithmes sont des exemples bien connus de ce que l’on appelle des problèmes-NP difficiles.
Aucun algorithme temps-polynomial n’existe pour un problème-NP difficile. Par ailleurs, la plupart
des informaticiens pensent que de tels algorithmes n’existent pas bien que cette importante
conjecture n’est jamais été prouvée. Des approches plus sophistiquées—le backtracting et le
branch-and-bound—permettent de résoudre certaines instances mais pas toutes de ces problèmes
(et des problèmes similaires) dans un temps inférieur au temps exponentiel. Alternativement, nous
pouvons utiliser une des algorithmes d’approximation tels que ce décrits à la Section 12.3.
Il est facile de voir qu’une instance du problème d’affectation est complètement définie par sa
matrice des coûts C. En fonction de cette matrice, le problème demande de choisir un des éléments
dans chaque ligne de la matrice tel que tous les éléments sélectionnés se trouvent dans des colonnes
différentes et la somme totale des éléments est la plus petite possible. Noter qu’aucune stratégie
évidente pour trouver la solution n’existe ici. En effet, le plus petit élément de la matrice entière
n’est pas nécessairement une composante de la solution optimale. Donc, opter pour la recherche
exhaustive peut paraître comme un mal inévitable.
Nous pouvons décrire les solutions faisables du problème d’affectation comme des n-uplets
( j1 , , j n ) dans lesquels la ième composante, i 1, , n , indique la colonne de l’élément
sélectionné dans la ième ligne (i.e. le numéro du job affecté à la ième personne). Par exemple, pour
la matrice de coût ci-dessus, (2, 3, 4, 1) indique une affectable possible de la Personne 1 au Job 2, la
Personne 2 au Job 3, la Personne 3 au Job 4 et la Personne 4 au Job 1. Les exigences du problème
d’affectation impliquent qu’il existe une correspondance bijective entre les affectations faisables et
les permutations de l’ensemble des n premiers entiers. Par conséquent, l’approche par recherche
exhaustive pour le problème d’affectation nécessite la génération de toutes les permutations des
entiers 1, 2 , , n , le calcul du coût total de chaque affectation et la sommation des éléments
correspondants de la matrice des coûts et finalement, la sélection de celle qui a la plus petite
somme.
74
Comme le nombre de permutations à considérer dans le cas général du problème d’affectation est
égal à n!; la recherche exhaustive est impraticable pour toutes les instances du problèmes.
Heureusement, il existe un algorithme beaucoup efficace pour ce problème appelé la méthode de
Hongroise proposée par les mathématiciens Hongrois König et Egarvary dont les travaux sous-
tendent cette méthode (voir par exemple, [Kol95]).
Ceci est une bonne nouvelle : le fait qu’un problème dont le domaine croit exponentiellement
n’implique pas nécessairement qu’il ne peut pas exister d’algorithme efficace pour le résoudre. En
effet, nous présentons par la suite plusieurs autres exemples de tels problèmes. Cependant, de tels
exemples sont plus une exception que la règle. Plus souvent, il n’existe pas d’algorithmes temps
polynomiaux pour des problèmes dont le domaine croit exponentiellement avec la taille (en
supposant que nous voulons les résoudre exactement).
Exercices 3.4
Problème 1. a) Supposons que chaque tour peut être engendré en un temps constant, quelle sera la
classe d’efficacité de l’algorithme de recherche exhaustive donné dans le texte pour le problème du
voyageur de commerce ?
b) Si cet algorithme est programmé sur un ordinateur qui effectue un milliard d’additions par
seconde, estimer le nombre maximum de cités pour lequel le problème peut être résolu en : (i) une
heure, (ii) 24 heures, (iii) un an, (iv) un siècle.
tel que chaque ligne, chaque colonne et chaque diagonale principale a la même somme.
a) Montrer que si une matrice carrée d’ordre n existe la somme en question doit être égale à
n ( n 1) / 2 .
2
b) Concevoir un algorithme de recherche exhaustive pour générer tous les carrés magiques
d’ordre n.
c) Chercher sur Internet ou dans votre bibliothèque un algorithme meilleur pour générer les
carrés magiques.
d) Implémenter les deux algorithmes—la recherche exhaustive et celui que vous aurez trouvé—
et effectuer une expérience pour déterminer la plus grande valeur de n pour laquelle chacun
des algorithmes est capable de trouver un carré magique d’ordre n en moins de une minute
sur la machine que vous utilisez.
75