У меня есть числа в определенном диапазоне (обычно от 0 до около 1000). Алгоритм выбирает несколько чисел из этого диапазона (от 3 до 10 чисел). Этот выбор делается довольно часто, и мне нужно проверить, была ли уже выбрана перестановка выбранных чисел.
например, один шаг выбирает [1, 10, 3, 18]
, а другой [10, 18, 3, 1]
, тогда второй выбор можно отбросить, потому что это перестановка.
Мне нужно сделать эту проверку очень быстро. Прямо сейчас я помещаю все массивы в хэш-карту и использую собственную хэш-функцию: просто суммирую все элементы, поэтому 1 + 10 + 3 + 18 = 32, а также 10 + 18 + 3 + 1 = 32. Для равных я использую набор битов, чтобы быстро проверить, находятся ли элементы в обоих наборах (мне не нужна сортировка при использовании набора битов, но он работает только тогда, когда диапазон чисел известен и не слишком большой).
Это работает нормально, но может генерировать множество коллизий, поэтому метод equals () вызывается довольно часто. Мне было интересно, есть ли более быстрый способ проверки на перестановки?
Есть ли хорошие хеш-функции для перестановок?
UPDATE
Я сделал небольшой тест: сгенерировал все комбинации чисел в диапазоне от 0 до 6 и длины массива от 1 до 9. Возможны 3003 перестановки, и хороший хеш должен генерироваться вблизи этого множества различных хешей (я использую 32-битные числа для хэша):
- 41 различных хешей для простого добавления (поэтому существует множество коллизий)
- 8 различных хэшей для значений XOR'ов вместе
- 286 различных хешей для умножения
- 3003 различных хешей для (R + 2e) и умножения, как предлагал abc (используя 1779033703 для R)
Таким образом, хэш abc может быть вычислен очень быстро и намного лучше, чем все остальные. Спасибо!
PS: я не хочу сортировать значения, когда мне это не нужно, потому что это будет слишком медленно.