分割統治アルゴリズムと動的プログラミングの違い


140

分割統治アルゴリズムと動的計画法アルゴリズムの違いは何ですか?2つの用語の違いは何ですか?それらの違いがわかりません。

簡単な例を挙げて、この2つの違いと、それらが類似していると思われる理由を説明してください。

回答:


156

分割統治

分割統治は、問題をサブ問題に分割し、各サブ問題を再帰的に征服し、これらのソリューションを組み合わせることで機能します。

動的プログラミング

動的プログラミングは、サブ問題が重複している問題を解決するための手法です。各サブ問題は1回だけ解決され、各サブ問題の結果は、将来の参照用にテーブル(通常は配列またはハッシュテーブルとして実装)に保存されます。これらのサブソリューションは、元のソリューションを取得するために使用できます。サブ問題のソリューションを保存する手法は、メモ化と呼ばれます。

あなたは考えるかもしれません DP = recursion + re-use

違いを理解するための典型的な例は、n番目のフィボナッチ数の取得に向けたこれらの両方のアプローチを見ることです。MITからこの資料を確認してください。


分割統治アプローチ 分割統治アプローチ

動的プログラミングのアプローチ ここに画像の説明を入力してください


9
どのようにして画像を作成しましたか?マウスを使用して?
Vihaan Verma 2013

34
この回答全体で最も重要なのは、「重複するサブ問題」です。DPにはそれがありますが、Divide and Conquerにはありません
Hasan Iqbal

@HasanIqbalAnik重複するサブ問題は、繰り返し発生する問題を意味します。上記の例でfn-2を解くように。したがって、D&Cにはそれがあるため、DPほど効率的ではありません。
Meena Chaudhary、2016

1
おかしい!「重複するサブ問題」とは問題のことですが、「動的プログラミング」は一種のアルゴリズムです。「問題」と「アルゴリズム」を区別することが重要だと思います。
ZHU 2017

はい、DPは重複部分をメモして、分割統治よりも有利になります。
imagineerTat 19'19

25

分割統治と動的プログラミングの他の違いは次のとおりです。

分割統治:

  1. サブ問題により多くの作業を行うため、より多くの時間を消費します。
  2. 分割統治では、副問題は互いに独立しています。

動的プログラミング:

  1. 副問題を一度だけ解決し、それをテーブルに格納します。
  2. 動的プログラミングでは、副問題は独立していません。

分割統治アルゴリズムは、必ずしもそれらのDP代替よりも多くの作業を行うわけではありません。1つの例は、最大の算術的進行を見つけるためのエリクソンのアルゴリズムです。
マイケル・フカラキス2016

17

場合によっては、再帰的にプログラミングするときに、同じパラメーターを使用して関数を複数回呼び出すことがありますが、これは不要です。

有名なフィボナッチ数の例:

           index: 1,2,3,4,5,6...
Fibonacci number: 1,1,2,3,5,8...

function F(n) {
    if (n < 3)
        return 1
    else
        return F(n-1) + F(n-2)
}

F(5)を実行してみましょう:

F(5) = F(4) + F(3)
     = {F(3)+F(2)} + {F(2)+F(1)}
     = {[F(2)+F(1)]+1} + {1+1}
     = 1+1+1+1+1

したがって、次のように呼びます。1回F(4)2回F(3)3回F(2)2回F(1)

動的プログラミングのアプローチ:同じパラメーターを使用して関数を複数回呼び出す場合は、結果を変数に保存して、次回から直接アクセスします。反復的な方法:

if (n==1 || n==2)
    return 1
else
    f1=1, f2=1
    for i=3 to n
         f = f1 + f2
         f1 = f2
         f2 = f

もう一度F(5)を呼び出しましょう:

fibo1 = 1
fibo2 = 1 
fibo3 = (fibo1 + fibo2) = 1 + 1 = 2
fibo4 = (fibo2 + fibo3) = 1 + 2 = 3
fibo5 = (fibo3 + fibo4) = 2 + 3 = 5

ご覧のように、複数の呼び出しが必要なときはいつでも、対応する変数にアクセスして値を再計算するのではなく取得します。

ちなみに、動的プログラミングは、再帰的なコードを反復的なコードに変換することを意味するものではありません。再帰的なコードが必要な場合は、サブ結果を変数に保存することもできます。この場合、この手法はメモ化と呼ばれます。この例では、次のようになります。

// declare and initialize a dictionary
var dict = new Dictionary<int,int>();
for i=1 to n
    dict[i] = -1

function F(n) {
    if (n < 3)
        return 1
    else
    {
        if (dict[n] == -1)
            dict[n] = F(n-1) + F(n-2)

        return dict[n]                
    }
}

したがって、Divide and Conquerとの関係は、D&Dアルゴリズムが再帰に依存していることです。そして、それらの一部のバージョンには、「同じパラメーターの問題を持つ複数の関数呼び出し」があります。D&DアルゴのT(n)を改善するためにDPが必要な例については、「マトリックスチェーン乗算」および「最長共通サブシーケンス」を検索してください。


17

動的プログラミングと分割統治法の類似点

今のところ、動的プログラミングは分割統治パラダイムの延長であると言えます

私はそれらをまったく異なるものとして扱いません。これらは両方とも、問題を同じまたは関連するタイプの2つ以上のサブ問題に再帰的に分解することによって機能するためこれらが直接解決できるほど単純になるまで。次に、副問題の解を組み合わせて、元の問題の解を与えます。

では、なぜ今でもパラダイム名が異なるのか、なぜ動的プログラミングを拡張機能と呼んだのか。これは、問題に特定の制限または前提条件がある場合にのみ、動的プログラミングアプローチを問題に適用できるためです。その後、動的プログラミングは、メモ化または集計手法を使用して、分割統治アプローチを拡張します。

少しずつ行きましょう…

動的プログラミングの前提条件/制限

今発見したように、動的プログラミングを適用するためには、問題を分割して征服する必要がある2つの重要な属性があります。

  • 最適な部分構造  —部分問題の最適解から最適解を構築できます

  • 重複するサブ問題  —問題は複数回再利用されるサブ問題に分解できます。または問題の再帰アルゴリズムが常に新しいサブ問題を生成するのではなく、何度も同じサブ問題を解決します

これらの2つの条件が満たされると、この分割統治問題は動的計画法を使用して解決できると言えます。

分割統治のための動的プログラミング拡張機能

ダイナミックプログラミングアプローチは、分割統治アプローチを拡張し、パフォーマンスを大幅に改善する可能性のあるサブ問題ソリューションを保存して再利用する2つの手法(memoizationtabulation)を備えています。たとえば、フィボナッチ関数の単純な再帰的な実装にはO(2^n)、DPソリューションが時間だけで同じことを行う場合の時間の複雑さがありO(n)ます。

メモ化(トップダウンキャッシュフィル)は、以前に計算された結果をキャッシュして再利用する手法を指します。したがって、メモ化されたfib関数は次のようになります。

memFib(n) {
    if (mem[n] is undefined)
        if (n < 2) result = n
        else result = memFib(n-2) + memFib(n-1)

        mem[n] = result
    return mem[n]
}

集計(ボトムアップキャッシュフィル)も同様ですが、キャッシュエントリのフィルに重点を置いています。キャッシュ内の値の計算は、反復的に行うのが最も簡単です。の集計バージョンは次のfibようになります。

tabFib(n) {
    mem[0] = 0
    mem[1] = 1
    for i = 2...n
        mem[i] = mem[i-2] + mem[i-1]
    return mem[n]
}

メモ化と集計の比較の詳細については、こちらをご覧ください

ここで把握しておく必要のある主な考え方は、分割統治問題にはサブ問題が重複しているため、サブ問題ソリューションのキャッシュが可能になり、メモ化/集計がシーンにステップアップするということです。

結局のところ、DPとDCの違いは何ですか

これでDPの前提条件とその方法論に精通したので、上記のすべてを1つの図にまとめる準備ができています。

動的プログラミングと分割統治

コード例を確認したい場合は、ここで2つのアルゴリズム例を見つける詳細な説明をご覧ください。DPとDCの違いを示す2進検索と最小編集距離(Levenshtein距離)です。


1
オフトピック:グラフィックタブレットを使用して描画しましたか?
Geon George

1
@GeonGeorgeいいえ、描画はペンで作成してスキャンしました
Oleksii Trekhleb

これは、私がDPの組織化について読んだ最良の回答の1つです
Ridhwaan Shakeel

8

これについてはすでにウィキペディアやその他の学術リソースを読んでいると思います。そのため、その情報は再利用しません。また、私は絶対にコンピュータサイエンスの専門家ではないことにも注意する必要がありますが、これらのトピックの理解について2セントを共有します...

動的プログラミング

問題を個別のサブ問題に分解します。フィボナッチ数列の再帰アルゴリズムは、最初にfib(n-1)を解くことによってfib(n)を解くため、動的プログラミングの例です。元の問題を解決するために、別の問題を解決します。

分割統治

これらのアルゴリズムは通常、同様の問題を解決し、最後にまとめます。Mergesortは、分割統治の典型的な例です。この例とフィボナッチの例の主な違いは、マージソートでは、分割は(理論的には)任意であり、どのように分割しても、マージとソートが行われることです。配列をどのように分割しても、配列をマージソートするには同じ量の作業を行う必要があります。fib(52)を解くには、fib(2)を解くよりも多くのステップが必要です


5

私はDivide & Conquer、再帰的なアプローチとして、またDynamic Programmingテーブルの充填として考えています。

たとえば、Merge SortDivide & Conquerアルゴリズムです。各ステップと同様に、配列を2つの半分に分割し、2つの半分を再帰的に呼び出しMerge Sortて、それらをマージします。

KnapsackであるDynamic Programmingあなたは、全体のナップザックの部分問題に最適なソリューションを表すテーブルを埋めているようなアルゴリズム。表の各エントリは、アイテム1〜jが与えられた状態で、重量wのバッグに入れて持ち運べる最大値に対応しています。


1
これは多くの場合に当てはまりますが、副問題の結果をテーブルに格納することが常に当てはまるとは限りません。
Gokul

2

分割統治には、再帰の各レベルで3つのステップが含まれます。

  1. 問題をサブ問題に分割します。
  2. それらを再帰的に解決することにより、副問題を克服します。
  3. 副問題の解を元の問題の解に結合します。
    • これはトップダウンアプローチです。
    • 副問題に対してより多くの作業を行うため、より多くの時間を消費します。
    • 例えば。フィボナッチ数列のn番目の項は、O(2 ^ n)時間の複雑度で計算できます。

動的計画法には、次の4つのステップが含まれます

。1 .最適解の構造を特徴付けます。
2. 最適解の値を再帰的に定義します。
3. 最適解の価値を計算します。
4. 構築し最適解を計算された情報から

  • これはボトムアップアプローチです。
  • 再計算するのではなく、以前に計算された値を使用するため、分割統治よりも時間がかかりません。
  • 例えば。フィボナッチ数列のn番目の項は、O(n)時間の複雑度で計算できます。

理解を容易にするために、総当たりのソリューションとしての分割統治と、動的プログラミングとしての最適化を見てみましょう。

NBサブ問題が重複する分割統治アルゴリズムは、dpでのみ最適化できます。


分割
統治

0
  • 分割統治
    • 彼らは重複しないサブ問題に割り込んだ
    • 例:階乗数、すなわちfact(n)= n * fact(n-1)
fact(5) = 5* fact(4) = 5 * (4 * fact(3))= 5 * 4 * (3 *fact(2))= 5 * 4 * 3 * 2 * (fact(1))

上記のように、fact(x)は繰り返されないため、階乗には重複しない問題があります。

  • 動的プログラミング
    • 彼らは重複するサブ問題に分かれました
    • 例:フィボナッチ数、つまりfib(n)= fib(n-1)+ fib(n-2)
fib(5) = fib(4) + fib(3) = (fib(3)+fib(2)) + (fib(2)+fib(1))

上記のように、fib(4)とfib(3)はどちらもfib(2)を使用します。同様に、非常に多くのfib(x)が繰り返されます。そのため、フィボナッチにはサブ問題が重複しています。

  • DPでサブ問題が繰り返された結果、そのような結果をテーブルに保持し、計算の労力を節約できます。これはメモ化と呼ばれます
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.