Я думаю, то, что вы ищете, напрямую невозможно. Одним из важных свойств равенства является то, что оно транзитивно. (т.е. если a == b и b == c, то a == c). Однако при измерении расстояния вам действительно не нужно это свойство. Пример:
Возьмите один поплавок (для простоты). Предположим, что мы хотим хэшировать каждое число с плавающей точкой, чтобы значения с плавающей точкой менее 1e-3 имели одинаковое значение. Теперь предположим, что мы добавили к этой хеш-таблице 1000 значений с плавающей запятой, все с точностью до 1e-4. Любые соседние 2 значения должны хешироваться в один и тот же тип с плавающей точкой, поскольку они ближе, чем 1e-3. Однако из-за транзитивности соседям по этим значениям также должно присваиваться одинаковое значение, а также их соседям и так далее. В результате все 1000 значений, включая пары дальше, чем 1e-3 друг от друга, будут хэшировать одно и то же целое число. Если бы вы нарисовали эти точки на картинке:
A B C D E F G H ... Y Z
Предположим, что все промежутки находятся на расстоянии <1e-3, но A и Z на расстоянии> 1e-3 (не в масштабе!). Это не может быть выполнено, потому что если hash (A) == hash (B) и hash (B) == hash (C) и т. Д. Для всех пар (поскольку они <1e-3 друг от друга), чем hash (A ) должен == хэш (Z). </p>
Один из возможных вариантов - определить области вашего векторного пространства, в которых все векторы будут хэшироваться до одинакового значения (то есть округлять их перед тем, как их хэшировать), но вы все равно можете получить 2 вектора на краях соответствующих им пространств, которые близки вместе, но хэш к другому значению. Вы можете обойти это путем поиска вектора во всех соседних пространствах. (т. е. в вышеприведенном 1-м случае вы округлили бы все векторы до ближайшего кратного 1e-3, а затем искали соседей, поэтому 5.3e-3 будет искать 5e-3, 4e-3 и 6-e3. В случаях с большими измерениями вам придется искать соседей во всех измерениях.)