Je vais essayer de clarifier l'algorithme de détection des cycles qui est fourni à l'adresse suivante http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare dans mes propres mots.
![drawing]()
Comment cela fonctionne
Ayons une tortue et un lièvre (nom des pointeurs) pointant vers le début de la liste avec un cycle, comme dans le schéma ci-dessus.
Faisons l'hypothèse que si nous déplaçons la tortue d'un pas à la fois, et le lièvre de deux pas à la fois, ils finiront par se rencontrer en un point. Montrons tout d'abord que 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
s'éloigne du cycle. Disons également que le point de rencontre est k
pas du début du cycle et la tortue et le lièvre se rencontrent quand la tortue a pris i
total des pas. (Lièvre aurait pris 2i
total des étapes d'ici là).
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 se déplace i
et dans ces i
les premières étapes du cycle. Ensuite, il passe par le cycle p
fois pour un nombre positif p
. Enfin, il passe à k
d'autres nœuds jusqu'à ce qu'il rencontre le lièvre.
Il en va de même pour le lièvre. Il se déplace 2i
et dans ces 2i
les premières étapes du cycle. Ensuite, il passe par le cycle q
fois pour un nombre positif q
. Enfin, il passe à k
plus de nœuds jusqu'à ce qu'il rencontre la tortue.
Le lièvre voyage deux fois plus vite que la tortue, et le temps est constant pour les deux lorsqu'ils atteignent le point de rencontre.
En utilisant la relation simple entre 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.
L'un de ces ensembles 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 nécessairement le plus petit i possible. En d'autres termes, la tortue et le lièvre pourraient s'être déjà rencontrés plusieurs fois auparavant. Cependant, puisque nous montrons qu'ils se rencontrent en un point au moins une fois, nous pouvons dire que l'hypothèse est correcte. Ils devraient donc 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 consiste à trouver le début du cycle.
Début du cycle
Lorsque 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 (c'est-à-dire à 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 rencontreront sera le début du cycle.
Prouvons cette hypothèse.
Supposons d'abord qu'un oracle nous dise ce qu'est m.
Ensuite, si on les laisse se déplacer de m + k pas, la tortue devra arriver au point où elles se sont rencontrées à l'origine (à k pas du début du cycle - voir dans la figure).
Auparavant, nous avons montré que m + k = (q - 2p) n
.
Comme m + k pas est un multiple de la longueur n du cycle, le lièvre, entre-temps, parcourrait le cycle (q-2p) fois et reviendrait au même point (à k pas du début du cycle).
Maintenant, au lieu de les laisser faire m + k pas, si nous les laissons faire seulement m pas, la tortue arrivera au début du cycle. Il manquerait au lièvre k pas pour effectuer (q-2p) rotations. Comme il a commencé k pas avant le début du cycle, le lièvre devrait arriver au début du cycle.
Par conséquent, 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 (toute première fois car la tortue vient d'arriver au cycle après m étapes et elle n'a jamais pu voir le lièvre qui était déjà dans le cycle).
Nous savons maintenant que le nombre de pas dont nous avons besoin pour les déplacer jusqu'à ce qu'ils se rencontrent est la distance entre le début de la liste et le début du cycle, m. Bien sûr, l'algorithme n'a pas besoin de savoir ce que m représente. Il va simplement déplacer la tortue et le lièvre un pas après l'autre jusqu'à ce qu'ils se rencontrent. Le point de rencontre doit être le début du cycle et le nombre d'étapes doit être la distance (m) au début du cycle. En supposant que nous connaissions la longueur de la liste, nous pouvons également calculer la longueur du cycle en soustrayant m de la longueur de la liste.
0 votes
Une autre explication : marcin-chwedczuk.github.io/
2 votes
Les gens ne se sont pas souciés de regarder au-delà des deux premières réponses à cette question. La troisième réponse est plutôt bonne.
0 votes
Je me demande si quelqu'un peut trouver facilement le début du cycle si l'on utilise l'algorithme de Brent.