Sự phức tạp của việc áp dụng một hoán vị tại chỗ


27

Thật ngạc nhiên, tôi đã không thể tìm thấy các bài báo về điều này - có thể đã tìm kiếm các từ khóa sai.

Vì vậy, chúng ta đã có một mảng của bất cứ thứ gì, và một hàm trên các chỉ số của nó; là hoán vị.ff

Làm thế nào để chúng ta sắp xếp lại mảng theo với bộ nhớ và thời gian chạy càng gần và càng tốt?fO(1)O(n)

Có bất kỳ điều kiện bổ sung khi nhiệm vụ này trở nên dễ dàng hơn? Ví dụ khi chúng ta biết rõ một hàm là nghịch đảo của ?fgf

Tôi biết một thuật toán theo chu kỳ và đi qua một chu kỳ cho mỗi chỉ số để kiểm tra xem nó có phải là ít nhất trong chu kỳ của nó không, nhưng một lần nữa, nó có thời gian chạy tồi tệ nhất O(n2), mặc dù trung bình nó có vẻ hoạt động tốt hơn. ..


Một quan sát dễ dàng: Nếu không chỉ mảng của các mục mà cả mảng chứa hàm f có thể ghi được, thì bạn có thể dễ dàng thực hiện tác vụ trong thời gian O (n) bằng cách sử dụng các thanh ghi số nguyên O (1) (mỗi chiều dài O (mỗi chiều dài O (1) log n) bit) và không gian bổ sung cho một mục bằng cách chỉ sau mỗi chu kỳ. Nhưng điều này không hoạt động nếu hàm f được cung cấp trên bộ lưu trữ chỉ đọc (hoặc f chỉ được cung cấp dưới dạng một lời tiên tri), mà tôi nghĩ là một giả định trong câu hỏi này.
Tsuyoshi Ito

23
Fich et al. 1995 : Không gian , không gian O ( log n ) . Nó cũng thảo luận về một số trường hợp đặc biệt. O(nlogn)O(logn)
Jukka Suomela

Vâng, tôi cho rằng chúng ta có f là một nhà tiên tri.
jkff

3
@JukkaSuomela, bạn nên biến nó thành một câu trả lời. Ngoài ra, coi là một hoán vị tùy ý, một đối số entropy đơn giản mang lại không gian và / hoặc thời gian O ( n log n ) , vì vậy tôi sẽ ngạc nhiên nếu bạn có thể làm tốt hơn O ( n log n ) về thời gian không gian. fO(nlogn)O(nlogn)
dùng834

Câu trả lời:


4

Tùy chọn 0: Cho phép tại chỗ (1995) bởi Faith E. Fich, J. Ian Munro, Patricio V. Poblete time O ( log 2 n ) space.O(nlogn)O(log2n)

Tùy chọn 1: Gian lận bằng cách nén hoán vị của bạn vào cấu trúc dữ liệu cô đọng, xem Munro http://www.itu.dk/people/ssrao/icalp03-a.pdf .

Tùy chọn 2: Sử dụng phân tách chu kỳ chính để lưu trữ perm một cách ngắn gọn và sử dụng khoảng trống thừa đó để gian lận http://oeis.org/A186202

Tùy chọn 3: Theo dõi chỉ số lớn nhất của mỗi chu kỳ thao tác. Đối với mỗi lần lặp, sử dụng chỉ số vô hình lớn nhất để di chuyển mọi thứ trong chu kỳ của nó theo một. Nếu nó chạm vào một chỉ mục đã thấy thì hoàn tác tất cả công việc đó vì chu trình đã bị thao túng. , không gian O ( # chu kỳ log n ) .O(n2)O(#cycleslogn)

Tùy chọn 4: Theo dõi chỉ số lớn nhất của mỗi chu kỳ được thao tác, nhưng chỉ thực hiện chúng theo lô có độ dài chu kỳ riêng biệt. Đối với mỗi lần lặp, sử dụng chỉ số vô hình lớn nhất để di chuyển mọi thứ trong chu kỳ của nó. Nếu nó đạt một chỉ số nhìn thấy hoàn tác tất cả các công việc đó vì chu trình thae đã bị thao túng. thời gian, O ( ( # chu kỳ _ với _ cùng _ kích thước ) * log n ) không gian.O(n2distinct_cycle_lengths)O((#cycles_with_same_size)logn)

Tùy chọn 5: Từ cùng một tờ giấy của Munro là Tùy chọn 0, Với xoay chu kỳ của p ( i ) nếu i là chỉ số lớn nhất trong chu kỳ đó. Thời gian O ( n 2 ) và không gian O ( log n ) .i=1..np(i)iO(n2)O(logn)


các phương thức nén có thể không tiết kiệm không gian nói chung: không gian trường hợp xấu nhất để lưu trữ một hoán vị là . Nhìn chung, 3, 4 và 5 dường như tệ như giải pháp mà OP đã biết hoặc giải pháp của Fich, Munro và Poblete. Và giải pháp đó đã được chỉ ra bởi @Jukkanlogn
Sasho Nikolov

# 5 sử dụng ít không gian hơn # 0 theo hệ số log (n).
Chad Brewbaker

1

Nếu bạn sử dụng biểu diễn chu kỳ của hoán vị, bạn cần thêm 1 phần tử mảng để lưu trữ mục hiện đang được hoán vị và bạn có thể chạy qua các chu kỳ trong các hoạt động O (N) tồi tệ hơn.


2
jkff đã nói rằng anh ta biết thuật toán theo chu kỳ, vì vậy anh ta rõ ràng muốn chính phép hoán vị được coi là (gần) một hộp đen. Như ông chỉ ra trong câu hỏi, chuyển đổi từ hộp đen (gần) sang biểu diễn chu kỳ có thể mất thời gian O (n ^ 2).
Joshua Grochow

Hộp đen p (i) là tốt. Bạn chỉ cần đi xung quanh chu kỳ cho đến khi bạn quay lại với tôi. Vấn đề là một trong những phức tạp của Kolomogorov để lưu trữ danh sách các mục đã được cập nhật để bạn không quay vòng chúng nhiều lần. Munro có giới hạn về điều đó. itu.dk/people/ssrao/icalp03-a.pdf
Chad

-2

Bất kỳ hoán vị của N mục có thể được chuyển đổi thành bất kỳ hoán vị khác bằng cách sử dụng N-1 hoặc ít hơn trao đổi. Trường hợp xấu nhất cho phương thức này có thể yêu cầu các cuộc gọi O (n ^ 2) đến nhà tiên tri của bạn, F (). Bắt đầu từ vị trí ít nhất. Đặt x là vị trí chúng ta hiện đang trao đổi.

Nếu F (x)> = x thì hoán đổi vị trí x và F (x). Khác, chúng ta phải tìm vị trí của mục ở vị trí F (x) hiện tại trong danh sách. Chúng ta có thể làm điều này với lần lặp sau. Đặt y = F (x). Làm cho đến khi y> = x: y = F (y): Kết thúc Do. Bây giờ trao đổi vị trí x và y.


3
O(n2)

Lấy làm tiếc. Tôi mới tham gia nhóm này. Tôi thích phương pháp này vì tính đơn giản của nó. Đôi khi tôi thấy sự đơn giản nhanh hơn hiệu quả. Tôi biết một phương thức khác yêu cầu các bước O (n), nhưng không gian O (nlogn).
Russell Phục sinh

1
Russell, thậm chí phân bổ và zeroing không gian O (n log n) đã là O (n log n), ý bạn là theo hướng khác?
jkff

Bạn không thực sự có phân bổ và không gian. Ý tưởng cơ bản là khi F (x)> x chúng ta cần nhớ nơi chúng ta đặt vật phẩm ở vị trí x. Đối với n thực sự lớn, tôi sẽ sử dụng cơ sở dữ liệu và chỉ cần ghi lại nơi mục x được di chuyển. Bản ghi có thể bị xóa khi x đến vị trí cuối cùng.
Russell Phục sinh

1
Nhưng tại sao sau đó bạn lại nói rằng nó yêu cầu không gian O (n log n)?
jkff

-2

Phương pháp này sử dụng nghịch đảo của F và yêu cầu n bit lưu trữ. Nếu x là vị trí của một mục trong mảng ban đầu, hãy để G (x) là vị trí của mục trong mảng được sắp xếp. Đặt B là một mảng n bit. Đặt tất cả n bit của B thành 0.

CHO x = 1 đến n-1: NẾU B (x) == 0 THEN: y = G (x): DO UNTIL x == y: Hoán đổi vị trí x và y: B (y) = 1: y = G ( y): LOOP: ENDIF: TIẾP X

Phương pháp này tiếp tục hoán đổi vật phẩm hiện tại ở vị trí x đến vị trí cuối cùng của vật phẩm. Vòng lặp bên trong kết thúc khi mục chính xác được hoán đổi vào vị trí x. Vì mỗi trao đổi di chuyển ít nhất một mục vào vị trí cuối cùng của mục, vòng lặp Do bên trong không thể thực hiện nhiều hơn n-1 lần trong khi chạy. Tôi nghĩ phương pháp này là O (n) thời gian và không gian.


2
Bạn đã nhìn vào tờ giấy? Hai thuật toán bạn liệt kê ở đây là hai thuật toán "hiển nhiên". Bài viết có ít rõ ràng hơn với sự đánh đổi không gian thời gian khác nhau, đặc biệt là không gian ít hơn nhiều.
Yuval Filmus
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.