Hầu như sắp xếp các số nguyên trong thời gian tuyến tính


16

Tôi quan tâm đến việc sắp xếp một mảng các giá trị nguyên dương theo thời gian tuyến tính (trong mô hình RAM với thước đo chi phí đồng nhất, nghĩa là các số nguyên có thể có kích thước logarit nhưng các hoạt động số học trên chúng được giả định đơn vị thời gian). Tất nhiên, điều này là không thể đối với các thuật toán sắp xếp dựa trên so sánh, vì vậy tôi quan tâm đến việc tính toán một loại "gần đúng", nghĩa là tính toán một số hoán vị của không thực sự được sắp xếp nói chung mà là "xấp xỉ tốt" của phiên bản sắp xếp . Tôi sẽ giả định rằng chúng ta đang sắp xếp các số nguyên theo thứ tự giảm dần vì nó làm cho phần tiếp theo trở nên dễ chịu hơn một chút, nhưng tất nhiên người ta có thể diễn đạt vấn đề theo cách khác.L=v1,,vnvσ(1),,vσ(n)LL

Một tiêu chí có thể có cho một loại sắp xếp gần đúng là (*): đặt là , với mỗi , chúng tôi yêu cầu (nghĩa là, danh sách "sắp xếp gần đúng" được giới hạn từ phía trên bởi hàm giảm ). Dễ dàng thấy rằng sắp xếp thực tế thỏa mãn điều này: phải không lớn hơn vì vậy nó nhiều nhất là và nói chung phải không lớn hơn làNivi1invσ(i)N/iiN/ivσ(2)vσ(1)(vσ(1)+vσ(2))/2N/2vσ(i)(jivσ(i))/iN/i.

Chẳng hạn, yêu cầu (*) có thể đạt được bằng thuật toán bên dưới (được đề xuất bởi @Louis). Câu hỏi của tôi là: Có công việc hiện tại về nhiệm vụ "gần như sắp xếp" số nguyên này trong thời gian tuyến tính, bằng cách áp đặt một số yêu cầu như (*) mà sắp xếp thực sự sẽ đáp ứng? Liệu thuật toán dưới đây, hoặc một số biến thể của nó, có một tên được thiết lập?

Chỉnh sửa: sửa lỗi thuật toán và thêm giải thích


Thuật toán:

INPUT: V an array of size n containing positive integers
OUTPUT: T

N = Σ_{i<n} V[i]
Create n buckets indexed by 1..n
For i in 1..n
| Add V[i] into the bucket min(floor(N/V[i]),n)
+

For bucket 1 to bucket n
| For each element in the bucket
| | Append element to T
| +
+

Thuật toán này hoạt động như dự định vì những lý do sau:

  1. Nếu một phần tử nằm trong nhóm thì . vjvN/j

    v được đặt vào thùng , do đó j ≤ \ lfloor N / v \ rfloor N / vj=min(N/v,n)jN/vN/v

  2. Nếu một phần tử nằm trong nhóm thì hoặc . vjN/(j+1)<vj=n

    v được đặt vào thùng , do đó hoặc . Trong trường hợp đầu tiên có nghĩa là và do đó .j=min(N/v,n)j=N/vj=nj=N/vjN/v<j+1N/(j+1)<v

  3. Đối với , có nhiều nhất là các phần tử trong các xô từ 1 đến .j<njj

    Đặt và gọi là tổng số phần tử trong một trong các nhóm 1..j. Bằng 2. chúng ta có mọi phần tử trong một thùng (với ) sao cho . Do đó, tổng của tất cả các phần tử trong các thùng từ đến lớn hơn . Nhưng tổng này cũng nhỏ hơn do đó và do đó mang lại cho chúng ta hoặc .j<nkv i i j N / ( j + 1 ) N / ( i + 1 ) < v K 1 j k × N / ( J + 1 ) KviijN/(j+1)N/(i+1)<vK1jk×N/(J+1)KNk×N/(j+1)<KNk/(j+1)<1k<j+1kj

  4. T thỏa mãn (*) tức là phần tử thứ của sao chojTT[j]N/j

    Đến 3. ta có , phần tử thứ của , xuất phát từ một nhóm với do đó .T[j]jTiijT[j]N/iN/j

  5. Thuật toán này mất thời gian tuyến tính.

    Việc tính toán mất thời gian tuyến tính. Các thùng có thể được thực hiện với một danh sách liên kết có chèn và lặp . Vòng lặp lồng nhau chạy nhiều lần như có các phần tử (tức là lần).NO(1)n


1
Không bỏ qua câu hỏi (+1, đây là một câu hỏi hay) nhưng sẽ không loại radix sắp xếp nhiều hơn những gì bạn cần?
Mehrdad

@Mehrdad: Cảm ơn bình luận của bạn! Radix sort sẽ sắp xếp các số nguyên, nhưng sẽ mất thời gian . O(nlog(maxivi))
a3nm

Bạn có thể bình luận về những gì chính xác là không mong muốn về sự phức tạp thời gian đó? Bạn có một số nguyên rất lớn và mọi thứ khác đều nhỏ không?
Mehrdad

1
@ a3nm radix sort không phải là O (n log n) mà là O (n) do đó tuyến tính nếu kích thước của các số nguyên là cố định, ví dụ số 32 bit hoặc số 64 bit. Các số bạn sắp xếp có kích thước thay đổi?
Xavier Combelle

1
@XavierCombelle: Có, tôi đang làm việc trong mô hình RAM và tôi không thể cho rằng các số nguyên đầu vào bị giới hạn bởi một hằng số.
a3nm

Câu trả lời:


8

Điều này nghe có vẻ giống như thuật toán ASort. Xem bài viết này của Giesen et. al.:

https://www.inf.ethz.ch/personal/smilos/asort3.pdf

Thật không may, thời gian chạy không hoàn toàn tuyến tính. Bài viết trên chứng minh rằng mọi thuật toán ngẫu nhiên dựa trên so sánh xếp hạng mục trong có giới hạn dưới của (giả sử ).n 2 / ν ( n ) n l o g ( ν ( n ) ) ν ( n ) < nnn2/ν(n)nlog(ν(n))ν(n)<n


EDIT , để đáp lại những làm rõ trong câu hỏi:

Những gì bạn đang làm chỉ đơn giản là một loại xô . Tuy nhiên, thuật toán sắp xếp xô không tuyến tính trong trường hợp này. Vấn đề: bạn phải tính tổng các số tự nhiên và sau đó thực hiện phép chia trên từng số đó. Vì các số không có kích thước không giới hạn, không còn là hoạt động thời gian không đổi. Sẽ mất nhiều thời gian hơn để thực hiện nhiều số bạn cần tổng hợp.N/V[i]

Bao lâu nữa? Phân chia phụ thuộc vào số chữ số, do đó, , lần hoạt động phân chia. Điều đó có lẽ nghe quen thuộc. :)nlg(n)n


1
Cảm ơn đã chỉ cho chúng tôi bài viết này! Quả thực đó là một chút liên quan đến câu hỏi. Tuy nhiên, thuật toán của tôi (không phải phiên bản gốc và phiên bản sửa đổi hơi khác nhau) không giống với ASort;. Đầu tiên, tôi tin rằng thuật toán của tôi chạy trong , không phải trong thời gian siêu tuyến như ASort. Thứ hai, tiêu chí (*) khá khác biệt với khoảng cách gần đúng của Spearman; ví dụ: tiêu chí (*) chặt chẽ hơn hoặc ít hơn tùy thuộc vào các giá trị của số nguyên, không giống như khoảng cách chân. Thứ ba, mặc dù cả thuật toán và ASort của chúng tôi đều là các yếu tố xô, tiêu chí khá khác nhau. O(n)
a3nm

@ a3nm Việc làm rõ những gì bạn đã đăng ở trên cho thấy bạn đang sử dụng một loại xô , là tuyến tính (và không dựa trên so sánh, có nghĩa là thử nghiệm hai mặt hàng với nhau). Vấn đề là nó không hoạt động cho tất cả các số nguyên toán học. Nó chỉ hoạt động nếu kích thước số nguyên bị giới hạn.
Trixie Wolf

Khi bạn nói "Nó chỉ hoạt động nếu kích thước nguyên bị giới hạn", tôi nghĩ điều này chỉ đúng nếu tôi thực sự sắp xếp các số nguyên. Nhưng nói chung, thuật toán tôi đã đăng không thực sự sắp xếp chúng, nó chỉ thực thi tiêu chí yếu hơn (*). Vì vậy, tôi nghĩ rằng nó chạy trong thời gian tuyến tính ngay cả khi kích thước số nguyên không bị giới hạn.
a3nm

2
@ a3nm Nó không tuyến tính. Xem phản ứng mở rộng của tôi ở trên.
Trixie Wolf

nlogn

2

Hóa ra, câu hỏi của tôi khá là không liên quan. Thật vậy, tôi đang làm việc trên máy RAM với thước đo chi phí thống nhất (nghĩa là chúng ta có các thanh ghi mà các thanh ghi không nhất thiết phải có kích thước không đổi nhưng có thể lưu trữ các số nguyên có kích thước logarit trong đầu vào và hoạt động trên các thanh ghi này mất nhiều thời gian, bao gồm ít nhất là bổ sung). Và trên thực tế, trong mô hình này, việc sắp xếp các số nguyên (bằng cách thực hiện một loại cơ số) có thể được thực hiện trong thời gian tuyến tính. Điều này được giải thích trong bài báo năm 1996 của Grandjean, Sắp xếp, thời gian tuyến tính và vấn đề thỏa đáng .

(Điều này không trả lời câu hỏi của tôi về việc liệu có những khái niệm được nghiên cứu kỹ về "gần như sắp xếp" một bộ số nguyên hay không, nhưng để chúng thú vị, có lẽ người ta sẽ cần những khái niệm yếu hơn này để dễ thực thi hơn, ví dụ, làm việc trên một yếu hơn mô hình hoặc bằng cách nào đó chạy trong thời gian tuyến tính. Tuy nhiên, hiện tại tôi không nhận thức được ý nghĩa trong trường hợp nà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.