Algoritmo di rilevamento del ciclo di Floyd | Determinazione del punto iniziale del ciclo


32

Sto cercando aiuto per comprendere l'algoritmo di rilevamento del ciclo di Floyd. Ho esaminato la spiegazione su wikipedia ( http://it.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare )

Vedo come l'algoritmo rileva il ciclo nel tempo O (n). Tuttavia, non sono in grado di visualizzare il fatto che una volta che i puntatori di tartaruga e lepre si incontrano per la prima volta, l'inizio del ciclo può essere determinato spostando indietro il puntatore di tartaruga per iniziare e quindi spostando sia la tartaruga che la lepre un passo alla volta. Il punto in cui si incontrano per la prima volta è l'inizio del ciclo.

Qualcuno può aiutare fornendo una spiegazione, si spera diversa da quella su Wikipedia, dato che non riesco a capirla / visualizzarla?


3
Ho trovato la risposta su StackOverflow. Grazie se qualcuno mi stesse esaminando. E per coloro che come me volevano una spiegazione, si prega di fare riferimento a: stackoverflow.com/questions/3952805/… La risposta scelta alla domanda, lo spiega!
Anurag Kapur

Ciao @Anurag. Per tua informazione, ho pubblicato un post sul blog sull'algoritmo "Tortoise and the Hare" qui
Kyle,

Sai perché la fastvariabile, o "lepre", deve muoversi a una velocità doppia rispetto alla tartaruga, piuttosto che a una sola?
devdropper87,

Risposte:


47

Puoi fare riferimento a "Rilevamento dell'inizio di un ciclo nell'elenco singolarmente collegato" , ecco un estratto:

inserisci qui la descrizione dell'immagine

Distanza percorsa slowPointerprima dell'incontro =x+y

fastPointer =(x+y+z)+y

Dal momento che fastPointerviaggia con il doppio della velocità di slowPointer, e il tempo è costante per entrambi quando raggiungono il punto di incontro. Quindi, usando la semplice relazione velocità, tempo e distanza ( slowPointerpercorsa metà della distanza):

2dist(slowPointer)=dist(fastPointer)2(x+y)=x+2y+z2x+2y=x+2y+zx=z

Quindi spostandosi slowPointerall'inizio dell'elenco collegato e realizzando entrambi slowPointere fastPointerspostando un nodo alla volta, entrambi hanno la stessa distanza da percorrere .

Raggiungeranno il punto in cui inizia il loop nell'elenco collegato.


2
Qui hai ipotizzato che si incontreranno dopo una rotazione. Ci possono essere casi (in cui il ciclo è piccolo) in cui potrebbero incontrarsi dopo un certo no. di rotazioni.
Navjot Waraich,

1
@JotWaraich l'immagine non è rappresentativa di tutti i casi; la logica tuttavia è ancora valida
denis631,

3
questa è la risposta più diretta su questo algoritmo in tutta Internet
Marshall X

7

Ho visto la risposta accettata come prova anche altrove. Tuttavia, sebbene sia facile da grok, non è corretto. Ciò che dimostra è

x=z

Quello che vuoi davvero dimostrare è (usando le stesse variabili descritte nel diagramma nella risposta accettata sopra):

z=x mod (y+z)

(y+z)L

quindi, ciò che vogliamo dimostrare è:

z=x mod L

O che z è congruente a x (modulo L)

La seguente prova ha più senso per me:

M=x+y

2(x+y)=M+kLkx+yL

x+y=kL

x=kLy

xLyMx+y


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.