Laissez-moi essayer de clarifier l'algorithme de détection de cycle qui est fourni à http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare dans mes propres mots.
Comment ça fonctionne
Prenons une tortue et un lièvre (nom des pointeurs) pointant vers le début de la liste avec un cycle, comme dans le diagramme ci-dessus.
Supposons que si nous déplaçons la tortue d'un pas à la fois, et le lièvre de 2 pas à la fois, ils finiront par se rencontrer à un moment donné. Montrons que tout d'abord cette hypothèse est vraie.
La figure illustre une liste avec un cycle. Le cycle a une longueur de n
et nous sommes initialement à m
quelques pas du cycle. Disons également que le point de rencontre est à k
quelques pas du début du cycle et que la tortue et le lièvre se rencontrent lorsque la tortue a franchi i
le pas. (Hare aurait alors franchi 2i
le pas.)
Les 2 conditions suivantes doivent être remplies:
1) i = m + p * n + k
2) 2i = m + q * n + k
Le premier dit que la tortue bouge i
pas et dans ces i
étapes, elle arrive d'abord au cycle. Ensuite, il passe par les p
temps de cycle pour un nombre positif p
. Enfin, il passe sur k
plus de nœuds jusqu'à ce qu'il rencontre le lièvre.
Un semblable est vrai pour le lièvre. Il déplace des 2i
étapes et dans ces2i
étapes, il arrive d'abord au cycle. Ensuite, il passe par les q
temps de cycle pour un nombre positif q
. Enfin, il passe sur k
plus de nœuds jusqu'à ce qu'il rencontre la tortue.
Comme le lièvre voyage avec le double de la vitesse de la tortue, le temps est constant pour les deux lorsqu'ils atteignent le point de rencontre.
Donc, en utilisant une simple relation vitesse, temps et distance,
2 ( m + p * n + k ) = m + q * n + k
=> 2m + 2pn + 2k = m + nq + k
=> m + k = ( q - 2p ) n
Parmi m, n, k, p, q, les deux premiers sont des propriétés de la liste donnée. Si nous pouvons montrer qu'il existe au moins un ensemble de valeurs pour k, q, p qui rend cette équation vraie, nous montrons que l'hypothèse est correcte.
Un tel ensemble de solutions est le suivant:
p = 0
q = m
k = m n - m
Nous pouvons vérifier que ces valeurs fonctionnent comme suit:
m + k = ( q - 2p ) n
=> m + mn - m = ( m - 2*0) n
=> mn = mn.
Pour cet ensemble, i
est
i = m + p n + k
=> m + 0 * n + mn - m = mn.
Bien sûr, vous devriez voir que ce n'est pas forcément le plus petit possible. En d'autres termes, la tortue et le lièvre se sont peut-être déjà rencontrés plusieurs fois. Cependant, comme nous montrons qu'ils se rencontrent à un moment donné au moins une fois, nous pouvons dire que l'hypothèse est correcte. Donc, ils devraient se rencontrer si nous déplaçons l'un d'eux d'un pas, et l'autre de deux pas à la fois.
Nous pouvons maintenant passer à la deuxième partie de l'algorithme qui est de savoir comment trouver le début du cycle.
Début du cycle
Une fois que la tortue et le lièvre se rencontrent, remettons la tortue au début de la liste et gardons le lièvre là où ils se sont rencontrés (ce qui est à k pas du début du cycle).
L'hypothèse est que si nous les laissons se déplacer à la même vitesse (1 pas pour les deux), la première fois qu'ils se reverront sera le début du cycle.
Prouvons cette hypothèse.
Supposons d'abord qu'un oracle nous dise ce qu'est m.
Ensuite, si nous les laissons se déplacer de m + k pas, la tortue devra arriver au point où elle s'est rencontrée à l'origine (à k pas du début du cycle - voir sur la figure).
Auparavant, nous l'avons montré m + k = (q - 2p) n
.
Puisque m + k pas est un multiple de la longueur du cycle n, le lièvre, dans le même temps, passerait par les temps du cycle (q-2p) et reviendrait au même point (à k pas du début du cycle).
Maintenant, au lieu de les laisser bouger de m + k pas, si on les laisse se déplacer seulement de m pas, la tortue arriverait au début du cycle. Hare serait à k étapes avant d'effectuer des rotations (q-2p). Puisqu'il a commencé k étapes avant le début du cycle, le lièvre devrait arriver au début du cycle.
En conséquence, cela explique qu'ils devraient se rencontrer au début du cycle après un certain nombre d'étapes pour la toute première fois (la toute première fois car la tortue vient d'arriver au cycle après m étapes et elle ne pourrait jamais voir le lièvre qui était déjà en le cycle).
Nous savons maintenant que le nombre de pas dont nous avons besoin pour les déplacer jusqu'à ce qu'ils se rencontrent s'avère être la distance entre le début de la liste et le début du cycle, m. Bien entendu, l'algorithme n'a pas besoin de savoir ce qu'est m. Il ne fera que déplacer la tortue et le lièvre un pas à la fois jusqu'à ce qu'ils se rencontrent. Le point de rencontre doit être le début du cycle et le nombre de pas doit être la distance (m) du début du cycle. En supposant que nous connaissons la longueur de la liste, nous pouvons également calculer la longueur du cycle de soustraction de m de la longueur de la liste.