Đây là một văn bản dài. Xin vui lòng chịu với tôi. Đun sôi xuống, câu hỏi là: Có một thuật toán sắp xếp radix tại chỗ khả thi ?
Sơ bộ
Tôi đã có một số lượng lớn các chuỗi có độ dài cố định nhỏ chỉ sử dụng các chữ cái CẦN A, BẠC, VĂN, VĂN và VĂN (vâng, bạn đã đoán ra: DNA ) mà tôi muốn sắp xếp.
Hiện tại, tôi sử dụng sử std::sort
dụng introort trong tất cả các triển khai STL phổ biến . Điều này hoạt động khá tốt. Tuy nhiên, tôi tin rằng loại radix phù hợp hoàn hảo với vấn đề của tôi và sẽ hoạt động tốt hơn nhiều trong thực tế.
Chi tiết
Tôi đã thử nghiệm giả định này với một triển khai rất ngây thơ và đối với các đầu vào tương đối nhỏ (trên 10.000), điều này là đúng (tốt, ít nhất là nhanh hơn gấp đôi). Tuy nhiên, thời gian chạy xuống cấp rất nhiều khi kích thước sự cố trở nên lớn hơn ( N > 5.000.000).
Lý do rất rõ ràng: sắp xếp radix yêu cầu sao chép toàn bộ dữ liệu (thực tế hơn một lần trong quá trình thực hiện ngây thơ của tôi). Điều này có nghĩa là tôi đã đặt ~ 4 GiB vào bộ nhớ chính của mình, điều này rõ ràng sẽ giết chết hiệu suất. Ngay cả nếu không, tôi không thể đủ khả năng sử dụng bộ nhớ này vì kích thước của vấn đề thực sự còn lớn hơn.
Trường hợp sử dụng
Lý tưởng nhất là thuật toán này sẽ hoạt động với bất kỳ độ dài chuỗi nào trong khoảng từ 2 đến 100, đối với DNA cũng như DNA5 (cho phép thêm một ký tự đại diện ký tự gợi Niết), hoặc thậm chí DNA với mã mơ hồ IUPAC (dẫn đến 16 giá trị riêng biệt). Tuy nhiên, tôi nhận ra rằng tất cả các trường hợp này không thể được bảo hiểm, vì vậy tôi hài lòng với bất kỳ cải thiện tốc độ nào tôi nhận được. Mã có thể quyết định động để gửi thuật toán nào.
Nghiên cứu
Thật không may, bài viết Wikipedia về radix sort là vô dụng. Phần về một biến thể tại chỗ là rác hoàn toàn. Phần NIST-DADS về sắp xếp cơ số nằm cạnh không tồn tại. Có một bài báo đầy hứa hẹn được gọi là Phân loại Radix thích ứng tại chỗ hiệu quả , mô tả thuật toán này MSLiến. Thật không may, bài báo này, quá thất vọng.
Đặc biệt, có những điều sau đây.
Đầu tiên, thuật toán chứa một số lỗi và không giải thích được nhiều. Cụ thể, nó không nêu chi tiết cuộc gọi đệ quy (tôi chỉ đơn giản giả định rằng nó tăng hoặc giảm một số con trỏ để tính giá trị dịch chuyển và mặt nạ hiện tại). Ngoài ra, nó sử dụng các chức năng dest_group
và dest_address
không đưa ra định nghĩa. Tôi không thấy cách thực hiện những điều này một cách hiệu quả (nghĩa là trong O (1); ít nhất dest_address
là không tầm thường).
Cuối cùng nhưng không kém phần quan trọng, thuật toán đạt được vị trí tại chỗ bằng cách hoán đổi các chỉ số mảng với các phần tử bên trong mảng đầu vào. Điều này rõ ràng chỉ hoạt động trên các mảng số. Tôi cần sử dụng nó trên chuỗi. Tất nhiên, tôi chỉ có thể gõ phím mạnh và tiếp tục giả định rằng bộ nhớ sẽ chấp nhận việc tôi lưu trữ một chỉ mục nơi nó không thuộc về. Nhưng điều này chỉ hoạt động miễn là tôi có thể ép các chuỗi của mình vào 32 bit bộ nhớ (giả sử số nguyên 32 bit). Đó chỉ là 16 ký tự (hãy bỏ qua cho đến lúc 16> log (5.000.000)).
Một bài báo khác của một trong những tác giả không đưa ra mô tả chính xác nào cả, nhưng nó cho thời gian chạy của MSL là tuyến tính phụ, điều này hoàn toàn sai.
Tóm tắt lại : Có bất kỳ hy vọng tìm thấy một triển khai tham chiếu làm việc hoặc ít nhất là một mã giả / mô tả tốt về một loại cơ số hoạt động tại chỗ hoạt động trên các chuỗi DNA?