Algorithme de recherche dans des espaces

publicité
Université de Mons
Faculté des Sciences
Institut d’Informatique
Service d’informatique théorique
Algorithme de recherche dans des espaces variables
appliqué au problème de coloration de graphes
Directeur : Mr Hadrien M ÉLOT
Rapporteurs : Mme Véronique B RUYÈRE
Mr Olivier G AUWIN
Année académique 2010-2011
Projet réalisé par
Xavier D UBUC
i
Remerciements
Je remercie mon directeur, Hadrien Mélot, pour sa disponibilité, son aide
précieuse et la relecture du présent document.
Je remercie aussi mes rapporteurs, Véronique Bruyère et Olivier Gauwin pour
leurs remarques et conseils judicieux après lecture du pré-rapport.
Je remercie également mon frère, Jérôme Dubuc, pour la correction orthographique et syntaxique ainsi que mon ami, Jérôme Descamps, pour l’aide apportée
pour rendre le texte plus accessible.
Finalement, un remerciement spécial à ma fiancée Morgane Capelleman pour ses
talents d’infographiste bien utiles pour certaines images.
ii
Table des matières
Introduction
1
2
3
1
La coloration de graphes
1.1 Rappel théorique . . . . . . . . . . . . . . .
1.2 Définition du problème . . . . . . . . . . . .
1.3 Historique . . . . . . . . . . . . . . . . . . .
1.4 Applications . . . . . . . . . . . . . . . . . .
1.5 Bornes sur le nombre chromatique . . . . . .
1.6 Algorithmes de calcul du nombre chromatique
La recherche par espaces variables
2.1 Idée générale . . . . . . . . . . . . .
2.2 Intuition de fonctionnement . . . . . .
2.3 3 ensembles pour la k-coloration . . .
2.4 Traducteurs pour la k-coloration . . .
2.5 Algorithmes sous-jacents . . . . . . .
2.6 Algorithme VSS pour la k-coloration .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
2
3
6
7
11
13
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
16
16
17
18
21
24
29
Une application du VSS
3.1 Modélisation . . . . . . . . . . . . . . . . . .
3.1.1 Structures . . . . . . . . . . . . . . . .
3.1.2 Heuristique . . . . . . . . . . . . . . .
3.2 Implémentation . . . . . . . . . . . . . . . . .
3.2.1 Structures de données & représentation
3.2.2 Algorithmique . . . . . . . . . . . . .
3.3 Résultats . . . . . . . . . . . . . . . . . . . . .
3.4 Difficultés . . . . . . . . . . . . . . . . . . . .
3.4.1 Compréhension . . . . . . . . . . . . .
3.4.2 Implémentation . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
34
34
34
36
38
38
42
45
49
49
50
Conclusion
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
51
TABLE DES MATIÈRES
iii
Annexes
54
A Exemple de la Belgique
54
B Améliorations de TabuCol
56
1
Introduction
Le problème de coloration de graphes (Graph Coloring Problem) (GCP)
est un problème NP-difficile bien connu. Il consiste à colorier les sommets d’un
graphe de telle manière que deux sommets adjacents ne soient pas coloriés avec
la même couleur. Le but ultime est d’utiliser le moins de couleurs possible. Le
nombre minimal de couleurs nécessaires pour colorier un graphe est appelé nombre
chromatique.
Les aboutissants de la résolution de ce problème sont souvent méconnus.
Et pourtant, ce dernier est employé dans de nombreuses applications telles que
l’affectation de fréquences dans les réseaux radio-mobiles et les problèmes d’optimisation avec contraintes (ordonnancement, établissement de planning, ...). Il
peut également servir de base pour résoudre un sudoku [1, 2].
Ce problème paradigmatique (c’est-à-dire qu’il s’agit d’un problème simple
et exemplaire) étant NP-difficile, il n’existe pas à ce jour d’algorithme performant
(polynômial) pour le résoudre, il faut donc faire appel aux métaheuristiques. Le
but de ce projet est d’appliquer une métaheuristique (récente) à la coloration d’un
graphe et à la recherche du nombre chromatique de celui-ci. Cette métaheuristique
s’appelle Variable Space Search (VSS), littéralement “Recherche dans des espaces variables” et a été proposée par Hertz, Plumettaz et Zufferey en 2008 [3].
Ce rapport consiste dans un premier temps à définir le problème de coloration de graphes (Graph Coloring Problem) (GCP), à relater son origine, son
importance et l’état de l’art. Ces trois sujets seront traités dans le Chapitre 1. La
métaheuristique employée dans le cadre de ce projet est, quant à elle, développée
dans le Chapitre 2 et une application de celle-ci sera explicitée dans le Chapitre 3.
2
Chapitre 1
La coloration de graphes
La coloration de graphes est un problème simple consistant à employer le
moins de couleurs possible pour colorier un graphe de manière à ce que 2 sommets adjacents ne soient pas de la même couleur. Ce problème n’est défini que
sur des graphes sans boucle (c’est évident, sinon un sommet, adjacent à lui même
via la boucle ; devrait être colorié par deux couleurs différentes) et habituellement
sur des graphes non-orientés. Le présent chapitre pose les bases théoriques et formelles du problème ainsi que le vocabulaire utilisé. Il présente également un court
historique, l’importance de ce problème et l’état de l’art.
1.1
Rappel théorique
Par souci de clarté, une définition formelle d’un graphe est requise afin de
fixer les notations et le vocabulaire utilisés. Cette définition est celle proposée par
Diestel [4].
Définition 1.1.1. Un graphe G = (V, E) est une structure de données caractérisées par les ensembles V et E. Ces ensembles sont définis comme suit :
– V est l’ensemble des sommets (aussi appelés noeuds) (V comme Vertex),
– E ⊆ V × V est l’ensemble des arêtes qui représentent les liens entre les
sommets (E comme Edge).
Il existe deux grandes familles de graphes :
– les graphes non-orientés, dans lesquels un sommet x est relié à un sommet y si et seulement si y est relié à x ou, autrement dit, la présence de
l’arête (x, y) implique l’existence de l’arête (y, x) ;
– les graphes orientés, dans lesquels l’existence de l’arête orientée (x, y)
n’implique pas spécialement l’existence de (y, x). Les arêtes orientées
portent aussi le nom d’arc.
Les figures 1.1 et 1.2 montrent une représentation graphique d’un exemple pour
chacun de ces types de graphes.
CHAPITRE 1. La coloration de graphes
3
1
2
3
4
F IGURE 1.1 – Graphe non-orienté
1
2
4
3
F IGURE 1.2 – Graphe orienté
1.2
Définition du problème
A présent, les graphes étant formellement définis, le problème de coloration
d’un graphe peut être posé de manière claire et formelle, lui aussi.
Définition 1.2.1. La k-coloration d’un graphe G = (V, E) peut être vue comme
une fonction :
c : V → {1, 2, ..., k}
qui assigne à chaque sommet v de G un nombre c(v) appartenant à {1, 2, ..., k}
appelé couleur.
La coloration d’un graphe n’est pas un problème en soi au vu de la définition, le problème est de rendre cette coloration légale. Une coloration légale est
une coloration possédant certaines propriétés qu’il est nécessaire d’énoncer avant
de la définir.
Définition 1.2.2. Une coloration définit des classes de couleur Vi (i ∈ {1, ..., k})
qui forment une partition de l’ensemble V , la classe de couleur Vi contenant tous
les sommets de couleur i.
CHAPITRE 1. La coloration de graphes
4
Définition 1.2.3. Une arête (x, y) est dite conflictuelle si c(x) = c(y) ou, en
terme de classes de couleur si Vc(x) = Vc(y) . De manière simple, il s’agit d’une
arête reliant deux sommets de même couleur.
Par exemple, dans la figure 1.3, l’arête (1, 2) est conflictuelle.
conflit
1
2
3
4
F IGURE 1.3 – Arête conflictuelle
Définition 1.2.4. Une coloration est dite partielle si tous les sommets ne sont pas
coloriés, autrement dit, si ∃v ∈ V tel que c(v) n’est pas définie. Dans ce cas, la
fonction c n’est pas totale.
La figure 1.4 donne un exemple de coloration partielle, c(4) n’existant pas.
1
2
3
4
F IGURE 1.4 – Coloration partielle
Définition 1.2.5. La k-coloration d’un graphe G = (V, E) est dite légale si et
seulement si :
– cette coloration n’est pas partielle,
– aucune arête de E n’est conflictuelle.
G est dit k-colorable.
CHAPITRE 1. La coloration de graphes
5
1
2
3
4
F IGURE 1.5 – Coloration légale
La figure 1.5 montre une 4-coloration légale d’un graphe.
Le problème de décision consistant à savoir si un graphe G donné est k-colorable
pour un k donné est un des aboutissants du projet. Le principal problème, qui
est le problème d’optimisation associé, consiste quant à lui à trouver le nombre
chromatique d’un graphe :
Définition 1.2.6. Le nombre chromatique d’un graphe G est le plus petit nombre
entier l tel que G est l-colorable. En d’autres termes, c’est l’entier l tel que G est
l-colorable et tel qu’il n’existe pas k < l tel que G est k- colorable. Ce nombre
est noté χ(G).
Pour terminer cette section, le vocabulaire spécifique ayant été défini, voici
un énoncé concis et précis des deux problèmes qui sont traités dans ce projet :
– le problème de décision de k-coloration d’un graphe (k-GCP) consiste,
pour un k et un graphe G donnés à déterminer si G est k-colorable.
Ce problème est NP-complet.
– le problème d’optimisation de coloration d’un graphe (GCP, Graph
Coloring Problem) consiste à déterminer le nombre chromatique d’un
graphe G donné. Ce problème est NP-difficile.
Il est à remarquer que les deux problèmes sont liés et l’un peut toujours servir de
base pour résoudre l’autre. En effet, le GCP permet de résoudre le k-GCP tout
simplement en s’arrêtant dès que l’algorithme a fourni une k- coloration légale (ou
une l-coloration avec l < k, si une telle coloration existe). Inversement, le k-GCP,
démarré avec une borne supérieure de χ(G) (typiquement, le nombre de noeuds)
et où k est décrémenté tant que G est k-colorable ; donne une solution pour le
GCP. Il existe de meilleures valeurs pour la borne supérieure de χ(G), données
par des expérimentations diverses menées par des chercheurs (voir section 1.5).
CHAPITRE 1. La coloration de graphes
1.3
6
Historique
Cette section présente un court historique de la branche de la théorie des
graphes (l’étude des graphes) consacrée à la coloration des graphes.
Cet historique débute en 1852 lorsqu’un mathématicien sud-africain, Francis Gutrie, postule la "four color conjecture" à partir d’observations faites sur la coloration d’une carte géographique des comtés d’Angleterre. La coloration des régions
de cette carte devait respecter le fait que deux régions partageant une frontière ne
pouvaient pas être coloriées avec la même couleur. Comme le nom de la conjecture l’indique, il s’est rendu compte que pour effectuer un tel travail, seulement
quatre couleurs étaient nécessaires [5].
Il venait de poser les bases de la coloration des graphes. Effectivement,
une carte géographique simplifiée (dans le sens où tous les pays sont considérés comme contigus) peut être facilement représentée par un graphe particulier,
un graphe planaire ; le lien entre la coloration de carte et la coloration de graphe
est donc vite établi. La simplification de la carte n’est pas toujours possible dans
la réalité (par exemple, les États-Unis avec l’Alaska).
(Pour rappel, un graphe planaire est un graphe qui peut être représenté dans le
plan de manière à ce que ses arêtes ne se croisent qu’en ses sommets)
Un exemple de la marche à suivre pour effectuer cette coloration est présenté dans
l’annexe A.
L’intuition pour trouver qu’il existe des cartes nécessitant quatre couleurs est
d’avoir un pays entouré par trois autres qui se touchent tous, comme par exemple
le Luxembourg (voir Figure 1.6). La difficulté du problème est de prouver que
quatre couleurs sont toujours suffisantes.
F IGURE 1.6 – Carte d’Europe partielle 4-coloriée
CHAPITRE 1. La coloration de graphes
7
En effet, beaucoup de mathématiciens ont essayé de prouver cette
"four color conjecture", en vain. Celle-ci, devenue un théorème, est d’ailleurs
connue pour avoir donné lieu à la première preuve majeure assistée par ordinateur
(dirigée par Appel & Haken en 1989 [6]).
Beaucoup de théories sur les graphes ont été développées suite à cette introduction de la coloration, comme, par exemple, le polynôme chromatique de
Birkhoff [7], le polynôme de Tutte [8] ou encore le "Strong perfect graph theorem" prouvé en 2002 par Chudnovsky, Robertson, Seymour & Thomas [9]. Ce
problème figure également dans les célèbres 21 problèmes NP-complets de Karp
[10].
1.4
Applications
En quoi la coloration de graphes est-elle importante, ou tout du moins,
utile ? Cette question est le fil rouge de cette section dans laquelle sont présentées quelques applications pratiques où la coloration de graphes joue un rôle. Ces
applications sont assez variées, allant du domaine du jeu avec la résolution de sudoku à l’ordonnancement de tâches (tant au niveau d’un processeur qu’au niveau
de la gestion d’emploi du temps de personnes) en passant par l’allocation de fréquences dans les réseaux radio-mobiles ou encore des résolutions de problèmes
plus mathématiques comme le Constraint Satisfaction Problem (CSP).
Allocation de fréquences
De manière simple et intuitive, certains réseaux de télécommunication étant
composés de plusieurs émetteurs, ceux-ci sont confrontés à un problème majeur :
les interférences. En effet, si deux émetteurs émettent sur la même fréquence, dès
lors qu’ils sont trop proches l’un de l’autre et qu’ils émettent en même temps, de
manière irrémédiable des interférences ont lieu (à moins qu’ils soient séparés par
une montagne ou quelque chose empêchant la propagation des ondes). La coloration de graphes peut permettre de résoudre ce problème.
Pour ce faire, il convient d’associer un graphe au réseau, ce graphe aura
comme sommets les différents émetteurs et une arête est placée entre ces émetteurs lorsqu’ils sont trop proches (ou, tout du moins lorsqu’il est désirable qu’ils
n’émettent pas à la même fréquence). Dès lors, si ce graphe est de nombre chromatique k, alors le réseau doit être capable d’utiliser au moins k fréquences différentes et il convient d’affecter des fréquences différentes à des noeuds n’ayant
pas la même couleur.
CHAPITRE 1. La coloration de graphes
8
Ordonnancement
L’ordonnancement de tâches consiste à ordonner ces dernières de manière
cohérente et sans conflit (une tâche peut être prioritaire sur une autre, la dernière utilisant peut-être les résultats de la première). Dans les systèmes actuels,
plusieurs processeurs sont utilisés pour une seule machine ce qui permet à deux
tâches d’être exécutées de manière concurrente. Il se peut dès lors que ces deux
tâches entrent en conflit si elles utilisent les mêmes ressources. En considérant
un graphe construit de telle sorte que chaque noeud est une de ces tâches et que
deux tâches sont reliées si elles utilisent les mêmes ressources, il est possible,
avec la coloration de graphes, de trouver une manière d’ordonnancer ces tâches
sans qu’elles n’entrent en conflit réel (sous l’hypothèse qu’un tel ordonnancement
soit possible).
Planification d’horaires
De manière assez semblable à l’ordonnancement, la génération du planning
d’une ou plusieurs personnes peut se faire à partir de la coloration de graphes. Par
exemple, un professeur d’université donnant plusieurs cours sur toute une année
ne peut en aucun cas donner deux cours différents au même moment. Sous forme
d’un graphe, chaque cours est représenté par un sommet et deux cours sont reliés
s’ils sont donnés par le même professeur. Il est alors aisé de transposer le résultat
de la coloration du graphe ainsi construit à l’allocation de laps de temps pendant
lesquels le professeur donne effectivement ses cours.
Algo1
IA
SDD
SDD2
AlgoApprox
Algo2
CompNet1
CompNet2
Compil
CalcEtCompl
F IGURE 1.7 – Exemple de graphe de planning
CHAPITRE 1. La coloration de graphes
9
Ainsi, par exemple, tous les noeuds coloriés en rouge représentent des cours
qui doivent être donnés le lundi de 8h à 10h. (le graphe renseigne uniquement le
fait que deux cours de la même couleur peuvent être donnés en même temps sans
donner lieu à des conflits, la génération du planning ne dépend donc pas que du
graphe)
Aspect ludique : résolution de sudoku
Voici le problème qui est posé : résoudre un sudoku semblable à celui représenté par la table 1.1. Pour rappel, résoudre un sudoku signifie remplir chaque
case de ce tableau avec un chiffre de l’ensemble {1, 2, 3, 4, 5, 6, 7, 8, 9} de telle
sorte qu’il n’y ait qu’une seule fois chaque chiffre dans une colonne, dans une
ligne et dans un carré.
4
2
7
8
5
9
5
3
7
4
1
5
2
2
3
6
1
3
9
4
6
5
7
8
6
3
6
7
2
8
9
TABLE 1.1 – Sudoku à résoudre
Il est possible de considérer ce sudoku comme un graphe de telle manière
que la coloration de ce graphe donne une résolution de celui-ci. En effet, un sudoku n’est rien d’autre qu’un graphe particulier comportant 81 noeuds et qui, pour
être résolvable, doit être 9-colorable. Dans ce graphe, les sommets correspondent
aux cases, et chaque arête représente le fait que les deux cases ainsi reliées ne
peuvent contenir le même chiffre. La numérotation suivante est utilisée :
1
10
19
28
37
46
55
64
73
2
11
20
29
38
47
56
65
74
3
12
21
30
39
48
57
66
75
4
13
22
31
40
49
58
67
76
5
14
23
32
41
50
59
68
77
6
15
24
33
42
51
60
69
78
7
16
25
34
43
52
61
70
79
8
17
26
35
44
53
62
71
80
9
18
27
36
45
54
63
72
81
CHAPITRE 1. La coloration de graphes
10
De cette manière, en ne considérant que les contraintes du carré (en abandonnant
donc les contraintes de la ligne et de la colonne), le premier carré (donc les cases
1, 2, 3, 10, 11, 12, 19, 20 et 21) peut être représenté par le graphe dessiné en Figure
1.8.
10
11
1
2
12
21
19
20
3
F IGURE 1.8 – Graphe partiel d’un sudoku
Il s’agit d’un graphe complet, c’est-à-dire qu’il possède le nombre maximal d’arêtes, ou autrement dit, que chaque sommet est relié à tous les autres.
Le sudoku en entier est donc représentable par un graphe contenant neuf sousgraphes semblables à celui ci-dessus reliés entre eux de manière à tenir compte
des contraintes de lignes et de colonnes. Le graphe contient alors au total 816
arêtes. Si une 9-coloration légale de ce graphe est trouvée, le sudoku est résolu.
Selon les mathématiciens Russell et Jarvis, il y a 5.472.730.538 sudoku différents [11] qui sont résolvables et qui ont une solution unique, de quoi ravir les
aficionados de ce sport cérébral.
Aspect mathématique : CSP
Le principe de ce problème est assez simple [12]. A partir d’un ensemble X
de variables entières avec un domaine de valeurs permises pour chacune d’entre
elles (tous ces domaines sont contenus dans un ensemble nommé D) ainsi que
d’un ensemble de contraintes C, le CSP consiste à trouver une assignation des
variables X avec des valeurs de leur domaine respectif qui satisfait à toutes les
contraintes de C. Il est dès lors très facile d’exprimer le CSP comme un problème
CHAPITRE 1. La coloration de graphes
11
de k-coloration et vice-versa.
En effet, on peut mettre en relation :
– les sommets du graphe avec les variables à assigner,
– les contraintes avec des arêtes (et dans l’autre sens chaque arête (i, j)
devient une contrainte disant que la variable xi doit être différente de la
variable xj ),
– les domaines en restreignant les couleurs autorisées pour certains noeuds
(et dans l’autre sens toutes les variables doivent appartenir au même domaine : {1, ..., k})
1.5
Bornes sur le nombre chromatique
Beaucoup de résultats ont été trouvés dans cette branche. Ces résultats concernent
principalement le fait de donner des bornes pour le nombre chromatique afin de
limiter les zones de recherches pour certains types de graphes. Cette section énumére ces différentes bornes.
Propriété 1.5.1. Le nombre chromatique d’un graphe G = (V, E), χ(G), est
compris entre 1 et le nombre de noeuds de G, |V |. En effet, si G ne possède
aucune arête, il est 1-colorable et dans le pire des cas, G est un graphe complet
(graphe contenant toutes les arêtes possibles) et il est donc |V |-colorable. On a
donc : 1 ≤ χ(G) ≤ |V |.
1
2
3
4
F IGURE 1.9 – Graphe complet
1
2
3
4
F IGURE 1.10 – Graphe sans arête
Propriété 1.5.2. Si un graphe G contient une clique de taille k, c’est-à-dire un
sous-graphe complet contenant k sommets, le nombre chromatique de G est supérieur ou égal à k. On pose w(G) comme étant la taille de la clique de taille
maximale de G, on a donc : χ(G) ≥ w(G). (Exemple : voir Figure 1.11)
CHAPITRE 1. La coloration de graphes
12
1
2
3
4
F IGURE 1.11 – Graphe avec une clique de taille maximale 3
Propriété 1.5.3. Soit ∆(G) le degré maximal d’un graphe G, ce nombre représente le nombre maximal d’arêtes incidentes à un noeud de G. Dès lors, il a
été prouvé par un algorithme glouton [13] que G est colorable avec, au plus,
∆(G) + 1 couleurs. On a donc : χ(G) ≤ ∆(G) + 1. (Exemple : voir Figure 1.12)
1
2
3
Noeud
1
2
3
4
Degré
1
3 = ∆(G)
1
1
4
→ χ(G) = 2 ≤ ∆(G) + 1 = 4
F IGURE 1.12 – Graphe 2-colorable G où ∆(G) = 3
Pour certains types de graphes, le nombre chromatique est connu. Il en va
ainsi pour les graphes planaires (4-colorables, comme dit précédemment) et les
graphes bipartis (2-colorables). Ces graphes bipartis sont des graphes dont l’ensemble de noeuds V peut être partitionné en deux sous-ensembles disjoints A et
B de telle manière que chaque arête du graphe relie un sommet de A à un sommet
de B. Une 2-coloration est donc simple à trouver, il suffit de colorier tous les sommets de A d’une couleur et tous les sommets de B d’une autre. (Les arbres sont
des cas particuliers de ces graphes, par exemple) Prouver qu’un graphe est biparti
peut être fait via un parcours en largeur adapté et donc en O(m + n) (m étant le
nombre d’arêtes et n le nombre de noeuds).
CHAPITRE 1. La coloration de graphes
1.6
13
Algorithmes de calcul du nombre chromatique
De nombreux algorithmes permettant de calculer le nombre chromatique
d’un graphe ont été développés au cours du temps, cette section effectue un court
historique de ces algorithmes.
Étant un problème N P -complet, les algorithmes exacts connus résolvant ce
problème sont de complexité exponentielle. Il existe cependant des algorithmes
polynômiaux pour des graphes particuliers (tester si un graphe est biparti par
exemple permettant ainsi d’exhiber le fait que son nombre chromatique est 2).
L’algorithme le plus basique est d’énumérer toutes les k-colorations possibles
pour tous les 1 ≤ k ≤ |V | et de chercher une coloration légale dont le k est
minimum. Le problème avec cette énumération c’est qu’elle est exponentielle. En
effet, il y a 2n 2-colorations possibles, 3n 3-colorations possibles, etc les générer
toutes depuis une certaine borne supérieure peut alors être très fastidieux. Pour
exemple, si on prend un graphe de n = 10 noeuds et que l’on énumère toutes les
k-colorations avec 1 < k ≤ 5, on obtient environ 1.09 107 colorations différentes.
Pour résoudre ce problème, il est donc nécessaire de se fier à des heuristiques. Il en existe plusieurs donnant de bons résultats, la plus intuitive étant celle
de Welsh-Powell [13] qui repose sur un tri topologique des sommets par ordre
décroissant de degrés. Cet algorithme glouton propose de parcourir ces sommets
triés (v1 , v2 , ... vi , ... v|V | ) l’un après l’autre en assignant à vi la plus petite couleur
non utilisée par ses voisins dans v1 , v2 , ... vi−1 et en ajoutant une nouvelle couleur
si aucune n’est disponible. En procédant de cette façon l’algorithme fournira une
k-coloration où k sera au plus égal au degré maximum de G (cf. résultats plus
haut). Par exemple, pour le graphe représenté en Figure 1.13, le tri topologique
peut donner plusieurs ordres dont : 10, 3, 2, 8, 5, 11, 4, 1, 6, 7, 9. L’algorithme procède alors comme suit :
– assigner la couleur 1 au sommet 10,
– assigner la couleur 1 au sommet 3,
– assigner la couleur 2 au sommet 2,
– assigner la couleur 2 au sommet 8,
– assigner la couleur 1 au sommet 5,
– assigner la couleur 3 au sommet 11,
– ...
pour donner au final le résultat obtenu en Figure 1.14.
CHAPITRE 1. La coloration de graphes
1
2
3
5
6
7
9
14
4
8
10
11
F IGURE 1.13 – Graphe pour l’algorithme glouton de Welsh-Powell
1
2
3
5
6
7
9
4
8
10
11
F IGURE 1.14 – Graphe colorié par l’algorithme glouton de Welsh-Powell
Cette heuristique, bien qu’elle semble fonctionner correctement, ne garantit
pas que le k trouvé soit le nombre chromatique de G. Elle ne rencontre donc pas
les objectifs fixés.
Une autre approche est également possible, celle des métaheuristiques. Une
métaheuristique est une heuristique qui peut être employée dans plusieurs problèmes différents. Il en existe de deux types :
– les métaheuristiques de population, qui utilisent une population de solutions qui évoluent au fil de l’exécution,
– les métaheuristiques à solution unique, qui utilisent une seule solution
qui s’améliore au fil de l’exécution.
Dans le cadre de la coloration de graphes, les algorithmes les plus efficaces
sont ceux utilisant ces métaheuristiques, il en existe des différents et variés. En effet, dans ce domaine, il existe un grand nombre d’articles traitant d’applications de
métaheuristiques de population, comme par exemple les algorithmes génétiques et
hybrides de Fleurent et Ferland [14] ou encore les algorithmes hybrides évolutifs
de Galinier et Hao [15].
CHAPITRE 1. La coloration de graphes
15
D’autres algorithmes, basés sur une solution unique, également efficaces, ont été
développés dans ce domaine. Parmi eux, il y a par exemple l’application de la recherche tabou à la coloration par Hertz et De Werra [16] ou, plus récemment,
la métaheuristique utilisant des solutions partielles et un schéma tabou réactif
de Bloechliger et Zufferey [17] ou encore la recherche par voisinage variable de
Avanthay, Hertz et Zufferey [18].
Cette dernière métaheuristique est très importante car elle sert de base à la
métaheuristique développée dans ce projet. En effet, en 2005, elle a été généralisée par la "Formulation Space Search" de Mladenovic [19] qui elle-même a été
généralisée par Hertz, Plumettaz et Zufferey avec la recherche par espace variable
(Variable Space Search) [3], métaheuristique dont fait l’objet ce projet et qui est
présentée dans le chapitre suivant.
16
Chapitre 2
La recherche par espaces variables
Ce chapitre développe la métaheuristique de Hertz, Plumettaz et Zufferey
appelée Variable Space Search (Recherche par espaces variables, VSS). Le but
est de présenter l’idée générale et de montrer comment ces personnes proposent
de l’appliquer à la coloration de graphes.
2.1
Idée générale
Avant de rentrer dans le vif du sujet, un petit rappel de la définition d’une
métaheuristique à solution unique s’impose afin de fixer le vocabulaire utilisé.
Une métaheuristique à solution unique est un algorithme d’optimisation qui est
défini par trois éléments :
– l’espace de recherche S, qui représente l’ensemble des solutions possibles au problème,
– la fonction objectif f (s), qui permet d’évaluer la qualité de la solution s,
– le voisinage N (s) (N (s) ⊆ S) qui représente un ensemble de solutions
atteignables à partir de la solution s via une opération de voisinage (appelée aussi "move" ou mouvement).
Afin d’appliquer une métaheuristique, il faut donc définir le problème au
travers de ces trois éléments.
La métaheuristique utilisée ici est un peu particulière. En effet, elle ne considère pas seulement un, mais un nombre arbitraire n d’espaces, avec chacun leur
fonction objectif, voisinage et opération de voisinage. Elle définit alors des outils
supplémentaires Tij appelés traducteurs qui vont permettre de transformer n’importe quelle solution de Si en solution de Sj et ce pour tout i, j ≤ n, i 6= j.
L’algorithme en lui-même est alors très simple, il est présenté dans l’algorithme 1.
CHAPITRE 2. La recherche par espaces variables
17
Algorithme 1 Variable Space Search
Entrée :
– une série d’espaces de recherche Si (1 ≤ i ≤ n) avec leur fonction objectif
fi et leur voisinage Ni respectifs,
– les traducteurs Tij ,
Sortie : la solution du problème
1: i ← 1
2: s ← Générer une solution initiale ∈ S1
3: Tant que le critère d’arrêt n’est pas rencontré faire
4:
s0 ← Faire une recherche locale dans Si à partir de s en utilisant la fonction
objectif fi et le voisinage Ni
5:
j ← (i mod n) + 1
6:
s ← Tij (s0 )
7:
i←j
8: fin Tant que
9: Retourner s
Il peut cependant être modifié dans le sens où il n’y a aucune obligation de
commencer à l’espace S1 ni de passer de l’espace Si à l’espace Si+1 . Ainsi, l’algorithme pourrait, par exemple, commencer par l’espace S42 et choisir l’espace
suivant en fonction de la qualité des solutions que cet espace a fourni par le passé.
Il est à noter qu’une solution admissible pour un certain ensemble Si ne
l’est pas forcément pour un espace Sj (i 6= j) ; autrement dit, il se peut que les
espaces considérés soient totalement différents (et il en va donc de même pour
leur fonction objectif et leurs voisinages).
2.2
Intuition de fonctionnement
F IGURE 2.1 – Fonctionnement du VSS
CHAPITRE 2. La recherche par espaces variables
18
Le problème principal auquel sont confrontées les métaheuristiques est de
s’échapper d’un optimum local (plus d’informations à ce sujet sont apportées dans
la section 2.5). Ceci la principale motivation de cette métaheuristique, en effet, un
optimum local dans un espace ne l’est pas spécialement dans un autre. Ainsi changer d’espace permet de s’échapper de l’optimum local dans lequel la recherche
locale est restée coincée.
L’algorithme, bien que complexe, suit une structure assez simple détaillée
dans la figure 2.1. Dans le cadre de la coloration de graphe, les auteurs de cette
métaheuristique recommande 3 espaces de solutions qui sont définis dans la section suivante.
L’algorithme de recherche locale dans l’espace S1 , TabuCol, permet de réduire significativement la valeur objectif de la solution courante mais peut parfois
avoir du mal à explorer toutes les régions de l’espace de recherche, il se bloque
assez facilement dans un optimum local. L’algorithme de recherche locale dans
S3 , S3Search, tient son rôle de là, il permet de diversifier de manière plus ou
moins forte la solution courante afin de “sauter” hors d’un optimum local et ce,
sans trop détériorer la solution. Par la suite, l’algorithme de recherche locale dans
S2 , PartialCol, permet de réduire très rapidement la valeur de la solution courante
en recolorant les noeuds non colorés jusqu’à atteindre un optimum local. L’algorithme repasse ensuite à TabuCol qui va commencer sa recherche dans une région
qui, avec espoir, il n’a pas encore visité.
2.3
3 ensembles pour la k-coloration
Cette section attaque le sujet de ce projet en profondeur. En effet, il consiste
à détailler les ensembles de solutions, leur fonction objectif et leurs voisinages
choisis pour la métaheuristique précédemment introduite afin de résoudre le problème de coloration de graphe.
Pour le problème de k-coloration de graphes, il convient d’utiliser trois ensembles. Afin de trouver ces trois ensembles, il faut se rappeler la définition d’une
coloration légale. Pour qu’une coloration soit légale, il faut qu’elle respecte deux
contraintes : tous les noeuds sont coloriés et il n’y a aucune arête conflictuelle.
Les deux premiers ensembles seront construits à partir d’une relaxation de l’une
de ces deux contraintes tandis que le dernier contiendra des solutions d’une toute
autre nature.
Premier espace
Description de l’ensemble S1 : cet espace contient toutes les k-colorations de G,
qu’elles soient légales ou pas.
CHAPITRE 2. La recherche par espaces variables
19
Fonction objectif f1 (s) : elle est égale au nombre d’arêtes conflictuelles que
contient s.
Voisinage N1 (s) : il contient toutes les k-colorations de G obtenues en modifiant
la couleur d’un et un seul sommet dans s.
Algorithme de recherche locale : TabuCol[16], cet algorithme permet d’effectuer la recherche locale dans l’ensemble S1 en se basant sur une recherche tabou.
(Plus d’informations sur cet algorithme dans la section 2.5)
Second espacee
Description de l’ensemble S2 : cet espace, proposé par Morgenstern [20], contient
toutes les k-colorations légales partielles de G (donc les colorations dont tous les
noeuds ne sont pas coloriés). Ces colorations sont représentées comme une partition de l’ensemble des noeuds en classes de couleur Vi avec la classe Vk+1 qui
contient tous les noeuds non-coloriés.
Fonction objectif f2 (s) : égale au nombre de noeuds appartenant à Vk+1 .
Voisinage N2 (s) : toutes les colorations obtenues à partir de s en effectuant un iswap. Un i-swap consiste à déplacer un noeud v de la classe Vk+1 à la classe Vi en
déplaçant tous les noeuds adjaçents de v de Vi dans Vk+1 .
Algorithme de recherche locale : PartialCol[17], cet algorithme, également basé
sur une recherche tabou a donné de bons résultats, il est donc utilisé ici. (Plus
d’informations sur cet algorithme dans la section 2.5)
Troisième espace
Cet espace est différent des deux autres en ce sens qu’il ne contient pas de
graphes coloriés mais des graphes orientés acycliques non coloriés. Il est nécessaire d’introduire un vocabulaire spécial pour cet espace. Ainsi, un graphe est dit
acyclique s’il n’admet aucun chemin de longueur arbitraire reliant un noeud à lui→
−
même. Ensuite, une orientation G d’un graphe non-orienté G est un graphe dont
chaque arête (u, v) est remplacée par une arête orientée de u vers v (u → v) ou de
v vers u (v → u) selon le choix fait. Un exemple d’orientation est donné dans la
Figure 2.2.
1
5
2
3
1
4
5
2
3
4
F IGURE 2.2 – Un graphe et une orientation de celui-ci
Gallai, Roy et Vitaver [21, 22, 23] ont prouvé séparément que la longueur
CHAPITRE 2. La recherche par espaces variables
20
→
−
→
−
maximale λ( G ) d’un chemin dans G est au moins égale au nombre chromatique
→
−
de G. Comme corollaire, le problème, qui consiste à orienter les arêtes de G
→
−
de telle manière qu’il soit sans cycle et que λ( G ) soit minimal, est équivalent à
trouver le nombre chromatique de G. (La conviction vient rapidement en essayant
de construire l’un à partir de l’autre et inversement)
1
5
2
3
4
F IGURE 2.3 – Orientation et un plus long chemin
Description de l’espace S3 : Gendron, Hertz et St-Louis [24] proposent de définir
→
−
cet espace comme l’espace des orientations acycliques G de G. De manière semblable aux classes de couleurs Vi pour S1 et S2 , l’espace S3 contiendra des classes
de longueur nommées Ui . La classe Ui est définie comme la classe contenant tous
les sommets dont le plus long chemin se terminant en ce sommet contient exactement i sommets. Ces classes Ui peuvent être plus nombreuses que les classes Vi
de couleurs, il est important de ne pas les confondre. Un exemple est donné dans
la figure 2.4.
→
−
→
−
Fonction objectif f3 ( G ) : égale à λ( G ).
→
−
→
−
→
−
Voisinage N3 ( G ) : on pose G λ le graphe construit à partir de G où toutes les
arêtes orientées qui n’appartiennent pas à un chemin de longueur maximale dans
→
−
→
−
G ont été enlevées (voir exemple figure 2.5). Dès lors, un voisin de G peut être
obtenu en choisissant un sommet x aléatoirement et en changeant l’orientation de
→
−
→
−
toutes les arêtes orientées de G dont la tête dans G λ est x (la tête d’une arête
orientée est le point d’arrivée de l’arête). Il est prouvé dans [24] qu’une telle opération de voisinage ne crée pas de cycle et augmente la longueur d’un plus long
chemin d’au plus une unité (voir exemple figure 2.6).
CHAPITRE 2. La recherche par espaces variables
1
5
2
3
Classe
U1
U2
U3
U4
21
4
Éléments
{1}
{2, 5}
{3}
{4}
F IGURE 2.4 – Classes Ui
1
5
2
3
4
1
2
5
3
4
F IGURE 2.5 – Orientation et Gλ
1
5
2
3
1
4
5
2
3
4
F IGURE 2.6 – G et son voisin en choisissant x = 3
→
−
(les arêtes en bleu sont celles de G λ )
Algorithme de recherche locale : de manière simplifiée, il s’agira d’un algorithme aléatoire en ce sens où le but principal sera de modifier “suffisamment”
la solution, en aucun cas de l’améliorer.
(Plus d’informations sur cet algorithme dans la section 2.5)
2.4
Traducteurs pour la k-coloration
Les différents ensembles sont maintenant bien définis et posés. Il reste à présent à spécifier comment l’algorithme transformera une solution d’un ensemble en
une solution d’un autre ensemble. Vu qu’il y a trois ensembles, il y a six traduc-
CHAPITRE 2. La recherche par espaces variables
22
teurs. Ces derniers sont présentés ci-dessous, accompagnés d’un exemple pour
chacun d’entre eux. Ces exemples ont été inspirés (ou tout simplement repris)
de ceux fournis par Hertz, Plumettaz et Zufferey [3]. Sur ces exemples les arêtes
conflictuelles sont coloriées en rouge et les couleurs sont considérées telles que
rouge = 1, bleu = 2 et vert = 3.
1. T12 construit une coloration partielle sans conflit à partir d’une coloration
totale non légale en choisissant de manière aléatoire un des deux sommets
de chaque arête conflictuelle et en insérant ce sommet dans la classe Vk+1
(donc retirer la couleur de ce sommet)
1
2
3
4
1
2
3
4
5
6
7
8
T12
5
6
7
8
F IGURE 2.7 – Application de T12
2. T21 construit une k-coloration de G à partir d’une k-coloration partielle sans
conflit de G en considérant les noeuds de Vk+1 un à un dans un ordre aléatoire et en leur donnant la couleur dans {1, ..., k} qui crée le moins d’arêtes
conflictuelles.
1
3
7
2
8
1
9
3
7
2
8
9
T21
4
5
4
6
5
6
F IGURE 2.8 – Application de T21
3. T13 construit une orientation de G en dirigeant les arêtes (u, v) telles que
u ∈ Vi et v ∈ Vj :
– de u vers v si i < j ou que i = j et que l’indice du noeud (son "numéro"
dans la structure de données) u est plus petit que celui de v,
– de v vers u sinon.
CHAPITRE 2. La recherche par espaces variables
1
1
T13
6
2
23
3
4
6
2
5
3
4
5
F IGURE 2.9 – Application de T13
4. T23 procède exactement de la même façon que T13 .
1
2
6
3
1
5
T23
7
2
6
3
5
7
4
4
F IGURE 2.10 – Application de T23
5. T31 construit une k-coloration en donnant la couleur i (1 ≤ i ≤ k) à chaque
sommet de la classe Ui et colorie les sommets restants dans un ordre aléatoire en leur donnant une couleur dans {1, ..., k} qui crée le moins d’arêtes
conflictuelles.
1
2
3
4
1
2
3
4
8
7
6
5
T31
8
7
Classe
U1
U2
U3
U4
6
Éléments
{1, 8}
{2, 7}
{3, 6}
{4, 5}
5
⇒
Classe
V1 (rouge)
V2 (bleu)
V3 (vert)
Éléments
{1, 4, 5, 8}
{2, 7}
{3, 6}
F IGURE 2.11 – Application de T31
CHAPITRE 2. La recherche par espaces variables
24
6. T32 ordonne dans un premier temps les classes Ui (1 ≤ i ≤ k) par ordre
décroissant de taille. Ensuite, les k premières classes sont respectivement
coloriées avec les couleurs {1, ..., k}. Finalement les classes excédentaires
sont fusionnées en une seule pour former la classe Vk+1 de l’ensemble S2
(les sommets non-coloriés).
6
4
2
9
11
6
1
4
2
9
11
1
T32
10
3
7
8
Classe
U1
U2
U3
U4
10
5
Éléments
{4, 6, 9}
{1, 2, 11}
{3, 7, 10}
{5, 8}
3
8
⇒
Classe
V1 (rouge)
V2 (bleu)
V3 (vert)
V4 (non-colorié)
7
5
Éléments
{4, 6, 9}
{1, 2, 11}
{3, 7, 10}
{5, 8}
F IGURE 2.12 – Application de T32
2.5
Algorithmes sous-jacents
Chaque ensemble est défini et l’algorithme est capable de passer de l’un à
l’autre avec les six traducteurs définis plus haut. Il ne reste donc plus qu’à définir
plus en détails les algorithmes utilisés pour la recherche locale dans chacun de ces
ensembles. Cette section concerne ces algorithmes, elle explique le fonctionnement global de chacun d’eux en commençant par l’algorithme de recherche dans
S1 . Viennent ensuite les algorithmes de recherche dans S2 et S3 . Avant de s’attaquer à ces algorithmes, elle décrit le fonctionnement de la recherche tabou qui est
utilisée dans les algorithmes TabuCol et PartialCol.
Recherche Tabou
Pour rappel, le but des métaheuristiques développées est de trouver l’optimal global d’une fonction objectif. Il est dès lors très important de trouver un
moyen de s’échapper d’optima locaux afin de poursuivre la recherche. En effet,
la technique consistant à prendre le "meilleur" voisin (au vu de sa valeur par la
CHAPITRE 2. La recherche par espaces variables
25
fonction objectif) ne permet pas d’atteindre l’optimal global.
Par exemple, sur la figure ci-dessous, une fois arrivé sur le pic indiqué par
"local maximum", on ne bougera plus car tous ses voisins sont "moins bien" que
lui ; or ce n’est pas le maximum global.
F IGURE 2.13 – Graphe d’une fonction objectif arbitraire
(image prise de [25])
Le principe général de la recherche tabou est simple, il consiste à autoriser
les mouvements d’une solution à un de ses voisins qui est "moins bien" que cette
solution à condition que le mouvement ne soit pas tabou. Un mouvement tabou
est un mouvement qui n’est pas autorisé, typiquement un mouvement qui ferait revenir l’algorithme sur ses pas. La recherche tabou tient donc en mémoire une liste
circulaire appelée liste tabou qui contiendra à toute itération i les mouvements
interdits pour cette itération. Cette liste est de taille fixe, ainsi un mouvement est
interdit pendant un certain nombre d’itérations. Lorsque cette liste est pleine et
qu’un mouvement doit être ajouté à la liste, le plus ancien est enlevé. Typiquement lors de l’itération consistant à passer de s à s0 , le mouvement s0 → s est
ajouté à la liste et le plus vieux (si la liste est pleine) est enlevé.
Il faut également spécifier un critère d’arrêt à cette méthode. Usuellement,
le critère d’arrêt est un nombre maximal d’itérations mais ce n’est pas toujours le
cas.
TabuCol, algorithme de recherche dans S1
Le but de cet algorithme (proposé par de Werra et Hertz [16]) est de minimiser la fonction f (s) qui représente le nombre d’arêtes conflictuelles, notre objectif
étant que cette valeur soit nulle afin que la coloration soit légale. Le fait que f doit
être proche de (voire égale à) 0 peut alors être utilisé dans le critère d’arrêt. La
liste tabou, quant à elle, contient des couples (x, i) et signifie qu’un sommet x ne
peut plus être colorié par la couleur i.
CHAPITRE 2. La recherche par espaces variables
26
L’algorithme génère aléatoirement un certain nombre (paramètre à préciser)
de voisins de la solution courante s (si ce voisin provient d’un mouvement de
la liste tabou, il en génère un autre). Pour rappel, un voisin de s est obtenu en
modifiant la couleur d’un et un seul sommet de s. Il choisit ensuite le meilleur
de ces voisins, s∗ c’est-à-dire celui avec la valeur de f la plus basse. Il effectue
alors le mouvement s → s∗ et ajoute le mouvement s∗ → s dans la liste tabou
(en supprimant le plus ancien si la liste est pleine). En effet, pour rappel, l’algorithme accepte les mouvements vers des solutions “moins bonnes” pourvu que ces
mouvements ne soient pas tabou. Le but de cette manoeuvre étant de se donner
les moyens de sortir d’un minimum local. L’algorithme continue ensuite selon le
même raisonnement avec s = s∗ et ce jusqu’à ce que f (s) = 0 ou qu’un nombre
maximal d’itérations (fixé au début) soit atteint. Dans ce dernier cas, si f (s) > 0
quand le nombre d’itérations est atteint, alors l’algorithme n’a pas trouvé de coloration légale.
D’autres améliorations sont apportées à cet algorithme mais il n’est pas important de les citer pour la compréhension de l’algorithme. Ces améliorations
permettent de réduire un peu plus le temps de calcul, elles sont détaillées dans
l’annexe B. L’algorithme 2 résume cet algorithme en pseudo-code.
Algorithme 2 TabuCol
Entrée :
– un graphe G = (V, E),
– un entier k représentant le nombre de couleurs,
– tabsize la taille de la liste tabou,
– neighbcount le nombre de voisins à générer,
– itermax le nombre maximal d’itérations.
Sortie : une k-coloration de G tentant de minimiser le nombre d’arêtes conflictuelles.
1: Génération d’une solution aléatoire initiale s
2: iter ← 0
3: T ← nouvelle liste de taille tabsize
4: Tant que f (s) > 0 et que iter < itermax faire
5:
Génération de neighbcount voisins si de s
(tels que le mouvement s → si 6∈ T )
∗
6:
s ← choisir le meilleur des si
(au sens de la valeur de la fonction objectif en s∗ )
7:
Ajouter s∗ → s à T (en enlevant la plus vieille valeur de T si T est pleine)
8:
s ← s∗
9:
iter ← iter + 1
10: fin Tant que
11: Retourner s
CHAPITRE 2. La recherche par espaces variables
27
PartialCol, algorithme de recherche dans S2
Cet algorithme, proposé par Bloechliger et Zufferey [17], a pour but de minimiser la fonction objectif qui représente la taille de l’ensemble Vk+1 des noeuds
non-coloriés. A chaque itération, il génère tous les voisins v de la solution courante s et évalue la taille de Vk+1 (notée L) pour chaque v et il choisit d’effectuer
le mouvement qui mène à la taille la plus petite si ce mouvement n’est pas tabou
ou que cette valeur est plus petite que la valeur optimale L∗ (obtenue avec la solution s∗ ) rencontrée jusque là. Si plusieurs mouvements mènent à la même valeur,
un choix aléatoire est effectué.
Pour rappel les voisins d’une solution s sont toutes les colorations que l’on
peut obtenir en appliquant un i-swap. Il s’agit de déplacer un noeud v de la classe
Vk+1 à une classe Vi (1 ≤ i ≤ k) mais également déplacer tous les sommets
adjacents à v de la classe Vi à la classe Vk+1 pour ne pas créer de conflit. Un tel
déplacement sera noté v ,→ Vi . L’algorithme 3 relate le fonctionnement de cet
algorithme de recherche en pseudo-code.
CHAPITRE 2. La recherche par espaces variables
28
Algorithme 3 PartialCol
Entrée :
– un graphe G = (V, E),
– un entier k représentant le nombre de couleurs,
– tabsize la taille de la liste tabou,
– itermax le nombre maximal d’itérations.
Sortie : une k-coloration de G tentant minimiser le nombre de noeuds noncoloriés.
1: Génération d’une solution initiale s.
2: iter ← 0
3: L∗ ← +∞
4: T ← nouvelle liste de taille tabsize
5: Tant que Vk+1 6= ∅ et que iter < itermax faire
6:
/* (Génération de tous les mouvements possibles) */
7:
M ← {(v ,→ Vl ) | v ∈ Vk+1 , 1 ≤ l ≤ k}
8:
Enlever de M les mouvements tabous qui ne mènent pas à une nouvelle
meilleure solution.
9:
Choisir le meilleur mouvement (u ,→ Vl ) ∈ M .
10:
Appliquer le mouvement (u ,→ Vl ) à s.
11:
/* (Tous les noeuds de la classe où on place u et qui lui sont adjacents sont
déplacés dans la classe Vk+1 , on ajoute alors tous les mouvements visant à
les renvoyer dans cette classe dans la liste tabou.) */
12:
Pour tout sommet w ∈ Vl adjacent à u faire
13:
Ajouter le mouvement (w ,→ Vl ) à T .
14:
fin Pour
15:
iter ← iter + 1
16:
Si |Vk+1 | < L∗ alors
17:
s∗ ← s
18:
L∗ ← |Vk+1 |
19:
iter ← 0
20:
fin Si
21: fin Tant que
22: Retourner s∗
Algorithme de recherche dans S3
Cet algorithme, appelé S3Search, a été proposé par Hertz, Plumettaz et
Zufferey [3]. Assez simple, l’algorithme consiste à générer des voisins de la solution initiale jusqu’à ce qu’un certain nombre d’arêtes MA aient été inversées. Le
but de cet algorithme n’est pas d’améliorer la solution mais surtout de la modifier un maximum, de la diversifier afin de s’extirper plus facilement des optimaux
locaux dans les autres espaces de solution.
CHAPITRE 2. La recherche par espaces variables
29
Algorithme 4 S3Search
Entrée :
– s3init , la solution initiale
– un entier λ représentant la longueur d’un plus long chemin,
– MA le nombre d’arêtes minimum à inverser.
Sortie : un graphe orienté essayant de minimiser la longueur d’un plus long chemin
1: inversed ← 0
2: Tant que inversed < MA faire
3:
s3init ← générer aléatoirement un voisin de s3init
4:
mettre à jour la variable inversed
5: fin Tant que
2.6
Algorithme VSS pour la k-coloration
Maintenant que toutes les étapes sont clairement posées et définies, il est
temps d’énoncer l’algorithme principal qui est utilisé pour ce problème. Cela sert
en quelque sorte de résumé pour la section et permet de bien fixer le fonctionnement de l’heuristique. Les auteurs proposent l’ordre S1 → S3 → S2 → S1 → ...
sur base de quelques expérimentations faits par leur soin. Ils proposent également
un pré-traitement avant d’appliquer le traducteur T13 ainsi qu’un post-traitement
après l’application de l’algorithme de recherche locale dans S3 , S3Search. Cette
section développe donc d’abord ces deux étapes supplémentaires et finit par énoncer l’algorithme au complet.
Pré-traitement
Soit sT C la solution donnée par l’algorithme TabuCol pour le graphe G.
Soit G0 le graphe obtenu à partir de G en enlevant toutes les arêtes conflictuelles
de la coloration spécifiée par sT C . La solution sresult , construite en appliquant
la coloration spécifiée par sT C au graphe G0 , est donc une coloration partielle
légale. Soit la solution s3init = T13 (sresult ), une dernière étape visant à modifier
cette solution est à appliquer, l’algorithme S3Search sera ensuite appliqué à cette
solution.
Cette modification consiste à, pour chaque arête conflictuelle Aconf de sT C :
– choisir aléatoirement une extrémité v de Aconf ,
– inverser l’orientation de toutes les arêtes orientées dont la tête est v ou
dont la queue est v dans G0λ , le choix étant aléatoire et identique pour
chaque arête considérée.
s3init est alors passé à l’algorithme S3Search. L’exemple ci-dessous permet de bien
comprendre le pré-traitement.
CHAPITRE 2. La recherche par espaces variables
30
Exemple 2.6.1. Dans cet exemple, l’hypothèse faite est que l’algorithme sélectionne à chaque fois l’extrémité d’indice inférieur (lors du choix aléatoire) sauf
dans le cas de 4 et 8 où il sélectionne 8. Il considére également toutes les queues
(lors du choix aléatoire entre têtes et queues).
Voici G,
1
2
3
4
5
6
7
8
F IGURE 2.14 – Graphe G initial
ST C a été calculée comme suit :
1
2
3
4
5
6
7
8
F IGURE 2.15 – Solution sT C
Dès lors, G0 est construit en enlevant de G les arêtes conflictuelles présentes
dans sT C :
1
2
3
4
5
6
7
8
F IGURE 2.16 – Graphe G0
sresult , la solution construite en appliquant la coloration définie par sT C à
G0 est donc comme suit :
1
2
3
4
5
6
7
F IGURE 2.17 – La solution sresult
8
CHAPITRE 2. La recherche par espaces variables
31
→
−
Après application de T13 , on obtient s3init ou autrement dit G 0 :
1
2
3
4
5
6
7
8
F IGURE 2.18 – La solution s3init
En supprimant toutes les arêtes n’étant pas sur un plus long chemin, dans le
→
−
but de construire G 0λ , on obtient exactement le même graphe, λ = 2.
Ensuite, pour chaque arête conflictuelle le pré-traitement sélectionne une
extrêmité v au hasard et inverse l’orientation dans G0 de toutes les arêtes
orientées u → v dans G0λ . On obtient alors le graphe suivant :
1
2
3
4
5
6
7
8
F IGURE 2.19 – La solution s3init modifiée
On obtient donc finalement s3init telle qu’elle sera passée à l’algorithme S3Search.
Post-traitement
L’application de S3Search sur s3init donne la solution sOR . Pour rappel, cette
solution concerne un sous-graphe du graphe initial, il faut donc transformer ce
sous-graphe en graphe compatible avec le graphe initial afin de ne pas biaiser
l’algorithme général (VSS). Le post-traitement permet justement d’appliquer cette
transformation. Il consiste à réinjecter séquentiellement les arêtes enlevées lors
du pré-traitement en leur donnant l’orientation qui minimise f3 , c’est-à-dire la
longueur du plus long chemin en terme de noeuds (aucun ordre n’est spécifié pour
traiter les arêtes).
Exemple 2.6.2. Même exemple que précédemment, en supposant que S3Search
n’a pas modifié la solution initiale. Dans cet exemple, les arêtes sont traitées dans
l’ordre (1, 5), (2, 6), (3, 7), (4, 8) ; dans ce cas-ci l’ordre n’est pas important mais
il pourrait l’être. En effet, il suffit par exemple, qu’une arête ajoutée à l’étape
d’avant ajoute un nouveau chemin de longueur égale à λ et que ce nouveau chemin puisse être étendu par l’arête que l’algorithme doit considérer à présent.
CHAPITRE 2. La recherche par espaces variables
32
Ajout en premier lieu de 5 → 1 car elle n’augmente pas λ alors que 1 → 5
augmente λ de 2.
1
2
3
4
5
6
7
8
F IGURE 2.20 – sOR après l’ajout de 5 → 1
Ajout ensuite de 2 → 6,
1
2
3
4
5
6
7
8
F IGURE 2.21 – sOR après l’ajout de 2 → 6
puis de 7 → 3,
1
2
3
4
5
6
7
8
F IGURE 2.22 – sOR après l’ajout de 7 → 3
et finalement de 4 → 8.
1
2
3
4
5
6
7
8
F IGURE 2.23 – sOR après l’ajout de 4 → 8
CHAPITRE 2. La recherche par espaces variables
33
Formulation de l’algorithme
A présent, voici une formulation en pseudo-code de l’algorithme au complet, permettant de clore cette section et ce chapitre en résumant briévement chaque
étape de l’algorithme et son fonctionnement global.
Algorithme 5 VSSColoration
Entrée :
– un graphe G = (V, E),
– un entier k représentant le nombre de couleurs,
– TM AX le temps maximal d’exécution,
– MA un paramètre pour l’algorithme de recherche dans S3 ,
– itermaxtabucol le nombre maximal d’itérations consécutives sans amélioration de TabuCol,
– itermaxpartcol le nombre maximal d’itérations consécutives sans amélioration de PartialCol.
Sortie : une k-coloration légale de G (dans la plupart des cas)
1: Génération d’une solution aléatoire initiale s1init ∈ S1
2: Tant que l’on n’a pas trouvé de k-coloration légale et que TM AX n’est pas
atteint faire
3:
sT C ← TabuCol(s1init ,itermaxtabucol )
4:
s3init ← Pré-traitement avec sT C
5:
sOR ← S3Search(s3init , MA )
6:
Post-traitement de sOR
7:
s2init ← T32 (sOR )
8:
sP C ← PartialCol(s2init ,itermaxpartcol )
9:
s1init ← T21 (sP C )
10: fin Tant que
11: Retourner s
Pour trouver le nombre chromatique du graphe, il convient d’appeler cet
algorithme en commençant avec une borne supérieure de χ(G) et de continuer
à l’appeler tant qu’une k-coloration légale est trouvée. Pour rappel, le choix de
l’ordre des espaces a été défini par les auteurs de l’article, après expérimentations
ils se sont rendu compte que cet ordre était un bon choix.
34
Chapitre 3
Une application du VSS
Toute la théorie a été posée, il ne reste plus qu’à vérifier tout ce qui a été
expliqué en appliquant le tout pour en faire un programme. Le langage choisi est le
JAVA afin de pouvoir bénéficier de l’orienté objet, pour faciliter la prise en charge
et la compréhension du projet (et du code) ainsi que de la portabilité de ce langage.
Le but ici n’est pas de concurrencer en terme de temps de calcul avec les auteurs
mais bien de reproduire des résultats similaires et vérifier la qualité des solutions.
Ce chapitre s’articule en quatre points principaux représentés par les différentes
sections : la modélisation, l’implémentation, les résultats obtenus et les difficultés
éprouvées.
3.1
Modélisation
Il s’agit ici de présenter l’organisation des classes JAVA utilisées afin de
donner une vue globale du fonctionnement du programme.
3.1.1
Structures
La première partie de l’implémentation, qui conditionne toute la suite du
projet, concerne les structures de données employées. En effet, les algorithmes
développés ci-haut manipulent et modifient des graphes et ces derniers peuvent
être implémentés de plusieurs manières. Le choix fait ici est d’abstraire le tout
par une interface Graph qui reprend toutes les méthodes que l’on pourrait appeler sur un graphe telles que connaître les successeurs d’un sommet ou encore le
nombre de sommets du graphe. Il est cependant nécessaire de pouvoir faire la différence entre un graphe orienté et un graphe non-orienté, c’est pour cela que les
classes abstraites DirectedGraph et UndirectedGraph qui implémentent l’interface Graph sont employées. Pour présenter simplement l’architecture de ces
classes dédiées aux structures de données, la Figure 3.1 contient un diagramme
de classe UML schématisant les relations entre ces classes. Il est à savoir, pour
CHAPITRE 3. Une application du VSS
35
comprendre le diagramme, qu’un sommet est représenté par un nombre entier et
qu’il en va de même pour une couleur.
Visual Paradigm for UML Standard Edition(University of Mons)
F IGURE 3.1 – Diagramme de classes des structures de données
Cette manière de modéliser permet d’abstraire totalement la manière dont
les sommets sont stockés par le graphe, le fait de comparer lesquelles des listes
ou des matrices d’adjacence sont les plus appropriées au problème pourrait être
un résultat intéressant. Il est également envisageable d’ajouter un autre type de
structure, en créant une classe de graphes l’utilisant et en la plaçant simplement
comme sous-classe des classes UndirectedGraph ou DirectedGraph selon le
type du graphe. De manière similaire, il est possible d’ajouter un type de graphes
différent (par exemple des graphes pondérés) en plaçant la classe créée comme
sous-classe de AbstractGraph.
Mis à part les graphes, il y a également des structures de données utilisées
pour les listes tabous et les élements que ces listes contiennent. De manière claire
et simplifiée il s’agit d’une liste capable de contenir à la fois des Configuration
ainsi que des “groupes” de Configuration symbolisés par la classe Configurations.
CHAPITRE 3. Une application du VSS
36
Visual Paradigm for UML Standard Edition(University of Mons)
F IGURE 3.2 – Diagramme de classes des structures tabous
3.1.2
Heuristique
Il convient de modéliser les trois espaces de solution et une solution de la
meilleure manière possible. Il y a essentiellement deux façons :
– soit une solution est une classe générale indépendamment de l’espace
auquel elle appartient et chaque espace de solutions est représenté par
une classe qui permet, entre autres de tester qu’une solution appartient
bien à l’espace,
– soit une solution d’un espace est représenté par une classe, chaque espace
de solutions aura donc son propre type de solutions représenté par une
classe (une classe pour l’espace S1 , une autre pour S2 et idem pour S3 ).
Vu que l’algorithme est amené à passer d’une solution d’un espace à une solution
d’un autre et que ces solutions ne sont pas toujours de la même forme (par exemple
une solution dans S1 est une coloration d’un graphe non-orienté, dans S3 c’est
une orientation de ce même graphe), le choix se porte sur la seconde solution.
L’interface Solution régit les solutions. En effet, une solution doit absolument
permettre de récupérer sa valeur pour la fonction objectif. Il y a donc les classes
S1Solution, S2Solution et S3Solution héritant de la classe Solution. La figure
3.3 contient un diagramme de classe UML schématisant les relations entre ces
classes.
Il convient ensuite d’implémenter les traducteurs et les algorithmes de recherche (locale et le VSS). De manière assez simple, une classe abstraite regroupe
les différents traducteurs sous forme de méthodes statiques tandis que chaque algorithme de recherche est représenté par sa propre classe (avec un héritage tout
de même au travers une classe mère LocalSearch ainsi qu’une classe TabuAlgorithm pour généraliser les deux algorithmes tabous). Plus de détails sont fournis
dans le diagramme UML correspondant dans la figure 3.4.
CHAPITRE 3. Une application du VSS
Visual Paradigm for UML Standard Edition(University of Mons)
F IGURE 3.3 – Diagramme de classes des solutions
Visual Paradigm for UML Standard Edition(University of Mons)
F IGURE 3.4 – Diagramme de classes des algorithmes
37
CHAPITRE 3. Une application du VSS
3.2
38
Implémentation
Cette section décrit quelques aspects techniques ayant fait l’objet d’un choix
lors de l’accomplissement du projet. Elle se divise en plusieurs sous-sections
concernant chacune un aspect différent du projet.
3.2.1
Structures de données & représentation
Représentation
Au niveau de la représentation, comme il est précisé plus haut, le premier
choix (bien que simple et évident) effectué est de représenter un sommet par un
nombre entier ; aucune information spéciale, à part la couleur, n’étant nécessaire.
Cette couleur est préférablement stockée dans un tableau d’entiers dédié à cet
effet.
Structures de données pour les graphes
Concernant les structures de données utilisées, il est à remarquer que, pour
gagner de l’espace mémoire, les graphes non-orientés (que ce soit avec listes ou
matrices) ne tiennent trace que des arêtes (i, j) avec i < j (vu que cela implique
l’existence de (j, i) et que les graphes non-orientés simples ne contiennent pas de
boucles).
Dès lors, la matrice d’adjacence M , telle que stockée par le programme, est de la
forme (pour n sommets) :


M1,2 M1,3 ... M1,n−1
M1,n

M2,3 ... M2,n−1
M2,n 




..
..
..
M =

.
.
.



Mn−2,n−1 Mn−2,n 
Mn−1,n
Ceci peut se traduire globalement en JAVA de deux manières différentes : un tableau 2-dimensionnel de taille n − 1 (pas de "ligne" pour le n-ème noeud) comprenant des lignes de plus en plus petites (la seconde taille du tableau étant donc
variable) ou un tableau unidimensionnel contenant toutes les lignes de la matrice
l’une après l’autre. (En ce qui concerne les listes, intuitivement, la case i du tableau contenant les listes d’adjacence abrite une liste qui ne contient que des éléments j > i.)
Que ce soit un tableau à 2 dimensions ou à une 1 seule dimension (appelé
vecteur), il a fallu prendre en compte le fait que ces structures ne sont pas complètes dans les méthodes parcourant les sommets pour ne pas dépasser les tailles
des tableaux/vecteurs stockés. Ainsi, par exemple, la méthode vérifiant si i est
successeur de j va en fait rechercher si l’arête (min (i, j), max (i, j)) existe.
CHAPITRE 3. Une application du VSS
39
Ensuite, selon le stockage (les 2 manières ont été implémentées), il y a d’autres
modifications d’indices à appliquer :
stockage par tableaux




{M
,
M
,
...,
M
,
M
},
1,2
1,3
1,n−1
1,n




 {M2,3 , ..., M2,n−1 , M2,n },

int[][] M =
;
..


.




 {M

n−1,n }
F IGURE 3.5 – Stokage par tableau 2-dimensionnel
Lors de la recherche de l’existence de l’arête (min (i, j), max (i, j)), il
faut savoir que la case [min (i, j) − 1][max (i, j) − 1] de la matrice peut
ne pas exister (pour rappel, un tableau en JAVA est numéroté à partir de
0). Prenons par exemple la recherche de l’existence de l’arête (n, n − 2),
il faut donc accéder à Mn−2,n , mais la matrice en JAVA ne contient que
deux éléments en M [n − 3], il faut donc, en fait, accéder à M [n − 3][1].
Plus généralement, pour connaître l’existence d’une arête (i, j) il faut
consulter la case M [min (i, j) − 1, (max (i, j) − min (i, j)) − 1].
stockage par vecteur
P
Le vecteur a besoin de (n − 1) + (n − 2) + (n − 3) + ... + 1 + 0 = n−1
i=0 i,
n(n − 1)
composantes. Il ressemble donc à ceci :
soit
2
(M1,2 , M1,3 , . . . M1,n , M2,3 , . . . M2,n , . . . Mn−1,n )
Pour une arête (i, j) donnée, comme dit précédemment, il faut en fait
chercher l’arête (i∗ , j ∗ ) où i∗ = min (i, j) et j ∗ = max (i, j). Ensuite,
pour trouver cette arête, il faut chercher dans le vecteur l’endroit correspondant à la bonne ligne de la matrice et ensuite atteindre la bonne
colonne. Pour ce faire, l’indice à atteindre est donné par :
∗ ∗
i (i + 1)
∗
i n−
+ j ∗ − (i∗ + 1)
2
(la première partie (entre [ ]) spécifie l’indice du premier élément de la
ligne i∗ de la matrice tandis que la seconde partie spécifie l’indice de la
colonne j ∗ pour la ligne i∗ )
Remarque 3.2.1. Les 2 stockages sont identiques en terme de complexité, tant
au niveau espace qu’au niveau temps. Le choix entre ces 2 stockages est donc
totalement arbitraire et est laissé aléatoire dans l’implémentation du projet. Le
stockage en vecteur est peut-être un peu préféré pour des raisons d’habitude de
programmation en C.
CHAPITRE 3. Une application du VSS
40
Structures de données pour les listes
Les listes étant utilisées un peu partout dans ce projet (liste de successeurs,
liste de prédécesseurs, liste de sommets appartenant à une même classe de couleur, ...), il est important que ces listes fournissent des opérations rapides pour la
recherche, l’ajout et la suppression d’éléments. Les listes sont donc triées par ordre
croissant permettant ainsi une recherche plus rapide (et donc une suppression plus
rapide) et sont doublement chaînées. Elles conservent en outre trois références de
manière permanente :
– la queue de la liste,
– la tête de la liste,
– le centre de la liste.
Cette dernière, assez inhabituelle peut permettre dans le meilleur des cas
de diviser la complexité par 2. En effet, lors de la recherche d’un élément, l’algorithme va l’utiliser pour commencer sa recherche au milieu de la liste dans certains
cas plutôt qu’au début ou à la fin. Voici comment l’algorithme fonctionne :
Algorithme 6 SearchSortedList
Entrée :
– L une liste triée,
– un entier k ≥ 0 à rechercher dans L.
Sortie : vrai si k ∈ L, faux sinon.
1: begin ← arg mini∈{center,f irst,last} |i.data − k|
2: current ← begin
3: Si current.data = k alors
4:
Retourner Vrai
5: Sinon Si current.data < k alors
6:
Tant que current.data < k faire
7:
current ← current.next
8:
fin Tant que
9: Sinon
10:
Tant que current.data > k faire
11:
current ← current.prev
12:
fin Tant que
13: fin Si
14: Retourner current.data = k
La référence vers le centre n’est pas toujours utile, en effet, dans certains cas
l’élément se trouve à côté d’une des références stockées mais l’algorithme débute
tout de même sa recherche à partir d’une autre référence (c’est en fait le pire des
cas). Pour s’en convaincre, il suffit de considérer la liste suivante dans laquelle
l’algorithme recherche 42 :
1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 42 → 500
CHAPITRE 3. Une application du VSS
41
Dans cet exemple, f irst = 1, last = 500 et center = 7.
Lors du calcul de l’arg min, les trois valeurs calulées sont :
– pour first : |1 − 42| = 41
– pour center : |7 − 42| = 35
– pour last : |500 − 42| = 458
La recherche va donc débuter à partir de center alors qu’elle devrait commencer à
partir de last.
De manière assez rapide et intuitive, l’intérêt de la référence center existe
lorsque les données “ne sont pas trop éloignées les unes des autres”. Lorsque les
données ne respectent pas cette condition (comme l’exemple précédent), il s’agit
du pire des cas de l’algorithme : la recherche, l’ajout et la suppression se font en
O( n2 ) (avec n la taille de la liste). En effet, l’algorithme ne parcourera que la partie
de la liste située entre center et last. Dans le cas où la condition est respectée, et
donc le meilleur des cas, la complexité est de O( n4 ) (vu que la donnée est proche
du départ choisi, elle ne peut être plus loin de ce départ que la moitié du chemin
entre lui et l’autre borne délimitant l’intervalle).
Au final, l’algorithme est donc en O( n2 ).
Ce n’est cependant pas la meilleure approche, une table de hashage ou un
tableau unidimensionnel de la taille du nombre de noeuds contenant des booléens
(vrai si l’élément indicé est contenu, faux sinon) mais une telle représentation pour
les listes d’adjacences revient au final à utiliser une matrice d’adjacence.
Structures de données pour la liste tabou
Cette structure est un peu particulière car il s’agit d’une liste circulaire. Pour
implémenter cela, il n’y a nul besoin que la liste soit réellement circulaire. Il suffit
en fait d’une liste chainée (doublement dans le cas de ce projet, via la classe LinkedList de JAVA) dans laquelle on ajoute tout élément à la fin de la liste et, lorsque
la capacité fixée est atteinte, la tête de la liste est supprimée. Cette structure, dans
le cadre de ce projet, possède une autre particularité. En effet, elle contient des
“TabuElement” qui sont simplement des éléments implémentant une interface permettant de définir n’importe quel type d’élément tabou pourvu que cet élément soit
doté d’un nombre d’itérations (tenure) pendant lesquelles il est considéré tabou.
Dans le cadre de ce projet, deux éléments forts semblables ont été implémentés ; il
s’agit de “Configuration” qui est simplement une configuration à éviter (typiquement un couple sommet-couleur) et “Configurations” qui représente un ensemble
de configurations de même tenure à éviter. La particularité des “Configurations”
est qu’il est possible d’ajouter plus d’éléments que la capacité de la liste vu qu’un
ensemble de configuration ne prend qu’une seule place dans la liste tabou. La
présence de ces deux éléments différents se justifient par les deux algorithmes utilisant ces listes tabous, TabuCol n’ajoute qu’un seul élément à la fois tandis que
PartialCol ajoute en général un groupe d’éléments à la liste.
CHAPITRE 3. Une application du VSS
3.2.2
42
Algorithmique
Cette section est destinée à expliquer l’implémentation de certains algorithmes évolués permettant de calculer certaines valeurs (ou autres) utilisées par
l’heuristique.
Calcul de longueur de chemins dans S3
Le premier algorithme envisagé était une fermeture transitive adaptée, algorithme donc en O(n3 ). Après réflexion, un algorithme récursif moins gourmand
a été trouvé (O(m) avec m le nombre d’arêtes, et donc O(n2 ) dans le pire des
cas). Il a été implémenté dans la classe S3Solution via les méthodes computeLongestPaths et longestPathTo. Le comportement de ces dernières est donné par les
algorithmes 7 et 8. Le fonctionnement de cet algorithme est assez simple en soi,
il se base sur la récursion suivante :
1 si i n’a aucun prédecesseur,
longestP aths[i] =
(maxv prédecesseur de i longestP aths[v]) + 1
L’algorithme commence par n’importe quel sommet (le sommet 0 ici) et
remonte les arêtes orientées jusqu’à un noeud sans prédécesseurs (il y en a forcément au moins un pour chaque chemin exploré sinon il y a un cycle dans le graphe)
en explorant toutes les possibilités afin de remplir le tableau longestP aths. Une
amélioration serait possible en démarrant l’algorithme du sommet de plus grand
degré incident (et donc le plus grand nombre de prédécesseurs) ou même d’un
sommet n’ayant pas de successeurs.
L’algorithme marque les noeuds par lesquels il est déjà passé auparavant, ceci
permet de ne pas calculer plusieurs fois les mêmes valeurs mais également de détecter un éventuel cycle dans le graphe. Lorsqu’il n’y a pas de cycle, un noeud
déjà marqué doit avoir une longueur de plus long chemin supérieure ou égale à
1 (vu qu’il y a au moins le chemin ne contenant que le noeud lui-même), si l’algorithme tombe sur un noeud déjà marqué (et donc déjà visité) dont la longueur
du plus long chemin est 0 cela signifie qu’il reconsidère un noeud pour lequel la
récursion n’a pas été terminée et donc qu’il y a un cycle dans le graphe.
Cet algorithme est lancé pour chaque noeud non-marqué du graphe (et donc lors
d’une éxécution, si aucun des chemins générés ne passent par un des noeuds du
graphe, l’algorithme relance une exploration à partir de ce noeud). Il parcourt donc
toutes les arêtes orientées du graphe une seule fois, ce qui lui vaut sa complexité
en O(n2 ) où n est le nombre de noeuds du graphe (pour rappel le nombre d’arêtes
d’un graphe m = O(n2 )).
CHAPITRE 3. Une application du VSS
Algorithme 7 LongestPathTo
Entrée :
– node, le noeud vers lequel le chemin doit aller,
– mark, le tableau de marquage des noeuds déjà visités,
– longestP aths, le tableau des plus longs chemins connus jusque là.
Sortie : la longueur du plus long chemin allant jusque node
1: Si mark[node] alors
2:
Si longestP aths[node] = 0 alors
3:
longestP aths[node] = +∞
4:
fin Si
5:
Retourner longestP aths[node]
6: Sinon
7:
mark[node] ← Vrai
8:
max ← 1 // le chemin ne contenant que le noeud lui-même
9:
Pour tous les prédécesseurs p de node faire
10:
longestP aths[p] ← LongestPathTo(p, mark, longestP ath)
11:
Si longestP aths[p] = +∞ alors
12:
Retourner +∞
13:
fin Si
14:
Si max < longestP aths[elem] + 1 alors
15:
max ← longestP aths[elem] + 1
16:
fin Si
17:
fin Pour
18:
longestP aths[node] ← max
19:
Retourner max
20: fin Si
43
CHAPITRE 3. Une application du VSS
44
Algorithme 8 ComputeLongestPaths
Entrée : G, un graphe orienté de n sommets.
1: lambda ← −1
2: mark ← nouveau tableau de n booléens initialisés à Faux
3: longestP aths ← nouveau tableau de n entiers initialisés à 0
4: Pour i allant de 0 à n − 1 faire
5:
Si Non mark[i] alors
6:
LongestPathTo(i, mark, longestP aths)
7:
fin Si
8:
Si longestP aths[i] > lambda alors
9:
lambda ← longestP aths[i]
10:
fin Si
11:
Si lambda = +∞ alors
12:
Le graphe est cyclique !
13:
fin Si
14: fin Pour
Les algorithmes tabous
Ces deux algorithmes (PartialCol et TabuCol) sont caractérisés par le fait
qu’il y a beaucoup d’itérations et que chacune d’entre elles consiste en la génération de voisins. Il est donc primordial que ces algorithmes soient optimaux et donc
que cette génération le soit également. De manière claire, en lisant les algorithmes,
il est facile de constater que, pour un certain noeud v, le nombre de voisins de v
de la même couleur que lui est une valeur souvent calculée. Pour ne pas parcourir
les voisins de chaque noeud dont cette valeur est désirée ou tous les noeuds d’une
classe de couleur, les algorithmes utilisent la programmation dynamique comme
suggéré dans [17]. La matrice γ(k × n) (avec k le nombre de couleurs utilisées
actuellement et n le nombre de noeuds) est donc définie comme suit :
γkn = nombre de voisins de n de couleur k
l’accès à ces valeurs n’est donc plus en O(nombre de voisins de n) mais en O(1).
Pour que cela reste en O(1), il convient de conserver cette matrice à jour lors des
différentes opérations de voisinages.
Lors des opérations de voisinages, deux modifications impliquent la matrice γ :
– colorer un noeud non coloré j par la couleur k, et d’incrémenter les
cases γkw , ∀w adjacent à j,
– enlever la couleur d’un noeud j qui était coloré par k, il convient donc
de décrémenter les cases γkw , ∀w adjacent à j.
CHAPITRE 3. Une application du VSS
45
De cette façon, ces algorithmes peuvent avoir une complexité beaucoup plus attrayante que précédemment bien qu’une opération de mise à jour soit nécessaire
lorsqu’un voisin est choisi et que l’on modifie la solution courante vers ce voisin.
Cela permet tout de même de générer (plutôt “simuler la génération”) des voisins
de manière assez rapide.
3.3
Résultats
Le but de ce projet était de lire, de comprendre et de reproduire l’expérience
menée par les auteurs de l’article sur la recherche par espaces variables appliquée
à la coloration de graphes. Jusque maintenant, le présent rapport s’est efforcé de
montrer que la lecture a bel et bien été faite et que la compréhension est totale. Il
a également montré comment l’expérience allait être reproduite, c’est-à-dire comment l’heuristique allait être implémentée en JAVA. A présent, la présente section
confronte les résultats obtenus par les auteurs à ceux obtenus par ce projet. Il est
évident que la différence de temps d’exécution et de résultats pourra être conséquente car elle dépend du langage utilisé, de la machine utilisée, du nombre de
personnes ayant collaborés pour le projet et de beaucoup d’autres facteurs.
Les résultats qu’ils ont reportés pour leur application en C++ ont été obtenus sur
un Pentium 4 de 2Ghz avec 512 MB de RAM. Pour l’application développée dans
le cadre de ce projet en JAVA, les résultats ont été obtenus sur un Intel core i3
2, 27Ghz avec 4 GB de RAM (pour information, l’application n’est pas multithreadée).
La première constatation est que l’algorithme développé semble fonctionner
en ce sens que sur n’importe quelle instance l’algorithme se rapproche de l’optimum (lentement parfois, mais tout de même) ce qui signifie que l’algorithme fonctionne réellement. Il s’agissait de l’un des aboutissants des projets qui est pleinement rempli : reproduire l’expérience. Cependant, force est de constater que les
performances divergent fortement. Il faut cependant bien se rendre compte que
l’application qu’ils ont développée doit avoir subi énormément d’améliorations
jusqu’au plus petit détail afin d’être la plus rapide possible alors que dans le cas
de l’application développée dans ce projet, la programmation objet était mise en
avant, en utilisant au maximum les mécanismes de polymorphisme.
Les tests sont effectués sur des instances choisies par les auteurs dans les
graphes de DIMACS challenge [26] avec les mêmes paramètres pour l’algorithme
que ceux qu’ils ont utilisés. Ces graphes sont réputés pour avoir un nombre chromatique difficile (voir les plus difficiles) à calculer. Pour l’expérience, vu la lenteur
relative de l’application en JAVA, les graphes sélectionnés seront des graphes dont
le nombre de noeuds n ne dépasse pas 500. Voici une première table reprenant les
résultats obtenus sans considérer les temps d’exécution. Elle se présente comme
suit :
CHAPITRE 3. Une application du VSS
46
– la première colonne reprend le nom du fichier considéré,
– la seconde colonne reprend la densité du graphe, cette valeur représente
la quantité d’arêtes existantes par rapport aux noeuds, il s’agit en fait du
quotient
du nombre
d’arêtes par le nombre de noeuds au carré
|E|
density = |V |2 ,
– la troisième colonne contient la meilleure borne connue suivi du nombre
chromatique (“ ?” s’il n’est pas connu),
– la quatrième colonne contient la meilleure borne trouvée à chaque run
(c’est-à-dire qu’à chaque lancement avec cette valeur de k, l’algorithme
trouve une k-coloration) par les auteurs,
– la cinquième colonne contient la meilleure borne trouvée à chaque run
pour l’application JAVA développée dans ce projet, il est à savoir que
pour les résultats de la quatrième ainsi que de la cinquième colonne, le
temps limite accordé à l’application est d’1 heure ;
– finalement, la dernière colonne montre l’écart entre les valeurs obtenues.
Graphe G
DSJC500.1
DSJC500.5
DSJC500.9
DSJR500.1c
DSJR500.5
flat300_28_0
le450_15c
le450_15d
le450_25c
le450_25d
∗
∗
density(G) k ∗ , χ kauthors
kJAV
A
0.1
12, ?
12
13
0.5
48, ?
49
53
0.9 126, ?
127
140
0.97
85, ?
86
99
0.47 126, ?
127
138
0.48 28, 28
31
33
0.165 15, 15
15
17
0.165 15, 15
15
17
0.17 25, 25
26
28
0.17 25, 25
26
28
∗
∗
|kJAV
A − kauthors |
1
4
13
13
11
2
2
2
2
2
La première constatation est que, dans aucun cas, l’application développée,
ici, n’est capable d’obtenir les mêmes résultats que l’application initiale (tout du
moins, en moins d’une heure). La seconde est que l’efficacité de l’algorithme est
directement liée à la densité du graphe. La raison à cela est que l’algorithme considère à plusieurs reprises les arêtes du graphe et donc, plus le graphe en possède
moins l’algorithme est rapide et efficace.
Les graphiques en figure 3.6 portent ces données par famille de graphe afin
de vérifier que les deux applications suivent les mêmes courbes d’évolution. Suivant ces graphes, les auteurs sont très proches de l’optimum trouvé jusqu’à présent
tandis que l’application développée dans le cadre de ce projet bien que un peu plus
loin en général suit le même genre de courbe.
CHAPITRE 3. Une application du VSS
47
F IGURE 3.6 – Graphiques des résultats
Voici à présent une seconde table comparant les temps d’exécution, le nombre
de cycles et d’itérations nécessaires à l’obtention des solutions. Ces temps ne sont
pas directement comparables car ils ne concernent pas la même valeur de k mais
peuvent être utiles pour dégager un facteur permettant de qualifier la différence de
vitesse d’exécution entre les deux applications et vérifier qu’il est avéré partout. Il
ne faut pas oublier que l’algorithme met en oeuvre quelques décisions aléatoires,
les données reprises ci-dessous sont donc des moyennes obtenues sur 10 runs.
Cette table se présente comme suit :
– la première colonne reprend le nom du fichier considéré,
– les colonnes 2 à 4 sont les données obtenues par les auteurs,
– les colonnes 5 à 7 sont les données obtenues par l’application JAVA,
– finalement, la dernière colonne montre le facteur de différence de temps.
(tous les temps sont exprimés en secondes)
Graphe G
DSJC500.1
DSJC500.5
DSJC500.9
DSJR500.1c
DSJR500.5
flat300_28_0
le450_15c
le450_15d
le450_25c
le450_25d
taut cycleaut
iteraut
97
17 19.799.000
162
82 10.524.000
169
62 7.754.000
291
165 20.020.000
183
60 9.066.000
39
32 4.173.000
6
4
497.000
4
39 4.761.000
1
1
183.000
1
1
117.000
tJ cycleJ
iterJ
146
1 107.625
279
1 134.741
230
1 102.769
195
1 100.824
241
1 152.427
78
1 125.433
133
1 103.332
126
1 101.753
127
1 106.746
118
1 100.630
Facteur
1, 5
1, 7
1, 3
0.67
1, 3
2
22
31
127
118
CHAPITRE 3. Une application du VSS
48
Comme le révèle la table, aucun facteur ne semble se dégager. Ce qui est
à remarquer, c’est que l’application en JAVA n’effectue jamais plus d’un cycle
pour trouver la k-coloration. Ceci est explicable par le fait qu’il faut beaucoup de
cycles pour ne fut-ce que décrémenter la valeur du k par 1 et qu’un cycle est énormément couteux dans le cas de cette application (ce temps dépend de la densité
du graphe et du nombre de noeuds). De plus, de manière non-explicable lors du
premier cycle, les itérations de l’algorithme TabuCol sont plus rapides que par la
suite. En poussant l’analyse, il semblerait que ce soit l’action du garbage collector
de JAVA qui est plus actif par la suite et qui entrave la vitesse du programme.
Lors des différentes exécutions, on remarque également que l’algorithme
arrive très souvent à une valeur de 1, 2 ou 3 pour la meilleure solution obtenue
jusque maintenant mais ne parvient pas à descendre plus bas de manière assez
rapide. On pourrait alors imaginer une manière de sortir de cet optimum local en
appliquant un très grand changement à la solution, encore plus grand que l’algorithme S3Search, ou une manière simple et rapide d’arriver à la solution optimale
afin d’améliorer l’algorithme tout entier.
Les graphiques en figure 3.7 portent ces données par famille de graphe afin
de vérifier que les deux applications suivent les mêmes courbes d’évolution au
niveau du temps d’exécution. Il faut cependant, comme pour les valeurs de la
table bien tenir compte du fait que ces temps sont obtenus pour des valeurs de k
différentes.
F IGURE 3.7 – Graphiques des temps d’exécution
Au niveau des temps d’exécution, les applications sont assez fortement espacées mais elles suivent à nouveau approximativement les mêmes courbes d’évolution.
Les graphes en figure 3.8 permettent de faire la même analyse pour le nombre
CHAPITRE 3. Une application du VSS
49
d’itérations bien qu’un pique pour le450_15d pour les auteurs perturbent leur
courbe d’évolution.
F IGURE 3.8 – Graphiques des nombres d’itérations
Au final, de ces résultats, nous pouvons conclure que cette heuristique fonctionne et, si elle est très bien programmée et optimisée, peut être assez rapide.
Il faut cependant déplorer que, dans certains cas, même les auteurs ne sont pas
parvenus à obtenir le nombre chromatique ni la borne la plus basse connue jusque
maintenant mais cela ne remet pas en cause le fonctionnement global de l’heuristique qui semble être au point.
3.4
Difficultés
Cette section regroupe les différentes difficultés éprouvées lors de la compréhension de la matière ainsi que de l’implémentation de l’heuristique. Elle s’articule, dès lors, autour de ces deux points en explicitant en détails chacune de ces
difficultés.
3.4.1
Compréhension
Les premières difficultés éprouvées peuvent être regroupées en un point, il
s’agit de l’espace de solutions 3. En effet, bien que simple une fois bien compris,
celui-ci peut être difficile à intégrer de prime abord. Cette difficulté vient probablement du fait que cet ensemble nécessite d’introduire beaucoup de théories ne
concernant pas la coloration de graphes et n’étant pas spécialement fortement utilisées en dehors de ce contexte. Certaines définitions peuvent alors être un peu
déroutantes, comme par exemple la définition d’orientation ou encore de chemin
le plus court, cette dernière notion étant particulièrement floue dans l’article. Par
→
−
exemple, lorsque les auteurs décrivent la construction du graphe G λ , ils écrivent
ceci :
CHAPITRE 3. Une application du VSS
“Given a solution G ∈ S
3
50
→
−
, let G λ denote the digraph obtained
by removing all arcs that do not belong to a longest path in G.
”
Il a été, dès lors, assez difficile de savoir s’il fallait choisir un chemin de longueur
maximale ou s’il fallait considérer tous les chemins de ce type. La logique et la
compréhension appliquée dans ce rapport est de les considérer tous.
3.4.2
Implémentation
L’implémentation a donné lieu, elle aussi, à quelques difficultés. Ces dernières sont explicitées dans cette sous-section.
Liste tabou
L’idée des configurations à éviter et des groupes de configurations à éviter
fut assez déroutante à mettre en oeuvre de par les différentes méthodes à implémenter correctement pour que les deux coïncident parfaitement avec l’interface
TabuElement.
Pré et post-traitement
Le pré-traitement et le post-traitement à effectuer entre les transitions de
l’espace 1 à 3 et 3 à 2 furent particulièrement éprouvants. En effet, le pré-traitement
doit inverser certaines arêtes du graphe dans certaines conditions ce qui, lorsqu’une seule des conditions est oubliée, peut créer des graphes cycliques (ce qui
est très problèmatique pour l’espace de recherche S3 ). De manière identique, le
post-traitement ajoute des arêtes au graphe (qui avaient été supprimées avant) dans
le sens minimisant le plus long chemin dans le graphe. Le problème de ceci est
que l’ajout dans un sens peut impliquer un cycle et donc une longueur de plus
long chemin égale à +∞. Ce dernier problème a d’ailleurs motivé la modification
de l’algorithme de calcul des longueurs des plus longs chemins (développé dans
la section 3.2.2) afin d’y incorporer une détection de cycle de manière à obtenir
une valeur infinie plutôt qu’une récursion infinie.
Algorithmes tabous
Les algorithmes tabous que sont TabuCol et PartialCol sont particulièrement difficiles à implémenter. En effet, la moindre petite erreur peut mettre en
cause l’ensemble du programme en ce sens où l’approche de la solution optimale
est totalement chamboulée. Ils furent l’objet de beaucoup d’attention pendant ce
projet afin d’éviter ce cas de figure et ceci ne fut pas de tout repos.
51
Conclusion
La coloration de graphes est un problème N P -complet bien connu et ses
applications sont multiples. En effet, la résolution de ce problème permet, entre
autres, de résoudre un sudoku, de gérer un réseau d’émetteurs/récepteurs, d’effectuer un ordonnancement ou encore de générer des emplois du temps. Ce problème
étant N P -complet, il ne peut être résolu par un algorithme exact en un temps raisonnable, il faut donc faire appel aux métaheuristiques. Celles-ci sont nombreuses
et ont déjà été appliquées avec succès à ce problème, elles sont en majorité basées
sur une population. Dans ce rapport, une métaheuristique à solution unique récente qui utilise différents espaces de recherches, voisinages et fonctions objectifs
a été exposée. Celle-ci, appelée Variable Space Search et développée par Hertz,
Plumettaz et Zufferey [3], a ensuite été appliquée à la coloration de graphes. Cette
métaheuristique un peu atypique met en jeu plusieurs espaces de recherche (trois
pour la coloration) complémentaires afin d’approcher de l’optimum local. Cette
métaheuristique a alors été programmée en JAVA afin d’être testée et permettre
d’en tirer quelques résultats.
Ces résultats, bien qu’assez décevants car assez éloignés de ceux récoltés par
les auteurs de l’article, ont permis de confirmer que la métaheuristique développée
par les trois auteurs fonctionne. De plus, si l’application mettant en oeuvre cette
métaheuristique est optimisée au maximum, elle fait partie des meilleurs algorithmes connus jusque maintenant pour résoudre ce problème N P -complet. Cette
métaheuristique fonctionne particulièrement bien sur les graphes peu denses, elle
pourrait donc être associée à une autre manière de procéder pour les graphes
denses (ou avec d’autres espaces de recherche ou encore d’autres transitions) pour
en tirer son plein potentiel.
52
Bibliographie
[1] Wikipedia. Graph coloring applications, December 2010. http://en.
wikipedia.org/wiki/Graph_coloring#Applications.
[2] Wikipedia.
Un exemple d’application de coloration de graphes,
December
2010.
http://fr.wikipedia.org/wiki/
Coloration_de_graphe#Un_exemple_d.27application_:
_l.27allocation_de_fr.C3.A9quences.
[3] N. Zufferey, M. Plumettaz, A. Hertz.
Variable space search for
graph coloring. Discrete Applied Mathematics, 156 :2551–2560, 2008.
doi :10.1016/j.dam.2008.03.022.
[4] R. Diestel. Graph Theory (4th edition). Springer-Verlag, Heidelberg : Graduate Texts in Mathematics, July 2010. ISBN 978-3-642-14278-9.
[5] Wikipedia. Graph coloring : History, December 2010. http://en.
wikipedia.org/wiki/Graph_coloring#History.
[6] Wolfgang Haken Kenneth Appel. Every Planar Map is Four-Colorable. Providence, RI : American Mathematical Society, 1989. ISBN 0821851039.
[7] G.D. Birkhoff. A determinant formula for the number of ways of coloring a
map. Ann. Math, 14 :42–46, 1912.
[8] W.T. Tutte. Graph Theory. Addison-Wesley, 1984.
[9] M. Chudnovsky, N. Robertson, P.Seymour, R.Thomas. The strong perfect
graph theorem. Annals of Mathematics, 164 :51–229, 2006. doi :10.4007/annals.2006.164.51.
[10] Richard M. Karp. Reducibility among combinatorial problems. Complexity of Computer Computations, pages 85–103, 1972. http://www.
cs.berkeley.edu/~luca/cs172/karp.pdf.
[11] Russel, Jarvis.
Sudoku enumeration problems, December 2010.
http ://www.afjarvis.staff.shef.ac.uk/sudoku/.
[12] V. Kumar. Algorithms for constraint-satisfaction problems : A survey. AI
Magazine, 13 :32–44, 1992.
[13] D.J.A. Welsh, M.B. Powell. An upper bound for the chromatic number of a
graph and its application to timetabling problems. The Computer Journal,
10(1) :85–86, 1967. doi :10.1093/comjnl/10.1.85.
BIBLIOGRAPHIE
53
[14] C. Fleurent, J.A. Ferland. Genetic and hybrid algorithms for graph coloring.
Annals of Operations Research, 63 (3) :437–461, 1996.
[15] P. Galinier, J.K. Hao. Hybrid evolutionary algorithms for graph coloring.
Journal of Combinatorial Optimization, 3 (4) :379–397, 1999.
[16] A. Hertz, D. de Werra. Using tabu search techniques for graph coloring.
Computing, 39 :345–351, 1987.
[17] I. Bloechliger, N. Zufferey. A graph coloring heuristic using partial solutions
and a reactive tabu scheme. Computers & Operations Research, 35 :960–
975, 2008.
[18] N. Zufferey, C. Avanthay, A. Hertz. A variable neighborhood search for
graph coloring. European Journal of Operational Research, 151 :379–388,
2003.
[19] M.Mladenović. Formulation space search — a new approach to optimization
(plenary talk). Vrnjacka Banja, Serbia, 2005.
[20] C. Morgenstern. Distributed coloration neighborhood search. DIMACS Series in Discrete Mathematics and Theoretical Computer Science, 26 :335–
357, 1996.
[21] T. Gallai. On directed paths and circuits. Theory of Graphs, Academic Press,
New York, pages 115–118, 1968.
[22] B. Roy. Nombre chromatique et plus longs chemins d’un graphe. Revue
AFIRO 1, pages 127–132, 1967.
[23] L.M. Vitaver. Determination of minimal coloring of vertices of a graph
means of boolean powers of the incidence matrix. Doklady Akademii Nauk
SSSR147, pages 758–759, 1963.
[24] B. Gendron, A. Hertz, P. St-Louis. On edge orienting methods for graph
coloring. Journal of Combinatioral Optimization, 13 :163–178, 2007.
[25] P. Norvig S. Russel. Artificial Intelligence : A Modern Approach (3rd edition). Pearson, 2010.
[26] Dimacs website. ftp://dimacs.rutgers.edu/pub/challenge/
graph/.
54
Annexe A
Exemple de la Belgique
La Belgique présente une géographie telle que ses provinces peuvent être
coloriées légalement avec seulement trois couleurs, voici les différentes étapes
utilisées dans le raisonnement pour appliquer la coloration de graphes à la coloration de carte. A partir de la carte vierge, le graphe planaire est créé puis colorié et
les résultats trouvés sont transposés à la carte.
F IGURE A.1 – Carte de Belgique non coloriée.
ANNEXE A. Exemple de la Belgique
FlandreOccidentale
FlandreOrientale
55
Anvers
Limbourg
BrabantFlamand
Hainaut
BrabantWallon
Liege
Namur
Luxembourg
F IGURE A.2 – Graphe planaire non colorié.
FlandreOccidentale
FlandreOrientale
Anvers
Limbourg
BrabantFlamand
Hainaut
BrabantWallon
Namur
Luxembourg
F IGURE A.3 – Graphe planaire 3-colorié
F IGURE A.4 – Carte de Belgique 3-coloriée
Liege
56
Annexe B
Améliorations de TabuCol
Deux mécanismes, proposés par les auteurs de l’algorithme, sont utilisés
pour améliorer les performances de cet algorithme : la fonction d’aspiration ainsi
qu’un critère supplémentaire pour stopper la génération de voisins.
Fonction d’aspiration
Cette fonction représente le niveau d’aspiration A(z) de la valeur de la fonction objectif à atteindre lorsque la valeur courante est z = f (s). Plus concrètement, si un mouvement tabou s → s0 est généré mais qu’il est tel que f (s0 ) ≤
A(z), alors le mouvement s → s0 n’est pas considéré tabou pour cette itération. Il
s’agit donc simplement d’un critère permettant d’effectuer un mouvement tabou
car il est peut-être bénéfique. De plus ce critère est mis à jour et est de plus en plus
restrictif, ainsi un mouvement rencontrant le critère d’aspiration à une certaine
itération ne le rencontrera probablement plus par la suite.
La fonction d’aspiration est définie pour toutes les valeurs de z possibles (donc de
0 à une certaine borne supérieure, le nombre de sommets par exemple). On l’initialise comme A(z) = z−1 pour toutes les valeurs de z. Ensuite, lors de la génération
d’un mouvement s → s0 tel que f (s0 ) ≤ A(f (s)), on place A(f (s)) = f (s0 ) − 1.
Critère d’arrêt supplémentaire
Ce critère est assez simple et est appliqué dans la boucle permettant de générer un nombre fixé neighcount de voisins aléatoirement. Dans cette boucle, dès
qu’un mouvement s → s0 tel que f (s0 ) < f (s∗ ) (où s∗ est la meilleure solution trouvée jusque maintenant) est généré, l’algorithme va directement effectuer
le mouvement s → s0 au lieu d’attendre d’avoir généré les neighcount voisins.
Cette amélioration va permettre de diminuer les temps de calcul (moins de voisins
générés) à chaque itération et donc améliorer les performances globales de l’algorithme.
ANNEXE B. Améliorations de TabuCol
57
L’algorithme devient donc :
Algorithme 9 TabuCol
Entrée :
– un graphe G = (V, E),
– un entier k représentant le nombre de couleurs,
– tabsize la taille de la liste tabou,
– neighbcount le nombre de voisins à générer,
– itermax le nombre maximal d’itérations.
Sortie : une k-coloration de G tentant de minimiser le nombre d’arêtes conflictuelles.
1: Génération d’une solution aléatoire initiale s
2: iter ← 0
3: T ← nouvelle liste de taille tabsize
4: Tant que f (s) > 0 et que iter < itermax faire
5:
neighbours ← {}
6:
count ← 0
7:
Tant que count < neighbcount ou que f (si ) < f (s) faire
8:
si ← nouveau voisin généré aléatoirement
9:
aspirationcriteria ← f (si ) ≤ A(f (s))
10:
Si aspirationcriteria ou s → si 6∈ T alors
11:
count ← count + 1
12:
ajouter si à neighbours
13:
Si aspirationcriteria alors
14:
A(f (s)) ← f (si ) − 1
15:
fin Si
16:
fin Si
17:
fin Tant que
18:
s∗ ← choisir le meilleur des si
(au sens de la valeur de la fonction objectif en s∗ )
19:
Ajouter s∗ → s à T (en enlevant la plus vieille valeur de T si T est pleine)
20:
s ← s∗
21:
iter ← iter + 1
22: fin Tant que
23: Retourner s
Téléchargement