2010-03-29 39 views
20

Theo số Optimal (best known) sequence of increments for shell sort algorithm, của Marcin Ciura, trình tự tốt nhất cho shellsort là 1, 4, 10, 23, 57, 132, 301, 701 ..., nhưng làm cách nào để tạo chuỗi như vậy? Trong bài báo Marcin Ciura, ông nói:Trình tự khoảng cách nhanh nhất cho sắp xếp vỏ?

Cả hai của Knuth và chuỗi Hibbard là tương đối xấu, bởi vì họ là xác định bởi tái phát tuyến tính đơn giản.

nhưng hầu hết các sách thuật toán tôi thấy có xu hướng sử dụng trình tự Knuth: k = 3k + 1, vì dễ tạo. Cách của bạn tạo ra một trình tự shellsort là gì?

+1

Ai đó đã đào ra trình tự của tôi :-) Tôi đã triển khai thuật toán sắp xếp trên tập dữ liệu rất hạn chế về kích thước - khoảng 10 đến 50 và tôi thấy shellsort là trình duyệt nhanh nhất trong phạm vi này. Tôi tìm kiếm kỹ lưỡng trình tự tốt nhất - và tìm thấy chủ yếu là Knuth, Sedgewicks, vv, mà chủ yếu dựa trên voodoo và kumba wamba. Marcin Ciuara có vẻ là một trong số ít những người thực sự đã làm một số tiêu chuẩn và có cái gì đó tốt hơn so với trình tự dựa trên một công thức ma thuật, và đây là lý do chính tôi đăng nó trên OEIS. Nhưng tôi không có câu trả lời cho bạn. – hirschhornsalz

+0

Trình tự phải được giảm nghiêm ngặt và yếu tố cuối cùng của nó luôn luôn là 1. Nếu khoảng cách là 1, nó có nghĩa là sắp xếp cổ điển. Vì vậy, chuỗi của Ciura chính xác là [701, 301, 132, 57, 23, 10, 4, 1]. Tôi đã thực hiện một số thử nghiệm và trình tự ban đầu của Shell hoạt động tốt hơn cho tôi. – Jabba

+0

Liên kết bạn đã cung cấp bị hỏng. _ "Tăng trưởng tốt nhất cho trường hợp trung bình của Shellsort" _: [abstract] (http://www.springerlink.com/content/2akgu9pvc6jl239g/) và [full paper] (http://sun.aei.polsl.pl/ ~ mciura/publikacje/shellsort.pdf) – user46874

Trả lời

5

Nếu tập dữ liệu của bạn có giới hạn trên xác định, thì bạn có thể mã hóa chuỗi bước. Bạn có lẽ chỉ nên lo lắng về tính tổng quát nếu tập dữ liệu của bạn có khả năng phát triển mà không có giới hạn trên.

Trình tự hiển thị dường như phát triển gần như là một chuỗi số mũ, mặc dù có quirks. Dường như phần lớn các số nguyên tố, nhưng cũng không có số nguyên tố trong kết hợp. Tôi không thấy một công thức thế hệ rõ ràng.

Câu hỏi hợp lệ, giả sử bạn phải xử lý các tập hợp lớn tùy ý, cho dù bạn cần nhấn mạnh hiệu suất trường hợp xấu nhất, hiệu suất trung bình hoặc hiệu suất gần như được sắp xếp. Nếu sau này, bạn có thể thấy rằng một sắp xếp chèn đơn giản bằng cách sử dụng tìm kiếm nhị phân cho bước chèn có thể tốt hơn một shellsort. Nếu bạn cần hiệu suất tốt nhất trong trường hợp xấu, thì trình tự của Sedgewick dường như được ưa chuộng. Chuỗi bạn đề cập được tối ưu hóa cho hiệu suất trung bình, trong đó số lần so sánh vượt quá số lần di chuyển.

+0

Không phải là công cụ của Sedgewick O (N^(4/3)) trong khi đưa ra trường hợp tốt nhất O (n * log (n))? Tôi có nghĩa là có nhanh hơn O (n * log^2 (n)) trình tự trường hợp xấu nhất nhưng với trường hợp xấu nhất tốt nhất ... – Ivan

13

Giấy của Ciura tạo ra chuỗi theo kinh nghiệm - tức là, ông đã thử một loạt các kết hợp và đây là một trong những cách làm việc tốt nhất. Việc tạo ra một trình tự shellsort tối ưu đã được chứng minh là phức tạp, và vấn đề cho đến nay vẫn có khả năng chống phân tích.

Mức tăng được biết đến nhiều nhất là Sedgewick's, mà bạn có thể đọc về here (xem trang 7).

4

tôi sẽ không xấu hổ để có những lời khuyên được đưa ra trong bài viết của Wikipedia Shellsort,

đối với số lượng trung bình các phép so sánh, khoảng cách nổi tiếng nhất trình tự là 1, 4, 10, 23, 57 Với , 132, 301, 701 và tương tự, với khoảng trống được tìm thấy bằng thực nghiệm. Khoảng cách tối ưu vượt quá 701 vẫn chưa được biết, nhưng tốt có thể thu được kết quả bằng cách mở rộng chuỗi trên theo công thức đệ quy h_k = \ lfloor 2,25 h_ {k-1} \ rfloor.

Trình tự Tokuda [1, 4, 9, 20, 46, 103, ...], được xác định theo công thức đơn giản h_k = \ lceil h'_k \ rceil, trong đó h'k = 2,25h'k - 1 + 1, h'1 = 1, có thể được đề xuất cho ứng dụng thực tế.

đoán từ bút danh, có vẻ như Marcin Ciura đã tự chỉnh sửa bài viết trên WP.

2

Trình tự là 1, 4, 10, 23, 57, 132, 301, 701, 1750. Đối với mỗi số tiếp theo sau 1750 nhân số trước đó với 2,25 và làm tròn xuống.

+0

Không, Không & Không !! Rõ ràng là nó sẽ thất bại với 4,10,23 ... – Enissay

+0

Đã thêm "sau 1750". Nó có đúng không? –

0

tôi đã tìm thấy chuỗi này tương tự như chuỗi Marcin Ciura của:

1, 4, 9, 23, 57, 138, 326, 749, 1695, 3785, 8359, 18298, 39744, etc. 

Ví dụ, chuỗi Ciura là:

1, 4, 10, 23, 57, 132, 301, 701, 1750 

Đây là một trung bình của số nguyên tố. Python mã để tìm nghĩa của số nguyên tố là ở đây:

import numpy as np 

def isprime(n): 
    ''' Check if integer n is a prime ''' 
    n = abs(int(n)) # n is a positive integer 
    if n < 2: # 0 and 1 are not primes 
     return False 
    if n == 2: # 2 is the only even prime number 
     return True 
    if not n & 1: # all other even numbers are not primes 
     return False 
    # Range starts with 3 and only needs to go up the square root 
    # of n for all odd numbers 
    for x in range(3, int(n**0.5)+1, 2): 
     if n % x == 0: 
      return False 
    return True 

# To apply a function to a numpy array, one have to vectorize the function 
vectorized_isprime = np.vectorize(isprime) 

a = np.arange(10000000) 
primes = a[vectorized_isprime(a)] 
#print(primes) 
for i in range(2,20): 
    print(primes[0:2**i].mean()) 

Đầu ra là:

4.25 
9.625 
23.8125 
57.84375 
138.953125 
326.1015625 
749.04296875 
1695.60742188 
3785.09082031 
8359.52587891 
18298.4733887 
39744.887085 
85764.6216431 
184011.130096 
392925.738174 
835387.635033 
1769455.40302 
3735498.24225 

Khoảng cách trong chuỗi đang dần giảm từ 2,5 đến 2. Có lẽ sự kết hợp này có thể cải thiện Shellsort trong tương lai.

Các vấn đề liên quan