配列なしのメモ化


14

Cormen et al。の「アルゴリズム概要」のセクション15.3 動的プログラミングの要素では、メモ化について次のように説明しています。

メモ化された再帰アルゴリズムは、各サブ問題の解決策のエントリをテーブルに保持します。各テーブルエントリには、エントリがまだ入力されていないことを示す特別な値が最初に含まれています。再帰アルゴリズムが展開するときにサブ問題に最初に遭遇すると、その解が計算されてテーブルに保存されます。このサブ問題に遭遇するたびに、テーブルに保存されている値を検索して返します。

さらに、脚注として追加します。

このアプローチでは、考えられるすべてのサブ問題パラメーターのセットがわかっていること、およびテーブルの位置とサブ問題の間の関係が確立されていることを前提としています。別のより一般的なアプローチは、サブ問題パラメーターをキーとしてハッシュを使用してメモすることです。

メモした値を(多次元)配列ではなく辞書に保存する必要がある(または簡単にする)よく知られているDPの問題はありますか?


背景:これが何らかの用途であれば、この質問の理由は、動的プログラミングを見たばかりの人に(自己均衡型)バイナリ検索ツリーの概念を動機付けようとしているからです。


私が扱う実際のソフトウェアでは、メモ化は比較的高価な関数(explogpowなど)をコード内のさまざまな場所から呼び出すことができ、頻繁に呼び出されるという事実を利用できます。特定のコードの場所ごとに同じ値。その場合、「辞書」はコード位置固有の変数に格納された単一の値にすることができます。
マイクダンラベイ

回答:


5

おそらくもっと良い例がありますが、ここに私の頭の上の1つを示します。

2つの文字列間の編集距離がであるかどうかを確認し、そうであれば、編集距離を計算するとします。標準の動的プログラミングアルゴリズムを使用して編集距離を計算できますが、編集距離がことがわかっている任意の場所で計算を「プルーニング」(再帰を停止)します。これは、おそらくテーブル全体を埋める必要がないことを意味します。一部のエントリを入力するだけで済みます。したがって、辞書を使用すると、パフォーマンスが向上します。STd>d


3

2つの例を提供したいと思います。

0-1ナップザック問題

0-1ナップザック問題(Wはナップザックの容量、Nはアイテムの量)の場合、体系的なボトムアップ列挙の代わりに、メモ化を伴うトップダウンの動的プログラミングを使用した方がよい場合があります。サイズWxNの 2D配列全体の(特にナップザックWの容量が大きいが、アイテムの重みの許可された組み合わせのカーディナリティがWよりもはるかに小さい場合)。

この場合、メモリを節約するために、2D配列の代わりにメモ化に辞書を使用することを選択できます。

Earley解析アルゴリズム

Earley解析アルゴリズムは、文脈自由文法に属する文の解析に使用できます。CYKアルゴリズム(ボトムアップDPアプローチに基づいており、メモ化に2Dテーブルを使用)とは対照的に、Earleyパーサーはメモ化に解析チャートと組み合わせてトップダウンアプローチを使用します。

生産与えられた:チャートの解析は、部分的に解析された文法のプロダクション(例えば含まれているX→AB、との成功したマッチング後にAのこの生産の一部、我々が解析し、チャート内で部分的にマッチした生産を保存:X→A•B点のポイントを、既に一致した部分に)。

解析チャート内の列の量はトークンの量に等しくなります。ただし、一般的な場合、列ごとに部分的に解析された文法的生成の量を推定することは非常に難しいかもしれません(文法とトークンの特定のシーケンスに依存します)。

したがって、辞書データ構造に基づいて解析チャートを実装する方が便利です。

自然言語処理ドメインでは、文法にチョムスキー標準形を必要としないため、通常、Earleyパーサーがより便利な選択です(CYKにはそのような要件があります)。


0

競合プログラミングの経験では、ハッシュテーブル(Python dictなど)を使用する方が、配列を使用するよりも便利なことがよくあります。これは、文字列、セット(frozensetPythonの場合)、タプル(string, int)などのハッシュ可能なデータ型をキーとして使用できるためです。配列を使用する場合、すべてのキーを(0から始まる)整数に手動で変換する必要があります。これは余分な作業を必要とし、ソースのメモとして、キーのスペースが事前にわからない場合は不可能です。したがって、辞書は配列よりも一般的です。

もちろん、配列の使用を回避できる場合、ハッシュを繰り返し計算する必要がないため、おそらく高速になります(一方で、配列全体を最初に初期化する必要があり、時間とメモリがかかります)が、コードを書くのに時間がかかる可能性がありますすべてのキーを整数に変換する余分な作業が必要だからです。

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