Tại sao cơ sở được sử dụng để tính băm trong Rabin Giàn Karp luôn luôn là số nguyên tố?


8

Thuật toán khớp chuỗi Rabin từ Karp yêu cầu hàm băm có thể được tính toán nhanh chóng. Một lựa chọn phổ biến là trong đó là số nguyên tố (tất cả các tính toán là mô-đun , trong đó là chiều rộng của một từ máy). Tại sao điều quan trọng đối với là số nguyên tố?

h(x0xn)=i=0nbixi,
b2wwb

Hãy cho tôi biết nếu tôi hiểu nhầm câu hỏi của bạn.
Yuval Filmus

@YuvalFilmus không, bạn đã lấy nó đúng cách ....
sdream

Câu trả lời:


9

Một tóm tắt nhanh đầu tiên. Chúng tôi đang tìm kiếm một mô hìnhP[1m] trong một chuỗi S[1n]. Thuật toán Rabin-Karp thực hiện điều này bằng cách xác định hàm bămh. Chúng tôi tính toánh(P) (đó là hàm băm của mẫu) và so sánh nó với h(S[1Giáo dụcm]), h(S[2Giáo dụcm+1])và như thế. Nếu chúng ta tìm thấy một hàm băm phù hợp, thì đó là một chuỗi con phù hợp tiềm năng.

Hiệu quả của thuật toán phụ thuộc vào khả năng tính toán h(S[r+1Giáo dụcS+1]) hiệu quả từ h(S[rGiáo dụcS]). Điều này được gọi là "băm lăn". Lưu ý rằng bất kỳ hàm băm cán hiệu quả nào cũng được, và đó vẫn là Rabin-Karp. Câu hỏi mà bạn đang hỏi là một lựa chọn cụ thể của hàm băm, nơi bạn sử dụng:

h(S[rGiáo dụcS])= =ΣTôi= =rSS[Tôi]pS-Tôimodq

Trong đó là số nguyên tố có cùng độ lớn với kích thước của bộ ký tự và là một số nguyên tố khác xác định mức độ chính xác của phạm vi của hàm băm, thường có cùng độ lớn với từ máy chia cho kích thước bộ ký tự. Nếu tôi đang đọc chính xác, bạn sẽ hỏi tại sao phải là số nguyên tố.pqq

Trong thực tế, đây là một câu hỏi tổng quát hơn. Trong rất nhiều tài liệu cũ (và hiện tại) về băm, lời khuyên là hàm băm nên được lấy modulo một số nguyên tố (ví dụ: bảng băm nên có kích thước nguyên tố).

Để hàm băm trở nên hữu ích nhất có thể, phạm vi của nó cần phải tương đối đồng đều, ngay cả khi tên miền của nó không. Văn bản ngôn ngữ tự nhiên (giả sử) không có phân phối tần số thống nhất, nhưng giá trị băm nên có.

Nếu là số nguyên tố, thì rất nhiều số khác tương đối nguyên tố với nó, và đặc biệt, tổng (đặc biệt nếu cũng là số nguyên tố!). Điều này làm cho phân phối tần số của các giá trị băm đồng đều hơn, mặc dù hàm băm tương đối yếu.qp

Điều quan trọng là phải hiểu rằng chúng tôi làm điều này bởi vì hàm băm yếu. Nếu hàm băm mạnh hơn, lấy phần còn lại khi chia cho số nguyên tố là không cần thiết; bạn có thể, ví dụ, lấy phần còn lại khi chia cho công suất hai, sẽ là một hoạt động mặt nạ bit rẻ hơn nhiều. Tuy nhiên, thật khó để thiết kế các hàm băm cán mạnh, đủ rẻ để thực hiện cho mọi ký tự đầu vào trong thuật toán Rabin-Karp.

Một cái gì đó đáng để chỉ ra rằng kỹ thuật "phần còn lại của một nguyên tố" này thường được sử dụng trong nhiều ứng dụng băm, nhưng lời khuyên này không phù hợp với phần cứng hiện đại. Lời khuyên này có ý nghĩa một lần, bởi vì trong khi hướng dẫn phân chia số nguyên cuối cùng luôn đắt tiền, thì các thao tác mà bạn đã sử dụng để tính hàm băm của mình, chẳng hạn như nhân số nguyên. Trên các CPU hiện đại, việc phân chia số nguyên sẽ tốn kém hơn nhiều so với phép nhân số nguyên.

Hệ số nhân bộ cộng mang theo hiện đại được sắp xếp đầy đủ, do đó bạn có thể có một số hướng dẫn như vậy được thực thi cùng một lúc. Các bộ chia hiện đại sử dụng thuật toán SPH hoặc Goldschmidt, là các chu trình đa chu kỳ và không thể thực hiện được. Bộ chia Goldschmidt cũng gắn kết đơn vị nhân, làm cho hiệu suất đạt được thậm chí còn lớn hơn.

Tôi đã có các chương trình trong đó hướng dẫn phân chia này là nút cổ chai và điều khó chịu là nó bị ẩn trong thư viện chuẩn.

Trên CPU hiện đại, đáng sử dụng hàm băm tinh vi hơn được xây dựng từ các hoạt động có thể kết hợp hoàn toàn (ví dụ: bội số hoặc thậm chí tra cứu bảng) và sử dụng các bảng băm có sức mạnh bằng hai, vì vậy thao tác modulo là mặt nạ bit. Làm bất cứ điều gì để tránh hoạt động phân chia đó.

Chỉ không dành cho Rabin-Karp.

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.