28強ダイナミックプログラミングの概要
13816 ワード
ダイナミックプログラミングとは
概要
注意:一般的なプログラミング分野での動的な意味-資料構造では、動的な割り当ては「プログラムの実行中に実行に必要なメモリを割り当てる方法」を指します.動的なプログラミングでは、「動的」は意味のない言葉です.
使用条件
1.最適な局所構造
大きな問題は小さな問題に分けることができ、小さな問題の答えは集中して大きな問題を解決することができる.
2.重複する部分的な問題
同じ小さな問題は繰り返し解決しなければならない.
例:フィボナッチ数列
フィボナッチの数は以下の通りです.
1 1 2 3 5 8 13 21 34 55 89 ...
点火式
隣接するアイテム間の関係を表す
フィボナッチ数列の点火式表示
再帰関数を使用すると、点化された形式で実現できます.
実施効率の低下
public class Main {
// 피보나치 함수(Fibonacci Function)을 재귀함수로 구현
public static int fibo(int x) {
if (x == 1 || x == 2) {
return 1;
}
return fibo(x - 1) + fibo(x - 2);
}
public static void main(String[] args) {
System.out.println(fibo(4));
}
}
に質問
┑┑┑:フィボナッチ再帰関数の指数時間複雑度
O(2^樹高N)
ダイナミックプログラミング実装
フィボナッチ数列は動的プログラミングの使用条件を満たし,動的プログラミングで有効な計算が可能である.
ダイナミックプログラミングの使用条件を満たす
1.最適な局所構造
大きな問題(ex.f(4))を小さな問題(ex.f(3)+f(2))に分けることができます.
2.重複する部分的な問題
同じ小さな問題を繰り返し解決する(ex.f(2))
タワー
小さな問題を再帰的に呼び出すことで大きな問題を解決
(小さな問題が解決すれば大きな問題の答えが得られる)
✅注釈現在-計算された(小さな問題の)結果をメモリ空間に記録する方法-同じ問題を再び呼び出すと、注釈された結果が得られる-厳密には、以前計算された結果を一時的に記録する広い概念であるため、動的プログラミングに限定されない.-どうさぶんせき
a.単純再帰関数と比較して、 b.実際の呼び出し-青色:呼び出し+演算と記憶値-実線:呼び出し+直ちに返す
=>青色f(3)に以前の値が格納されているため、実線f(3)が呼び出されるが、すぐに戻るので深く入り込まない.
=>定数時間を無視(戻る)O(N)
import java.util.*;
public class Main {
// 한 번 계산된 결과를 메모이제이션(Memoization)하기 위한 배열 초기화
public static long[] d = new long[100];
// 피보나치 함수(Fibonacci Function)를 재귀함수로 구현 (탑다운 다이나믹 프로그래밍)
public static long fibo(int x) {
// 종료 조건(1 혹은 2일 때 1을 반환)
if (x == 1 || x == 2) {
// 상수시간 소요
return 1;
}
// 이미 계산한 적 있는 문제라면 그대로 반환
if (d[x] != 0) {
// 상수시간 소요
return d[x];
}
// 아직 계산하지 않은 문제라면 점화식에 따라서 피보나치 결과 반환
d[x] = fibo(x - 1) + fibo(x - 2);
return d[x];
}
public static void main(String[] args) {
System.out.println(fibo(50));
}
}
ベースフレーム
ダイナミックプログラミングの典型的な形式です.
下から下へ、小さな問題を一つ一つ解決し、先に計算した問題値を利用して、次の問題に進みます.
再帰関数を使用しないため、重複する部分的な問題は発生せず、Bottom-Upは下から上へ、重複した部分的な問題についてコメントし、解答します.( リファレンス )
public class Main {
public static long[] d = new long[100];
public static void main(String[] args) {
// 첫 번째 피보나치 수와 두 번째 피보나치 수는 1
d[1] = 1;
d[2] = 1;
int n = 50; // 50번째 피보나치 수를 계산
// 피보나치 함수(Fibonacci Function) 반복문으로 구현(보텀업 다이나믹 프로그래밍)
for (int i = 3; i <= n; i++) {
d[i] = d[i - 1] + d[i - 2];
}
System.out.println(d[n]);
}
}
ダイナミックプログラミングVS分割征服
-大問題を小問題に分け、小問題の答えを集約して大問題を解決する場合
動的プログラミングの問題の処理方法
与えられた問題が動的プログラミングタイプであることを決定することは重要である
-他のアルゴリズムで解くことができない場合は、動的プログラミングを考慮しましょう.
Reference
この問題について(28強ダイナミックプログラミングの概要), 我々は、より多くの情報をここで見つけました https://velog.io/@jhjcoding/28강-다이나믹-프로그래밍-개요テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol