giải quyết đụng độ trong phép biến đổi khoá băm bằng phương pháp địa chỉ mở

25 1.3K 0
giải quyết đụng độ trong phép biến đổi khoá băm bằng phương pháp địa chỉ mở

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

HỌC VIỆN KỸ THUẬT QUÂN SỰ KHOA CÔNG NGHỆ THÔNG TIN o0o BÀI TẬP MÔN HỌC PHÂN TÍCH THIẾT KẾ THUẬT TOÁN Đề tài : GIẢI QUYẾT ĐỤNG ĐỘ TRONG PHÉP BIẾN ĐỔI KHOÁ BĂM BẰNG PHƯƠNG PHÁP ĐỊA CHỈ MỞ GV hướng dẫn: Đại tá - TS ĐÀO THANH TĨNH Người thực hiện: Thiếu tá - KS PHẠM HỒNG SƠN Lớp : CH CNTT K17 - Học viện KTQS Hà Nội, tháng 02 năm 2006 2 MỤC LỤC Trang Mục lục 2 Đặt vấn đề 3 Phần 1 Giải quyết đụng độ trong phép biến đổi khoá băm bằng phương pháp địa chỉ mở 5 1.1. tả chung 5 1.2. Phương pháp thăm tuyến tính (Linear Probing) 6 1.3. Phương pháp thăm bậc hai (Quadrratic Probing) 10 1.4. Phương pháp thăm kép (Double Hashing) 13 Phần 2 Phân tích phép biến đổi khoá bằng phương pháp địa chỉ mở 16 3.1. Phân tích phép biến đổi khoá 16 3.2. Một số lưu ý khi sử dụng phương pháp thử 18 Phần 3 Chương trình minh hoạ 19 Tài liệu tham khảo 23 3 BÀI TẬP Môn học: Phân tích và thiết kế thuật toán Người thực hiện: PHẠM HỒNG SƠN Lớp: CH CNTT K17 - Học viện KTQS GIẢI QUYẾT ĐỤNG ĐỘ TRONG PHÉP BIẾN ĐỔI KHOÁ BẰNG PHƯƠNG PHÁP ĐỊA CHỈ MỞ ĐẶT VẤN ĐỀ Các phép toán trên các cấu trúc dữ liệu như danh sách, cây nhị phân,… phần lớn được thực hiện bằng cách so sánh các phần tử của cấu trúc, do vậy thời gian truy xuất không nhanh và phụ thuộc vào kích thước của cấu trúc. Phép băm được đề xuất và hiện thực trên máy tính từ những năm 50 của thế kỷ 20. Nó dựa trên ý tưởng: biến đổi giá trị khóa thành một số (xử lý băm) và sử dụng số này để đánh lại chỉ cho bảng dữ liệu. Nhiều ứng dụng yêu cầu một tập hợp động chỉ hỗ trợ các phép toán từ điển như INSERT, SEARCH, DELETE. Các phép toán này trên bảng băm sẽ giúp hạn chế số lần so sánh, và vì vậy sẽ cố gắng giảm thiểu được thời gian truy xuất. Độ phức tạp của các phép toán trên bảng băm trong trường hợp tối ưu thường có bậc là O(1) và không phụ thuộc vào kích thước của bảng băm. Thông thường bảng băm được sử dụng khi cần xử lý các bài toán có dữ liệu lớn và được lưu trữ ở bộ nhớ ngoài. Ta có thể ta cấu trúc của một bảng băm tổng quát như sau: Tập khóa K Hàm băm h(k) Tập địa chỉ M Trong đó: - K: tập các khoá - M: tập các địa chỉ - h(k): hàm băm dùng để ánh xạ một khoá k từ tập các khoá K thành một địa chỉ tương ứng trong tập M. 4 Với mỗi loại bảng băm cần thiết phải xác định tập khóa K, xác định tập địa chỉ M và xây dựng hàm băm h cho phù hợp. Quá trình biến đổi từ tập khoá K ra tập địa chỉ M tương ứng gọi là phép biến đổi khoá. Phép biến đổi khoá được thực hiện qua hai bước: - Bước thứ nhất của phép biến đổi khoá là tính toán hàm h(k) để biến đổi tập khoá K thành tập địa chỉ M trong bảng. Trường hợp lý tưởng là những khoá khác nhau thông qua hàm h(k) sẽ cho những địa chỉ khác nhau tương ứng trong bảng. Nhưng trong thực tế thì hai hoặc nhiều khoá khác nhau sau khi qua phép biến đổi khoá h(k) lại cho cùng một địa chỉ trong bảng. - Bước thứ hai của phép biến đổi khoá là quá trình giải quyết sự đụng độ cho những khoá khác nhau nhưng có cùng một địa chỉ trong bảng. Phép biến đổi khoá tốt là phải đảm bảo giải quyết hợp lý về thời gian và bộ nhớ. Nếu không bị giới hạn về bộ nhớ thì có thể tìm kiếm một khóa bất kì với một lần truy xuất bộ nhớ bằng cách cho khoá đó chính là địa chỉ của bộ nhớ. Ngược lại nếu không bị giới hạn về thời gian tìm kiếm thì ta có thể sử dụng một bộ nhớ có kích thước tối thiểu với phương pháp tìm kiếm tuần tự. Có nhiều phương pháp giải quyết đụng độ. Một trong những cách giải quyết đódùng danh sách liên kết bởi ta không thể biết trước số các khoá khác nhau có cùng địa chỉ trong bảng là bao nhiêu. Một cách giải quyết khác với thời gian nhanh hơn là dùng danh sách có kích thước cố định. Trong bảng băm với phương pháp kết nối trực tiếp mỗi địa chỉ của bảng băm tương ứng một danh sách liên kết. Các phần tử bị xung đột được kết nối với nhau trên một danh sách liên kết. Phương pháp kết nối trực tiếp có một nhược điểm là phải duy trì các danh sách liên kết và mỗi phần tử phải có thêm vùng liên kết để chỉ đến phần tử kế tiếp trong danh sách. Một cách khác để giải quyết đụng độ là khi có đụng độ xảy ra thì ta sẽ tìm đến địa chỉ kế tiếp nào đó trong bảng cho đến khi tìm thấy phần tử mong muốn hoặc vị trí kế tiếp là vị trí trống (không thấy). Do đó phương pháp này được gọi là phương pháp địa chỉ mở. Dãy các chỉ số của bước thứ 2 (để xác định vị trí kế tiếp) phải luôn luôn như nhau đối với mỗi khoá cho trước. Trong phạm vi của đề tài, sau đây là những phân tích, đánh giá các kỹ thuật (phương pháp) tạo địa chỉ mở trong phép biến đổi khoá. Nội dung đề tài gồm 3 phần chính: - Phần 1: tả các cách biến đổi khoá băm bằng phương pháp địa chỉ mở. - Phần 2: nêu lên những phân tích, đánh giá của phương pháp địa chỉ mở - Phần 3: Chương trình minh hoạ Phần 1 5 GIẢI QUYẾT ĐỤNG ĐỘ TRONG PHÉP BIẾN ĐỔI KHOÁ BĂM BẰNG PHƯƠNG PHÁP ĐỊA CHỈ MỞ 1.1. tả chung Bảng băm sử dụng phương pháp địa chỉ mở sẽ lưu giữ các phần tử ngay trong bảng chứ không dùng mảng làm các chỉ điểm đầu. Ô thứ i của bảng chứa phần tử có giá trị băm là i. Nhưng có thể có nhiều phần tử có cùng giá trị băm nên ta thường gặp trường hợp ta muốn đưa vào ô thứ i một phần tử nhưng ô này đã bị chiếm bởi phần tử j nào đó. Như vậy, khi thiết kế một bảng địa chỉ mở ta phải có cách để giải quyết sự đụng độ này. Trong phương pháp địa chỉ mở ta gọi m là số phần tử của bảng băm và n là số phần tử đã sử dụng. Bảng băm được gọi là đầy khi n=m-1. Như vậy bảng băm bao giờ cũng phải có ít nhất 1 phần tử trống. Khi tìm kiếm 1 phần tử trong bảng băm, có 3 trường hợp có thể xảy ra đối với vị trí kế tiếp là: 1. Nếu phần tử tại vị trí này là phần tử cần phải tìm thì giải thuật kết thúc thành công (tìm thấy). 2. Nếu phần tử tại vị trí này là vị trí trống thì giải thuật kết thúc không thành công (không tìm thấy). 3. Nếu phần tử tại vị trí này không phải là vị trí cần tìm thì ta tiếp tục xét vị trí kế tiếp. Để có thể nhận biết được các vị trí trống của bảng băm ta cho khoá của các phần tử tại các vị trí này là một giá trị đặc biệt free, chẳng hạn như 1 số nguyên tố lớn nhất. Một cách tổng quát, giải thuật tìm kiếm khoá k trong phương pháp địa chỉ mở có thể tả như sau: x:= h(k); i:= 0; While (T[x].key <>free) and (T[x].key <> k ) do begin x:= (h(k) + G(i)) mod m ; i:= i + 1; end; if T[x].key = k then t×m thÊy else kh«ng t×m thÊy“ ” “ ” Trong đó: 6 - h(k): hàm băm biếm đổi khoá k thành vị trí trong bảng băm - G(i): hàm tạo ra dãy các chỉ số của phép thăm thứ 2 Thông thường có ba kỹ thuật được dùng để tính toán các dãy của phép thăm thứ hai cho phương pháp định địa chỉ mở: Phương pháp thăm tuyến tính, phương pháp thăm bậc hai và Phương pháp thăm kép. Sau đây ta lần lượt xem xét các phương pháp thăm trên. 1.2. Phương pháp thăm tuyến tính (Linear Probing) 1.2.1. tả phương pháp Một phương pháp địa chỉ mở đơn giản nhất là phương pháp thăm tuyến tính: Khi thêm phần tử vào bảng băm nếu bị đụng độ thì sẽ địa chỉ kế tiếp… cho đến khi gặp địa chỉ trống đầu tiên thì thêm phần tử vào địa chỉ này. - Cấu trúc dữ liệu: Bảng băm trong trường hợp này được cài đặt bằng danh sách kề có m phần tử, mỗi phần tử của bảng băm là một mẫu tin có một trường key để chứa khoá của phần tử. Khi khởi động bảng băm thì tất cả trường key được gán NullKey; - Khi thêm phần tử có khoá k vào bảng băm, hàm băm h(k) sẽ xác định địa chỉ i trong khoảng từ 0 đến m-1: + Nếu chưa bị xung đột thì thêm phần tử mới vào địa chỉ này. + Nếu bị xung đột thì hàm băm lại lần 1, hàm h 1 (k) sẽ xét địa chỉ kế tiếp, nếu lại bị xung đột thì hàm băm băm lại lần 2, hàm h 2 (k) sẽ xét địa chỉ kế tiếp nữa, …, và quá trình cứ thế cho đến khi nào tìm được địa chỉ trống và thêm phần tử mới vào địa chỉ này. Ví dụ: Cho tập khoá k 1 12 23 21 24 17 14 22 13 9 Giá trị h(k) = k mod 10 1 2 3 1 4 7 4 2 3 9 (Ở đây ta có m = 10) Sau đây ta xem xét lần lượt giá trị khoá k được chèn vào bảng băm theo phương pháp tuyến tính: i k - h(1) = 1: đưa 1 vào vị trí tương ứng với i = 1 - h(12) = 2: đưa 12 vào vị trí tương ứng với i = 2 7 0 9 1 1 2 12 3 23 4 21 5 24 6 14 7 17 8 22 9 13 - Khi tìm một phần tử có khoá k trong bảng băm, hàm băm h(k) sẽ xác định địa chỉ i trong khoảng từ 0 đến m-1, tìm phần tử khoá k trong bảng băm xuất phát từ địa chỉ i. Các chỉ số x i dùng để thử là: x 0 = h(k) x i = (x 0 + i) mod m với i = 1, , m-1 Khi có đụng độ xảy ra thì ta tìm đến vị trí kế tiếp (chỉ số tăng lên 1). Như vậy phương pháp thử tuyến tính sẽ có G(i)=i. Khi giải thuật kết thúc không thành công, việc thêm một phần tử mới vào trong bảng sẽ được thực hiện dễ dàng bằng cách chứa phần tử này tại vị trí trống khi kết thúc giải thuật. Ta có khai báo như sau: Const free = maxint; type Item = record k : integer; {kho¸} data : integer; {dữ liệu} end; var T: array [0 m-1] of item; n: integer; 1.2.2. Khởi tạo bảng băm Khi tạo bảng băm ta cho tất cả vị trí của bảng bămtrống và số phần tử đang sử dụng bằng 0. Thủ tục Hash_Initialize dùng để tạo bảng băm trống như sau: Procedure Hash_Initialize; var 8 i: Integer; begin for i:=0 to m-1 do T[i].key:=free; n:=0; {số phần tử ®ang sử dụng} end; 1.2.3. Thêm 1 khóa vào bảng băm Hàm Hash_Insert(k:integer) thực hiện việc thêm 1 phần tử có khoá k vào trong bảng băm và trả về vị trí của phần tử này ở trong bảng hoặc trả về giá trị m nếu bảng bị đầy. Function Hash_Insert(k:integer): integer; var k: Integer; begin if n = m-1 then Hash_Insert:= m else begin x:=h(k); While T[x].k<>free do begin x:=x+1; if x >= m then x:= x - m end; T[x].key=k; n:= n + 1; Hash_Insert: = x; end; end; 1.2.4. Tìm kiếm một khóa trong bảng băm Hàm Hash_Search(k:integer) thực hiện việc tìm kiếm khoá k trong bảng băm và trả về vị trí của phần tử này nếu tìm thấy hoặc trả về giá trị m nếu không tìm 9 thấy. Function Hash_Search(k:integer): integer; var x: Integer; begin x:=h(k); While (T[x].key<>free) and (T[x].key<>k) do begin x:=x+1; if x >= m then x: = x - m end; if T[x].key = k then Hash_Search:=x else Hash_Insert:= m; end; 1.2.5. Loại bỏ 1 phần tử của bảng băm Để tránh trường hợp tìm kiếm không thành công mà khoá cần tìm đã có trong bảng băm, khi loại bỏ phần tử ở vị trí j thì ta phải di chuyển phần tử khác trống kế tiếp về vị trí trống này. Điều kiện để di chuyển phần tử khác trống kế tiếp ở vị trí thứ i về vị trí trống thứ j nếu r = h(T[i].k) nằm ngoài vùng vòng từ vị trí j đến vị trí i, tức là r không thoả mãn các trường hợp sau đây: i → j → r → r → i → j → i → r → j → j < r <=i r <= i < j i < j < r Khi chuyển phần tử ở vị trí i đến vị trí j thì vị trí i trở thành vị trí trống, sau đó ta phải di chuyển phần tử khác trống kế tiếp đến vị trí i này và quá trình di chuyển này tiếp tục cho đến khi nào phần tử kế tiếp là phần tử trống. Hash_Delete(i: integer); Var i, j, r : integer; a, cont: boolean; 10 [...]... kiếm thành công nếu bảng băm chứa ít hơn 99% 16 Phần 2 PHÂN TÍCH PHÉP BIẾN ĐỔI KHOÁ BẰNG PHƯƠNG PHÁP ĐỊA CHỈ MỞ 3.1 Phân tích phép biến đổi khoá Ta thấy phương pháp địa chỉ mở không thích hợp trong trường hợp có 1 số lớn các phần tử có cùng giá trị hàm băm, nhưng việc tìm kiếm trên bảng băm thì được thực hiện dễ dàng trong trường hợp này Các kỹ thuật định địa chỉ mở có thể bất lợi trong tình huống khi... h’(k) là hàm băm phụ, còn c 1, c2 là các hằng số phụ và i = 0, 1, , m-1 11 Như vậy trong phương pháp pháp thăm bậc 2 ta có G(i) = c 1i + c2i2 là một hàm bậc hai của biến i Trong phương pháp thăm bậc hai, nếu băm lần đầu bị xung đột thì sẽ đến địa chỉ mới, ở lần thứ i sẽ xét phần tử cách (c 1i + c2i2) cho đến khi gặp địa chỉ trống đầu tiên thì thêm phần tử vào địa chỉ này Phương pháp này làm... Kích thước bảng băm của phương pháp địa chỉ mở lớn hơn so với kích thước bảng băm của phương pháp kết nối trực tiếp, bởi vì ta phải có m>n, nhưng vùng nhớ tổng cộng của phương pháp này lại nhỏ hơn bởi vì các phần tử không có vùng liên kết Giả sử tất cả các khoá trong bảng băm đều có cùng xác suất và hàm băm phân bố chúng đều đặn trên miền chỉ số của bảng Khi ta thêm một khoá mới vào bảng băm có kích thước... của bảng băm, nếu a = 0 ⇒ bảng băm là trống; a = 1 ⇒ bảng băm gần đầy Sau đây là bảng các giá trị của kỳ vọng E các phép thử theo hệ số tải a a 0,1 0,25 0,5 0,75 0,9 0,95 0,99 E 1,05 1,15 1,39 1,85 2,56 3,15 4,66 Từ bảng kết quả này ta nhận thấy tính hiệu quả khá tốt của phép biến đổi khoá Kể cả trong trường hợp bảng băm đã đầy tới 90% Trên đây là việc phân tích phương pháp giải quyết đụng độ với giả... m; end; 1.4 Phương pháp thăm kép (Double Hashing) 1.4.1 tả phương pháp Ta cũng có thể tránh hiện tượng gom tụ bằng cách dùng phương pháp thăm kép Về cơ bản cũng giống như phương pháp thăm tuyến tính, nhưng thay 13 vì xét các vị trí liên tiếp đi sau vị trí đụng độ ta dùng hàm băm thứ 2 để cho mật độ tăng cố định được dùng trong các lần thử sau đó Điều này được thực hiện dễ dàng bằng cách sử... kiếm đối với những khoá có giá trị hàm băm khác Hiện tượng này được gọi là “gom tụ” (clustering), có thể làm cho phương pháp thử tuyến tính thực hiện rất chậm khi bảng băm gần đầy Ta có thể tránh được hiện tượng gom tụ bằng cách dùng phương pháp thăm bậc hai Phương pháp thăm bậc hai sử dụng một hàm băm có dạng tổng quát như sau: h(k,i) = (h’(k) + c1i + c2i2) mod m Giống như phương pháp thăm tuyến... m; {bảng băm đầy} else begin T[x].key:= k; {ChÌn thªm kho¸ k vµo} n: = n + 1; Search:= x; end; end; Số lần so sánh trung bình cho 1 lần tìm kiếm thành công có lớn hơn chút ít so với phương pháp thử tuyến tính, nhưng phương pháp này tránh được hiện tượng gom tụ Phương pháp băm kép sử dụng ít phép thử hơn sơ với phương pháp thử tuyến 15 tính (trường hợp trung bình) Số lần so sánh trung bình trong trường... được viết bằng ngôn ngữ Borland Delphi Để tiện cho việc so sánh kết quả của ba kỹ thuật thăm dò, chương trình sử dụng chung một tập dữ liệu liệu khoá chung cho cả ba kỹ thuật thăm Tập dữ liệu khoá là các số tự nhiên được nhập trực tiếp từ bàn phím hoặc có thể sinh ngẫu nhiên trong khoảng từ 0 đến 100 Giao diện chương trình minh hoạ cách tạo dữ liệu cho bảng băm bằng phương pháp địa chỉ mở Sau đây... giả thiết rằng các khoá còn lại của bảng băm trải đều trên các vị trí của bảng Nhưng trong thực tế các phương pháp có hiệu quả kém hơn một chút Khi phân tích chi tiết phương pháp thử tuyến tính ta nhận được kỳ vọng của 18 a các phép thử là: E = 2 Với Kỳ vọng này ta nhận được một vài giá trị của 1− a hàm E như sau: 1− a 0,1 0,25 0,5 0,75 0,9 0,95 E 1,06 Kết quả này cho thấy, phương pháp đơn giản nhất... cũng đạt hiệu quả cao hơn, đặc biệt 2,50 5,50 trong các phép loại bỏ hay chèn thêm khoá vào cấu trúc dữ liệu 10,50 Tuy nhiên cũng cần nói tới nhược điểm lớn nhất của phép biến đổi khoá đó là kích thước của bảng băm bị cố định và không thể điều chỉnh theo yêu cầu thực tế Như vậy khi thiết kế dữ liệu ta cần căn cứ vào số phần tử để ước lượng kích thước của bảng băm để tránh hiệu quả kém cũng như lãng phí . của phương pháp địa chỉ mở - Phần 3: Chương trình minh hoạ Phần 1 5 GIẢI QUYẾT ĐỤNG ĐỘ TRONG PHÉP BIẾN ĐỔI KHOÁ BĂM BẰNG PHƯƠNG PHÁP ĐỊA CHỈ MỞ 1.1. Mô tả chung Bảng băm sử dụng phương pháp địa. nếu bảng băm chứa ít hơn 99%. 16 Phần 2 PHÂN TÍCH PHÉP BIẾN ĐỔI KHOÁ BẰNG PHƯƠNG PHÁP ĐỊA CHỈ MỞ 3.1. Phân tích phép biến đổi khoá Ta thấy phương pháp địa chỉ mở không thích hợp trong trường. vấn đề 3 Phần 1 Giải quyết đụng độ trong phép biến đổi khoá băm bằng phương pháp địa chỉ mở 5 1.1. Mô tả chung 5 1.2. Phương pháp thăm dò tuyến tính (Linear Probing) 6 1.3. Phương pháp thăm dò bậc

Ngày đăng: 12/05/2014, 19:49

Từ khóa liên quan

Mục lục

  • CHƯƠNG TRÌNH MINH HOẠ

  • Chương trình minh hoạ cách tạo bảng bảng băm theo ba kỹ thuật: thăm dò tuyến tính (Linear brobing), thăm dò bậc hai (Quadratic brobing) và thăm dò kép (Double brobing). Chương trình được viết bằng ngôn ngữ Borland Delphi.

  • Để tiện cho việc so sánh kết quả của ba kỹ thuật thăm dò, chương trình sử dụng chung một tập dữ liệu liệu khoá chung cho cả ba kỹ thuật thăm dò. Tập dữ liệu khoá là các số tự nhiên được nhập trực tiếp từ bàn phím hoặc có thể sinh ngẫu nhiên trong khoảng từ 0 đến 100.

  • procedure Brobing.LinearClick(Sender: TObject);

  • var

  • i,j: integer;

  • begin

  • InputKey;

  • for i:=0 to dem-1 do

  • begin

  • tempbk:=kn[i] mod m;

  • if bk[tempbk]=-1 then bk[tempbk]:=kn[i]

  • else

  • begin

  • j:=1;

  • while bk[(tempbk+j) mod m]<>-1 do j:=j+1;

  • bk[(tempbk+j) mod m]:=kn[i];

  • end;

  • end;

  • HashTable1.RowCount:=m+1;

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan