fonction de hachage parfait
Je suis d'essayer de hachage les valeurs
10, 100, 32, 45, 58, 126, 3, 29, 200, 400, 0
J'ai besoin d'une fonction qui va de la carte à un tableau qui a une taille de 13 sans provoquer des collisions.
J'ai passé plusieurs heures à réfléchir à ce plus et googler et ne peut pas comprendre cela. Je n'ai pas une solution viable.
Comment pourrais-je aller sur la recherche d'une fonction de hachage de ce genre? J'ai joué avec gperf, mais je ne comprends pas vraiment et je ne pouvais pas obtenir les résultats que je cherchais.
- Cela sonne comme des devoirs ... de toute façon, écrire un programme pour le faire pour vous! 🙂 Venir avec une formule générique, probablement à l'aide de pow ou une opération au niveau des bits, et le module (hey, il y a déjà un exemple dans une réponse!), et puis l'ordinateur de l'plunk, à travers des valeurs jusqu'à ce qu'il y a une "fonction de hachage parfait de match trouvé". Je l'ai fait pour mon CS devoirs il y a des années et il a très bien fonctionné 😉
- On dirait que vous essayez de trouver une minimum parfaite de la fonction de hachage.
- Sur la deuxième pensées... tu as 11 points de données. Pourquoi voulez-vous à la carte pour un tableau de taille 13? Quelle est la signification de ce numéro 13?
- J'ai couru à vos numéros en "gperf" et il se produit un parfait fonction de hachage. Regardez le résultat que vous avez obtenu et vous verrez une fonction appelée 'hash' là.
Vous devez vous connecter pour publier un commentaire.
Trouvé Un
J'ai essayé un peu les choses et trouvé un semi-manuellement:
La semi-manuel a été la suivante ruby script que j'ai utilisé pour tester des fonctions candidates avec une gamme de paramètres:
si vous le connaissez touches, puis il est trivial pour produire un parfait fonction de hachage -
gcc -O0
c'est 5 fois plus rapide qu'une simple table linéaire de recherche sur ma machine, avec-O2
la recherche linéaire prend plus d'une seconde ettime
rapports un temps total de0.00
pour 1 millions de recherches... Il est presque identique à la accepté de répondre à la vitesse de plus de 100 millions d'itérations avec-O0
et à moins de 0,2 s avec-O2
. Et cette fonction de hachage est plus rapide si tout ce que vous devez faire est de travailler si la clé est présente/valide -hash(n)==-1
nécessite pas d'accès à la mémoire... et vous pouvez ajouter des touches avec la fonction reste parfait.O(n)
mais souventO(1)
ouO(log(n))
O(log(n))
de recherche pour trouver le bon interrupteur cas, qui va à l'encontre de l'objectif de l'aide de la fonction de hachage pour une table de hachage. En outre, vous pouvez dériver la fonction de hachage parfait au moment de l'exécution, parfois.Sur certaines plates-formes (par exemple, embedded), modulo est cher, donc
% 13
est préférable d'éviter. MaisAND
opération de bits n'est pas cher, et l'équivalent modulo une puissance de 2.J'ai essayé d'écrire un programme simple (en Python) recherche pour un de hachage parfait de votre 11 points de données, à l'aide de formes simples comme
((x << a) ^ (x << b)) & 0xF
(où& 0xF
est équivalent à% 16
, donnant un résultat dans l'intervalle 0..15, par exemple). J'ai été en mesure de trouver la suite de collision de hachage qui donne un indice dans l'intervalle 0..15 (exprimé en C macro):Voici le programme en Python, j'ai utilisé:
Juste quelques quasi-analytiques divagations:
Dans votre ensemble de nombres, onze en tout, trois sont impairs et huit sont même.
En regardant les formes les plus simples de hachage - %13 - va donner la suite des valeurs de hachage:
10 - 3,
100 - 9,
32 - 6,
45 - 6,
58 - 6,
126 - 9,
3 - 3,
29 - 3,
200 - 5,
400 - 10,
0 - 0
Qui, bien sûr, est inutilisable en raison du nombre de collisions. Quelque chose de plus élaboré est nécessaire.
Pourquoi le mentionner?
Étant donné que les numéros sont si peu complexes - ou plutôt, "moins simple" - algorithme sera probablement plus lent que soit l'instruction switch ou (ce que je préfère), il suffit de parcourir un unsigned short/long vecteur de taille onze postes et à l'aide de l'index de la correspondance.
Pourquoi utiliser un vecteur de recherche?
Bob Jenkins est un programme pour cela aussi: http://burtleburtle.net/bob/hash/perfect.html
Sauf si vous êtes très chanceux, il n'y a pas "gentil" fonction de hachage parfait pour un jeu de données. Parfait algorithmes de hachage généralement utiliser une simple fonction de hachage sur les touches (à l'aide d'assez de bits c'est donc sans collision) puis utiliser un tableau pour y mettre fin.
J'ai fait une rapide vérification et à l'aide de la fonction de hachage SHA256 et ensuite de faire modulaire de la division par 13 travaillé quand je l'ai essayé dans Mathematica. En c++, cette fonction devrait être dans la bibliothèque openssl. Voir ce post.
Si vous faites beaucoup de hachage et de la recherche si, modulaire division est une jolie opération coûteuse pour le faire à plusieurs reprises. Il est une autre façon de cartographie de n bits en fonction de hachage dans un je-peu d'indices. Voir ce post par Michael Mitzenmacher sur la façon de le faire avec un peu de décalage de l'opération en C. Espère que ça aide.
Essayez les solutions suivantes qui correspond à votre n valeurs uniques indices entre 0 et 12
(1369%(n+1))%13