¿Cómo hash un punto de geometría en un plano 2D?

Los números tienden a agruparse en la mayoría de los planos de coordenadas; porque, nos gusta usar números dentro de un rango cómodo. Por esta razón, la combinación trivial xor no es deseable, ya que todos los números donde x == ycolisionarán, como lo serán todos los números donde x + 1 == yy así sucesivamente.

Para evitar esto, le recomiendo que invierta los bytes de la coordenada y antes de xor con la coordenada x. Esto combinará el área de mayor variabilidad (los bytes de orden inferior) de una entrada con el área de menor variabilidad (los bytes de orden superior) de la otra entrada. Tal algoritmo dará una distribución más pareja al considerar grupos de números (digamos los valores de x entre 1 y 1000).

Dado que los algoritmos de hash funcionan mejor cuando el hash produce un campo numérico sin agrupamiento pesado, tal solución realmente hará que las estructuras de datos relacionadas con el hash sean más rápidas debido a una colisión de hash menos frecuente.

Por supuesto, lo siguiente no está optimizado, y es probable que pueda recortarlo para que se ajuste a sus necesidades, pero esta es la idea subyacente:

public int hashCode() {

    long bits = Double.doubleToLongBits(y);
    byte[] ybits = new byte[] {
        (byte)((y >> 56) & 0xff),
        (byte)((y >> 48) & 0xff),
        (byte)((y >> 40) & 0xff),
        (byte)((y >> 32) & 0xff),
        (byte)((y >> 24) & 0xff),
        (byte)((y >> 16) & 0xff),
        (byte)((y >> 8) & 0xff),
        (byte)((y >> 0) & 0xff),
    };
    byte[] xbits = new byte[] {
        (byte)((x >> 56) & 0xff),
        (byte)((x >> 48) & 0xff),
        (byte)((x >> 40) & 0xff),
        (byte)((x >> 32) & 0xff),
        (byte)((x >> 24) & 0xff),
        (byte)((x >> 16) & 0xff),
        (byte)((x >> 8) & 0xff),
        (byte)((x >> 0) & 0xff),
    };
    // this combines the bytes of X with the reversed order
    // bytes of Y, and then packs both of those into 4 bytes
    // because we need to return an int (4 bytes).
    byte[] xorbits = new byte[] {
         (xbits[0]^ybits[7])^(xbits[4]^ybits[3]),
         (xbits[1]^ybits[6])^(xbits[5]^ybits[2]),
         (xbits[2]^ybits[5])^(xbits[6]^ybits[1]),
         (xbits[3]^ybits[4])^(xbits[7]^ybits[0]),
    };

    int value = 0;
    for (int i = 0; i < 3; i++) {
       value = (value << 8) + (by[i] & 0xff);
    }
    return value;
}

Las optimizaciones iniciales que sugeriría serían almacenar en caché el código hash en el objeto para búsquedas posteriores, y si el perfil sugiere que es un problema, quizás administre las matrices creadas / destruidas de manera más eficiente.

Respuesta 1

Puede usar la función que desee. Todo depende de los valores típicos que tengan sus coordenadas y de qué tan bueno quiere que sea la función hash.

Si, por ejemplo, todos sus puntos están en el rango de 1 a 1 millón, entonces podría usar algo como esto (este es el código C ++, no sé qué idioma está usando).

size_t hashCode = (size_t)x * (size_t)y;

O puede agregar los valores, o multiplicar los valores, o hacer lo que quiera.

size_t hashCode = (size_t)(x+y);

o

size_t hashCode = (size_t)(x*y);

o incluso

size_t hashCode = (size_t)(x*y) + (size_t)(x+y);
Respuesta: 2

Tengo una aplicación web que consiste en un servicio web con dos operaciones: createA y createB. Se registra un controlador para el punto final. Este controlador abre una sesión e inicia una transacción cuando ...

Tengo una función de Oracle my_func () que devuelve la tabla de tipo de usuario. Ahora puedo seleccionar de esta manera: SELECCIONAR * DE LA TABLA (my_func (3)); Pero mi proyecto no debería depender de la base de datos, y yo ...

Los ejemplos funcionan mejor, imagine que Object es un Byte e intentamos convertirlo en un largo ... Actualmente, el código de byte se parece un poco a este Byte b = Byte.valueOf (1); Fuente del objeto = b; Largo largo = (...

Estoy usando el dominio de datos para la autenticación de inicio de sesión. funciona bien. También estoy usando componentes primefaces 3.2 en mi aplicación, también funcionan bien, PERO el problema ocurre en la página de inicio antes de iniciar sesión. Las primeras caras ...