Se eu tenho uma lista de valores-chave de 1 a 100 e quero organizá-los em uma matriz de 11 intervalos, fui ensinado a formar uma função mod
Agora todos os valores serão colocados um após o outro em 9 linhas. Por exemplo, no primeiro intervalo, haverá . No segundo, haverá etc.
Digamos que eu decidi ser um garoto mau e usar um não primo como minha função de hash - pegue 12. Usando a função Hashing
resultaria em uma tabela de hash com valores no primeiro intervalo, etc. no segundo e assim por diante.
Essencialmente, eles são a mesma coisa. Não reduzi colisões e não espalhei melhor as coisas usando o código hash do número primo e não consigo ver como isso é benéfico.
data-structures
hash
hash-tables
primes
CodyBugstein
fonte
fonte
Respostas:
Considere o conjunto de chaves e uma tabela de hash em que o número de buckets é . Como é um fator , as chaves que são múltiplos de serão divididas em hash para baldes que são múltiplos de :m = 12 3 12 3 3K={0,1,...,100} m=12 3 12 3 3
Se é distribuído uniformemente (ou seja, todas as chaves em têm a mesma probabilidade de ocorrer), então a escolha de não é tão crítica. Mas, o que acontece se não for distribuído uniformemente? Imagine que as chaves com maior probabilidade de ocorrência são os múltiplos de . Nesse caso, todos os buckets que não sejam múltiplos de ficarão vazios com alta probabilidade (o que é realmente ruim em termos de desempenho da tabela de hash).K m K 3 3K K m K 3 3
Essa situação é mais comum do que parece. Imagine, por exemplo, que você esteja acompanhando os objetos com base em onde eles estão armazenados na memória. Se o tamanho da palavra do computador for de quatro bytes, você usará chaves de hash com múltiplos de . Escusado será dizer que escolher como um múltiplo de seria uma escolha terrível: você teria baldes de completamente vazios e todas as suas chaves colidiriam nos baldes de restantes .m 4 3 m / 4 m / 44 m 4 3m/4 m/4
Em geral:
Portanto, para minimizar as colisões, é importante para reduzir o número de factores comuns entre e os elementos de . Como isso pode ser alcançado? Escolhendo para ser um número com poucos fatores: um número primo .K mm K m
fonte
Se uma colisão é menos provável usando números primos depende da distribuição de suas chaves.
Se muitas de suas chaves tiverem o formato sua função hash for , essas chaves direcionadas para um pequeno subconjunto dos buckets se if dividir . Portanto, você deve minimizar o número de , o que pode ser alcançado escolhendo um primo.H ( n ) = n mod m b n ba+k⋅b H(n)=nmodm b n b
Se, por outro lado, você gosta de ter de a baldes e sabe que as diferenças que são múltiplos de são mais prováveis do que as diferenças que são múltiplos de e , você pode escolher para sua aplicação muito especial.12 11 2 3 1211 12 11 2 3 12
fonte
Se isso tem impacto (também) depende de como você trata as colisões. Ao usar algumas variantes de hash aberto , o uso de números primos garante que slots vazios sejam encontrados desde que a tabela esteja suficientemente vazia.
Tente mostrar o seguinte, por exemplo:
fonte
Se a sua função hash tiver a forma onde é primo e é escolhido aleatoriamente, a probabilidade de duas chaves distintas serem hash no mesmo intervalo é de . Portanto, para , que é muito pequeno.h(k)=a×kmodm m a 1m m=1009 Pr{h(x)=h(y),x≠y}=0.00099108027
Esse esquema é conhecido como: Hashing Universal.
fonte