Độ phức tạp của thuật toán trộn ngẫu nhiên Fisher-Yates


15

Câu hỏi này liên quan đến thuật toán Fisher-Yates để trả về một sự xáo trộn ngẫu nhiên của một mảng nhất định. Các trang Wikipedia nói rằng sự phức tạp của nó là O (n), nhưng tôi nghĩ rằng nó là O (n log n).

Trong mỗi lần lặp i, một số nguyên ngẫu nhiên được chọn giữa 1 và i. Đơn giản chỉ cần viết số nguyên trong bộ nhớ là O (log i) và vì có n lần lặp, nên tổng số là

O (log 1) + O (log 2) + ... + O (log n) = O (n log n)

thuật toán ngây thơ không tốt hơn. Am i thiếu cái gì ở đây?

Lưu ý: Thuật toán ngây thơ là gán cho mỗi phần tử một số ngẫu nhiên trong khoảng (0,1), sau đó sắp xếp mảng liên quan đến các số được gán.

Câu trả lời:


24

Tôi nghi ngờ rằng ở đây, giống như trong hầu hết các thuật toán hoạt động, chi phí đọc và ghi số bit được giả định là một hằng số. Đó là một tội lỗi nhỏ, miễn là bạn không bị mang đi và sụp đổ P và PSPACE một cách tình cờ .Ôi(đăng nhậpn)


4
Trong khi đó thực sự là một "tội lỗi nhỏ", tôi nghĩ đó là một tội lỗi lớn của sư phạm TCS mà điều này không bao giờ được đề cập rõ ràng! Mỗi sinh viên CS tự khám phá điều này và nghĩ rằng điều gì đó quan trọng là sai cho đến khi họ được thông báo rằng mọi người đều biết điều này nhưng không ai nói về điều đó. Ngoài ra, có phải đã có một brouhaha vài năm trước khi ai đó khai thác mô hình O (log n) để đưa ra thuật toán thời gian phụ cho một số vấn đề nổi tiếng được phỏng đoán là Omega (n ^ 3)? Điều đó đã bao giờ được giải quyết?
Randomwalker

2
Tôi không biết về brouhaha mà bạn đang đề cập đến. Vì không đề cập đến nó, bạn chắc chắn đúng. Sau lần đầu tiên tôi đọc bài đăng của Jeff Erickson, bây giờ tôi biến nó thành một điểm để chứng minh P = PSPACE trong lớp hình học của tôi chỉ vì những cú đá :)
Suresh Venkat

1
Cảm ơn câu trả lời. Tôi không bao giờ biết đó là một vấn đề lớn. Các liên kết cung cấp một đọc tốt.
Tomer Vromen

1
Dòng dưới cùng: luôn luôn làm cho mô hình của bạn rõ ràng.
Jukka Suomela

2
Tôi nghĩ lý do chính mà chúng ta để cho cắn ops là hằng số thời gian là (trong thời gian đa thức), bạn có thể lập trình một bảng truy cập tra cứu liên tục thời gian cho tất cả các cặp của O ( log n ) toán hạng -bit, đối với hầu hết mô hình tính toán "hiện đại". Không có gì "tội lỗi" về điều đó ... với tôi, tôi thấy tài sản này là một tài sản đơn giản có thể được thừa nhận mà không mất tính tổng quát. Ôi(đăng nhậpn)Ôi(đăng nhậpn)
Ryan Williams

17

Mô hình tính toán tiêu chuẩn giả định rằng các phép toán số học trên các số nguyên có tỷ lệ O (log n) có thể được thực hiện trong thời gian không đổi, vì các hoạt động đó thường được đưa vào phần cứng. Vì vậy, trong thuật toán Fisher-Yates, "ghi số nguyên i vào bộ nhớ" chỉ mất thời gian O (1).

Tất nhiên, việc phân tích thuật toán theo các hoạt động bit là hoàn toàn có ý nghĩa, nhưng mô hình chi phí bit ít dự đoán về hành vi thực tế. Ngay cả vòng lặp đơn giản cũng for i = 1 to n: print(i)yêu cầu các hoạt động bit O (n log n).


Điểm đẹp với vòng lặp. Không bao giờ nhận thấy rằng ...
Tomer Vromen

8

Đây là câu trả lời cho "[Thuật toán Fisher-Yates] không tốt hơn thuật toán ngây thơ. Tôi có thiếu điều gì ở đây không?" mà bạn đã hỏi trong câu hỏi.

Trong thuật toán "ngây thơ" của bạn sử dụng các số thực: bạn sử dụng bao nhiêu bit chính xác? Nếu bạn đang tính độ phức tạp của bit (như bạn đang làm cho Fisher-Yates) và thuật toán sử dụng k bit ngẫu nhiên cho các số thực, thì thời gian chạy của nó sẽ là Ω (kn log n), vì so sánh hai k- số thực bit mất (k) thời gian. Nhưng k cần ít nhất là (log n) để ngăn hai phần tử được ánh xạ tới cùng một số thực, điều đó có nghĩa là thuật toán mất Ω (n log 2 thời gian n), chậm hơn so với Fisher-Yates xáo trộn bởi hệ số của log n.

Nếu bạn chỉ đếm số lượng các phép toán số học và so sánh và bỏ qua độ phức tạp bit của chúng, thì Fisher-Yates là Θ (n) và thuật toán của bạn là Θ (n log n), vẫn là một yếu tố của log n.


Tôi nghi ngờ rằng thuật toán "ngây thơ" có ẩn ý đó ...
Tomer Vromen

1
Thuật toán "ngây thơ" có thể được thực hiện sạch trong thời gian tuyến tính như sau. Gán mỗi phần tử một số nguyên ngẫu nhiên trong khoảng từ 1 đến n ^ 3, sau đó sắp xếp các số theo thời gian O (n) thông qua sắp xếp cơ số. (Với xác suất cao, không có hai yếu tố sẽ nhận được số ngẫu nhiên cùng Nếu có trùng lắp, cải tổ chúng đệ quy..)
Jeffε

@JeffE: Cảm ơn! Điều đó rất sạch sẽ và có độ phức tạp tương tự như Fisher-Yates. Sau khi đăng bài này, tôi thực sự cảm thấy rằng thuật toán của ngây thơ không nên tệ hơn ... Tôi đã bỏ lỡ thực tế là các số n-bit có thể được sắp xếp trong O (nk), không cần O (nklog n). Nhưng tôi đoán Knuth-Fisher-Yates vẫn tốt hơn trong các hằng số: nó yêu cầu các bit ngẫu nhiên (log n!) Chính xác một số nguyên ngẫu nhiên từ 1 đến n, sau đó 1 đến n-1, v.v., đó là tối ưu (thay vì 3n log n), và nó có thể được thực hiện tại chỗ chỉ với bộ nhớ phụ không đổi.
ShreevatsaR

6

Không có gì đặc biệt về số nguyên cho vấn đề này.

Chẳng hạn, các bảng băm (lưu trữ bất kỳ loại giá trị nào) không phải là thời gian truy cập O (1) nếu hàm băm phải đọc toàn bộ giá trị để tính toán hàm băm của nó. Do đó, các phần tử duy nhất yêu cầu trung bình n bit để thể hiện, cho dù cách biểu diễn của bạn thông minh đến mức nào và bất kỳ hàm băm nào đọc toàn bộ đầu vào của nó do đó sẽ mất ít nhất thời gian để tính toán. Trong thực tế, chúng nhanh hơn cây đỏ đen, nhưng không có triệu chứng, chúng không tốt hơn.

Brouhaha được tham chiếu bởi Randomwalker là về một bài báo POPL 2008 ( http://portal.acm.org/citation.cfm?doid=1328438.1328460 ), được thảo luận tại đây: http://blog.computationalcomplexity.org/2009/05/shaving- log-with-unit-cost.html

Trong bài đăng đó, Lance Fortnow mô tả làm thế nào khi còn là một sinh viên, anh ta phàn nàn rằng việc sắp xếp thực sự đòi hỏi n log ^ 2 n thời gian nếu chúng ta phải đọc tất cả các bit log của hai yếu tố để so sánh chúng, có vẻ như là một sự phản đối hợp lý.


Tôi không nhận được tác giả của bài viết trên blog. Ông phàn nàn rằng sắp xếp thực sự là O (n log ^ 2 n), nhưng sau đó nói rằng giấy là rắn?
Tomer Vromen

Bài viết rất chắc chắn (nghĩa là không sai) ở chỗ có một mô hình trong đó các phép toán số học mất thời gian đơn vị và trong mô hình đó, thuật toán của bài báo là lần đầu tiên đạt được các phép toán o (n ^ 3).
Dave Doty

Tôi không nhận được sự phản đối O (n log ^ 2 n) vì về mặt bit, đầu vào chính nó có kích thước O (n log n). Btw, như một lưu ý phụ, mức độ bình luận chất lượng trên blog phức tạp cao hơn rất nhiều sau đó ....
arnab

4

Trang Wikipedia nói rằng độ phức tạp của nó là O (n), nhưng tôi nghĩ rằng đó là O (n log n).

Trên thực tế, O (n log n) là giới hạn thấp hơn cho vấn đề này trong các mô hình trong đó sắp xếp là O (n log n). Nếu tất cả các hoán vị đều có khả năng như nhau thì thuật toán như một hàm từ các luồng ngẫu nhiên đến hoán vị phải là tính từ. Có n! hoán vị vì vậy trong một cái gì đó giống như mô hình cây quyết định, có các nhánh có độ dài ít nhất là O (log n!) = O (n log n).

1-εÔi(ε)


3

Trong TCS, chúng tôi xem xét - nếu không được nêu rõ ràng - sự phức tạp trên Máy Turing. Mặc dù điều này tốt cho mục đích lý thuyết, nhưng kết quả không thực sự hữu ích vì chúng tôi thực hiện các mô hình máy khác nhau (nghĩa là xấp xỉ hữu hạn) trong phần cứng. Do đó, đây là một câu hỏi khả thi để yêu cầu sự phức tạp trên các mô hình đó. Ví dụ, chúng tôi thường cho rằng các máy đăng ký (tương tự CPU thực) có thể thực hiện các hoạt động nguyên tử trên hai thanh ghi trong thời gian không đổi - đây là những gì có thể đã được sử dụng ở đây.

Tóm lại: Bạn nghĩ về các TM, các tác giả bài viết về các RM. Bạn đều đúng.

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.