Thuật toán phát hiện chu kỳ của Floyd | Xác định điểm bắt đầu của chu kỳ


32

Tôi đang tìm kiếm sự giúp đỡ để hiểu thuật toán phát hiện chu kỳ của Floyd. Tôi đã trải qua phần giải thích trên wikipedia ( http://en.wikipedia.org/wiki/Cycle_detection#Tortoir_and_hare )

Tôi có thể thấy thuật toán phát hiện chu kỳ trong thời gian O (n). Tuy nhiên, tôi không thể hình dung được thực tế là lần đầu tiên con rùa và con thỏ gặp nhau, bắt đầu chu kỳ có thể được xác định bằng cách di chuyển con trỏ rùa trở lại để bắt đầu và sau đó di chuyển cả hai con rùa và mỗi lần một bước. Điểm mà lần đầu tiên họ gặp nhau là bắt đầu chu kỳ.

Ai đó có thể giúp đỡ bằng cách cung cấp một lời giải thích, hy vọng khác với một trên wikipedia, vì tôi không thể hiểu / hình dung nó?


3
Tôi tìm thấy câu trả lời trên stackoverflow. Cảm ơn nếu có ai đang xem xét điều này cho tôi. Và đối với những người như tôi muốn một lời giải thích, xin vui lòng tham khảo: stackoverflow.com/questions/3952805/ đá Câu trả lời được chọn cho câu hỏi, giải thích nó!
Anurag Kapur

Xin chào @Anurag. Chỉ để biết thông tin của bạn, tôi đã thực hiện một bài đăng trên blog về thuật toán "Rùa và thỏ" ở đây
Kyle

Bạn có biết tại sao fastbiến số hay "thỏ rừng" cần di chuyển với tốc độ gấp đôi tốc độ như rùa, thay vì chỉ đi trước?
devdropper87

Giải thích cặn kẽ
Jayesh

Câu trả lời:


47

Bạn có thể tham khảo "Phát hiện bắt đầu một vòng lặp trong danh sách liên kết đơn" , đây là đoạn trích:

nhập mô tả hình ảnh ở đây

Khoảng cách di chuyển slowPointertrước khi gặp =x+y

Quãng đường đi được fastPointertrước khi gặp = x + 2y + z=(x+y+z)+y

fastPointerhành trình với tốc độ gấp đôislowPointerthời gian là không đổi cho cả hai khi đến điểm gặp gỡ. Vì vậy, bằng cách sử dụng tốc độ, thời gian và khoảng cách đơn giản ( slowPointerđi được một nửa quãng đường):

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

Do đó bằng cách di chuyển slowPointerđể bắt đầu danh sách được liên kết, và tạo cả hai slowPointerfastPointerđể di chuyển một nút tại một thời điểm, cả hai đều có cùng khoảng cách để che .

Họ sẽ đạt đến điểm mà vòng lặp bắt đầu trong danh sách được liên kết.


2
Ở đây bạn đã đưa ra một giả định rằng họ sẽ gặp nhau sau một vòng quay. Có thể có trường hợp (trong đó chu kỳ nhỏ) nơi họ có thể gặp nhau sau khi không. của phép quay.
Navjot Waraich

1
@JotWaraich hình ảnh không đại diện cho tất cả các trường hợp; tuy nhiên logic vẫn giữ
denis631

3
đây là câu trả lời thẳng thắn nhất về thuật toán này trên toàn bộ Internet
Marshall X

7

Tôi đã thấy câu trả lời được chấp nhận là bằng chứng ở nơi khác quá. Tuy nhiên, trong khi nó dễ dàng để mò mẫm, nó không chính xác. Những gì nó chứng minh là

x=z (điều này rõ ràng là sai và sơ đồ chỉ làm cho nó có vẻ hợp lý do cách nó được phác họa).

Những gì bạn thực sự muốn chứng minh là (sử dụng các biến giống như được mô tả trong sơ đồ trong câu trả lời được chấp nhận ở trên):

z=x mod (y+z)

L(y+z) là độ dài vòng lặp,L

vì vậy, những gì chúng tôi muốn chứng minh là:

z=x mod L

Hoặc z đó đồng dạng với x (modulo L)

Bằng chứng sau đây có ý nghĩa hơn với tôi:

Điểm gặp gỡ,M=x+y

k x + y L2(x+y)=M+kL , trong đó là hằng số. Về cơ bản, khoảng cách di chuyển của con trỏ nhanh là cộng với một số bội số chiều dài vòng lặp,kx+yL

x+y=kL

x=kLy

Phương trình trên chứng minh rằng giống với một số bội của độ dài vòng lặp, trừ . Vì vậy, nếu con trỏ nhanh bắt đầu tại điểm gặp gỡ, hoặc tại , thì nó sẽ kết thúc ở đầu vòng lặp.L y M x + yxLyMx+y


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.