1. Trang chủ
  2. » Luận Văn - Báo Cáo

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

Đ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

Thông tin cơ bản

Định dạng
Số trang 25
Dung lượng 895 KB

Nội dung

GIẢI QUYẾT ĐỤNG ĐỘ TRONG PHÉP BIẾN ĐỔI KHOÁ BĂMTrong 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.. - hk: hàm băm biếm đổi khoá k thành vị trí

Trang 1

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

Trang 2

Hà Nội, tháng 02 năm 2006

Trang 3

Phần 2 Phân tích phép biến đổi khoá

bằng phương pháp địa chỉ mở

16

Trang 4

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ể mô 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

Trang 5

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

đó là 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: mô 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

Trang 6

GIẢI QUYẾT ĐỤNG ĐỘ TRONG PHÉP BIẾN ĐỔI KHOÁ BĂM

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ể mô tả như sau:

end;

if T[x].key = k then t×m thÊy else kh«ng t×m thÊy“ ” “ ”

Trong đó:

Trang 7

- 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 dò 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

dò thứ hai cho phương pháp định địa chỉ mở: Phương pháp thăm dò tuyến tính, phương pháp thăm dò bậc hai và Phương pháp thăm dò kép

Sau đây ta lần lượt xem xét các phương pháp thăm dò trên

1.2 Phương pháp thăm dò tuyến tính (Linear Probing)

1.2.1 Mô 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 dò tuyến tính: Khi thêm phần tử vào bảng băm nếu bị đụng độ thì sẽ dò đị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 h1(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 h2(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ụ:

(Ở đâ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 dò tuyến tính:

- h(12) = 2: đưa 12 vào vị trí tương ứng với i = 2

Trang 8

Ta có khai báo như sau:

Const free = maxint;

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ăm là trố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

Trang 9

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;

begin

x:=h(k);

While T[x].k<>free do begin

x:=x+1;

if x >= m then x:= x - m 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

Trang 10

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:

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;

Trang 11

until (not cont) or (not a);

if cont then T[j].key:= T[i].key until not cont

tử mới tại vị trí p Điều này dẫn đến trường hợp sau đó ta không thể thêm 1 phần

tử có khoá là k2 tại vị trí p, mặc dù hàm băm h(k2) cho giá trị là p, như vậy ta phải tìm đến vị trí trống kế tiếp để thêm phần tử khoá k2 vào bảng băm Thời gian tìm kiếm vị trí trống kế tiếp sẽ rất dài khi bảng băm gần đầy

Trường hợp xấu nhất là việc thêm 1 phần tử mới có giá trị hàm băm nào đó

có thể làm tăng đáng kể số lần tìm 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

Trang 12

Như vậy trong phương pháp pháp thăm dò bậc 2 ta có G(i) = c1i + c2i 2 là một hàm bậc hai của biến i

Trong phương pháp thăm dò bậc hai, nếu băm lần đầu bị xung đột thì sẽ dò đến địa chỉ mới, ở lần dò thứ i sẽ xét phần tử cách (c1i + 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 việc tốt hơn phương pháp dò tuyến tính, tuy nhiên để bảng băm đạt hiệu quả cao nhất các giá trị c1, c2 và m phải chịu một ràng buộc nào đó

Một cách đơn giản ta cho G(i) = i2 , khi đó dãy các chỉ số để thử sẽ là:

- h(12) = 2: đưa 12 vào vị trí tương ứng với i = 2

- h(23) = 3: đưa 23 vào vị trí tương ứng với i = 3

- h(21) = 1: vị trí này đã bị chiếm

+ h(21) 1 = (1+1 2 ) mod 10 = 2 cũng bị chiếm + h(21) 2 = (1+2 2 ) mod 10 = 5 còn trống, ta đưa 21 vào vị trí 5

- h(24) = 4: đưa 24 vào vị trí tương ứng với i = 4

- h(17) = 7: đưa 17 vào vị trí tương ứng với i = 7

- h(14) = 4: vị trí này đã bị chiếm

+ h(14) 1 = (4+1 2 ) mod 10 = 5 cũng bị chiếm + h(14) 2 = (4+2 2 ) mod 10 = 8 còn trống, ta đưa 14 vào vị trí 8

- h(22) = 2: vị trí này đã bị chiếm

+ h(22) 1 = (2+1 2 ) mod 10 = 3 bị chiếm + h(22) 2 = (2+2 2 ) mod 10 = 6 còn trống, ta đưa 22 vào vị trí 6

- h(13) = 3: vị trí này đã bị chiếm

+ h(13) 1 = (3+1 2 ) mod 10 = 4 bị chiếm + h(13) 2 = (3+2 2 ) mod 10 = 7 bị chiếm + h(13) 3 = (3+3 2 ) mod 10 = 0 còn trống, ta đưa 13 vào vị trí 0

1.3.2 Thêm 1 khoá mới 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

Trang 13

Function Hash_Insert(k:integer): integer;

1.3.3 Tìm kiếm 1 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 thấy

Function Hash_Search(k:integer): integer;

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

dò kép Về cơ bản cũng giống như phương pháp thăm dò tuyến tính, nhưng thay

Trang 14

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ử dụng một hàm băm thứ hai h2(k) Khi đó hàm băm kép có dạng:

h(k) = (h1(k) + i*h2(k)) mod m

Như vậy trong phương pháp pháp thăm kép ta có G(i) = i*h2(k)

Trong đó h1(k) và h2(k) là các hàm băm phụ Vị trí ban đầu được thăm dò là T[h1(k)], các vị trí dò kế tiếp là độ dịch từ các vị trí trước đó theo một lượng (h2(k) mod m) Như vậy khác với trường hợp thăm dò tuyến tính và thăm dò bậc hai, dãy thăm dò ở đây phụ thuộc vào khoá k theo hai cách: vị trí thăm dò ban đầu, độ dịch chuyển hoặc cả hai yếu tố trên

Hàm băm thứ 2 (h2(k)) phải được chọn cẩn thận vì ngược lại chương trình có thể không thực hiện gì cả

Nếu chọn y = 0, chương trình sẽ lặp vô tận khi xảy ra đụng độ

Có nhiều cách để chọn hàm băm thứ hai (h2(k)) tuỳ thuộc vào kích thước của bảng băm (m):

- m và y phải là 2 số nguyên tố cùng nhau bởi vì trong trường hợp ngược lại

sẽ có những chuỗi phép thử rất ngắn Điều này bắt buộc m phải là số nguyên tố

- Một cách tiện dụng để bảo đảm dung hoà được các yếu tố trên, ta chọn m là luỹ thừa của 2 và thiết kế h2(k) sao cho nó luôn tạo ra số lẻ

Ví dụ:

(Ở đây ta có m = 8 và chọn hàm h2(k) = m - 1)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 dò kép:

- h (12) = 4: đưa 12 vào vị trí tương ứng với i = 4

Trang 15

+ h1(k) = k mod m

+ h2(k) = 1 + (k mod m’)

Trong đó m’ chọn nhỏ hơn m Chẳng hạn m’ = m - 1 hoặc m’ = m - 2

1.4.2 Tìm kiếm và thêm 1 khoá mới vào bảng băm

Hàm Search(k:integer) thực hiện việc tìm kiếm và thê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 vị trí thêm vào nếu giá trị của hàm nhỏ hơn m hoặc trả về giá trị m nếu bảng băm bị đầy

Function Hash_Search(k:integer): integer;

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

Trang 16

(a = n/m gọi là hệ số tải của bảng băm)

Thực tế số phép thử trung bình nhỏ hơn 5 lần cho trường hợp tìm kiếm không thành công nếu bảng băm chứa ít hơn 80% và cho trường hợp tìm kiếm thành công nếu bảng băm chứa ít hơn 99%

Phép thử trung bình nhỏ hơn 5 lần cho trường hợp tìm kiếm không thành công nếu bảng băm chứa ít hơn 80% và cho trường hợp tìm kiếm thành công nếu bảng băm chứa ít hơn 99%

Trang 17

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 mà số lần thêm vào là loại bỏ chưa biết trước là bao nhiêu

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 m đã chứa n phần tử, xác suất để có 1 vị trí trống ở lần thử đầu tiên là

m

n

1− , đây cũng là xác suất p1 cần cho một lần so sánh Xác suất cần một lần thử thứ hai bằng tích xác suất lần thử đầu tiên có đụng độ với xác suất để có một vị trí trống trong lần thử thứ hai Một cách tổng quát gọi pi là xác suất của phép thêm vào cần đến i phép thử, ta có:

m

nm

p1 = −

1m

nm

*m

nm

*1m

1n

*m

nm

*2im

2in

*

*2m

nm

*1m

1n

Trang 18

1nm

1

*

*2m

2n

*1m

1n

*m

n

*)1n(

1m

nm

*m

n

*2m

nm

++

−+

=

hay

1nm

1m

Bởi vì số lần thử cần thiết để thêm vào một phần tử của bảng băm cũng chính

là số lần thử cần thiết để tìm kiếm nó, nên kỳ vọng có thể được dùng để tính số trung bình E các phép thử cần thiết để truy xuất một khoá ngẫu nhiên trong bảng

Xét bảng có kích thước m đã chứa n khoá thì:

)hh

(n

1m2im

1n

1mEn

1

1 i

11

hm = + + +

là hàm điều hoà Hm có thể xấp xỉ với hm = ln(m) + g với g là hàng số Euler.nếu ta đặt

1m

na

1mlna

1)1nmln(

)1mln(

a

1

−+

+

=+

−+

=

ta có thể coi a là hệ số tải 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 E 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%

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

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

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
[1] Đào Thanh Tĩnh - Cấu trúc dữ liệu và giải thuật (Tài liệu ôn thi cao học ngành CNTT) - HVKTQS - 2005 Sách, tạp chí
Tiêu đề: Cấu trúc dữ liệu và giải thuật
[2] Hà Huy Khoái - Nhập môn số học thuật toán - Nxb KHKT – 1997 Sách, tạp chí
Tiêu đề: Nhập môn số học thuật toán
Nhà XB: Nxb KHKT – 1997
[3] Nguyễn Trung Trực - Cấu trúc dữ liệu. Đại học bách khoa thành phố HCM - 1997 Sách, tạp chí
Tiêu đề: Cấu trúc dữ liệu
[4] Thomas H. Cormen, Charles E. Leiserson, Ronald L. RivestGiáo trình thuật toán - Nxb Thống kê - 2002 [5] Robert Sedgewick - Algoritms, Addison WesleyNxb KHKT - 1994 Sách, tạp chí
Tiêu đề: Giáo trình thuật toán" - Nxb Thống kê - 2002[5] Robert Sedgewick - "Algoritms, Addison Wesley
Nhà XB: Nxb Thống kê - 2002[5] Robert Sedgewick - "Algoritms
[6] Kenneth H.Rosen - Toán rời rạc ứng dụng trong tin họcNxb KHKT - 1997 Sách, tạp chí
Tiêu đề: Toán rời rạc ứng dụng trong tin học
Nhà XB: Nxb KHKT - 1997
[7] Dictionary of Algorithms and Data Structures Khác

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w