ตารางแฮช - cp.eng.chula.ac.th

27
ตารางแฮช (Hash Tables) © S. Prasitjutrakul 2006 04/10/49 2 หัวขอ การใชตารางเก็บขอมูลดวยฟงกชันดัชนี การเก็บขอมูลแบบแยกกันโยง ฟงกชันแฮช กลวิธีการเขียนฟงกชันแฮช การแฮชในจาวา การกําหนดเลขที่อยูเปด การเกาะกลุมของขอมูล

Upload: others

Post on 25-May-2022

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: ตารางแฮช - cp.eng.chula.ac.th

ตารางแฮช(Hash Tables)

copy S Prasitjutrakul 2006 041049 2

หวขอการใชตารางเกบขอมลดวยฟงกชนดชนการเกบขอมลแบบแยกกนโยงฟงกชนแฮชกลวธการเขยนฟงกชนแฮชการแฮชในจาวาการกาหนดเลขทอยเปดการเกาะกลมของขอมล

copy S Prasitjutrakul 2006 041049 3

ทเกบขอมลbull เกบในรายการ (list) O(n)bull เกบในตนไมเอวแอล O(log n)bull ทาอยางไรใหเรวกวาน

12157

สบ ฿1

5

32671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿815252

ยางลบ ฿5

root

5

size

header

5

size

copy S Prasitjutrakul 2006 041049 4

ใชฟงกชนดชนคานวณตาแหนงbull key ของขอมลคอสวนของขอมลทใชในการคนbull มตารางซงแตละชองเปนทเกบขอมลbull หา f(key) เพอแปลง key ไปเปน index ของตารางbull ฟงกชนดชนหาไมยาก ถาจองตารางขนาดใหญ ๆ

12157

สบ ฿1532671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿8

15252ยางลบ ฿5

0 1 2 3 4 6 75 8 9 10 11 12

f(key) = key 10

copy S Prasitjutrakul 2006 041049 5

Tablepublic class Table implements Set private Object[] tableprivate int size = 0

public Table(int m) table = new Object[m] public boolean isEmpty() return size == 0 public int size() return size

public void add(Object x) if (table[f(x)] == null)++size table[f(x)] = x

public void remove(Object x) if (table[f(x)] = null ampamp table[f(x)]equals(x))--size table[f(x)] = null

public void contains(Object x) return table[f(x)] = null ampamp table[f(x)]equals(x)

private int f(Object x)

Θ(1)

copy S Prasitjutrakul 2006 041049 6

ฟงกชนดชนนนหายากbull เมอตองเกบอยางประหยดbull เมอตองประกนวาไมเกดการ ชนbull ถารชดขอมลทจะจดเกบกอน กอาจหาสตรทไมชนไดbull แตในทางปฏบต ไมร

12157

สบ ฿1532671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿8

15252ยางลบ ฿5

0 1 2 3 4 6 75 8 9 10 11 12

f(key) = key 10

38227หว ฿40

copy S Prasitjutrakul 2006 041049 7

0

1

2

3

4

5

6

เปลยนกลยทธ อนญาตใหชนไดbull จะไดเกบขอมลในตารางทไมใหญมากbull แตตองหาวธแกไขปญหาการชน ททางานไดเรว ๆ

bull จดเกบกลมขอมลทชนกนไวในรายการเดยวกน

Separate Chaining

14 7

h(x) = x 7

22 1

3 38

46

40

6 13 27 20

copy S Prasitjutrakul 2006 041049 8

SeparateChainingpublic class SeparateChaining

private LinkedList[] tableprivate int size = 0

public SeparateChaining(int m) LinkedList[] table = new LinkedList[m]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()public int size()

return sizepublic boolean isEmpty()

return size == 0

copy S Prasitjutrakul 2006 041049 9

public class SeparateChaining public boolean contains(Object x)

return table[h(x)]contains(x)public void add(Object x)

table[h(x)]add(0 x)++size

public void remove(Object x)

int i = h(x)int s = table[i]size()table[i]remove(x)if (s gt table[i]size()) size--

private int h(Object x)

SeparateChaining

contains และ remove ใชเวลาแปรตามความยาว list

add ใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 10

λ = n m

การกระจายของขอมลbull ถาขอมลกระจายทวตาราง

ndash แตละชองเกบรายการยาว asymp λndash ถา λ นอย คนหาไดเรว

bull ถาไมกระจายndash มบางรายการยาวเกน λ มากndash การคนหาชาเหมอนเกบดวย list

0123456789

260 80180321401

252 92

4764185105

76

10828129

01234567

180 260

401

60 252 92 764 4 76 28 108

321 105 185 129

ขนาดของตารางปรมาณ

ขอมล

h(x) = x 8

h(x) = x 10

load factor

copy S Prasitjutrakul 2006 041049 11

การกระจายของขอมลbull ขนกบ

ndash x คยของขอมลndash h(x) ฟงกชนการแปลงคยเปนเลขทชองของตาราง

bull ถากลมขอมลมคย x ทมคากระจายอยแลวndash ถาใชตาราง 100 ชอง กให h(x) = x 100ndash ถาใชตาราง 2k ชอง กให h(x) = k บตทางขวาของ x

bull ถากลมขอมลมคยทมคาเปนระเบยบndash รหสนกศกษา รหสประจาตวบตรประชาชน ndash ตองออกแบบ h(x) ใหทา x ทมระเบยบให เละndash เรยก h(x) วาฟงกชนแฮช (Hash function)

copy S Prasitjutrakul 2006 041049 12

ฟงกชนแฮช (Hash Function)bull wwwwebstercom

ndash hash to chop (as meat and potatoes) into small piecesbull สอ เสถบตร

ndash สบ แหลก นามาโขลกเขาดวยกน

hash

493-01020-21

10291

493-01020-21 rarr 10291

493-87628-21 rarr 76102

473-12332-21 rarr 40001

463-09872-21 rarr 00012

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 2: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 3

ทเกบขอมลbull เกบในรายการ (list) O(n)bull เกบในตนไมเอวแอล O(log n)bull ทาอยางไรใหเรวกวาน

12157

สบ ฿1

5

32671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿815252

ยางลบ ฿5

root

5

size

header

5

size

copy S Prasitjutrakul 2006 041049 4

ใชฟงกชนดชนคานวณตาแหนงbull key ของขอมลคอสวนของขอมลทใชในการคนbull มตารางซงแตละชองเปนทเกบขอมลbull หา f(key) เพอแปลง key ไปเปน index ของตารางbull ฟงกชนดชนหาไมยาก ถาจองตารางขนาดใหญ ๆ

12157

สบ ฿1532671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿8

15252ยางลบ ฿5

0 1 2 3 4 6 75 8 9 10 11 12

f(key) = key 10

copy S Prasitjutrakul 2006 041049 5

Tablepublic class Table implements Set private Object[] tableprivate int size = 0

public Table(int m) table = new Object[m] public boolean isEmpty() return size == 0 public int size() return size

public void add(Object x) if (table[f(x)] == null)++size table[f(x)] = x

public void remove(Object x) if (table[f(x)] = null ampamp table[f(x)]equals(x))--size table[f(x)] = null

public void contains(Object x) return table[f(x)] = null ampamp table[f(x)]equals(x)

private int f(Object x)

Θ(1)

copy S Prasitjutrakul 2006 041049 6

ฟงกชนดชนนนหายากbull เมอตองเกบอยางประหยดbull เมอตองประกนวาไมเกดการ ชนbull ถารชดขอมลทจะจดเกบกอน กอาจหาสตรทไมชนไดbull แตในทางปฏบต ไมร

12157

สบ ฿1532671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿8

15252ยางลบ ฿5

0 1 2 3 4 6 75 8 9 10 11 12

f(key) = key 10

38227หว ฿40

copy S Prasitjutrakul 2006 041049 7

0

1

2

3

4

5

6

เปลยนกลยทธ อนญาตใหชนไดbull จะไดเกบขอมลในตารางทไมใหญมากbull แตตองหาวธแกไขปญหาการชน ททางานไดเรว ๆ

bull จดเกบกลมขอมลทชนกนไวในรายการเดยวกน

Separate Chaining

14 7

h(x) = x 7

22 1

3 38

46

40

6 13 27 20

copy S Prasitjutrakul 2006 041049 8

SeparateChainingpublic class SeparateChaining

private LinkedList[] tableprivate int size = 0

public SeparateChaining(int m) LinkedList[] table = new LinkedList[m]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()public int size()

return sizepublic boolean isEmpty()

return size == 0

copy S Prasitjutrakul 2006 041049 9

public class SeparateChaining public boolean contains(Object x)

return table[h(x)]contains(x)public void add(Object x)

table[h(x)]add(0 x)++size

public void remove(Object x)

int i = h(x)int s = table[i]size()table[i]remove(x)if (s gt table[i]size()) size--

private int h(Object x)

SeparateChaining

contains และ remove ใชเวลาแปรตามความยาว list

add ใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 10

λ = n m

การกระจายของขอมลbull ถาขอมลกระจายทวตาราง

ndash แตละชองเกบรายการยาว asymp λndash ถา λ นอย คนหาไดเรว

bull ถาไมกระจายndash มบางรายการยาวเกน λ มากndash การคนหาชาเหมอนเกบดวย list

0123456789

260 80180321401

252 92

4764185105

76

10828129

01234567

180 260

401

60 252 92 764 4 76 28 108

321 105 185 129

ขนาดของตารางปรมาณ

ขอมล

h(x) = x 8

h(x) = x 10

load factor

copy S Prasitjutrakul 2006 041049 11

การกระจายของขอมลbull ขนกบ

ndash x คยของขอมลndash h(x) ฟงกชนการแปลงคยเปนเลขทชองของตาราง

bull ถากลมขอมลมคย x ทมคากระจายอยแลวndash ถาใชตาราง 100 ชอง กให h(x) = x 100ndash ถาใชตาราง 2k ชอง กให h(x) = k บตทางขวาของ x

bull ถากลมขอมลมคยทมคาเปนระเบยบndash รหสนกศกษา รหสประจาตวบตรประชาชน ndash ตองออกแบบ h(x) ใหทา x ทมระเบยบให เละndash เรยก h(x) วาฟงกชนแฮช (Hash function)

copy S Prasitjutrakul 2006 041049 12

ฟงกชนแฮช (Hash Function)bull wwwwebstercom

ndash hash to chop (as meat and potatoes) into small piecesbull สอ เสถบตร

ndash สบ แหลก นามาโขลกเขาดวยกน

hash

493-01020-21

10291

493-01020-21 rarr 10291

493-87628-21 rarr 76102

473-12332-21 rarr 40001

463-09872-21 rarr 00012

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 3: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 5

Tablepublic class Table implements Set private Object[] tableprivate int size = 0

public Table(int m) table = new Object[m] public boolean isEmpty() return size == 0 public int size() return size

public void add(Object x) if (table[f(x)] == null)++size table[f(x)] = x

public void remove(Object x) if (table[f(x)] = null ampamp table[f(x)]equals(x))--size table[f(x)] = null

public void contains(Object x) return table[f(x)] = null ampamp table[f(x)]equals(x)

private int f(Object x)

Θ(1)

copy S Prasitjutrakul 2006 041049 6

ฟงกชนดชนนนหายากbull เมอตองเกบอยางประหยดbull เมอตองประกนวาไมเกดการ ชนbull ถารชดขอมลทจะจดเกบกอน กอาจหาสตรทไมชนไดbull แตในทางปฏบต ไมร

12157

สบ ฿1532671ชอน ฿10

89133จาน ฿12

98105ดนสอ ฿8

15252ยางลบ ฿5

0 1 2 3 4 6 75 8 9 10 11 12

f(key) = key 10

38227หว ฿40

copy S Prasitjutrakul 2006 041049 7

0

1

2

3

4

5

6

เปลยนกลยทธ อนญาตใหชนไดbull จะไดเกบขอมลในตารางทไมใหญมากbull แตตองหาวธแกไขปญหาการชน ททางานไดเรว ๆ

bull จดเกบกลมขอมลทชนกนไวในรายการเดยวกน

Separate Chaining

14 7

h(x) = x 7

22 1

3 38

46

40

6 13 27 20

copy S Prasitjutrakul 2006 041049 8

SeparateChainingpublic class SeparateChaining

private LinkedList[] tableprivate int size = 0

public SeparateChaining(int m) LinkedList[] table = new LinkedList[m]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()public int size()

return sizepublic boolean isEmpty()

return size == 0

copy S Prasitjutrakul 2006 041049 9

public class SeparateChaining public boolean contains(Object x)

return table[h(x)]contains(x)public void add(Object x)

table[h(x)]add(0 x)++size

public void remove(Object x)

int i = h(x)int s = table[i]size()table[i]remove(x)if (s gt table[i]size()) size--

private int h(Object x)

SeparateChaining

contains และ remove ใชเวลาแปรตามความยาว list

add ใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 10

λ = n m

การกระจายของขอมลbull ถาขอมลกระจายทวตาราง

ndash แตละชองเกบรายการยาว asymp λndash ถา λ นอย คนหาไดเรว

bull ถาไมกระจายndash มบางรายการยาวเกน λ มากndash การคนหาชาเหมอนเกบดวย list

0123456789

260 80180321401

252 92

4764185105

76

10828129

01234567

180 260

401

60 252 92 764 4 76 28 108

321 105 185 129

ขนาดของตารางปรมาณ

ขอมล

h(x) = x 8

h(x) = x 10

load factor

copy S Prasitjutrakul 2006 041049 11

การกระจายของขอมลbull ขนกบ

ndash x คยของขอมลndash h(x) ฟงกชนการแปลงคยเปนเลขทชองของตาราง

bull ถากลมขอมลมคย x ทมคากระจายอยแลวndash ถาใชตาราง 100 ชอง กให h(x) = x 100ndash ถาใชตาราง 2k ชอง กให h(x) = k บตทางขวาของ x

bull ถากลมขอมลมคยทมคาเปนระเบยบndash รหสนกศกษา รหสประจาตวบตรประชาชน ndash ตองออกแบบ h(x) ใหทา x ทมระเบยบให เละndash เรยก h(x) วาฟงกชนแฮช (Hash function)

copy S Prasitjutrakul 2006 041049 12

ฟงกชนแฮช (Hash Function)bull wwwwebstercom

ndash hash to chop (as meat and potatoes) into small piecesbull สอ เสถบตร

ndash สบ แหลก นามาโขลกเขาดวยกน

hash

493-01020-21

10291

493-01020-21 rarr 10291

493-87628-21 rarr 76102

473-12332-21 rarr 40001

463-09872-21 rarr 00012

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 4: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 7

0

1

2

3

4

5

6

เปลยนกลยทธ อนญาตใหชนไดbull จะไดเกบขอมลในตารางทไมใหญมากbull แตตองหาวธแกไขปญหาการชน ททางานไดเรว ๆ

bull จดเกบกลมขอมลทชนกนไวในรายการเดยวกน

Separate Chaining

14 7

h(x) = x 7

22 1

3 38

46

40

6 13 27 20

copy S Prasitjutrakul 2006 041049 8

SeparateChainingpublic class SeparateChaining

private LinkedList[] tableprivate int size = 0

public SeparateChaining(int m) LinkedList[] table = new LinkedList[m]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()public int size()

return sizepublic boolean isEmpty()

return size == 0

copy S Prasitjutrakul 2006 041049 9

public class SeparateChaining public boolean contains(Object x)

return table[h(x)]contains(x)public void add(Object x)

table[h(x)]add(0 x)++size

public void remove(Object x)

int i = h(x)int s = table[i]size()table[i]remove(x)if (s gt table[i]size()) size--

private int h(Object x)

SeparateChaining

contains และ remove ใชเวลาแปรตามความยาว list

add ใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 10

λ = n m

การกระจายของขอมลbull ถาขอมลกระจายทวตาราง

ndash แตละชองเกบรายการยาว asymp λndash ถา λ นอย คนหาไดเรว

bull ถาไมกระจายndash มบางรายการยาวเกน λ มากndash การคนหาชาเหมอนเกบดวย list

0123456789

260 80180321401

252 92

4764185105

76

10828129

01234567

180 260

401

60 252 92 764 4 76 28 108

321 105 185 129

ขนาดของตารางปรมาณ

ขอมล

h(x) = x 8

h(x) = x 10

load factor

copy S Prasitjutrakul 2006 041049 11

การกระจายของขอมลbull ขนกบ

ndash x คยของขอมลndash h(x) ฟงกชนการแปลงคยเปนเลขทชองของตาราง

bull ถากลมขอมลมคย x ทมคากระจายอยแลวndash ถาใชตาราง 100 ชอง กให h(x) = x 100ndash ถาใชตาราง 2k ชอง กให h(x) = k บตทางขวาของ x

bull ถากลมขอมลมคยทมคาเปนระเบยบndash รหสนกศกษา รหสประจาตวบตรประชาชน ndash ตองออกแบบ h(x) ใหทา x ทมระเบยบให เละndash เรยก h(x) วาฟงกชนแฮช (Hash function)

copy S Prasitjutrakul 2006 041049 12

ฟงกชนแฮช (Hash Function)bull wwwwebstercom

ndash hash to chop (as meat and potatoes) into small piecesbull สอ เสถบตร

ndash สบ แหลก นามาโขลกเขาดวยกน

hash

493-01020-21

10291

493-01020-21 rarr 10291

493-87628-21 rarr 76102

473-12332-21 rarr 40001

463-09872-21 rarr 00012

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 5: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 9

public class SeparateChaining public boolean contains(Object x)

return table[h(x)]contains(x)public void add(Object x)

table[h(x)]add(0 x)++size

public void remove(Object x)

int i = h(x)int s = table[i]size()table[i]remove(x)if (s gt table[i]size()) size--

private int h(Object x)

SeparateChaining

contains และ remove ใชเวลาแปรตามความยาว list

add ใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 10

λ = n m

การกระจายของขอมลbull ถาขอมลกระจายทวตาราง

ndash แตละชองเกบรายการยาว asymp λndash ถา λ นอย คนหาไดเรว

bull ถาไมกระจายndash มบางรายการยาวเกน λ มากndash การคนหาชาเหมอนเกบดวย list

0123456789

260 80180321401

252 92

4764185105

76

10828129

01234567

180 260

401

60 252 92 764 4 76 28 108

321 105 185 129

ขนาดของตารางปรมาณ

ขอมล

h(x) = x 8

h(x) = x 10

load factor

copy S Prasitjutrakul 2006 041049 11

การกระจายของขอมลbull ขนกบ

ndash x คยของขอมลndash h(x) ฟงกชนการแปลงคยเปนเลขทชองของตาราง

bull ถากลมขอมลมคย x ทมคากระจายอยแลวndash ถาใชตาราง 100 ชอง กให h(x) = x 100ndash ถาใชตาราง 2k ชอง กให h(x) = k บตทางขวาของ x

bull ถากลมขอมลมคยทมคาเปนระเบยบndash รหสนกศกษา รหสประจาตวบตรประชาชน ndash ตองออกแบบ h(x) ใหทา x ทมระเบยบให เละndash เรยก h(x) วาฟงกชนแฮช (Hash function)

copy S Prasitjutrakul 2006 041049 12

ฟงกชนแฮช (Hash Function)bull wwwwebstercom

ndash hash to chop (as meat and potatoes) into small piecesbull สอ เสถบตร

ndash สบ แหลก นามาโขลกเขาดวยกน

hash

493-01020-21

10291

493-01020-21 rarr 10291

493-87628-21 rarr 76102

473-12332-21 rarr 40001

463-09872-21 rarr 00012

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 6: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 11

การกระจายของขอมลbull ขนกบ

ndash x คยของขอมลndash h(x) ฟงกชนการแปลงคยเปนเลขทชองของตาราง

bull ถากลมขอมลมคย x ทมคากระจายอยแลวndash ถาใชตาราง 100 ชอง กให h(x) = x 100ndash ถาใชตาราง 2k ชอง กให h(x) = k บตทางขวาของ x

bull ถากลมขอมลมคยทมคาเปนระเบยบndash รหสนกศกษา รหสประจาตวบตรประชาชน ndash ตองออกแบบ h(x) ใหทา x ทมระเบยบให เละndash เรยก h(x) วาฟงกชนแฮช (Hash function)

copy S Prasitjutrakul 2006 041049 12

ฟงกชนแฮช (Hash Function)bull wwwwebstercom

ndash hash to chop (as meat and potatoes) into small piecesbull สอ เสถบตร

ndash สบ แหลก นามาโขลกเขาดวยกน

hash

493-01020-21

10291

493-01020-21 rarr 10291

493-87628-21 rarr 76102

473-12332-21 rarr 40001

463-09872-21 rarr 00012

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 7: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 13

ตวอยางฟงกชนแฮชstatic int h1(int x)

long hash = (2654435769L x) amp 0xFFFFFFFFLreturn (int) (hash gtgt 22)

x 1 2 3 4 5 6 7 8

static int h2(int x) x = ~x + (x ltlt 15)x ^= (x gtgtgt 11)x += (x ltlt 3)x ^= (x gtgtgt 5)x += (x ltlt 10)x ^= (x gtgtgt 16)return x

h1(x) 632 241 874 483 92 725 334 966

h2(x) 500 1001 507 978 486 1014 403 933

copy S Prasitjutrakul 2006 041049 14

กลวธการเขยนฟงกชนแฮชbull การวเคราะหเลขโดด (digit analysis)bull การคณ (multiplicative hashing)bull การพบ (folding) bull การหาร (modulus hashing)

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 8: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 15

การวเคราะหเลขโดด (Digit Analysis)bull คดเลอกเลขโดดบางหลกของคยมาพจารณาbull มนใจวาทตดไปไมทาใหเกดความเอนเอยงในการกระจายของคย

bull เชนndash รหสนสตวศวฯ ปตร มรปแบบ xx3xxxxx21 ndash กตดเลข 3 และ 21 ออกจากการพจารณาndash k = 4830109521 ndash k1 = ⎣ k 100 ⎦ k1 = 48301095ndash k2 = ⎣ k1 106 ⎦ k2 = 48ndash k3 = k2105 + k1 105 k3 = 4801095

copy S Prasitjutrakul 2006 041049 16

การคณ (Multiplicative Hashing)bull คณคยดวยจานวนจรง A ทมคาระหวาง (01)bull นาเศษมาคณกบขนาดของตาราง (m = 2p)

( )( )h x m xA xA⎢ ⎥= minus ⎢ ⎥⎣ ⎦⎣ ⎦

x

times A times 232 (0ltAlt1)

xA times 232

32 bits

สวนทเปนเศษของ xA

(xA-⎣xA⎦) times 232

(xA-⎣xA⎦) times 2pp bits

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 9: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 17

การคณ Fibonacci Hashingbull ถา A = golden ratio 06180339887จะแยกคยทมคาใกลกนออกจากกนไดด

int multHash(int x int p)

long s = 2654435769L

long hash = (s x) amp 0xFFFFFFFFL

return (hash gtgt (32-p))

040503154705597430941590946412213806188336851

for (int i = 0 i lt 10 i++)

Systemoutprint(multHash(i 16)+)

5 1ˆ2

φ minus=

06180339887 times 232

copy S Prasitjutrakul 2006 041049 18

การพบ (Folding)bull แบงคยออกเปนสวนๆ แลวนามา รวม กนbull รวม equiv บวก xor

2 1 0 2

9 3 8 4

5 0 5 0

2 1 0 2 9 3 8 4 5 0 5 0

+

1 6 5 3 6

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 10: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 19

การหาร (Modulus Hashing)bull h(x) = x pbull ไมควรเลอก

ndash p = 10q เพราะเลอกเฉพาะ q หลกขวา ถาคยเปนฐานสบndash p = 2q เพราะเลอกเฉพาะ q บตขวาndash p ทมคานอย ๆ เปนตวประกอบ

bull ถา c คอตวประกอบรวมของ p และ xbull คา x p จะเปนจานวนเทาของ c

bull ถา c มคานอย ๆ จะมคยจานวนมากทได x p มคาเปนจานวนเทาของตวประกอบนน ซงไมกระจาย

bull โดยทวไปเลอก p ทเปนจานวนเฉพาะ

copy S Prasitjutrakul 2006 041049 20

ขอมลใด ๆ กเปลยนเปนจานวนเตมไดbull double หรอ float rarr จานวนเตม

ndash DoubledoubleToLongBits(d)ndash FloatfloatToIntBits(f)

bull boolean true rarr 1 false rarr 0bull สตรง rarr จานวนเตม

ndash ขอมลเปนสตรงภาษาองกฤษตวใหญ กมองเปนเลขฐาน 26DATA rarr 3x263 + 0x262 + 19x261 + 0x260 = 53222

bull ออบเจกต rarr จานวนเตมndash แปลงขอมลภายในใหเปนจานวนเตมแลวนามา รวม กน

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 11: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 21

ตวอยาง

public int h(String s) int hash = 0for (int i=0 iltslength() i++)

hash = 31 hash + scharAt(i)return (hash amp 0x7FFFFFFF)

public int h(Point2D p) long bits = DoubledoubleToLongBits(pgetX())bits ^= DoubledoubleToLongBits(pgetY()) 31hash = (((int) bits) ^ ((int) (bits gtgt 32)))return (hash amp 0x7FFFFFFF)

copy S Prasitjutrakul 2006 041049 22

การแฮชเอกภพ (Universal Hashing)bull วธ hash ทผานมา เดาพฤตกรรมได

ndash ชดขอมลทชนกนมากวนน กจะชนกนมากตลอดไปbull ใชสตร h(x) = ((ax + b) p) m)

ndash x isin 0 1 u ndash 1 u คอจานวนคยทเปนไปไดndash m คอขนาดตารางndash หา p ซงคอจานวนเฉพาะหนงตวในชวง [u 2u)

ndash 0 lt a lt p และ 0 le b lt p

bull สมเลอกคา a และ b กอนใชงานndash ชดขอมลทชนกนมากวนน อาจชนกนนอยวนหนาndash สามารถพสจนไดวา จานวนการชนเฉลยเทากบ λ

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 12: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 23

0 10 20 30 40 50 60 k

100

075

050

025

000

ปฏทรรศนวนเกด (Birthday Paradox)bull ตองมคนในหองกคนขนไป จงจะโอกาสเกนครงทจะมคนเกดวนเดอนเดยวกนสองคนขนไป

366 365 364 366 11 05

366 366 366 366

k⎛ minus + ⎞⎛ ⎞⎛ ⎞⎛ ⎞ ⎛ ⎞minus gt⎜ ⎟⎜ ⎟⎜ ⎟ ⎜ ⎟⎜ ⎟⎝ ⎠⎝ ⎠⎝ ⎠ ⎝ ⎠⎝ ⎠

คน โอกาสทมวนเกดไมซากน =366

366⎛ ⎞⎜ ⎟⎝ ⎠

365

366⎛ ⎞⎜ ⎟⎝ ⎠

364

366⎛ ⎞⎜ ⎟⎝ ⎠

366 1

366

kminus +⎛ ⎞⎜ ⎟⎝ ⎠

k

23

copy S Prasitjutrakul 2006 041049 24

ฟงกชนแฮชในจาวา

bull คลาส Object มเมทอดชอ hashCode() โดยทndash ถา xequals(y) เปนจรง

xhashCode() ตอง == yhashCode()bull hashCode ทคลาส Object คนคาตาแหนงเรมตนของออปเจกตในหนวยความจาndash ออปเจกตตางกน ได hashCode ตางกนndash value object ควร overrides hashCode ใหออปเจกตสองตวทมคาเทากนตองม hashCode เหมอนกน

Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Integer(1234)hashCode())Systemoutprintln(new Object()hashCode())Systemoutprintln(new Object()hashCode())

12341234822251018581223

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 13: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 25

ตวอยางการเขยน hashCode() public class Point2D

private double x ypublic int hashCode()

long bits = DoubledoubleToLongBits(x)bits ^= DoubledoubleToLongBits(y) 31return (((int) bits) ^ ((int) (bits gtgt 32)))

public class Book

private String nameprivate String publisherprivate double pricepublic int hashCode()

return namehashCode() ^ publisherhashCode()

copy S Prasitjutrakul 2006 041049 26

อกครง SeparateChainingpublic class SeparateChaining

public boolean contains(Object e)

return table[h(e)]contains(e)public void add(Object e)

table[h(e)]add(0 e)++size

public void remove(Object e)

int i = h(e)int s = table[i]size()table[i]remove(e)if (s gt table[i]size()) size--

private int h(Object x)

return Mathabs(xhashCode()) tablelength

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 14: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 27

Rehashing

Rehashingλ = 18 λ = 4

λ = 2

ถาฟงกชนแฮชกระจายด

การลบและคนใชเวลา O(λ)

ถาควบคม λ ไมใหเกนคาคงตว k

การลบและคนใชเวลาคงตว

copy S Prasitjutrakul 2006 041049 28

SeparateChaining Rehashpublic void add(Object e)

table[h(e)]add(0 e)++sizeif (sizetablelength gt= threshold) rehash()

private void rehash()

LinkedList[] oldTable = tabletable = new LinkedList[2tablelength]for (int i=0 ilttablelength i++)

table[i] = new LinkedList()for (int i=0 iltoldTablelength i++)

Object[] items = oldTable[i]toArray()for (int j=0 jltitemslength j++)

table[ h(items[j]) ]add(0 items[j])

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 15: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 29

การแกปญหาการชนแบบอนbull แบบแยกกนโยง (separate chaining)

ndash แตละชองในตารางเกบรายการโยงของขอมลndash ขอมลทชนกนเกบอยดวยกน ไมกระทบขอมลอนndash เปลองตวโยง (links)

bull แบบเลขทอยเปด (open addressing)ndash แตละชองในตารางเกบขอมลndash ถาชน กหาชองวางใหมในตารางเพอเกบขอมลndash λ = nm le 1 เสมอ ตองคมไมใหเกนเกณฑ (λ le 05)ndash มหลายวธในการหาชองวางใหมในตาราง เมอเกดการชน

bull การตรวจเชงเสน (linear probing)bull การตรวจกาลงสอง (quadratic probing)bull การตรวจสองชน (double hashing)

copy S Prasitjutrakul 2006 041049 30

การตรวจเชงเสน (Linear Probing)bull เมอชน หาชองวางถดไปดวยวธดตวถดไปเรอย ๆbull ให hj(x) คอชองท probe หลงจากชนครงท jbull h0(x) = h(x) คอชองท hash เรมตน (home address)

hj(x) = (h(x) + j) m hj(x) = (hjndash1(x) + 1) m

0 1 2 3 4 5 6 7 8 9 10 11 12

ใช h(x) = x 13 แลวเพมขอมลทมคยตามลาดบดงน

17 32 26 7 4 43 12 11 24

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 16: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 31

LinearProbingHashSetpublic class LinearProbingHashSet implements Set private Object[] tableprivate int size = 0public LinearProbingHashSet(int m) table = new Object[m]

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

copy S Prasitjutrakul 2006 041049 32

LinearProbingHashSetpublic void add(Object e)

int i = indexOf(e)if (table[i] == null)

table[i] = e++size

public void remove(Object e)

int i = indexOf(e)if (table[i] = null)

table[i] = null--size

43 h(x) = x 13

26 24 17 4 32 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

7

ผด

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 17: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 33

สถานะของชองเกบขอมล

bull แตละชองม 3 สถานะndash ชองวาง ๆ ไมเคยมขอมลมาเกบเลยndash ชองทเกบขอมลทถกลบไปแลวndash ชองทมขอมลเกบอย

table[i] == null

table[i] == DELETED

table[i] = null ampamp = DELETED

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

public void remove(Object e) int i = indexOf(e)if (table[i] = null)

table[i] = null--size

DELETEDDELETED เปนออบเจกตทไมเทากบออบเจกตอน การทางานใน indexOf จะคนตอไปเมอพบ DELETED

copy S Prasitjutrakul 2006 041049 34

Rehashpublic class LinearProbingHashSet implements Set

private Object[] tableprivate int size = 0

public void add(Object e) int i = indexOf(e)if (table[i] == null) table[i] = e++size

private static final Object DELETED = new Object()

private int numNonNulls = 0

++numNonNullsif (numNonNulls gt tablelength2) rehash()

private void rehash() Object[] old = tabletable = new Object[4size]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

ไมไดใชชอง DELETED มาใชใหมเลย

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 18: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 35

การนาชอง DELETED มาใชใหมpublic void add(Object e)

int empty = -1int h = h(e)for (int j=0 jlttablelength j++)

if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 1) tablelength

if (table[h] == null)

if (empty = -1) h = emptytable[h] = e++size ++numNonNullsif (numNonNulls gt tablelength2) rehash()

int h = indexOf(e)

if (empty == -1) ++numNonNulls

26 24 17 4 43 11 12

0 1 2 3 4 5 6 7 8 9 10 11 12

43

copy S Prasitjutrakul 2006 041049 36

การเกาะกลมปฐมภม (Primary Clustering)

bull ถาใช linear probling แลวเพมขอมลตวใหมอกตวลงตารางขางลางน อยากทราบวา ขอมลใหมนจะถกนาไปเกบไวทชองใดดวยความนาจะเปนสงสด

Cookie Monster Effect

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 19: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 37

การตรวจกาลงสอง (Quadratic Probing)bull เพอขจดการเกาะกลมปฐมภมbull หลกเลยงการตรวจชองตด ๆ กนbull ใหตรวจแบบกาวกระโดดหาง ๆ

hj(x) = (h(x) + j2 ) m hj(x) = (hjndash1(x) + 2j ndash 1) m

+1 +3 +5 +7

hj(x) = (h(x)+j2) m

hjndash1 (x) = (h(x)+(j ndash 1)2) m

hj(x) ndash hjndash1 (x) = (j2 ndash (j ndash 1)2 ) m

= (j2 ndash j2 + 2j ndash 1) m

hj(x) = (hjndash1 (x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 38

การตรวจกาลงสองไมตรวจทกชองbull ลองเพม 30 อกตว ( h(x) = x 13 )

0 1 17 4 5 7 8

0 1 2 3 4 5 6 7 8 9 10 11 12

h(x) = 4(4+12)13 = 5(4+22)13 = 8(4+32)13 = 0(4+42)13 = 7(4+52)13 = 3(4+62)13 = 1

(4+72)13 = 1(4+82)13 = 3(4+92)13 = 7(4+102)13 = 0(4+112)13 = 8(4+122)13 = 5(4+132)13 = 4

มชองวางอาจหาไมพบ

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 20: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 39

เมอตารางมขนาดเปนจานวนเฉพาะ

bull การตรวจกาลงสองจะดอยางนอยครงหนงของตารางbull ดงนน ถา load factor le frac12 กสบายใจไดวาจะหาชองวางพบ เมอเพมขอมล

bull พสจน ให 0 le i lt j le ⎣m2⎦ ถาขางบนไมจรง ตองมการ probe ครงท i และ j ทดชองซากน

bull เปนไปไมได (j ndash i) ไมเปน 0 (j+i) กไมเปน mอกทง (j ndash i)(j+i) m ne 0 เพราะทงสองพจน lt mและ m เปนจานวนเฉพาะ

h(x) + j2 equiv h(x) + i2 mod mj2 equiv i2 mod m

(j2 ndash i2) equiv 0 mod m(j ndash i)(j + i) equiv 0 mod m

copy S Prasitjutrakul 2006 041049 40

QuadraticProbingHashSetbull เหมอน LinearProbingHashSet ตางกนแคเปลยน

h = (h + 1) tablelength

เปนh = (h + 2j-1) tablelength

bull ตอง rehash เมอ load factor เกนครงbull ขนาดของตารางเปนจานวนเฉพาะตลอด

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 21: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 41

construct และ rehashimport javamathBigIntegerpublic class QuadraticProbingHashSet implements Set private static final Object DELETED = new Object()private Object[] tableprivate int size numNonNulls

public QuadraticProbingHashSet(int m) table = new Object[nextPrime(m)]

private int nextPrime(int n) BigInteger bi = new BigInteger(IntegertoString(n))return binextProbablePrime()intValue()

private void rehash() Object[] old = tabletable = new Object[nextPrime(4size)]size = numNonNulls = 0for(int i = 0 ilt oldlength i++)if (old[i] = null ampamp old[i] = DELETED) add(old[i])

เชน n=5000 จะได 5003

copy S Prasitjutrakul 2006 041049 42

indexOfpublic boolean isEmpty() return size == 0 public int size() return size

public boolean contains(Object e) return table[indexOf(e)] = null

private int indexOf(Object e) int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + 2j - 1) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

hj(x) = (hjndash1(x) + 2j ndash 1) m

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 22: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 43

remove และ addpublic void remove(Object e) int i = indexOf(e)if (table[i] = null) table[i] = DELETED --size

public void add(Object e) int empty = -1int h = h(e)for (int j=0 jlttablelength j++) if (table[h] == DELETED ampamp empty == -1) empty = hif (table[h] == null || table[h]equals(e)) breakh = (h + 2j-1) tablelength

if (table[h] == null) if (empty = -1) h = emptytable[h] = e++size if (empty == -1) ++numNonNullsif (numNonNulls gt tablelength2) rehash()

copy S Prasitjutrakul 2006 041049 44

การเกาะกลมbull การเกาะกลมปฐมภม (primary clustering)

ndash เหนไดดวยตา ขอมลอยตด ๆ กนndash กลมทโต ยงมโอกาสโตขนndash การคนจะชาเหมอนการคนแบบลาดบ

bull การเกาะกลมทตยภม (secondary clustering)ndash ขอมลทม h(x) เดยวกน จะตรวจชองในตารางเหมอนกนndash ระยะกระโดดของการตรวจแปรตามหมายเลขครงทชนndash hj(x) = (h(x) + j) m hj(x) = (h(x) + j2) m

ndash แกปญหานได โดยใหขอมลทม h(x) เดยวกน ไมจาเปนตองมระยะโดดของการตรวจเหมอนกน

ndash ใหระยะกระโดดคานวณจากคาของขอมล

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 23: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 45

การแฮชสองชน (Double Hashing)bull ใชฟงกชนแฮชอกตวเพอคานวณระยะกระโดดbull ทาใหชดขอมลทแฮชไปทชองเดยวกน อาจมระยะกระโดดตางกน

bull โดยท g(x) m ne 0 (เพอไมใหยาอยกบท) เชนndash g(x) = R ndash (x R) R เปนจานวนเฉพาะ และ R lt m

bull และ ตวหารรวมมากของ g(x) และ m ตองเปน 1 จะไดตรวจทกชองในตารางndash ประกนเงอนไขนไดโดยให m เปนจานวนเฉพาะndash h(x) = 0 g(x) = 4 m = 8 จะตรวจชอง 0 และ 4 เทานนndash h(x) = 0 g(x) = 4 m = 7 จะตรวจชอง 0 4 1 5 2 6 3

hj(x) = (h(x) + jg(x)) m hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 46

DoubleHashingHashSetpublic class DoubleHashingHashSet implements Set

private int indexOf(Object e) int h = h(e)int g = g(e)for (int j=0 jlttablelength j++) if (table[h] == null) return hif (table[h]equals(e)) return hh = (h + g) tablelength

throw new AssertionError(ตารางเตมไดไง)

private int h(Object e) return Mathabs(ehashCode()) tablelength

private int g(Object e) return 11 ndash (Mathabs(ehashCode()) 11)

hj(x) = (hjndash1(x) + g(x)) m

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 24: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 47

เปรยบเทยบการเกาะกลม

การตรวจเชงเสน (linear probing)

การตรวจกาลงสอง (quadratic probing)

การแฮชสองชน (double hashing)

λ = 08

copy S Prasitjutrakul 2006 041049 48

เปรยบเทยบจานวนการตรวจเฉลยbull การตรวจเชงเสนตรวจจานวนชองมากกวาแบบอนbull การตรวจกาลงสองและแบบสองชนใกลเคยงกนbull ถา λ le 05 ทงสามแบบไมตางกนมาก

116326711372794970544λ = 09

5322055642161284300λ = 08

344174370182602216λ = 07

254153272159363175λ = 06

202139214143250150λ = 05

167128175131189133λ = 04

143119147121152121λ = 03

ไมพบพบไมพบพบไมพบพบ

Double HashingQuadratic ProbingLinear Probing

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 25: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 49

เปรยบเทยบจานวนการตรวจเฉลย

1 + λ1 + λ2แบบแยกกนโยง (λ ge 0)

การแฮชสองชน (0 le λ le 1)

การตรวจเชงเสน (0 le λ le 1)

หาไมพบหาพบ

จานวนการตรวจเฉลย

1 11

2 1 λ⎛ ⎞+⎜ ⎟minus⎝ ⎠

1 1ln

λ 1 λminus1

1 λminus

ถาม เกบขอมลโดยใชการตรวจเชงเสน ถาตองการตรวจโดยเฉลยไมเกน 5 ครงตองควบคมใหตารางแฮชม λ เปนเทาใด

ตอบ 2

1 15 1

2 (1 λ)

⎛ ⎞ge +⎜ ⎟⎜ ⎟minus⎝ ⎠

2

19

(1 λ)ge

minusλ 2 3le1 λ 19minus ge

2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

copy S Prasitjutrakul 2006 041049 50

เปรยบเทยบเวลาการทางาน1117=1x3x3x32x3x3x3x3x322x3x322222x3x3x3222x32

ArraySet 164987

BSTSet 1112

AVLSet 430

LinearProbingHashSet 1903

QuadraticProbingHashSet 390

SeparateChainingHashSet 350

สราง Set ดวย เวลาการทางาน (ms)

ตอนทางานเสรจ set มขอมลจานวน 73816 ตว

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 26: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 51

เปรยบเทยบเนอทbull แบบตรวจเชงเสน

ndash ตองการเกบ 1200 ตวndash ให λ = 05 m = 2400ndash ตารางคออาเรยของ object

reference (ชองละ 4 ไบต)ndash ตารางใชเนอท 42400 = 9600

ไบตndash ใชเนอททงหมด 9600 ไบตndash λ = 05 จากสตรไดจานวนการ

ตรวจเฉลยเปน 25 ชอง

bull แบบแยกกนโยงndash ตองการตรวจเฉลยจานวน 25 ชองndash จากสตร ตองให λ = 15ndash ตองการเกบ 1200 ตวndash ตองมตาราง 120015 = 800 ชองndash ตารางใชเนอท 4800 = 3200 ไบตndash ถาใช singly linked list ไมมปมหว

ตองม 1200 ปม ใชเนอท 12008 = 9600 ไบต

ndash รวมเปน 3200+9600 = 12800 ไบต

probes = 1 + λ2

1 11

2 (1 λ)

⎛ ⎞+⎜ ⎟⎜ ⎟minus⎝ ⎠

probes =

copy S Prasitjutrakul 2006 041049 52

แบบแยกกนโยงกบแบบเลขทอยเปดbull แบบแยกกนโยง

bull เปลองตวโยงbull ไมมขอจกจกเรองการลบขอมลbull กลมขอมลทชนกนเองมผลกระทบในกลมกนเอง

ไมมผลตอกลมอนbull แบบกาหนดเลขทอยเปด

ndash ประหยดกวา ถงแมจะม λ ตาndash ขอมลอยใกลกน ระบบ cache ทาใหเขาถงขอมลไดเรว

กวาแบบโยงไปมาndash การลบขอมลมผลตอการเกาะกลมขอมลndash ขอมลทชนกนจะมผลกระทบกบขอมลอน ๆ

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน

Page 27: ตารางแฮช - cp.eng.chula.ac.th

copy S Prasitjutrakul 2006 041049 53

ขอควรระวงbull ไมเหมาะกบบรการทเกยวของกบอนดบของขอมล

ndash getMin getMax ndash ตองคนทงตาราง Θ(m+n)

bull ตองระวงเรองฟงกชนแฮชpublic class Book

private String isbnpublic int hashCode()

return 0

return isbnhashCode() amp amp7FFFFFFFH|

copy S Prasitjutrakul 2006 041049 54

สรปการคน เพม ลบขอมลในตารางแฮชทาไดรวดเรวสามารถปรบเวลาการทางานใหเรวขนดวยการใชเนอทเขาแลก เพอใหได λ ทเหมาะสมฟงกชนแฮชมผลตอประสทธภาพการทางาน