Biarkan saya mencoba untuk mengklarifikasi algoritma deteksi siklus yang disediakan di http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare dengan kata-kata saya sendiri.
Bagaimana itu bekerja
Mari kita memiliki kura-kura dan kelinci (nama pointer) yang menunjuk ke awal daftar dengan siklus, seperti pada diagram di atas.
Mari berhipotesis bahwa jika kita memindahkan kura-kura 1 langkah sekaligus, dan membagi 2 langkah sekaligus, mereka akhirnya akan bertemu pada suatu titik. Mari kita tunjukkan bahwa pertama-tama hipotesis ini benar.
Angka tersebut menggambarkan daftar dengan siklus. Siklus memiliki panjang n
dan kami awalnya beberapa m
langkah menjauh dari siklus. Juga katakanlah bahwa titik pertemuan adalah beberapa k
langkah menjauh dari siklus awal dan kura-kura dan kelinci bertemu ketika kura-kura telah mengambil i
langkah-langkah total. (Kelinci akan mengambil 2i
langkah total saat itu.)
2 kondisi berikut harus berlaku:
1) i = m + p * n + k
2) 2i = m + q * n + k
Yang pertama mengatakan bahwa kura-kura bergerak i
langkah-langkah dan dalam i
langkah - langkah ini pertama kali sampai ke siklus. Kemudian ia melewati waktu siklus p
untuk beberapa angka positif p
. Akhirnya melewati lebih k
banyak node sampai bertemu kelinci.
Hal serupa juga berlaku untuk kelinci. Ini bergerak 2i
langkah-langkah dan langkah- 2i
langkah ini pertama kali sampai ke siklus. Kemudian ia melewati waktu siklus q
untuk beberapa angka positif q
. Akhirnya melewati lebih k
banyak node sampai bertemu kura-kura.
Saat kelinci berjalan dengan dua kali lipat kecepatan kura-kura, dan waktu konstan untuk keduanya ketika mereka mencapai titik pertemuan.
Jadi dengan menggunakan hubungan kecepatan, waktu dan jarak yang sederhana,
2 ( m + p * n + k ) = m + q * n + k
=> 2m + 2pn + 2k = m + nq + k
=> m + k = ( q - 2p ) n
Di antara m, n, k, p, q, dua yang pertama adalah properti dari daftar yang diberikan. Jika kita dapat menunjukkan bahwa setidaknya ada satu set nilai untuk k, q, p yang membuat persamaan ini benar, kita menunjukkan bahwa hipotesisnya benar.
Satu set solusi tersebut adalah sebagai berikut:
p = 0
q = m
k = m n - m
Kami dapat memverifikasi bahwa nilai-nilai ini berfungsi sebagai berikut:
m + k = ( q - 2p ) n
=> m + mn - m = ( m - 2*0) n
=> mn = mn.
Untuk set ini, i
adalah
i = m + p n + k
=> m + 0 * n + mn - m = mn.
Tentu saja, Anda harus melihat bahwa ini belum tentu yang terkecil yang saya bisa. Dengan kata lain, kura-kura dan kelinci mungkin sudah pernah bertemu sebelumnya. Namun, karena kami menunjukkan bahwa mereka bertemu di beberapa titik setidaknya sekali kita dapat mengatakan bahwa hipotesis itu benar. Jadi mereka harus bertemu jika kita memindahkan salah satu dari mereka 1 langkah, dan yang lainnya 2 langkah sekaligus.
Sekarang kita bisa menuju ke bagian kedua dari algoritma yang adalah bagaimana menemukan awal siklus.
Awal Siklus
Setelah kura-kura dan kelinci bertemu, mari kita meletakkan kura-kura kembali ke awal daftar dan simpan kelinci di tempat mereka bertemu (yang berjarak beberapa langkah dari siklus awal).
Hipotesisnya adalah jika kita membiarkan mereka bergerak dengan kecepatan yang sama (1 langkah untuk keduanya), pertama kali mereka bertemu lagi adalah siklusnya.
Mari kita buktikan hipotesis ini.
Pertama-tama mari kita asumsikan beberapa oracle memberi tahu kita apa itu m.
Kemudian, jika kita membiarkan mereka bergerak m + k langkah, kura-kura harus tiba pada titik yang mereka temui semula (k langkah menjauh dari siklus awal - lihat pada gambar).
Sebelumnya kami menunjukkan itu m + k = (q - 2p) n
.
Karena langkah m + k adalah kelipatan dari panjang siklus n, kelinci, pada saat yang bersamaan, akan melewati siklus (q-2p) kali dan akan kembali ke titik yang sama (k langkah menjauh dari awal siklus).
Sekarang, alih-alih membiarkan mereka bergerak langkah m + k, jika kita membiarkan mereka bergerak hanya langkah m, kura-kura akan tiba di awal siklus. Kelinci akan menjadi k langkah-langkah pendek menyelesaikan rotasi (q-2p). Karena itu dimulai k langkah di depan siklus awal, kelinci harus tiba di siklus awal.
Akibatnya, ini menjelaskan bahwa mereka harus bertemu di siklus dimulai setelah beberapa langkah untuk pertama kalinya (sangat pertama karena kura-kura baru saja tiba di siklus setelah langkah m dan tidak pernah bisa melihat kelinci yang sudah ada di siklus).
Sekarang kita tahu bahwa jumlah langkah yang kita butuhkan untuk memindahkannya sampai bertemu ternyata menjadi jarak dari awal daftar ke awal siklus, m. Tentu saja, algoritma tidak perlu tahu apa itu m. Itu hanya akan memindahkan kedua kura-kura dan berbagi satu langkah pada satu waktu sampai mereka bertemu. Titik pertemuan harus menjadi awal siklus dan jumlah langkah harus jarak (m) ke awal siklus. Dengan asumsi kita tahu panjang daftar, kita juga bisa, menghitung panjang siklus pengurangan m dari panjang daftar.