動的プログラミングの事例の区別:例が必要です!


19

私はしばらくの間、動的プログラミングに取り組んできました。動的プログラミングの再帰を評価する標準的な方法は、必要なすべての値のテーブルを作成し、行ごとに入力することです。たとえば、Cormen、Leiserson et al: "Introduction to Algorithms"を参照してください。

2次元のテーブルベースの計算スキーム(行ごとの塗りつぶし)に焦点を当て、セルの依存関係の構造、つまり、別のセルを計算する前にどのセルを実行する必要があるかを調べます。セルiが依存するセルのインデックスのセットを示します。Γはサイクルフリーである必要があることに注意してください。Γ(i)iΓ

計算された実際の関数から抽象化し、その再帰構造に集中します。正式には、次の形式の場合、繰り返し動的プログラミングであると考えます。d

d(i)=f(i,Γ~d(i))

Γ DI= { JD J| JΓ DI}Fしないいくつかの(計算)関数使用D経由以外のΓの dはi[0m]×[0n]Γ~d(i)={(j,d(j))jΓd(i)}fdΓ~d

粒度制限すると(現在のセルの左、左上、上、右上、...に)粗い部分に1が有効の3例(アップ対称性及び回転)は、本質的に存在していることを観察しますテーブルへの入力方法を通知する動的プログラミングの再帰:Γd

動的プログラミングセルの依存関係の3つのケース

赤い領域は(過剰近似)を示します。ケース1と2はサブセットを認め、ケース3は最悪の場合です(インデックス変換まで)。赤い領域全体Γで覆われている必要はないことに注意してください。テーブルのすべての赤い部分の一部のセルは、それを赤く塗るのに十分です。白い領域には、必要なセルが含まれないようにする必要があります。ΓΓ

ケース1の例は、編集距離最長共通サブシーケンスであり、ケース2はBellman&FordおよびCYKに適用されます。あまり明らかではない例には、提案されたケースに合うように回転できるため、行(または列)ではなく対角線で機能するものが含まれます。例については、ジョーの回答を参照してください。

ただし、ケース3の(自然な)例はありません!だから私の質問は:ケース3の動的プログラミングの再帰/問題の例は何ですか?


2
ケース3はケース1と2を包含しています。
JeffE

見た目にもかかわらず、そうではありません。たとえば、ケース1のインスタンスは左上の領域に必要なセルを持つことができませんが、ケース3のインスタンス左上の領域に必要なセルを持つ必要があります。説明を編集して明確にしました。
ラファエル

回答:


15

パターンにまったく適合しない動的プログラミングアルゴリズムの例は他にもたくさんあります。

  • 最も長く増加するサブシーケンス問題には、1次元のテーブルのみが必要です。

  • テーブルが3つ以上の次元を必要とするいくつかの自然な動的プログラミングアルゴリズムがあります。例:ビットマップで最大面積の白い長方形を見つけます。自然な動的プログラミングアルゴリズムは、3次元テーブルを使用します。

  • しかし最も重要なことは、動的プログラミングはテーブルに関するものではありません。それは巻き戻しの再帰についてです。巻き戻される反復が整数の範囲を超えていないため、中間結果を格納するために使用されるデータ構造が配列ではない自然な動的プログラミングアルゴリズムがたくさんあります。2つの簡単な例は、ツリー内で最大の独立した頂点のセットを見つけることと、2つのツリーの最大の共通サブツリーを見つけることです。より複雑な例は、AroraとMitchellによるユークリッド巡回セールスマン問題の -近似アルゴリズムです。(1+ϵ)


ご回答ありがとうございます。ただし、質問を2次元の問題と標準的なテーブルベースの計算スキーム(その点をさらに明確にするために編集)に明示的に制限しました。私はより一般的なフレームワークを知っていますが、現時点ではそれに興味はありません。
ラファエル

9
さて、しかし、私はあなたがポイントを逃していると本当に思います。
ジェフ

多くの賛成票があるので、私はこのことを明確にすべきだと思った。
ラファエル

2
@Raphaelは正しいです。私の「答え」は答えではなく、質問に対する批判ですが、コメントするには長すぎました。
-JeffE

3

アッカーマン関数の計算はこの精神に基づいています。を計算するには、大きなkについてA m n 1 およびA m 1 k を知る必要があります。2番目の座標が減少するか、最初の座標が減少し、2番目の座標が増加する可能性があります。A(m,n)A(m,n1)A(m1,k)k

列の数は無限であり、計算は通常記憶を使用してトップダウンで行われるため、これは要件に理想的に適合しませんが、言及する価値があると思います。


1
いいえ、ような入れ子は、動的プログラミングに実際には役立ちません。Hehe、これはとても奇妙なので、私の定義が何らかの形でそのようなケースを除外していることを確認する必要があります。非原始再帰DP、私のああ...A(m1,A(m,n1))
ラファエル

1
良い答えなので、なぜこの答えがダウン投票されたのかはわかりません。アッカーマン関数は、動的プログラミングに非常に適しています。一般に、同じ引数に対して繰り返し計算される再帰的に定義された関数は、動的プログラミングに役立ちます。これを見るには、実装して実行時間を比較するだけです。通常のアッカーマン関数で計算するのに何年もかかるものは、動的プログラミング関数で数秒かかることがあります。
ジュール

@Jules:正規のテーブルスキームの問題は、事前にテーブルサイズの(プリミティブな再帰)バウンドがわからないことです。もちろん、メモを作成できますが、通常の方法ではできません。はい、それはDPにとって実行可能かもしれませんが、それは私の質問が関係している問題のクラスに適合しません。
ラファエル

1
DPの要件として、テーブルサイズにアプリオリな限界があるとは思わないのですか?実際、JeffEが述べているように、キャッシュはテーブルである必要はありません。任意の連想データ構造を使用できます。DPは本当に非常に単純なアイデアです。再帰的に定義された関数を計算したいが、この関数は同じ引数で繰り返し呼び出されます。DPは、各ケースを1回だけ計算するようにキャッシュを導入する最適化です。2つの有界整数の関数であっても、どちらの場合にも当てはまらない関数がたくさんあります。
ジュール

2

これはケース3に完全には適合しませんが、動的プログラミングを教えるために使用される非常に一般的な問題であるマトリックスチェーン乗算をキャプチャするケースがあるかどうかはわかりません。この問題を解決するために(および他の多くの場合、これは単なる標準的な問題です)、行ごとではなく対角ごとに行列を埋めます。

したがって、ルールは次のようになります。

diagMatrix


1
このように書かれているので、どのような場合にも当てはまりません。ただし、時計回りに45度回転すると、ケース2(およびすべての暗黙のプロパティ)が得られます。これは、対角線から角に向かって動作する他の例にも当てはまります。しかし、言及してくれてありがとう!
ラファエル

@Raphaelこれらが同等であることはすぐには明らかではないので、質問でそのことを言及してください。
ジョー

0

私はその愚かな例を知っていますが、次のような単純な反復的な問題だと思います

正方行列の数値の合計を見つける

資格があるかもしれません。従来の「列ごとの行ごと」は、ケース3のように見えます。


-1

これはまさにあなたが探しているサーチスペースではありませんが、私は助けになるかもしれない私の頭の上部のアイデアを持っています。

問題点:

与えられた n×n マトリックスは言う、 M各行のエントリ(左から右)と各列(上から下)の両方が昇順で並べ替えられ、各列のエントリが昇順で並べられている別個の整数。整数の位置を見つけるための効率的なアルゴリズムを与えるバツM (または、整数が行列に存在しないと言います)。

回答

これは、次の再帰的な方法で解決できます。

n×n行列があります。させるk=1+n2。今比較するバツmkk。もしバツ<mkk 任意の要素を破棄できます mj にとって kn そして kjn すなわち、探索空間は 1/4。同様に、バツ>mkk、検索スペースは 1/4。したがって、最初の反復の後、探索空間のサイズは34n2。これを次のようにさらに再帰的に実行できます。3つの比較を行います。バツ 残りの3つの象限のそれぞれに中央の要素があり、残りの検索スペースのサイズは 343n2 等々。


1
これは動的プログラミングのインスタンスではありませんか?
ラファエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.