2008-08-25 12 views
10

Tôi đã viết một loại O (n!) Để giải trí mà không thể tối ưu hóa một cách trivially để chạy nhanh hơn mà không thay thế hoàn toàn. [Và không, tôi không chỉ ngẫu nhiên hóa các mục cho đến khi chúng được sắp xếp].Làm thế nào để viết một loại tồi tệ hơn O (n!)

Làm thế nào tôi có thể viết một loại Big-O thậm chí tệ hơn, mà không cần thêm rác không liên quan có thể được kéo ra để giảm độ phức tạp của thời gian?

http://en.wikipedia.org/wiki/Big_O_notation có nhiều thời gian phức tạp khác nhau được sắp xếp theo thứ tự phát triển.

Chỉnh sửa: Tôi đã tìm thấy mã, đây là loại xác định O (n!) Của tôi với tính năng gây cười thú vị để tạo danh sách tất cả các kết hợp của danh sách. Tôi có một phiên bản get_all_combinations dài hơn một chút để trả về kết hợp có thể lặp lại, nhưng tiếc là tôi không thể làm cho nó thành một câu lệnh đơn lẻ. [Hy vọng rằng tôi đã không giới thiệu lỗi bằng cách sửa chữa lỗi chính tả và loại bỏ các dấu gạch trong đoạn mã dưới đây]

def mysort(somelist): 
    for permutation in get_all_permutations(somelist): 
     if is_sorted(permutation): 
      return permutation 

def is_sorted(somelist): 
    # note: this could be merged into return... something like return len(foo) <= 1 or reduce(barf) 
    if (len(somelist) <= 1): return True 
    return 1 > reduce(lambda x,y: max(x,y),map(cmp, somelist[:-1], somelist[1:])) 

def get_all_permutations(lst): 
    return [[itm] + cbo for idx, itm in enumerate(lst) for cbo in get_all_permutations(lst[:idx] + lst[idx+1:])] or [lst] 

Trả lời

0

Một cách mà tôi có thể nghĩ đến sẽ đến tính toán vị trí bài của từng phần tử thông qua một hàm thay đổi dần dần các phần tử lớn đến cuối và các phần tử nhỏ vào đầu. Nếu bạn sử dụng một hàm dựa trên trig, bạn có thể làm cho các phần tử thẩm thấu qua danh sách thay vì đi trực tiếp tới vị trí cuối cùng của chúng. Sau khi bạn đã xử lý từng phần tử trong tập hợp, sau đó thực hiện traversal đầy đủ để xác định xem mảng có được sắp xếp hay không.

Tôi không tích cực rằng điều này sẽ cung cấp cho bạn O (n!) Nhưng nó vẫn phải là khá chậm.

2

Luôn luôn NeverSort, đó là O (∞):

def never_sort(array) 
    while(true) 
    end 
    return quicksort(array) 
end 

PS: Tôi thực sự muốn nhìn thấy O xác định của bạn (! N) loại; Tôi không thể nghĩ rằng bất kỳ đó là O (n!), Nhưng có một giới hạn trên hữu hạn trong tính toán cổ điển (aka là xác định).

PPS: Nếu bạn đang lo lắng về trình biên dịch lau ra rằng có sản phẩm nào trong khi khối, bạn có thể buộc nó không bằng cách sử dụng một biến cả trong và ngoài khối:

def never_sort(array) 
    i=0 
    while(true) { i += 1 } 
    puts "done with loop after #{i} iterations!" 
    return quicksort(array) 
end 
0

Tôi nghĩ rằng nếu bạn làm rất nhiều sao chép sau đó bạn có thể nhận được một "hợp lý" tìm kiếm bạo lực (N!) để có N^2 thời gian cho mỗi trường hợp cho N! * N^2

8

Có một (đã được chứng minh!) Thuật toán phân loại tồi tệ nhất được gọi là slow sort sử dụng mô hình “nhân và đầu hàng” và chạy theo thời gian.

Trong khi thuật toán của bạn chậm hơn, nó không tiến triển đều đặn nhưng thay vào đó thực hiện các bước nhảy ngẫu nhiên. Ngoài ra, trường hợp tốt nhất của sắp xếp chậm vẫn còn theo cấp số nhân trong khi của bạn là hằng số.

0

Làm thế nào về vòng lặp qua tất cả các mảng t của n số nguyên (n-tuples của số nguyên là đếm được, vì vậy đây là doable mặc dù nó là một vòng lặp vô hạn tất nhiên), và cho mỗi người trong số này:

  • nếu nó các phần tử chính xác là các mảng của mảng đầu vào (xem bản ngã dưới đây!) và mảng được sắp xếp (ví dụ, ví dụ, nhưng tôi chắc chắn chúng ta có thể làm tồi tệ hơn), sau đó trả về t;
  • nếu không tiếp tục lặp lại.

Để kiểm tra xem hai mảng a và b có độ dài n chứa các phần tử giống nhau hay không, thuật toán đệ quy sau đây: lặp lại tất cả các cặp (i, j) của các chỉ số giữa 0 và n-1, vài ví dụ kiểm tra

  • nếu a [i] == b [j]:
  • nếu như vậy, trở về TRUE nếu và chỉ nếu một cuộc gọi đệ quy trên danh sách thu được bằng cách loại bỏ a [i] từ a và b [j] từ b trả về TRUE;
  • tiếp tục lặp qua các cặp vợ chồng và nếu tất cả các cặp vợ chồng đã hoàn thành, hãy trả lại FALSE.

Thời gian sẽ phụ thuộc rất nhiều vào việc phân phối các số nguyên trong mảng đầu vào.

Nghiêm túc, có một điểm cho câu hỏi như vậy không?

Edit:

@ Jon, sắp xếp ngẫu nhiên của bạn sẽ được trong thời gian O (n!) Trung bình (vì có n hoán vị, bạn có xác suất 1/n của việc tìm kiếm một trong những quyền!). Điều này giữ cho các mảng của các số nguyên khác nhau, có thể hơi khác nếu một số phần tử có nhiều lần xuất hiện trong mảng đầu vào, và sau đó sẽ phụ thuộc vào sự phân bố của các phần tử của mảng đầu vào (trong các số nguyên).

1

Bạn luôn có thể thực hiện sắp xếp Ngẫu nhiên. Nó hoạt động bằng cách sắp xếp lại tất cả các phần tử một cách ngẫu nhiên, sau đó kiểm tra xem nó có được sắp xếp hay không. Nếu không, nó ngẫu nhiên khu nghỉ dưỡng chúng. Tôi không biết làm thế nào nó sẽ phù hợp với ký hiệu big-O, nhưng nó chắc chắn sẽ chậm!

1

Đây là loại sắp xếp hữu hạn, chậm nhất mà bạn có thể nhận được:

Liên kết từng hoạt động của Quicksort với chức năng Beaver bận.

Khi bạn nhận được> 4 thao tác, bạn sẽ cần ký hiệu mũi tên lên :)