¿Cómo evitar los cambios de tamaño en cascada al cambiar el tamaño de las tablas hash?

8

Con los métodos convencionales de resolución de colisiones, como el encadenamiento separado y el sondeo lineal / cuadrático, la secuencia de la sonda para una clave puede ser arbitrariamente larga: simplemente se mantiene corta con alta probabilidad manteniendo el factor de carga de la tabla bajo. Las colisiones durante la repetición no son un problema, ya que no afectan el factor de carga.

Sin embargo, con el hash de cuco (y otros métodos que ofrecen el peor tiempo de búsqueda de O (1)?), Debe producirse un cambio de tamaño cuando la secuencia de la sonda para una clave es demasiado larga. Pero cuando las teclas se barajan durante la repetición, puede ser que creen una secuencia de sondeo demasiado larga para una tecla, lo que requiere otro cambio de tamaño, posiblemente varios, si esto sucede varias veces seguidas. La probabilidad es pequeña, especialmente con una buena función hash, pero lo he visto suceder.

¿Hay alguna forma, salvo generar explícitamente una función hash perfecta durante la repetición, para garantizar que los cambios de tamaño no puedan caer en cascada de esta manera? ¿Posiblemente específico para un esquema de resolución de colisión dado? La literatura que he encontrado hasta ahora parece pasar completamente por alto el asunto. Tenga en cuenta que también me interesa reducir las tablas hash, no solo cultivarlas.

Anónimo
fuente

Respuestas:

1

Pregunta cómo evitar las repeticiones en cascada, pero ya dio la respuesta en su publicación. Mantiene la probabilidad de que ocurran malos eventos pequeños.

Ya que mencionas hash cuckoo. La probabilidad de que obtenga una secuencia de sondeo larga es . Entonces, si repite, está insertando elementos desde cero. La probabilidad de que la repetición no sea exitosa es entonces , por lo que con una probabilidad muy alta es exitosa. En expectativa, solo necesita un número constante de intentos. Si observa que tiene problemas para volver a escribir, debe aumentar el tamaño de su tabla y modificar su factor de carga. Alternativamente, puede seleccionar una mejor familia de funciones hash.O(1/n2)nO(1/n)

A.Schulz
fuente
-1

Creo que tengo una solución, inspirada en el hashing lineal :

Si las funciones hash se mantienen constantes (es decir, no cambian al cambiar el tamaño) y la tabla siempre crece al duplicar las ranuras, entonces, después de que la tabla crece, mantiene que

Hmod2L={HmodL+LorHmodL

donde es el hash de una clave y es el número anterior de ranuras. Esto significa que una clave permanece donde está o se mueve a una ranura única en el área recién asignada, que está garantizada de estar vacía.HL

Para aplicar esto al hash cuckoo (d-ary), simplemente cambie el tamaño de cada una de las subtablas individualmente y no mueva las teclas entre las subtablas.

Para reducir la tabla, debe confirmar que uno de es vacante para cada tecla de la tabla, y si es así, muévalos a su{HmodL2+L2, HmodL2}HmodL2 ranuras . Por supuesto, esto es ... No estoy seguro de si hay una mejor manera de hacerlo que ejecutar la verificación para cada eliminación una vez que el factor de carga cae por debajo de la mitad.O(n)

Anónimo
fuente
No estoy seguro de que esto funcione. ¿Qué pasa si su función hash es h (x) = c, para alguna constante c?
jbapple