移動からの線形探索を次のプロービング(ハッシュcollisons)
-
23-09-2019 - |
質問
私の現在の実装のハッシュテーブルはリニアプロービングと現在に移動しようとしている二次プロービング(降のチェーンかダブルハッシュがあります。っくりとした少数の論文、チュートリアル、wikipedia。それでもまだ知らないようだ。
リニアプロービング、基本的には、ステップ1は、こうしています。する場合の挿入、削除の要素のハッシュテーブルながらプレーする必要がありま算出するハッシュということ:
index = hash_function(key) % table_size;
その後、模索しながら、挿入または削除いてループのテーブルまでを見たいのは、無料でバケツのようになります:
do {
if(/* CHECK IF IT'S THE ELEMENT WE WANT */) {
// FOUND ELEMENT
return;
} else {
index = (index + 1) % table_size;
}
while(/* LOOP UNTIL IT'S NECESSARY */);
しては次を探るものと思いま必要なのは、変化をどのように"インデックス"ステップサイズの計算がうかわからないかっています。見ているが、さまざまなコードは、すべてやや異なります。
また、実装の二次プロービングのハッシュ関数に変更に対応する(全てではないのです。が変化する本当に必要なものがするのですか、それとも避ける修正のハッシュ機能をお使いの二次プロービング?
編集: 読みものが指摘するようにEli Bendersky以下のと思うんのアイデアです。こちらのコードの一部で http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_hashtable.aspx:
15 for ( step = 1; table->table[h] != EMPTY; step++ ) {
16 if ( compare ( key, table->table[h] ) == 0 )
17 return 1;
18
19 /* Move forward by quadratically, wrap if necessary */
20 h = ( h + ( step * step - step ) / 2 ) % table->size;
21 }
ある2つのものを得られません...ば次のプロービングは、一般的に使用 c(i)=i^2
.しかし、上記のコードで行なっているような c(i)=(i^2-i)/2
リラックスして過ごせました実装このマーコードがいない:
index = (index + (index^index)) % table_size;
---とい:
index = (index + (index^index - index)/2) % table_size;
場合は、何も入っていて:
index = (index + (index^index)/2) % table_size;
...原因などの見その他のコード例ダイビングによります。がわかりませんしょうか---
1) なぜでしを差し引いたステップ?
2) なぜでダイビングで2?
解決
いての変更のハッシュ関数のための二次プロービング最も単純な形態の二次プロービングは本当に"を追及するとともにそれに伴う正方形の計算を行位置の代わりにリニア1,2,3です。
り良い資源 こちらの.以下のからあります。これは、最も単純な形態の二次プロービング時の多項式 c(i) = i^2
を使用してい
により一般的な場合には、式:
することができるのでおconstants.
く、心とした二次プロービングに役立つだける場合があります。としての Wikipedia 状態:
二次プロービングも良好でメモリ キャッシュので憶 地域の参考;しかし、線形 プロービングより高い地域, そのため、キャッシュす。二次プロービングを避け、より良い クラスタリングの問題で起こりうると リニアプロービングはないのです 免疫.
編集: のように多くのコンピュータ科学の正確な定数多項式の次のプロービングはヒューリスティック.Yes,最も単純な形態は i^2
, がるものをつ選んでくださいその他の多項式.Wikipediaの例 h(k,i) = (h(k) + i + i^2)(mod m)
.
することは難しいだろうにお答えし"なぜ"について質問です。の"なぜ"ここはなぜ必要な次のプロービングは全くないのでしょうか。この問題はその他の形態のプロービングやクラスタ化されたテーブルは?それともかく、自己学習?
この共通の衝突解像技術のためのハッシュテーブルはチェーンまたはリニアプロービング二次プロービングは、ヒューリスティックオプションもございますは、特段の事情がある場合、ないとかやっているものから使用をお勧めします。
他のヒント
があるのは、これまでにない実二次体プロービングの場合テーブルのサイズは、電源の2:
step = 1;
do {
if(/* CHECK IF IT'S THE ELEMENT WE WANT */) {
// FOUND ELEMENT
return;
} else {
index = (index + step) % table_size;
step++;
}
} while(/* LOOP UNTIL IT'S NECESSARY */);
の代わりにみるオフセット0, 1, 2, 3, 4...からの指数は、ここではオフセット0, 1, 3, 6, 10...(ith プローブをオフセット(i*i+1))/2、この二次).
この保証は毎のハッシュテーブルもご確空バケットがある場合) の提供 のテーブルのサイズは、電源の2.
こちらはスケッチの証明:
- 与テーブルサイズnのいしていますが、わたしはnで独自の価値の(i*i+1))/2(mod n)i=0...n-1までの番号が付いている。
- できることを証明する矛盾に満ちているものです。いがあることはnよりも少なくなり独自の価値:その場合、少なくとも二つの異なる整数値の範囲[0,n-1]に、(i*i+1))/2(mod n)は同じです。呼これらのp、q、p < q.
- すなわち(p-p+1))/2=q*(q+1))/2(mod n)
- =>(p2 +p)/2=q2 +q)/2(mod n)
- =>p2 +p=q2 +q(mod2n)
- =>q2 -p2 +q-p=0(mod2n)
- Factorise=>q-p)(p+q+1)=0(mod2n)
- (q-p)=0のときは、自明な場合はp=q.
- (p+q+1)=0(mod2n)は不可能な当社の価値観のp及びqは、範囲[0,n-1]、q>p,so(p+q+1)の範囲でなければな[2,2n-2]となります。
- していまmodulo2nしても取り扱っておりますの難場合の両方の要因がゼロでないものの、増殖を0(mod2n):
- 観察することの差の二つの要因(q-p)および(p+q+1)(2p+1)は、奇数で要因の一つでなければなり、その他必要と覗けます。
- (q-p)(p+q+1)=0(mod2n)=>(q-p)(p+q+1)で割れる2n. の場合n(こ2n)は、電源の2, この要求にも要因となる複数の2nがすべての要因の2n2に対し】なしの素因の奇数の要因。
- がq-p)の最大値のn-1(p+q+1)の最大値2n-2などステップ9)でもできる複数の2n.
- この場合は不可能です。
- そのための前提があることはnよりも少なくなり独自の価値(ステップ2)はfalseです。
の場合はテーブルサイズ ない 電源の2では、この滝のほ歩10.)