特定の範囲(通常は0から約1000)の番号があります。アルゴリズムは、この範囲からいくつかの数値を選択します(約3から10の数値)。この選択は非常に頻繁に行われるため、選択した数値の順列がすでに選択されているかどうかを確認する必要があります。
たとえば、1つのステップが選択[1, 10, 3, 18]
され、別のステップが選択されると[10, 18, 3, 1]
、2番目の選択は順列であるため破棄できます。
このチェックを非常に速く行う必要があります。今、私はすべての配列をハッシュマップに入れ、カスタムハッシュ関数を使用しています。つまり、すべての要素を合計するだけなので、1 + 10 + 3 + 18 = 32、さらに10 + 18 + 3 + 1=32です。等しい場合は、ビットセットを使用して、要素が両方のセットにあるかどうかをすばやく確認します(ビットセットを使用する場合は並べ替えは必要ありませんが、数値の範囲がわかっていて大きすぎない場合にのみ機能します)。
これは問題なく機能しますが、多くの衝突を生成する可能性があるため、equals()メソッドが頻繁に呼び出されます。順列をチェックするより速い方法があるかどうか疑問に思いましたか?
順列に適したハッシュ関数はありますか?
アップデート
私は少しベンチマークを行いました:0から6の範囲の数値のすべての組み合わせ、および配列の長さ1から9を生成します。3003の可能な順列があり、この多くの異なるハッシュの近くで適切なハッシュを生成する必要があります(32ビットの数値を使用します)ハッシュの場合):
- 追加するだけの41の異なるハッシュ(したがって、衝突がたくさんあります)
- 値を一緒にXORするための8つの異なるハッシュ
- 乗算用の286の異なるハッシュ
- (R + 2e)の3003の異なるハッシュと、abcが示唆しているように乗算(Rに1779033703を使用)
したがって、abcのハッシュは非常に高速に計算でき、他のすべてのハッシュよりもはるかに優れています。ありがとう!
PS:遅くなりすぎるので、必要のないときに値を並べ替えたくありません。