본문 바로가기
Study

다이나믹 프로그래밍(Dynamic Programming)

by ksb0511 2020. 5. 1.

 다이나믹 프로그래밍은 "한 번 푼 걸 다시 풀어야 하는 문제의 경우 효율적으로 풀 수 있게끔 하는 알고리즘"이다. 문제를 비효율적으로 반복해서 풀다보면, 프로그램 속도가 느려지기도 하고, 말 그대로 정말 비효율적인 코딩이 된다.

 

 대표적인 예시를 들어보자면, 피보나치 수열이 있다. 피보나치 수열은 앞의 두 숫자를 더해서 수가 나열되는 규칙을 지니고 있다. 이 것을 점화식으로 표현하자면, 

이렇게 간단하게 표현할 수 있다.

문제를 이런 식으로 풀다보면, 계속해서 구했던 값인데도 불구하고 비효율적으로 계속해서 다시 구해야되는 일이 발생한다. 5라는 숫자를 넣어서 예를 들자면,

5는 굉장히 작은 축에 속하는 숫자임에도 불구하고, 2를 3번이나 다시 계산해야된다. 더 큰 숫자의 경우에는 더 비효율적이다. 이럴 때에 다이나믹 프로그래밍을 이용하면  굉장히 효율적으로 풀 수 있다.

 

다이나믹 프로그래밍을 쓰려면 두 가지 조건이 충족되어야 한다.

 

<조건>

1. 큰 문제를 작은 문제로 나눠서 풀 수 있다.

2. 작은 문제의 정답이 큰 문제에서의 작은 문제 답과 동일하다.

 

이 조건이 충족되었다면, 다이나믹 프로그래밍을 사용할 수 있다. 다이나믹 프로그래밍에 대해 피보나치를 대입해서 얘기해보자면, 구한 결과 값은 배열에 저장해서 동일한 계산을 여러 번 반복되어 수행되는 것을 방지하여 효율적인 프로그래밍을 구현하면 된다. 아까 5를 계산할 때에는 2를 3번 다시 계산해야 했지만, DP를 이용한다면 1번만 계산하면 된다.(배열에 이미 그 값이 저장되어 있기 때문에 갖다 쓰기만 하면 됨) 이것을 메모이제이션(Memoization)이라고 한다.

 메모이제이션에 대해 짧게 짚고 넘어가자면,

메모이제이션이란, 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다.(출처: 위키백과)

즉, 이 기술은 동적 계획법(Dynamic Programming)에서 핵심이 되는 기술이라고 할 수 있다.

 

피보나치 수열을 동적 계획법에 맞게 효율적인 코딩을 한다면 코드는 아래와 같다.

public class DP_fibonacci {
	static int[] data= new int[100];

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(fibonacci(5));

	}
	
	private static int fibonacci(int x) {
		if(x<=0) 
			return 0;
		else if(x<2) // 첫 번째와 두 번째 수는 항상 1로 고정되어 있기 때문에..
			return 1;
		if(data[x]!=0) { // 이미 계산 했던 값이 있을 경우
			return data[x];
		}
		else {
			data[x]=fibonacci(x-1)+fibonacci(x-2);
			return data[x];
		}
	}

}

 

'Study' 카테고리의 다른 글

DFS ( 깊이 우선 탐색 )  (0) 2020.05.22
Stack, queue(스택, 큐)  (0) 2020.04.17

댓글