Algorithm - Dynamic Programming

2022. 11. 3. 15:40·Algorithm

 

Dynamic Programming

 

Dynamic Programming(동적계획법)이란?

하나의 큰 문제를 여러개의 작은 문제로 나누어 그 결과를 저장 후 다시 큰 문제를 해결할 때 사용하는 방법이다.

쉽게 말하면 "기억하며 풀기"이다.

재귀와 유사하지만 일반적인 재귀방식으로 연산할시 동일한 작은 문제들이 여러번 호출되어 비효율적이다.

 

재귀 - 피보나치 수열

재귀의 예시로 피보나치 수열에 대해 살펴보자

//재귀 방식으로 구현한 피보나치 수열
public class fibo {
    static int count=0;
    private static int fibona(int n){
        int result = 0;
        count++;
        if(n==0) return 0;
        if(n==1) return 1;
        return fibona(n-2) + fibona(n-1);
    }
    public static void main(String[] args) {
        System.out.println(fibona(6));
        System.out.println(count);
    }
}

/* 출력 결과
8
25
*/

이 경우 fibona(6)을 호출시 8의 결과를 얻기 위해 총 15번 메소드의 호출이 이루어졌다.

파라미터의 수가 6이었기에 25번 호출이 되었지만 파라미터가 커질수록 메소드의 호출횟수는 급격하게 늘어날 것이다

그 이유는 fibona 메소드의 시간복잡도는 n이 1증가할 때마다 2배씩 늘어나므로 O(2^n)이 된다.

 

Dynamic Programming 조건

DP를 적용하기 위해서는 조건이 필요하다

1.동일한 작은 문제들이 반복해서 나타나는 경우 사용 가능

2.부분 문제의 최적 결과 값을 사용해 전체 문제의 최적 결과를 낼 수 있는 경우

 

구현 방식
  • Bottom-Up 방식 (Tabulation)
    • 아래에서부터 계산을 수행하고 누적시켜서 전체 큰 문제를 해결하는 방식 (반복문)
    • 함수를 별도로 호출하지 않아 시간과 메모리를 더 절약할 수 있다.
  • Top-Down 방식 (Memoization)
    • 위에서부터 바로 호출을 시작하여 결과 값을 재귀를 통해 전이시켜 재활용하는 방식
    • 가독성이 좋으며 점화식을 이해하기 쉬움
    • DP는 기억하며 풀기이기 때문에 이 케이스에 해당한다

 

 

1. Memoization과 recursive를 성능,가독성 면에서 비교 분석해주세요
   그리고 피보나치 수를 구하는 함수를 DP와 recurve를 이용해서 각각 구현하고 아래를 테스트 해주세요
   => f(1),  f(100) f(10000)
     * 특이사항이 있다면 원인을 분석해주세요
     
public class fibo {
    static int count=0;
    static int[] dp = new int[100];
    private static int fibona(int n){
        if(n==0) return 0;
        if(n==1) return 1;
        return fibona(n-2) + fibona(n-1);
    }

    private static int dpfibo(int n){
        if(n==1||n==2) return 1;
        if(dp[n]!=0) return dp[n];
        return dp[n] = dpfibo(n-1)+dpfibo(n-2);
    }
    public static void main(String[] args) {
        
        long beforeTime = System.currentTimeMillis();
        System.out.println(fibona(30));
        long afterTime = System.currentTimeMillis();
        System.out.println("시간차이: " +(afterTime - beforeTime));
        long before_Time = System.currentTimeMillis();
        System.out.println(dpfibo(30));
        long after_Time = System.currentTimeMillis();
        System.out.println("시간차이: " +(after_Time - before_Time));
    }
}



'Algorithm' 카테고리의 다른 글

Algorithm - 정렬  (0) 2023.07.05
Algorithm - Hash  (0) 2022.10.27
Algorithm - Graph  (0) 2022.10.20
Algorithm - 우선순위 큐(Priority Queue)  (0) 2022.10.20
Algorithm - Tree  (0) 2022.10.20
'Algorithm' 카테고리의 다른 글
  • Algorithm - 정렬
  • Algorithm - Hash
  • Algorithm - Graph
  • Algorithm - 우선순위 큐(Priority Queue)
해변
해변
  • 해변
    이노 메모장
    해변
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Java
      • C
      • Python
      • HTML
      • Project
      • Algorithm
      • DataBase
      • OS
      • Block Chain
      • CHATGPT
      • ML
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    java
    빅오표기법
    자바
    Do it! 클론코딩
    니꼴라스
    )
    wㅜ
    링크드리스트
    c
    정렬알고리즘
    버블정렬
    자료구조
    8퀸문제
    시간복잡도
    알고리즘
    AWT
    재귀함수
    자바GUI
    python
    Big-O
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
해변
Algorithm - Dynamic Programming

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.