ダブル ハッシュは、ハッシュ テーブルでオープン アドレッシングと組み合わせて使用されるコンピュータ プログラミング手法であり、衝突が発生したときにキーの 2 次ハッシュをオフセットとして使用して、ハッシュ衝突を解決します。オープン アドレッシングを使用したダブル ハッシュは、テーブル上の古典的なデータ構造です。
二重ハッシュ法では、1 つのハッシュ値をテーブルへのインデックスとして使用し、目的の値が見つかるまで、空の位置に到達するまで、またはテーブル全体が検索されるまで、間隔を繰り返し進めます。ただし、この間隔は 2 番目の独立したハッシュ関数によって設定されます。線形プローブや二次プローブなどの代替の衝突解決方法とは異なり、間隔はデータによって異なるため、同じ位置にマッピングされる値は異なるバケット シーケンスを持ちます。これにより、衝突の繰り返しとクラスタリングの影響が最小限に抑えられます。
2 つのランダムで一様かつ独立したハッシュ関数と がある場合、バケットのハッシュ テーブル内の値 のバケット シーケンス内の 番目の位置は次のようになります。 一般に、と はユニバーサル ハッシュ関数のセットから選択され、は の範囲を持ち、 はの範囲を持つように選択されます。二重ハッシュはランダム分布を近似します。より正確には、ペアワイズ独立ハッシュ関数は、任意のキーのペアが同じバケット シーケンスに従う確率 を生成します。
hの選択2(ク)
二次ハッシュ関数にはいくつかの特性が必要です。
- インデックスがゼロになることはありません。
- テーブル全体を循環するはずです。
- 計算は非常に高速になるはずです。
- それは からペアワイズ独立でなければなりません。
- の分布特性は無関係です。これは乱数ジェネレータに類似しています。
- すべては| T | と互いに素でなければなりません。
実際には:
- 両方の関数に除算ハッシュが使用される場合、除数は素数として選択されます。
- | T | が2の累乗の場合、最初と最後の要件は通常、常に奇数を返すことで満たされます。これには、1ビットの無駄により衝突の可能性が2倍になるという副作用があります。[1]
分析
に格納されている要素数を とすると、の負荷係数は です。つまり、まず 2 つのユニバーサル ハッシュ関数と をランダムに、均一に、独立に選択して、二重ハッシュ テーブル を構築します。すべての要素は、と を使用した二重ハッシュによって に格納されます。キー が与えられた場合、-st ハッシュの位置は次のように計算されます。
が固定の負荷係数 を持つものとします。Bradford とKatehakis [2]は、最初に選択したハッシュ関数を使用した場合、 での失敗した検索のプローブの期待数は、入力の分布に関係なく になることを示しました。ハッシュ関数のペアワイズ独立性で十分です。
他のすべてのオープン アドレス指定形式と同様に、ハッシュ テーブルが最大容量に近づくと、二重ハッシュは線形になります。通常のヒューリスティックは、テーブルの読み込みを容量の 75% に制限することです。最終的には、他のすべてのオープン アドレス指定方式と同様に、より大きなサイズへの再ハッシュが必要になります。
バリエーション
ピーター・ディリンジャーの博士論文[3]は、ブルームフィルタのようにハッシュ関数が集合として扱われる場合、二重ハッシュによって望ましくない同等のハッシュ関数が生成されることを指摘しています。および の場合、および ハッシュの集合は 同一です。これにより、衝突の可能性が期待される の2倍になります。
さらに、大部分が重複するハッシュ セットが多数存在します。 および の場合、 であり、の追加ハッシュ値の比較 ( の範囲の拡張) は役に立ちません。
トリプルハッシュ
ハッシュ関数に二次項[4](三角数)または偶数項(トリプルハッシュ)[5]を追加すると、ハッシュ関数はいくらか改善されますが[4]、この問題は解決されません。
- そして
それから
強化されたダブルハッシュ
3次項 [4]または(四面体数)[1]を追加すると、問題は解決します。これは拡張ダブルハッシュと呼ばれる手法です。これは前方差分によって効率的に計算できます。
struct key ; /// 不透明/// 必要に応じて他のデータ型を使用します。(ラッピングを保証するには符号なしである必要があります。) extern unsigned int h1 ( struct key const * ), h2 ( struct key const * );
///拡張ダブルハッシュを使用して、
2 つの基礎ハッシュ関数 h1() と h2() から k 個のハッシュ値を計算します。戻り値として、 /// hashes[i] = h1(x) + i*h2( x ) + (i*i*i - i)/6 が返されます。 ///
C の unsigned 型の自動ラッピング (モジュラー削減) を利用します。
void ext_dbl_hash ( struct key const * x , unsigned int hashes [], unsigned int n ) { unsigned int a = h1 ( x ), b = h2 ( x ), i ;
hashes [ i ] = a ; for ( i = 1 ; i < n ; i ++ ) { a += b ; // 2次差を加算して3次を得るb += i ; // 1次差を加算して2次を得る// i++ は定数差を加算して1次を得るhashes [ i ] = a ; } }
衝突問題を解決することに加えて、拡張ダブルハッシュ法は、の特性に対するダブルハッシュ法の数値的制限も取り除き、特性が に似ている(ただし からは独立している)ハッシュ関数を使用できるようにします。[1]
参照
参考文献
- ^ abc Dillinger, Peter C.; Manolios, Panagiotis (2004 年 11 月 15 ~ 17 日)。確率的検証におけるブルーム フィルタ(PDF) 。第 5 回コンピュータ支援設計における形式手法に関する国際会議 (FMCAD 2004)。テキサス州オースティン。CiteSeerX 10.1.1.119.628。doi : 10.1007 /978-3-540-30494-4_26。
- ^ Bradford, Phillip G.; Katehakis, Michael N. (2007 年 4 月)、「組み合わせ展開器とハッシュに関する確率的研究」(PDF)、SIAM Journal on Computing、37 (1): 83–111、doi :10.1137/S009753970444630X、MR 2306284、2016年 1 月 25 日の オリジナル(PDF)からアーカイブ。
- ^ Dillinger, Peter C. (2010 年 12 月). Adaptive approximate State Storage (PDF) (博士論文). ノースイースタン大学. pp. 93–112.
- ^ abc Kirsch, Adam; Mitzenmacher, Michael (2008 年 9 月). 「ハッシュを減らしても同じパフォーマンス: より優れたブルーム フィルターの構築」(PDF) .ランダム構造とアルゴリズム. 33 (2): 187–218. CiteSeerX 10.1.1.152.579 . doi :10.1002/rsa.20208.
- ^ Dillinger 2004 のように、三角数で定義されることもあります。
外部リンク
- キャッシュがハッシュに与える影響、Gregory L. Heileman および Wenbin Luo 著、2005 年。
- ハッシュテーブルアニメーション
- klib は、二重ハッシュ機能を備えた C ライブラリです。
