Utilisateur:NotARealCat/Brouillon

L'algorithme, appelé ainsi d'après son inventeur, est dû à John Hopcroft[1] et il a été présenté en 1971; l'algorithme est décrit par le pseudo-code suivant :

P := {F, Q \ F};                                             "Partition initiale"
W := l'ensemble vide;                                        "Candidats en attente"
for each a in A do
     ajouter (min(F, Q\F),a) à W;                            "Initialisation de l'ensemble W"
while (W  l'ensemble vide) do
     choisir ensemble (Z,a) dans W et l'enlever de W
     for each X de P coupé par (Z,a) en X' et X'' do         "Calcul de la coupe"
          remplacer X in P par les deux ensembles X' et X''  "Raffinement de la partition"
          for each b in A do                                 "Mise-à-jour de l'ensemble" 
               if (X,b) est in W                             "des candidats en attente"
                    remplacer (X,b) in W par (X',b) et (X'',b)
               else
                    ajouter le plus petit de (X',b) et (X'',b) à W;
          end;
     end;
end;

L'algorithme débute avec la partition la plus grossière, dont les deux classes sont composées des états terminaux et des autres. La partition est progressivement raffinée en un nombre croissant de classes plus petites. Chaque tour de l'algorithme partage des ensembles d'états en deux parties plus petites.

L'opération de base est la coupure (« splitting » en anglais)[2]. Un ensemble d'états est coupé par la paire formée d'un ensemble et d'une lettre si les ensembles

et

sont tous les deux non vides. Dans le cas contraire, on dit que est stable pour .

L'algorithme maintient un ensemble de couples , candidats à couper des éléments de la partition en cours; cet ensemble de candidats en attente est appelé le « waiting set » en anglais.

Le lemme suivant[3] est facile à prouver, mais il est à la base du mécanisme de mise-à-jour du waiting set dans l'algorithme :

Lemme — Soient et deux ensembles d'états, avec et disjoints non vides, et soit une lettre.

  • Si est stable pour et pour , alors est stable pour .
  • Si est stable pour et pour , alors est stable pour .

L'algorithme choisit itérativement un ensemble dans l'ensemble candidats en attente , et pour chaque partie de la partition courante, il teste si est coupé par . Dans l’affirmative, la partition est mise à jour en remplaçant par les deux parties et résultant de la coupure. De plus, l'ensemble des candidats en attente est augmenté, pour toute lettre , de et (X'',b) ou du plus petit de et , selon que est dans ce waiting set ou non.

La complexité en temps de l’algorithme de Hopcroft, dans le pire des cas, est est le nombre d'états de l'automate et est la taille de l'alphabet. La borne est conséquence du fait que, pour chacune des transitions de l'automate, les ensembles retirés du waiting set qui contiennent l'état d'arrivé d'une transition sont de taille divisé par deux au moins moitié à chaque fois, donc chaque transition participe à au plus étapes de coupure dans l'algorithme. Une structure de données appropriée permet de réaliser le raffinement d'une partition par une coupure en un temps proportionnel au nombre de transitions qui y sont impliquées[1],[4].

L'algorithme de Hopcroft est le plus efficace des algorithmes de minimisation connus en 2010[5]. L'algorithme initial demande que l'automate de départ soit déterministe et complet. Une extension au cas des automates incomplets a aussi été décrite[6]. L'implémentation est en temps , où est le nombre de transitions de l'automate. On a toujours

Il reste un certain degré de liberté dans le choix du candidat que l'on retire de l'ensemble des candidats en attente. Cela dépend aussi du choix de la structure de donnée choisie : l'ensemble peut être par exemple organisé en pile (structure LIFO) ou en file (structure FIFO). Des expériences pratiques ont conclu à une meilleure efficacité de la représentation par pile plutôt que par file, et cet avantage a été démontré. Il a aussi été prouvé qu'un choix approprié de la stratégie permet à l'algorithme de Hopcroft d'être toujours meilleur que l'algorithme de Moore[5]. En particulier, l'algorithme a une complexité en moyenne en .


Modification modifier

Algorithme de Hopcroft, pseudo-code et explication modifier

Cet algorithme, présenté par John Hopcroft en 1971, fusionne les états non-distinguables d'un automate (nondistinguishable states en anglais). Il fonctionne par raffinement successif d'une partition initialement grossière de l'ensemble   des états de l'automate déterministe fini à minimiser. Chaque élément de la partition finale est une classe d'équivalence pour la relation   de Myhill-Nerode.

Relation de Myhill-Nérode — Soit un langage   et deux mots   et  . On a   si et seulement si pour tout mot  , on a équivalence entre   est dans   et   est dans  .

On définit avant tout l'opération primordiale dans l'algorithme de Hopcroft : la coupure (ou splitting en anglais). Un ensemble d'états   est coupé par la paire   formée d'un ensemble d'états   et d'une lettre   si les ensembles

  et  

sont tous les deux non vides. Si ça n'est pas le cas, on dit alors que   est stable pour le couple  .

On pose au préalable le lemme suivant; qui est à la base du mécanisme de mise à jour de la pile d'attente  .

Lemme — Soient   et   deux ensembles d'états, avec   et   disjoints non vides, et soit   une lettre.

  • Si   est stable pour   et pour  , alors   est stable pour  .
  • Si   est stable pour   et pour  , alors   est stable pour  .

Le but de l'algorithme est d'obtenir par coupes successives un automate déterministe minimal. On rappelle qu'un automate déterministe est minimal si et seulement si tous ses états sont séparables. L'algorithme procède donc en testant la stabilité de chaque groupe d'états de la partition   par toutes les coupes possibles.

Initialement, l'algorithme débute avec la partition   composée de l'ensemble des états terminaux   et de l'ensemble des états non terminaux  .   est la file d'attente des candidats pour raffiner la partition  . On ajoute à   tout couple de la forme  , avec   une lettre de  ,   l'ensemble de plus petit cardinal entre   et  .

A chaque itération de la boucle while, on prend un couple   de  . Si tout élément de P est stable par cette coupe, on retire le couple   de  . Sinon, pour chaque élément non stable par la coupe  , on rajoute à la partition P les deux sous-ensembles obtenus par la coupure de ces éléments par  . On ajoute alors à W l'ensemble des  , avec  le plus petit ensemble obtenu par la coupe.

A chaque itération, soit la pile   se vide d'un élément, soit   se raffine.   ne pouvant se raffiner indéfiniment, l'automate étant fini, le nombre d'itérations est donc fini, majoré par le nombre de transitions de l'automate. Dans le cas d'un automate complet, cette borne vaut  , avec   l'alphabet et n le nombre d'état. Ceci prouve donc la terminaison de l'algorithme.

Complexité et optimalité modifier

L'algorithme de Hopcroft s'exécute en pire cas en  , où   désigne le cardinal de l'alphabet et   désigne le nombre d'état de l'automate. Il y a au plus   transitions, et pour chacune d'entre elles, les ensembles retirés de   contenant l'état d'arrivée de la transition voient leurs tailles diminuer au moins de moitié. De ce fait, chaque transition participe au plus à   étapes de coupure.

On peut adapter l'algorithme au cas des automates déterministes finis non complets. La complexité en temps de cette version de l'algorithme est en  , où   est le nombre totale de transition de l'automate, qui vérifie  . L'algorithme de Hopcroft est le plus efficace des algorithmes de minimisation connus actuellement en 2016.

Il est possible d'appliquer l'algorithme de Hopcroft à partir de plusieurs structures de données différentes, notamment pour le choix de la coupe à tester. Les expériences montrent que la structure de pile pour   est la plus efficace, par la suite cet avantage a été démontré. Un choix adapté de la coupe tentée permet à l'algorithme de Hopcroft d'être toujours meilleur que l'algorithme de Moore[7]. La complexité en moyenne de l'algorithme est en  

  1. a et b Hopcroft 1971.
  2. Le terme coupure est employé par Carton 2008, p. 49.
  3. Carton 2008, p. 49.
  4. Aho, Hopcroft et Ullman 1974
  5. a et b Erreur de référence : Balise <ref> incorrecte : aucun texte n’a été fourni pour les références nommées BBCF
  6. Anti Valmari, « Fast brief practical DFA minimization », Information Processing Letters, vol. 112, no 6,‎ , p. 213-217 (DOI 10.1016/j.ipl.2011.12.004).
  7. « Analyse d’algorithmes, langages et automates », sur https://www.lix.polytechnique.fr/, (consulté le )