要するに、無料のポリオミノをハッシュする方法は?
これは次のように一般化できます:任意の 2D 整数座標のコレクションを効率的にハッシュする方法。セットには負でない整数の一意のペアが含まれており、変換、回転、反転のいずれもマッピングできない場合にのみ、セットは一意と見なされます。別のセットと同じですか?
せっかちな読者のために、私は力ずくのアプローチを十分に認識していることに注意してください. 私はより良い方法を探しています -- または、他の方法が存在しないという非常に説得力のある証拠を探しています。
ランダムなポリオミノを生成するために、いくつかの異なるアルゴリズムに取り組んでいます。それらの出力をテストして、それらがどの程度ランダムであるかを判断したいと思います。つまり、特定の注文の特定のインスタンスが他のインスタンスよりも頻繁に生成されているかどうかを判断します。視覚的に、フリー ポリオミノのさまざまな方向を識別するのは非常に簡単です。たとえば、次のウィキペディアの図は、「F」ペントミノの 8 つの方向すべてを示しています (出典)。
このポリオミノにどのように数字を付けるか、つまり、自由なポリオミノをハッシュしますか? 「名前付き」ポリオミノの事前に入力されたリストに依存したくありません。とにかく、広く合意された名前はオーダー 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 つの向きは、たとえば次のようになります。
[[1,0], [0,1], [1,1], [2,1]]:
|012
-+---
0| X
1|XXX
入力 polyomino は、X 軸と Y 軸に対して整列するように既に正規化されており、正の座標のみを持っていると想定できます。正式には、各セット:
- x 値が 0 の座標が少なくとも 1 つある
- y 値が 0 である座標が少なくとも 1 つある
- x < 0 または y < 0 の座標はありません
以下で説明する、一般的な力ずくのアプローチで必要とされる整数演算の数の増加を回避する新しいアルゴリズムを本当に探しています。
強引な
こことここ で提案されているブルートフォースソリューションは、各座標をバイナリフラグとして使用して各セットを符号なし整数としてハッシュし、すべての可能な回転 (および私の場合は反転) の最小ハッシュを取得することで構成されます。各回転/反転も必要です。原文に訳します。これにより、「フリー」ハッシュを取得するために、入力セットごとに合計 23 のセット操作が行われます。
- 回転 (6x)
- フリップ (1x)
- 翻訳 (7x)
- ハッシュ (8x)
- 計算されたハッシュの最小値を見つける (1x)
各ハッシュを取得する一連の操作は次のとおりです。
- ハッシュ
- 回転、平行移動、ハッシュ
- 回転、平行移動、ハッシュ
- 回転、平行移動、ハッシュ
- 反転、変換、ハッシュ
- 回転、平行移動、ハッシュ
- 回転、平行移動、ハッシュ
- 回転、平行移動、ハッシュ