コンピュータサイエンス において、ブロダルキューは、 最悪 時間制約 が非常に小さいヒープ /優先度キュー 構造である。O ( 1 ) {\displaystyle O(1)} 挿入、最小値の検索、結合(2 つのキューをマージ)、減少キー、O ( l o g ( n ) ) {\displaystyle O(\mathrm {log} (n))} 削除最小値と一般削除の場合。これらは、運用コストの償却に頼らずにこれらの境界を達成した最初のヒープバリアントです。ブロダルキューは、その発明者であるゲルト・ストルティング・ブロダルにちなんで名付けられました。[ 1 ]
他の優先度キュー構造よりも漸近的な境界は優れているものの、ブロダル自身が言うように「非常に複雑」であり、「実際には適用できない」。[ 1 ] ブロダルと岡崎は、ブロダルキューの 永続的 (純粋関数型 )バージョンについて述べている。 [ 2 ]
意味 ブロダルキューは2つの木の集合である T 1 {\displaystyle T_{1}} そしてT 2 {\displaystyle T_{2}} そして5つのガイドがあります 。ガイドデータ構造 の定義は次のセクションで説明します。どちらのツリーでも、各ノードにはランク があり、このランクは後の操作に役立ち、直感的にはノードを根とするサブツリーのサイズの対数に対応します。 個数 私 ( x ) {\displaystyle {\text{arity}}_{i}(x)} ノードの子ノードの数x {\displaystyle x} ランク付き私 {\displaystyle i} また、t 1 t1 木の根のためにT 1 {\displaystyle T_{1}} そしてt 2 t2 木の根のためにT 2 {\displaystyle T_{2}} 。各時点において、ノードを根とするすべてのサブツリーは、次の 5 つの不変条件を満たす 必要があります(これらは後ほど と呼ばれます) 。ランク \displaystyle {\text{ランク}}} 不変量):
リーフランク {\displaystyle {\text{LEAF-RANK}}} : もしx {\displaystyle x} 葉っぱであれば、ランク ( x ) = 0 \displaystyle {\text{rank}}(x)=0} 、親ランク {\displaystyle {\text{親ランク}}} :ランク ( x ) < ランク ( 親 ( x ) ) \displaystyle {\text{rank}}(x)<{\text{rank}}({\text{parent}}(x))} 、次ランク順位 {\displaystyle {\text{NEXT-RANK-ARITY}}} : もしランク ( x ) > 0 \displaystyle {\text{rank}}(x)>0} 、 それから個数 ランク ( x ) − 1 ( x ) ⩾ 2 \displaystyle \text{arity}}_{{\text{rank}}(x)-1}(x)\geqslant 2} 、ARITY-BOUND {\displaystyle {\text{アリティ制限}}} :個数 私 ( x ) ∈ { 0 、 2 、 3 、 … 、 7 } \displaystyle \text{arity}}_{i}(x)\in \{0,2,3,\dots ,7\}} 私たちは、個数 私 ( x ) ≠ 1 {\displaystyle {\text{arity}}_{i}(x)\neq 1} 、ルートランク {\displaystyle {\text{ルートランク}}} :T 2 = ∅ {\displaystyle T_{2}=\emptyset } またはランク ( t 1 ) ⩽ ランク ( t 2 ) \displaystyle {\text{rank}}(t_{1})\leqslant {\text{rank}}(t_{2})} 。ここ次ランク順位 {\displaystyle {\text{NEXT-RANK-ARITY}}} ノードを根とする部分木のサイズは、そのノードのランクに対して少なくとも指数関数的で あることを保証します。さらに、ARITY-BOUND {\displaystyle {\text{アリティ制限}}} は、与えられたノードの各ランクの子の数を制限します。これは、すべてのノードがランクと次数を 持つことを意味します。O ( ログ n ) {\displaystyle O(\log n)} 。
Brodalキューでは、すべてのノードが親ノードよりも大きな値を持つとは限りません。この条件に違反するノードは違反ノードと呼ばれます。しかし、 違反ノード の数は比較的少なく抑えたいと考えます。違反ノードを追跡するために、各ノードに対して2つのセットを作成します。V ( x ) {\displaystyle V(x)} そしてW ( x ) {\displaystyle W(x)} より大きいノードx {\displaystyle x} 直感的に、V ( x ) {\displaystyle V(x)} ノードはより大きいですかx {\displaystyle x} ランクが大きい(つまり、y ∈ V ( x ) {\displaystyle y\in V(x)} もしランク ( y ) ⩾ ランク ( t 1 ) \displaystyle {\text{rank}}(y)\geqslant {\text{rank}}(t_{1})} )、 そしてW ( x ) {\displaystyle W(x)} ランクの小さいノードは(ランク ( y ) < ランク ( t 1 ) \displaystyle {\text{rank}}(y)<{\text{rank}}(t_{1})} これらのセットは二重リンクリストを使用して実装されているため、 順序 があります。特に、違反しているすべてのノードがに追加されます。V ( x ) {\displaystyle V(x)} リストの先頭に追加され、違反しているノードはすべて追加されます。W ( x ) {\displaystyle W(x)} 同じランクのノードの隣に挿入されます。w 私 ( x ) {\displaystyle w_{i}(x)} ノードの数を表すW ( x ) {\displaystyle W(x)} 階級私 {\displaystyle i} のV ( x ) {\displaystyle V(x)} そしてW ( x ) {\displaystyle W(x)} リストはこれらの 5 つの不変条件を満たします (セット {\displaystyle {\text{セット}}} 不変量):
最小ノード 最小ノード :t 1 = ミニ ( T 1 ∪ T 2 ) {\displaystyle t_{1}=\min(T_{1}\cup T_{2})} 条件違反 {\displaystyle {\text{条件違反}}} : もしy ∈ V ( x ) ∪ W ( x ) {\displaystyle y\in V(x)\cup W(x)} それからy ⩾ x {\displaystyle y\geqslant x} 親権侵害 {\displaystyle {\text{親権侵害}}} : もしy < 親 ( y ) {\displaystyle y<{\text{parent}}(y)} するとノードが存在するx ≠ y {\displaystyle x\neq y} そのためy ∈ V ( x ) ∪ W ( x ) {\displaystyle y\in V(x)\cup W(x)} Wランクバウンド {\displaystyle {\text{Wランクバウンド}}} :w 私 ( x ) ⩽ 6 {\displaystyle w_{i}(x)\leqslant 6} Vランク行き {\displaystyle {\text{Vランクバウンド}}} : 表記することでV ( x ) = ( v | V ( x ) | 、 … 、 v 2 、 v 1 ) {\displaystyle V(x)=(v_{|V(x)|},\dots ,v_{2},v_{1})} 、 我々は持っています:ランク ( v 私 ) ⩾ ⌊ 私 − 1 α ⌋ \displaystyle \text{rank}}(v_{i})\geqslant \left\lfloor {\frac {i-1}{\alpha }}\right\rfloor } ある定数に対してα {\displaystyle \alpha } 。すべてのノードはランクを持っていますO ( ログ n ) {\displaystyle O(\log n)} のWランクバウンド {\displaystyle {\text{Wランクバウンド}}} そしてVランク行き {\displaystyle {\text{Vランクバウンド}}} 、 全てV ( x ) {\displaystyle V(x)} そしてW ( x ) {\displaystyle W(x)} サイズはO ( ログ n ) {\displaystyle O(\log n)} 。
また、木の根の不変量もいくつかあります。T 1 {\displaystyle T_{1}} そしてT 2 {\displaystyle T_{2}} :t 1 t1 そしてt 2 t2 (ルーツ {\displaystyle {\text{ルーツ}}} 不変量)。
ルートアリティ {\displaystyle {\text{ルートアリティ}}} :t 私 ∈ { 2 、 3 、 … 、 7 } のために 私 ∈ { 0 、 1 、 … 、 ランク ( t 私 ) − 1 } t_i ∈ {2,3,\dots ,7} (i ∈ {0,1,\dots ,rank(t_i)-1}) 、Vサイズ製本 {\displaystyle {\text{V-SIZE-BOUND}}} :| V ( x ) | ⩽ α ランク ( t 1 ) {\displaystyle |V(x)|\leqslant \alpha {\text{ rank}}(t_{1})} 、W-ELEMENTS-RANK {\displaystyle {\text{W-ELEMENTS-RANK}}} : もしy ∈ W ( t 1 ) {\displaystyle y\in W(t_{1})} 、 それからランク ( y ) < ランク ( t 1 ) \displaystyle {\text{rank}}(y)<{\text{rank}}(t_{1})} 。のVサイズ製本 {\displaystyle {\text{V-SIZE-BOUND}}} 不変量は基本的に、ランクを上げるとt 1 t1 1つにつき、最大でα {\displaystyle \alpha } 新たな「大きな」違反(ここで「大きな」とは高いランクを持つことを意味する)は、Vランク行き {\displaystyle {\text{Vランクバウンド}}} 不変。一方、W-ELEMENTS-RANK {\displaystyle {\text{W-ELEMENTS-RANK}}} 不変条件は、すべての違反がW ( x ) {\displaystyle W(x)} は「小さい」ので、この不変条件は定義に従って真である。W {\displaystyle W} 不変条件を維持するWランクバウンド {\displaystyle {\text{Wランクバウンド}}} そしてルートアリティ {\displaystyle {\text{ルートアリティ}}} これは些細なことではなく、これらを維持するために私たちは減少キー {\displaystyle {\text{DecreaseKey}}} 次のセクションで定義するガイド を使用して実装できる操作。毎回、減少キー {\displaystyle {\text{DecreaseKey}}} この作戦では、基本的に以下のことを行います 。
新しい違反を追加V ( t 1 ) {\displaystyle V(t_{1})} またはW ( t 1 ) {\displaystyle W(t_{1})} 違反の程度に応じて。 避けるためにV ( t 1 ) {\displaystyle V(t_{1})} そしてW ( t 1 ) {\displaystyle W(t_{1})} 規模が大きくなりすぎないように、段階的に2種類の変換を行います。 息子たちを動かすt 2 t2 にt 1 t1 ランクを上げるt 1 t1 違反件数を減らすW ( t 1 ) {\displaystyle W(t_{1})} ランク違反2件を置き換えることによってk {\displaystyle k} 階級違反1件k + 1 {\displaystyle k+1}
ガイドデータ構造 この定義は、ブロダルの論文の定義に基づいています。[ 3 ]
変数のシーケンス があると仮定しますx k 、 … 、 x 1 {\displaystyle x_{k},\dots ,x_{1}} そして私たちはそれを確実にしたいのです∀ 私 ⩽ k 、 x 私 ⩽ T {\displaystyle \forall i\leqslant k,x_{i}\leqslant T} ある閾値に対してT {\displaystyle T} 許可されている唯一の操作は減らす ( 私 ) {\displaystyle {\text{削減}}(i)} これは減少するx 私 {\displaystyle x_{i}} 少なくとも2倍になり、x 私 + 1 {\displaystyle x_{i+1}} 最大で 1 だけ。一般性を失うことなく 、減らす ( 私 ) {\displaystyle {\text{削減}}(i)} 削減するx 私 {\displaystyle x_{i}} 2ずつ増加し、x 私 + 1 {\displaystyle x_{i+1}} 1による。
もしx j {\displaystyle x_{j}} 1つ増加すると、ガイドの目的はどのインデックスについて教えてくれるかです私 {\displaystyle i} 応募する減らす ( 私 ) {\displaystyle {\text{削減}}(i)} しきい値を尊重するため。ガイドは、O ( 1 ) {\displaystyle O(1)} への呼びかけ減らす {\displaystyle {\text{削減}}} 各増加に対応する関数。
ガイドは別のシーケンスにアクセスできますx k ′ 、 … 、 x 1 ′ {\displaystyle x'_{k},\dots ,x'_{1}} そのためx 私 ⩽ x 私 ′ {\displaystyle x_{i}\leqslant x'_{i}} そしてx 私 ′ ∈ { T − 2 、 T − 1 、 T } {\displaystyle x'_{i}\in \{T-2,T-1,T\}} 増加後もx j {\displaystyle x_{j}} 我々は持っていますx j ⩽ x j ′ {\displaystyle x_{j}\leqslant x'_{j}} 私たちはガイドに助けを求める必要はありません。x j {\displaystyle x_{j}} 「はるか下」T {\displaystyle T} しかし、もしx j = x j ′ {\displaystyle x_{j}=x'_{j}} 増加前は、x j + 1 > x j ′ {\displaystyle x_{j}+1>x'_{j}} 変更後。
説明を簡略化するために、次のように仮定できます。T = 2 {\displaystyle T=2} 、 となることによってx 私 ′ ∈ { 0 、 1 、 2 } {\displaystyle x'_{i}\in \{0,1,2\}} ガイドはブロックを 次の順序で作成します。x 私 ′ {\displaystyle x'_{i}} 形の2 、 1 、 1 、 … 、 1 、 0 {\displaystyle 2,1,1,\dots ,1,0} 私たちが許可する場所には1 {\displaystyle 1} ガイドでは、ブロックに含まれていない各要素は、1 {\displaystyle 1} または0 {\displaystyle 0} 例えば、次のようなシーケンスのブロックがあります。x 私 ′ {\displaystyle x'_{i}} 。
1 、 2 、 1 、 1 、 0 _ 、 1 、 1 、 2 、 0 _ 、 2 、 0 _ 、 1 、 0 、 2 、 1 、 0 _ {\textstyle 1,{\underline {2,1,1,0}},1,1,{\underline {2,0}},{\underline {2,0}},1,0,{\underline {2,1,0}}}
このガイドは3つの配列 で構成されています。
x {\displaystyle x} 配列x k 、 … 、 x 1 {\displaystyle x_{k},\dots ,x_{1}} x ′ {\displaystyle x'} 配列x k ′ 、 … 、 x 1 ′ {\displaystyle x'_{k},\dots ,x'_{1}} p {\displaystyle p} すべてのポインタの配列p 私 {\displaystyle p_{i}} そのためにx 私 ′ {\displaystyle x'_{i}} 同じブロック内にある場合、同じメモリセルに値が含まれていることを示します。x 私 ′ {\displaystyle x'_{i}} ブロック内にない場合は、p 私 {\displaystyle p_{i}} メモリセルを指し示します⊥ {\displaystyle \bot } 。この定義に基づくと、ガイドには2つの重要な特性がある 。
ブロック内の各要素について、ブロックの最も左の要素を時間内に見つけることができます。O ( 1 ) {\displaystyle O(1)} 。 ブロックを時間内に破壊することができますO ( 1 ) {\displaystyle O(1)} 割り当てることによって⊥ {\displaystyle \bot } ブロックの各要素が指すメモリセルへ。 このようにして、ガイドはどのインデックスを減らす {\displaystyle {\text{REDUCE}}} 時間が経つにつれてO ( 1 ) {\displaystyle O(1)} 以下に例を示します 。
2 、 1 、 1 、 0 _ 、 2 、 1 、 1 、 1 、 0 _ 2 、 1 、 1 、 0 _ 、 2 、 2 、 1 、 1 、 0 _ インクリメント x 私 ′ 2 、 1 、 1 、 1 _ 、 0 、 2 、 1 、 1 、 0 _ 減らす 2 、 1 、 1 、 1 _ 、 1 、 0 、 1 、 1 、 0 _ 減らす 2 、 1 、 1 、 1 、 1 、 0 _ 、 1 、 1 、 0 ブロックを再確立する {\displaystyle {\begin{array}{ll}{\underline {2,1,1,0}},{\underline {2,1,1,1,0}}&\\{\underline {2,1,1,0}},{\underline {2,{\color {red}2},1,1,0}}&{\text{Increment }}x'_{i}\\{\underline {2,1,1,{\color {green}1}}},{\underline {{\color {blue}0},2,1,1,0}}&{\text{REDUCE}}\\{\underline {2,1,1,1}},{\underline {{\color {green}1},{\color {blue}0},1,1,0}}&{\text{REDUCE}}\\{\underline {2,1,1,1,1,0}},1,1,0&{\text{reestablish blocks}}\\\end{array}}}
ブロックを再確立するために、最初のブロックに追加された 1 と 0 のポインタは、最初のブロックの他のすべての要素と同じセルを指すようになり、2 番目のブロックのセルの値は次のように変更されます。⊥ {\displaystyle \bot } 前の例では、減らす {\displaystyle {\text{REDUCE}}} 操作が必要だったが、これは実際にはすべてのインスタンスに当てはまる。したがって、キューはO ( 1 ) {\displaystyle O(1)} 財産を再建するための活動。
ブロダルキューの操作 さまざまな優先度キュー 操作を実装するには、まずツリーに対するいくつかの基本的な変換について説明する必要があります。
優先キュー操作
キューを作成する キューを作成する ( ) {\displaystyle {\text{MakeQueue}}()} 空のツリーを2つ返します。
FindMin FindMin ( Q ) {\displaystyle {\text{FindMin}}(Q)} リターンt 1 {\displaystyle t_{1}} 。
上映時間の概要 以下に、さまざまなヒープ データ構造の時間計算量 [ 4 ] を示します。略語am.は、与えられた計算量が償却済みであることを示し、そうでない場合は最悪の場合の計算量です。「 O ( f )」および「Θ ( f )」の意味については、ビッグ O 記法を 参照してください。操作名は、最小ヒープを前提としています。
↑ make-heapは、 n 個 の未ソート要素のシーケンスからヒープを構築する操作です。meldが O (log n ) 時間で実行される場合(どちらの複雑さも償却可能) は、 Θ ( n ) 時間で実行できます。 [ 5 ] [ 6 ] 別のアルゴリズムは、バイナリ ヒープに対してΘ ( n )を達成します。 [ 7 ] 1 2 3 永続 ヒープ ( decrease-key をサポートしない)の場合、汎用変換によりmeld のコストがinsert のコストに削減され、 delete-min の新しいコストはdelete-min とmeld の古いコストの合計になります。 [ 10 ] ここでは、 meld は Θ (1) 時間 ( 挿入 のコストが償却される場合)で実行され、 delete-min は依然として O (log n )で実行されます。歪んだ二項ヒープに適用すると、最適な最悪ケース複雑度を持つ永続ヒープである Brodal-Okasaki キューが得られます。 [ 9 ] ↑ 下限Ω ( ログ ログ n ) 、 {\displaystyle \Omega (\log \log n),} [ 13 ] 上限O ( 2 2 ログ ログ n ) 。 {\displaystyle O(2^{2{\sqrt {\log \log n}}}).} [ 14 ] 1 2 Brodalキューと厳密なフィボナッチヒープは、ヒープの最悪ケースの計算量において最適値を達成します。これらは当初、命令型データ構造として記述されました。Brodal-Okasakiキューは、キー減少 をサポートしていない点を除いて、同じ最適値を達成する永続的なデータ構造です。
参考文献 1 2 Gerth Stølting Brodal (1996). 最悪ケースにおける効率的な優先度キュー。第 7 回 ACM-SIAM 離散アルゴリズムシンポジウム議事録、pp. 52–58 ↑ Gerth Stølting Brodal および Chris Okasaki (1996). Optimal purely functional priority queues . Journal of Functional Programming. 1 2 ブローダル、ガース・ストルティング (1996)。「最悪の場合の効率的な優先キュー」(PDF) 。 {{cite web}}: CS1 maint: url-status (リンク)1 2 3 4 コーメン、トーマス H. チャールズ・E・ライザーソン ; リベスト、ロナルド L. (1990)。 アルゴリズム入門 (第 1 版)。 MIT プレスとマグロウヒル。 ISBN 0-262-03141-8 。1 2 3 Sleator, Daniel Dominic ; Tarjan, Robert Endre ( 1986 年 2月 ) 。 「自己調整ヒープ」 。SIAM Journal on Computing。15 ( 1 ) : 52–69。CiteSeerX 10.1.1.93.6678。doi : 10.1137 / 0215004。ISSN 0097-5397 。 1 2 Tarjan, Robert (1983). "3.3. 左ヒープ". データ構造とネットワークアルゴリズム . pp. 38–42 . doi : 10.1137/1.9781611970265 . ISBN 978-0-89871-187-5 。↑ Hayward, Ryan; McDiarmid, Colin (1991). "Average Case Analysis of Heap Building by Repeated Insertion" (PDF) . J. Algorithms . 12 : 126– 153. CiteSeerX 10.1.1.353.7888 . doi : 10.1016/0196-6774(91)90027-v . 2016-02-05 の オリジナル (PDF) からアーカイブ済み 。2016-01-28 に 取得。 ↑ "二項ヒープ | Brilliant Math & Science Wiki" . brilliant.org . 2019-09-30 に取得. 1 2 Brodal, Gerth Stølting; Okasaki, Chris (1996年11月)、「最適な純粋関数型優先度キュー」、 Journal of Functional Programming 、 6 (6): 839–857 、 doi : 10.1017/s095679680000201x ↑ 岡崎クリス (1998). 「10.2. 構造的抽象化」. 純粋関数型データ構造 (第 1 版). pp. 158–162 . ISBN 9780521631242 。↑ 高岡忠雄 (1999) 『2-3ヒープの理論』 (PDF) 、 12 ページ ↑ Iacono, John (2000), "ペアリングヒープの上限の改善", Proc. 7th Scandinavian Workshop on Algorithm Theory (PDF) , Lecture Notes in Computer Science, vol. 1851, Springer-Verlag, pp. 63–77 , arXiv : 1110.4428 , CiteSeerX 10.1.1.748.7812 , doi : 10.1007/3-540-44985-X_5 , ISBN 3-540-67690-2 ↑ Fredman, Michael Lawrence (1999年7月) 「ペアリングヒープと関連データ構造の効率について」 (PDF) . Journal of the Association for Computing Machinery . 46 (4): 473– 501. doi : 10.1145/320211.320214 . ↑ Pettie, Seth (2005). Towards a Final Analysis of Pairing Heaps (PDF) . FOCS '05 Proceedings of the 46th Annual IEEE Symposium on Foundations of Computer Science. pp. 174–183 . CiteSeerX 10.1.1.549.471 . doi : 10.1109/SFCS.2005.75 . ISBN 0-7695-2468-0 。↑ ハウプラー、ベルンハルト。セン、シッダールタ。 タージャン、ロバート E. (2011 年 11 月) 「ランクペアリングヒープ」 (PDF) 。 サイアム J. コンピューティング 。 40 (6): 1463 ~ 1485 年。 土井 : 10.1137/100785351 。 ↑ Fredman, Michael Lawrence ; Tarjan, Robert E. (1987 年 7 月). "Fibonacci heaps and their uses in improved network optimization algorithms" (PDF) . Journal of the Association for Computing Machinery . 34 (3): 596– 615. CiteSeerX 10.1.1.309.8927 . doi : 10.1145/28869.28874 . ↑ Brodal, Gerth Stølting ; Lagogiannis, George; Tarjan, Robert E. (2012). Strict Fibonacci heaps (PDF) . Proceedings of the 44th symposium on Theory of Computing - STOC '12. pp. 1177– 1184. CiteSeerX 10.1.1.233.1740 . doi : 10.1145/2213977.2214082 . ISBN 978-1-4503-1245-5 。↑ Brodal, Gerth S. (1996)、 「最悪ケースにおける効率的な優先度キュー」 ( PDF) 、 第7回ACM-SIAM離散アルゴリズムシンポジウム議事録 、pp. 52–58 ↑ Goodrich, Michael T. ; Tamassia, Roberto (2004). "7.3.6. ボトムアップヒープ構築". Data Structures and Algorithms in Java (第3 版). pp. 338–341 . ISBN 0-471-46983-1 。↑ 「オーフス大学のガース・シュトルティング・ブローダルのウェブサイト」 。 2016 年 2 月 18 日 に取得 。