なぜ最小優先度キュー(ヒープベース)で、「セットキー」だけでなく「減少キー」と呼ばれるのですか?


7

min-priorityキューで減少キーを呼び出すとき、基本的にキーを設定しているので、誤って高いキーを置くことができますよね?では、なぜ「set-key」または「update-key」と呼ばれないのでしょうか。なぜ(ウィキペディアや他のソースによると)最小優先度キューに「減少キー」があり、最大優先度キューに「増加キー」があるのですか?「set-key」の両方がないのはなぜですか。それを減らすか増やす場合は、ヒーププロパティを不変に保つために何をすべきですか。

つまり、最小ヒープで減少キーを呼び出して、より大きな値を指定するとどうなるでしょうか。例外をスローしますか?「set-key」と呼んで、あらゆる種類の値を処理しないのはなぜですか。

回答:


8

良い質問。データ構造PriorityQueueの重要なアプリケーションの1つは、ダイクストラのアルゴリズムです。各ノードは初期ノードからの距離を取得します。これは、より短いパスが検出されると更新されます。したがって、更新は一方向のキーのみを変更します。

DecreaseKeyの実装における問題は、(値を更新するのではなく)減少するだけではないということではありません。バイナリヒープの場合、増加と減少の両方に対して非常に効率的な方法があります。どちらも、ツリー内のパスに沿って(上向きまたは下向きに)ノードを他のノードと交換します。問題は、実際にどこに鍵があるかを知ることです。効率的に検索することはできないため、個別の「インデックス」を保持する必要があります。パスに沿って更新が行われると、減少したキーがIndaxで変更されるだけでなく、パスに沿った他のキーも変更されます。

抽象データ構造の場合、特定のコンテキストで重要な操作のみを指定する必要があります。したがって、ダイクストラのモチベーションを考えると、私たちはDecreaseKeyだけを持っています。バイナリヒープの場合、操作を拡張することは初歩的なことですが、Leftist Heap、Fibonacci Heap、Brodal HeapなどのPriorityQueueの他の実装ではそうではない場合があります。

新しい値が間違った方向にあるときに特定の実装が行うことは、その実装次第です。


1

メソッドの命名はいくつかの教科書(例えばCLRS)でおそらく意図的です:

  1. バイナリヒープのキーを「フロートダウン」または「バブリング」するロジックは、どちらの方向(アップ/ダウン)であるかがわかっていれば簡単です。たとえば、キーを「バブルアップ」するのは、ノードの親を再帰的に呼び出すだけであり、再帰的に進む前に各子と比較する必要がある場所でフローティングすることです。
  2. 最大/最小ヒープを使用する多くのアルゴリズムでは、キーを増減するだけでよいので、対応する「フローティングダウン」または「バブリングアップ」メソッドを提供するだけで十分です。

ジェネリックな「キーの設定」メソッドを実装したい場合は、これらの2つのルーチンを組み合わせて、キーをバブルアップするかフロートダウンする必要があるかどうかに基づいて、どちらの方向に進むかを決定できます。

ヘンドリックの発言に加えて、技術的に言えばキー減少操作で十分であるダイクストラまたはプリムのアルゴリズムであっても、バイナリヒープを使用して、各キーの位置を追跡する必要必ずしもないことに注意してください。

これらのアルゴリズムでは、特定のキーがヒープから一度だけ抽出されます。たとえば、ダイクストラでは、グラフノードは最短パスツリーに一度だけ追加され、プリムのアルゴリズムでは、エッジ最小スパニングツリーに一度だけ追加されます。

したがって、キーの位置を追跡する(またはアルゴリズムがそれらを減らす必要があるときにそれらを検索する)代わりに、キーに新しい(この場合はより低いをヒープに挿入するだけです(ヒープの重複につながります)。 、そしてヒープから「キー」を抽出したら(キーは貪欲に消費するものではないため、技術的には衛星データ)、その後の抽出をすべて無視できます(たとえば、O1)。

ヒープ内のそのようなセットとキーの重複は明らかにコストがかかります Oスペースは複雑ですが、結合されたソリューションは、ヒープ内の位置の知識や追跡を必要としない「キーを減らす」方法と考えることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.