Короче: Как хэш свободного полиомино?
Это можно было бы обобщить на: Как эффективно хешировать произвольный набор двумерных целочисленных координат, где множество содержит уникальные пары неотрицательных целых чисел, а множество считается уникальным тогда и только тогда, когда нет перевода, вращения, или флип может сопоставить его идентично другому набору?
Для нетерпеливых читателей обратите внимание, что я полностью понимаю подход грубой силы. Я ищу лучший способ - или очень убедительное доказательство того, что другого пути не существует.
Я работаю над некоторыми разными алгоритмами для генерации случайных polyominos. Я хочу проверить их вывод, чтобы определить, насколько они случайны, т.е. Некоторые экземпляры заданного порядка генерируются чаще, чем другие. Визуально очень легко идентифицировать разные ориентации свободного полиомино, например, следующая иллюстрация в Википедии показывает все 8 ориентаций пентино "F" (Источник):
Как бы поставить номер на этом полиомино, т.е. хэш свободного полиомино? Я не хочу зависеть от преполированного списка "названных" полиоминосов. Во всяком случае, имена с широким согласием существуют только для заказов 4 и 5.
Это не обязательно равносильно перечислению всех свободных (или односторонних или фиксированных) многочленов данного порядка. Я хочу только подсчитать количество раз, когда отображается данная конфигурация. Если генерирующий алгоритм никогда не создает определенного полиомино, он просто не будет считаться.
Основная логика подсчета:
testcount = 10000 // Arbitrary
order = 6 // Create hexominos in this test
hashcounts = new hashtable
for i = 1 to testcount
poly = GenerateRandomPolyomino(order)
hash = PolyHash(poly)
if hashcounts.contains(hash) then
hashcounts[hash]++
else
hashcounts[hash] = 1
Я ищу эффективный алгоритм PolyHash
. Входные полиомины просто определяются как набор координат. Одна ориентация T tetronimo может быть, например:
[[1,0], [0,1], [1,1], [2,1]]:
|012
-+---
0| X
1|XXX
Можно предположить, что этот входной полиомино уже будет нормализован, чтобы быть выровненным относительно осей X и Y и иметь только положительные координаты. Формально каждый набор:
- Будет иметь по крайней мере 1 координату, где значение x равно 0
- Будет иметь по крайней мере 1 координату, где значение y равно 0
- Не будет координат, где x < 0 или y < 0
Я действительно ищу новые алгоритмы, которые избегают увеличения числа целых операций, требуемых общим подходом грубой силы, описанным ниже.
Грубая сила
Предлагается решение грубой силы здесь и здесь хэширования каждого набора как целого числа без знака с использованием каждой координаты в качестве двоичного флага и принятия минимального хэша всех возможных поворотов (и в моем случае переворачивает), где каждый поворот/флип также должен быть переведен в начало координат. Это дает в общей сложности 23 заданных операции для каждого набора входных данных, чтобы получить "свободный" хеш:
- Повернуть (6x)
- Flip (1x)
- Перевести (7x)
- Hash (8x)
- Найти минимальные вычисленные хэши (1x)
Если последовательность операций для получения каждого хэша:
- Hash
- Повернуть, Перевести, Хэш
- Повернуть, Перевести, Хэш
- Повернуть, Перевести, Хэш
- Flip, Translate, Hash
- Повернуть, Перевести, Хэш
- Повернуть, Перевести, Хэш
- Повернуть, Перевести, Хэш