Mengapa lebih baik menggunakan bilangan prima sebagai mod dalam fungsi hashing?

58

Jika saya memiliki daftar nilai kunci dari 1 hingga 100 dan saya ingin mengaturnya dalam array 11 ember, saya telah diajarkan untuk membentuk fungsi mod

H=kmod 11

Sekarang semua nilai akan ditempatkan satu demi satu dalam 9 baris. Misalnya, dalam ember pertama akan ada 0,11,22 . Dalam yang kedua, akan ada 1,12,23 dll.

Katakanlah saya memutuskan untuk menjadi anak nakal dan menggunakan non-prime sebagai fungsi hashing saya - ambil 12. Menggunakan fungsi Hashing

H=kmod 12

akan menghasilkan tabel hash dengan nilai 0,12,24 dalam bucket pertama, 1,13,25 dll di kedua dan seterusnya.

Pada dasarnya mereka adalah hal yang sama. Saya tidak mengurangi tabrakan dan saya tidak menyebar lebih baik dengan menggunakan kode hash bilangan prima dan saya tidak bisa melihat bagaimana itu selalu bermanfaat.

CodyBugstein
sumber
Pertanyaan yang relevan, mengapa kita menggunakan xor di hash-function stackoverflow.com/questions/5889238/…
shuva

Jawaban:

63

Pertimbangkan kumpulan kunci dan tabel hash di mana jumlah ember adalah . Karena adalah faktor , kunci yang merupakan kelipatan dari akan di-hash ke bucket yang merupakan kelipatan dari :K={0,1,...,100}m=1231233

  • Kunci akan di-hash ke bucket .{0,12,24,36,...}0
  • Kunci akan di-hash ke bucket .{3,15,27,39,...}3
  • Kunci akan di-hash ke bucket .{6,18,30,42,...}6
  • Kunci akan di-hash ke bucket .{9,21,33,45,...}9

Jika terdistribusi secara merata (yaitu, setiap kunci dalam kemungkinan sama terjadi), maka pilihan tidak begitu kritis. Tetapi, apa yang terjadi jika tidak terdistribusi secara merata? Bayangkan bahwa kunci yang paling mungkin terjadi adalah kelipatan . Dalam hal ini, semua bucket yang bukan kelipatan akan kosong dengan probabilitas tinggi (yang benar-benar buruk dalam hal kinerja tabel hash).KKmK33

Situasi ini lebih sering terlihat. Bayangkan, misalnya, bahwa Anda melacak objek berdasarkan tempat mereka disimpan dalam memori. Jika ukuran kata komputer Anda adalah empat byte, maka Anda akan hashing kunci yang merupakan kelipatan dari . Tidak perlu dikatakan bahwa memilih menjadi kelipatan akan menjadi pilihan yang mengerikan: Anda akan memiliki ember yang benar-benar kosong, dan semua kunci Anda bertabrakan dalam ember tersisa .4m43m/4m/4

Secara umum:

Setiap kunci dalam yang berbagi faktor umum dengan jumlah ember akan di-hash ke sebuah ember yang merupakan kelipatan dari faktor ini.Km

Oleh karena itu, untuk meminimalkan tabrakan, penting untuk mengurangi jumlah faktor umum antara dan unsur . Bagaimana ini bisa dicapai? Dengan memilih menjadi bilangan yang memiliki beberapa faktor: bilangan prima .mKm

Mario Cervera
sumber
Saya baru saja melihat bahwa permintaan saya sejalan dengan jawaban Anda. Apakah menurut Anda fungsi hash di kueri saya bagus?
overexchange
@exexchange: Saya menjawab pertanyaan Anda. Jawaban ini mungkin juga menarik bagi Anda.
Mario Cervera
mengapa begitu sehingga pilihan m hanya penting jika K miring? bukankah benar bahwa kita akan memiliki kinerja yang lebih buruk dengan m buruk bahkan jika K didistribusikan secara seragam?
vorou
Tergantung pada apa yang Anda maksud dengan "bad ". Jika Anda berarti "kecil dibandingkan dengan jumlah elemen dalam tabel hash" (yaitu, faktor beban tinggi ), maka, kinerja akan buruk. Namun, jika yang Anda maksud "tidak prima", maka fakta ini tidak begitu penting jika semua kunci sama-sama mungkin karena mereka akan didistribusikan secara merata di tabel hash. Pertanyaan itu sendiri memberikan contoh. m
Mario Cervera
16

Apakah kemungkinan tabrakan menggunakan bilangan prima tergantung pada distribusi kunci Anda.

Jika banyak dari kunci Anda memiliki bentuk dan fungsi hash Anda adalah , maka tombol-tombol ini pergi ke subset kecil dari ember IFF membagi . Jadi, Anda harus meminimalkan jumlah seperti itu , yang dapat dicapai dengan memilih bilangan prima.a+kbH(n)=nmodmbnb

Jika di sisi lain Anda suka memiliki hingga ember dan Anda tahu bahwa perbedaan yang merupakan kelipatan dari lebih mungkin daripada perbedaan yang merupakan kelipatan dari dan , Anda dapat memilih untuk aplikasi yang sangat spesial.1112112312

frafl
sumber
1
Tetapi jika kunci saya tidak memiliki bentuk maka tidak masalah? Apakah itu benar? a+k×bm
CodyBugstein
1
@lmray, jika kunci Anda didistribusikan secara merata, tidak masalah. Jika tidak, itu akan tergantung pada distribusi presisi untuk menjadi masalah atau tidak. mm
Pemrogram
Baru saja mengembalikan suntingan terakhir, saya lupa bahwa . 12>11
frafl
3
Apakah maksud Anda bahwa "pergi ke subset kecil ember jika membagi "? bm
Mikhail Dubov
8

Apakah ini berdampak (juga) tergantung pada bagaimana Anda memperlakukan tabrakan. Saat menggunakan beberapa varian hashing terbuka , menggunakan bilangan prima menjamin slot kosong ditemukan selama tabel cukup kosong.

Coba perlihatkan yang berikut ini, misalnya:

Asumsikan kita ingin memasukkan elemen yang hash ke alamat dan menyelesaikan collision dengan mencoba posisi selanjutnya untuk .a + i 2 i = 1 , 2 , aa+i2i=1,2,

Tunjukkan bahwa prosedur ini selalu menghasilkan posisi kosong jika tabel hash berukuran , a perdana lebih besar dari , dan setidaknya setengah dari semua posisi bebas.p 3pp3

Petunjuk: Gunakan fakta bahwa modulo cincin residu kelas adalah bidang jika adalah prima dan karena itu memiliki paling banyak solusi.p i 2 = c 2ppi2=c2

Raphael
sumber
2

Jika fungsi hash Anda dalam bentuk mana adalah prima dan dipilih secara acak, maka probabilitas bahwa 2 hash kunci yang berbeda untuk bucket yang sama adalah . Jadi untuk , yang sangat kecil.h(k)=a×kmodmma1mm=1009Pr{h(x)=h(y),xy}=0.00099108027

Skema ini dikenal sebagai: Universal Hashing.

saadtaame
sumber