Tôi đã tự hỏi về độ phức tạp của một số phương thức tích hợp sẵn của Ruby, hai phương pháp này nói riêng. Tôi nghĩ rằng tốt nhất tôi đã có thể đến với một phương pháp hoán vị của riêng tôi là Θ (n · n!), Ruby có tích hợp hoạt động tốt hơn không? Nếu có, hãy giúp tôi hiểu thuật toán của họ.Độ phức tạp của phương pháp #permutation và #repeated_permutation của Ruby là gì?
Trả lời
hoán vị
Array#permutation
trả về một Enumerator với n!
Mảng, vì vậy mức độ phức tạp thời gian sẽ có ít nhất O(n!)
.
tôi đã viết phương pháp này:
def slow_method(n)
(1..n).to_a.permutation.each do |p|
p
end
end
Nó không làm bất cứ điều gì với p
, hy vọng buộc thế hệ của tất cả các hoán vị. Xây dựng một mảng của tất cả các hoán vị sẽ sử dụng quá nhiều bộ nhớ.
Phương pháp này được gọi là 10 lần đối với n từ 10 đến 13, và thời gian trung bình trong vài giây là:
t10 = 0.618895
t11 = 6.7815425
t12 = 82.896605
t13 = 1073.015602
O(n!)
trông giống như một xấp xỉ hợp lý:
t13/fact(13)*fact(12)/t12 #=> 0.995694114280165
t13/fact(13)*fact(11)/t11 #=> 1.0142685297667369
t13/fact(13)*fact(10)/t10 #=> 1.0103498450722133
O(n*n!)
không :
t13/(fact(13)*13)*fact(12)*12/t12 #=> 0.9191022593355369
t13/(fact(13)*13)*fact(11)*11/t11 #=> 0.8582272174949312
t13/(fact(13)*13)*fact(10)*10/t10 #=> 0.777192188517087
Thế hệ có vẻ là O(n!)
, nhưng làm bất cứ điều gì với các mảng tạo ra sẽ mang lại sự phức tạp tổng thể để O(n*n!)
.
Tại sao không phải là thế hệ O(n*n!)
? Nó có thể đến từ thực tế là khi đệ quy tạo ra [1,2,3,4,5].permutation
, các hoán vị còn lại là như nhau cho [1,2]
và [2,1]
.
O(n!)
đã quá chậm đến mức n
sẽ không bao giờ lớn hơn 10, vì vậy, O(n*n!)
không tệ hơn nhiều. Đối với n=20
, n!
là 2432902008176640000
và n*n!
là 48658040163532800000
.
Tiếp xúc nhiều lần hoán vị
[1,2,...n].repeated_permutation(k)
tạo n**k
Mảng của các yếu tố k.
Độ phức tạp phải là O(n**k)
hoặc O(k*n**k)
.
Đối với k=n
, nó sẽ trở thành O(n**n)
hoặc O(n**(n+1))
, thậm chí còn tệ hơn nhiều so với số permutation
.
Kudo để đo thời gian! Nhưng bạn không trả lời câu hỏi thứ hai của họ, đó là cách thuật toán Ruby hoạt động. – akuhn
Làm thế nào tốt đẹp của bạn để viết "Kudo" nhưng vẫn downvote câu trả lời của tôi. Tại sao chính xác? Một nửa câu trả lời vẫn tốt hơn không ai cả. Tôi đã viết câu trả lời này sau 3 tháng không hoạt động, mặc dù nó dường như thu hút một vài người. –
Có các thuật toán để tạo lặp lại tất cả các hoán vị của danh sách.
Làm cách nào? Thuật toán tạo tất cả các hoán vị của [1,2,3,4,...,n]
theo thứ tự từ điển. Cho một hoán vị thuật toán tạo ra hoán vị từ vựng tiếp theo trong thời gian O(1)
.
Đây là những bước
- Tìm chỉ số lớn nhất
k
màa[k] < a[k + 1]
, nếu không có chỉ số như vậy tồn tại các hoán vị là hoán vị cuối cùng - Tìm chỉ số lớn nhất
l
lớn hơnk
màa[k] < a[l]
- Hoán đổi giá trị của
a[k]
với giá trị củaa[l]
- Đảo ngược chuỗi từ
a[k + 1]
tối đa và bao gồm phần tử cuối cùnga[n]
Độ phức tạp là gì?
Mỗi bước là O(1)
và có O(n!)
hoán vị, vì vậy tổng độ phức tạp là O(n!)
.
Các bước 1 và 2 trông giống như 'O (n)'. Bạn có thể giải thích tại sao mỗi bước là O (1)? –
- 1. Độ phức tạp của OrderedDictionary là gì?
- 2. Độ phức tạp của set_intersection trong C++ là gì?
- 3. Độ phức tạp tiệm cận của List.Add là gì?
- 4. Độ phức tạp của chức năng nhật ký là gì?
- 5. Độ phức tạp thời gian của trình tự phương thức Linq OrderBy(). ThenBy() là gì?
- 6. Thời gian phức tạp của phương pháp HashMap
- 7. Độ phức tạp của bộ nhớ của std :: sort() và std :: sort_heap() là gì?
- 8. Độ phức tạp của thuật toán
- 9. Độ phức tạp của HashMap.containsValue() trong java là bao nhiêu?
- 10. Sự phức tạp của các phương pháp từ điển này là gì?
- 11. Thời gian phức tạp của phương pháp JavaConverters asScala
- 12. Độ phức tạp Big-O của mã của tôi là gì?
- 13. Sự khác nhau giữa "phức tạp" metric và "phức tạp/phương pháp" metric
- 14. Độ phức tạp của ưu tiênQueue addAll()
- 15. Giảm độ phức tạp của Cyclomatic
- 16. Độ phức tạp của dict.keys trong Python là bao nhiêu?
- 17. Tại sao độ phức tạp của phương thức list.append() của python là O (1)?
- 18. Độ phức tạp của LinkedList.getLast() trong Java là bao nhiêu?
- 19. Độ phức tạp của thời gian A * là gì và nó bắt nguồn như thế nào?
- 20. Độ phức tạp thời gian của random.sample
- 21. Độ phức tạp của thuật toán
- 22. Bạn có thấy độ phức tạp của chu trình là một biện pháp hữu ích không?
- 23. Độ phức tạp của mã đã cho là bao nhiêu?
- 24. Độ phức tạp của HashMap.containsKey() trong java là bao nhiêu?
- 25. Đặt tên các phương pháp phức tạp
- 26. Các công cụ phân tích phức tạp mã vượt quá độ phức tạp của chu trình
- 27. Phương pháp đệ quy làm tăng độ phức tạp của cyclomatric
- 28. Độ phức tạp nhất của trò chơi N-Queens là gì?
- 29. Độ phức tạp thời gian của thuật toán tam giác pascal là gì
- 30. Độ phức tạp thời gian của hàm này trong sơ đồ là gì?
[Điều này cho 'repeat_permutation'] (https://github.com/ruby/ruby/blob/trunk/array.c#L5218) và [this for' permutation'] (https://github.com/ ruby/ruby / blob/trunk/array.C# L4979) (nhiều ngữ cảnh cho 'hoán vị' [ở đây] (https://github.com/ruby/ruby/blob/trunk/array.c#L5081)) sẽ giúp bạn. – EvilTak