Làm thế nào là bảng băm O (1) có tính đến tốc độ băm?


8

Bảng băm được cho là khấu hao Θ(1) sử dụng tiếng nói đơn giản chaining và tăng gấp đôi tại một năng lực nhất định.

Tuy nhiên, điều này giả định độ dài của các phần tử là không đổi. Tính toán các hash của một phần tử đòi hỏi phải trải qua các phần tử, lấy Θ(l) thời gian mà l là chiều dài.

Nhưng để phân biệt giữa n phần tử, chúng ta cần các phần tử có độ dài ít nhất là lgn bit; mặt khác theo nguyên tắc pigeonhole họ sẽ không khác biệt. Các hàm băm đi qua lgn bit của nguyên tố là sẽ mất Θ(lgn) thời gian.

Vì vậy, chúng ta có thể thay vì nói rằng tốc độ của một bảng băm, có tính đến một hàm băm hợp lý trong đó sử dụng tất cả các bộ phận của đầu vào, thực sự là Θ(lgn) ? Tại sao, sau đó, các bảng băm trong thực tế có hiệu quả để lưu trữ các phần tử có độ dài thay đổi, chẳng hạn như chuỗi và số nguyên lớn?



4
Câu trả lời là họ không có . Kiểu phân tích băm này không tính đến kích thước (hoặc số bit) của các phần tử, mà chỉ tính vô số của chúng.
Nikos M.

Nhưng nếu một cái nhìn lên bản đồ băm đó sẽ là không xem xét việc đọc và viết các bit như mô tả, là Θ ( l g n ) , sau đó theo các tiêu chuẩn giống nhau, một tìm kiếm nhị phân hoặc bất kỳ quá trình khác mà chúng tôi thường xem xét Θ l g n thực sự sẽ là Θ ( l g 2 n ) phải không? Θ(1)Θ(lg n)Θlg nΘ(lg2 n)


@tAllan Một tìm kiếm nhị phân thông thường sẽ là nhưng nếu bạn giữ những vật được sắp xếp theo trình tự chút phím của họ và làm tìm kiếm nhị phân so sánh 'một chút tại một thời điểm' (xem chi tiết phức tạp bỏ qua), bạn có thể có thể đạt Θ ( log n ) . Θ(log2n)Θ(logn)
Phục hồi lại

Câu trả lời:


3

Câu chuyện mà bảng băm được khấu hao theo một lời nói dối một sự đơn giản hóa. Θ(1)

Điều này chỉ đúng nếu:
- Lượng dữ liệu để băm trên mỗi mục là không đáng kể so với số lượng K eys và tốc độ băm của một mắt K là nhanh - . - Số lượng ollutions C nhỏ - c . - Chúng tôi không tính đến thời gian cần thiết để R esize bảng băm - r .k
c
r

Chuỗi lớn để băm
Nếu giả thiết đầu tiên là sai thời gian chạy sẽ đi lên đến . Điều này chắc chắn đúng với các chuỗi lớn, nhưng đối với các chuỗi lớn, một phép so sánh đơn giản cũng sẽ có thời gian chạy là Θ ( k ) . Vì vậy, một băm không là tiệm chậm, mặc dù băm sẽ luôn chậm hơn so với một so sánh đơn giản, bởi vì so sánh có một lựa chọn đầu ra ergo O ( 1 ) , Ω ( k ) và băm luôn luôn phải băm đầy đủ chuỗi O ( k ) , Ω ( k )Θ(k)
Θ(k)O(1)Ω(k)O(k)Ω(k).

Lưu ý rằng số nguyên tăng trưởng rất chậm. 8 byte có thể lưu trữ giá trị lên tới ; 8 byte là một lượng nhỏ để băm. Nếu bạn muốn lưu trữ các gợi ý thì chỉ cần nghĩ về chúng như các chuỗi. 1018

Thuật toán băm chậm
Nếu số tiền băm chi tiêu là không đáng kể so với việc lưu trữ dữ liệu thì rõ ràng giả định trở nên không thể thực hiện được. Trừ khi băm mật mã được sử dụng, điều này không phải là một vấn đề.Θ(1)

Rằng điều quan trọng là > > k . Chừng nào chứa Θ ( 1 ) là một tuyên bố công bằng.n >> kΘ(1)

Nhiều va chạm
Nếu chức năng băm kém, hoặc bảng băm nhỏ hoặc kích thước của bảng băm là va chạm vụng về sẽ xảy ra thường xuyên và thời gian chạy sẽ chuyển sang . Nên chọn chức năng băm để các va chạm hiếm khi xảy ra trong khi vẫn nhanh nhất có thể, khi nghi ngờ lựa chọn ít va chạm hơn với chi phí băm chậm hơn. Một nguyên tắc nhỏ là bảng băm phải luôn đầy dưới 75%. Và kích thước của bảng băm không nên có bất kỳ mối tương quan nào với chức năng băm. Thông thường kích thước của bảng băm là (tương đối) nguyên tố. O(log(n))



Thay đổi kích thước bảng băm
Vì một bảng băm gần đầy sẽ tạo ra quá nhiều va chạm và bảng băm lớn (trống) là một sự lãng phí không gian, nhiều triển khai cho phép bảng băm phát triển (và thu nhỏ!) Khi cần.
Sự phát triển của một bảng có thể liên quan đến một bản sao đầy đủ của tất cả các mục (và có thể là cải tổ lại), vì việc lưu trữ cần phải liên tục vì lý do hiệu suất.
Chỉ trong các trường hợp bệnh lý, việc thay đổi kích thước của bảng băm mới là một vấn đề để thay đổi kích thước (tốn kém nhưng hiếm) được khấu hao qua nhiều cuộc gọi.

Chạy thời gian
Vì vậy, thực tế thời gian chạy của một bảng băm là . Trung bình mỗi k , c , r được giả sử là hằng số (nhỏ) trong thời gian chạy được khấu hao và do đó chúng tôi nói rằng Θ ( 1 ) là một tuyên bố công bằng. Θ(kcr)
kcrΘ(1)

Để quay lại câu hỏi của bạn
Xin vui lòng cho tôi biết cách diễn giải, tôi đã cố gắng trích xuất các bộ ý nghĩa khác nhau, hãy bình luận nếu tôi bỏ lỡ một số

Bạn dường như quan tâm đến độ dài của đầu ra của hàm băm. Hãy gọi đây là ( n thường được coi là số lượng vật phẩm được băm). m sẽ là l o g ( n ) vì m cần xác định duy nhất một mục trong bảng băm. Điều này có nghĩa là m phát triển rất chậm. Với 64 bit, số lượng mục băm sẽ chiếm một phần lớn của RAM có sẵn trên toàn thế giới. Với 128 bit, nó sẽ vượt xa lưu trữ đĩa có sẵn trên trái đất. Tạo băm 128 bit không khó hơn băm 32 bit, vì vậy không , thời gian để tạo băm không phải là O (mnmlog(n)

(hoặc O ( l o g ( n ) ) nếu bạn muốn). O(m)O(log(n))

Hàm băm đi qua các bit của phần tử sẽ mất thời gian Θ ( l o g ( n ) ) . log(n)Θ(log(n))

Nhưng hàm băm không đi qua các bit của các phần tử. Mỗi một mục (!!) nó chỉ đi qua dữ liệu . Ngoài ra độ dài của đầu vào (k) không liên quan đến số lượng phần tử. Điều này quan trọng, bởi vì một số thuật toán không băm phải kiểm tra nhiều phần tử trong bộ sưu tập để tìm phần tử phù hợp (không). Bảng băm chỉ thực hiện trung bình 1 hoặc 2 so sánh cho mỗi mục được xem xét trung bình trước khi đưa ra kết luận. O ( k )log(n)
O(k)

Tại sao các bảng băm hiệu quả để lưu trữ các phần tử có độ dài thay đổi?

Bởi vì không phân biệt độ dài của đầu vào ( ), độ dài của đầu ra ( ) luôn giống nhau, va chạm rất hiếm và thời gian tra cứu là không đổi. Tuy nhiên, khi độ dài khóa tăng lên so với số lượng vật phẩm trong bảng băm ( ) thì câu chuyện thay đổi ...m k nkm
kn

Tại sao các bảng băm hiệu quả để lưu trữ các chuỗi lớn?

Các bảng băm không hiệu quả lắm đối với các chuỗi rất lớn.

not n>>kΘ(k)k1 k2

Θ(1)


Θ(1)



k,c,rO(1)

1
Ω(lgn)O(1)O(1)

Tôi muốn được hoàn thành với tất cả các yếu tố của thời gian chạy. Chúng tôi đồng ý rằng chỉ có độ dài khóa thực sự là một mối quan tâm khi băm. Tôi đã sửa lỗi log (n) mà OP nêu ra. Tôi đã đọc sai điều đó, bởi vì đó không phải là vấn đề khi băm IMO.
Johan

Tôi hy vọng câu trả lời phù hợp hơn với câu hỏi của OP bây giờ.
Johan

3

A[i]=A[j]

NNwA[i]=A[j]2w

lognnNNO(logn)A[i]=A[j]O(1)

Như tôi đã nói ở trên, chúng tôi thường phân tích các thuật toán bằng mô hình RAM. Ngoại lệ phổ biến duy nhất là số học số nguyên, đặc biệt là phép nhân số nguyên, thường được phân tích liên quan đến số lượng các phép toán bit.

Tại sao chúng ta sử dụng mô hình RAM? Vì nó có sức mạnh dự đoán nhiều hơn (vis thực tế). Giả định rằng kích thước đầu vào nhiều nhất theo cấp số nhân về kích thước của một từ máy thường là hợp lý, đặc biệt đối với các bộ xử lý 64 bit hiện đại và các thao tác trên các từ máy không mất thời gian liên tục trong các CPU thực tế.


Các bảng băm có cấu trúc dữ liệu phức tạp hơn và chúng thực sự bao gồm ba loại: loại khóa, loại băm và loại giá trị. Từ quan điểm của loại giá trị , bảng băm chỉ là một mảng được tôn vinh, vì vậy hãy bỏ qua khía cạnh đó. Các loại băm luôn có thể được giả định bao gồm một số ít từ máy. Các loại chìa khóa thỏa mãn một tính chất đặc biệt: đó là hashable , có nghĩa là nó có một hoạt động băm mà (ở mức tối thiểu) là một số chức năng xác định (một hàm luôn trả về giá trị tương đương).

Bây giờ chúng tôi có thể giải quyết câu hỏi của bạn: mất bao lâu để băm khóa? Câu trả lời phụ thuộc vào mô hình tính toán. Lần này chúng ta có ba mô hình phổ biến: hai mô hình trước đó và mô hình nhà tiên tri.

Trong mô hình nhà tiên tri , chúng tôi giả sử rằng hàm băm được cung cấp cho chúng tôi bởi một "nhà tiên tri" có thể tính toán hàm băm của một khóa tùy ý trong thời gian không đổi.

NNO(N)N

Khi chúng tôi phân tích thời gian chạy của các thuật toán bảng băm, chúng tôi thường sử dụng mô hình orory. Điều này thường được thể hiện bằng một ngôn ngữ khác: chúng tôi chỉ đơn giản nói rằng chúng tôi đếm số lần gọi của hàm băm. Điều này có ý nghĩa, vì thông thường các ứng dụng của hàm băm là thuật ngữ chi phối trong thời gian chạy của thuật toán bảng băm và do đó để phân tích độ phức tạp thời gian thực tế, tất cả những gì bạn phải làm là nhân số lượng lệnh băm với thời gian chạy của hàm băm.

Khi phân tích thời gian chạy của thuật toán sử dụng bảng băm dưới dạng cấu trúc dữ liệu, chúng ta thường quan tâm đến thời gian chạy thực tế, thường là trong mô hình RAM. Một tùy chọn ở đây là thực hiện những gì đã được đề xuất trong đoạn trước, cụ thể là nhân thời gian chạy của các hoạt động bảng băm (được đưa ra theo số lượng các lệnh gọi hàm băm) với thời gian chạy của hàm băm.

1,2,4,,2mO(2m)O(m2m)

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.