Algorithms summary korean

39
알고리즘 - 기초 강영민 동명대학교 게임공학과

description

2014학년도 1학기 알고리즘 수업 요약

Transcript of Algorithms summary korean

Page 1: Algorithms summary korean

알고리즘 - 기초강영민

동명대학교 게임공학과

Page 2: Algorithms summary korean

알고리즘

• 계산을 위한 “단계별” 절차

• 입력/출력

• 간단하고 명료

• 유한한 단계

• 실행 가능한 절차

Page 3: Algorithms summary korean

알고리즘 분석

• 점근적(asymptotic) 분석

• 함수의 상한과 하한에 대한 분석

!

• 항들 중 과 두 항은 n이 매우 큰 수가 되면 중요하지 않게 됨

• f(n)를 점근적으로 와 동등하다고 함

• 빅오(big-Oh), 빅 오메가(big-Omega), 빅 쎄타(big-Theta)

f(n) = n3 + 20n2 + 10n

20n2 10n

n3

f(n) = O(g(n) : f is bounded above by g

f(n) = ⌦(g(n)) : f is bounded below by g

f(n) = ⇥(g(n)) : f is bounded both above and below by g

상한

하한

Page 4: Algorithms summary korean

기초적 자료 구조 - 배열과 링크드 리스트

• 배열과 링크드 리스트의 장단비교

• 임의 접근 (시간)

• 배열이 나음

• 메모리 효율 (공간)

• 링크드 리스트가 나음

Page 5: Algorithms summary korean

링크드 리스트 구조

• 단일 연결 리스트(singly linked)

• 1 노드에 1 링크 (next)

• 이중 연결 리스트(doubly linked)

• 1 노드에 2개 링크 (prev. 와 next)

• 공통적으로 사용되는 자료

• head와 tail 포인터

Page 6: Algorithms summary korean

기초적인 자료 구조 - 스택• 스택

• 후입선출(Last in, First out)

• 자료

• top: 최근 삽입 데이터의 인덱스

• array: stack에 담긴 자료

• 연산

• push: 데이터 추가

• pop: 데이터 제거

Page 7: Algorithms summary korean

기초적인 자료 구조 - 큐(QUEUE)• 큐

• 선입선출(First in, First out)

• 데이터

• front, rear: 인덱스

• array: 큐에 담긴 데이터

• 연산

• add: 데이터 추가

• remove: 데이터 제거 rear

add remove

Page 8: Algorithms summary korean

기초적인 자료 구조 - 트리

• 그래프 G = {V, E}

• 정점집합 V와 간선집합 E의 집합

!

!

• 트리(tree)

• 사이클이 없는 그래프(acyclic graph)

Page 9: Algorithms summary korean

트리

• 루트(root)가 있는지 없는지에 따라 다른 특성

• 루트가 있는 트리

• 계층 구조 루트

Page 10: Algorithms summary korean

계층적 트리

• 1 개의 루트 노드

• 각 노드는 복수의 자식을 가질 수 있음

• n = 최대 자식 개수

• n-ary 트리

• 이진 트리(binary tree)

• 최대 자식 개수 = 2

• 레벨, 높이…

레벨 1

레벨 2

레벨 3

노드 10의 높이 = 2

루트 노드의 높이 = 트리의 높이

Page 11: Algorithms summary korean

정렬 - 선택정렬

• 리스트 L = { 정렬된 부분리스트 L(+), 정렬되지 않은 부분리스트 L(-) }

• 초기화: L = L(+)L(-)

• L(+) = nil

• L(-) = L

• 루프

• L(-)에서 가장 작은 값을 가진 “min”을 찾고, 이 “min”과 L(-)에서 가장 앞에 있는 원소의 자리를 바꾼다

• L(-)의 첫 원소를 L(-)에서 제거하고 L(+)에 넣는다

• L(+)=L이 될 때까지 루프를 반복한다.

L(+)

L(-)

Page 12: Algorithms summary korean

정렬 - 거품정렬

• 리스트 L = { 정렬된 부분 L(+), 정렬되지 않은 부분 L(-) }

• 초기화: L = L(-)L(+)

• L(-) = L

• L(+) = nil

• 루프:

• L(-)의 왼쪽에서 오른쪽으로

• 인접한 두 개의 원소를 비교하여 큰 것이 오른쪽에 놓이도록 만든다

• 가장 큰 원소가 L(-)의 오른쪽 끝에 놓이게 된다

• L(-)의 가장 오른쪽 끝 원소를 L(+)에 넣는다

• L(+)=L이 될 때까지 루프를 반복한다

L(-) L(+) = 0

max will be here

L(-) L(-)

compare

compare

compare

...

Page 13: Algorithms summary korean

정렬 - 삽입정렬

• 리스트 L = { 정렬된 부분 L(+), 정렬되지 않은 부분 L(-) }

• 초기화: L = L(+)L(-)

• L(+) = nil

• L(-) = L

• 루프

• L(-)에서 첫 번째 원소 x를 선택한다

• 이 원소 x가 놓을 위치를 L(+)에서 찾는다

• 해당 위치에 x를 삽입하고 x이후의 L(+)는 뒤로 한 칸씩 민다

• L(+)=L이 될 때까지 루프를 반복한다

Page 14: Algorithms summary korean

어떤 정렬이 좋은 정렬인가?

• 지금까지의 방법들 - 평균적 시간 복잡도

!• 거의 정렬된 데이터는?

• 삽입정렬이 더 나음

• 왜?

• “적절한 위치”를 쉽게(적은 비교로) 찾을 수 있음

• 많은 경우

• 거의 정렬된 리스트가 주어짐 (충돌 처리…)

• 삽입 정렬이 거품정렬보다 좋다

• http://http.developer.nvidia.com/GPUGems3/elementLinks/32fig01.jpg

O(n2)

Page 15: Algorithms summary korean

퀵 정렬(QUICK SORT) 더 빠른 정렬?• 퀵 정렬

• 리스트 L을 정렬하려고 한다

• 피벗(pivot): L에 있는 어떤 한 원소

• L(-): 리스트에서 피벗보다 작은 원소들로 구성된 부분

• L(+): 리스트에서 피벗보다 큰 원소들로 구성된 부분

• 퀵 정렬 알고리즘

• L에서 x를 선택한다

• L을 L(-)와 x, 그리고 L(+)로 나눈다

• L(-)과 L(+)에 재귀적으로 퀵 정렬 함수를 호출한다

Page 16: Algorithms summary korean

퀵(QUICK) 정렬은 얼마나 ‘퀵’할까?

• 운이 좋은 경우

• 피벗이 리스트를 균등하게 쪼갠다

• 재귀호출의 깊이 = lgn

• 재귀호출 트리의 각 단계(level)에서 O(n) 작업이 필요

• 전체적인 시간 복잡도 =

• 운이 나쁜 경우 (예: 이미 정렬된 데이터)

• 피벗이 최소 혹은 최대 값을 가질 수 있음

• O(n) 재귀 호출

• 전체적인 시간 복잡도

• 평균: O(n lg n)

O(n lg n)

O(n2)

Page 17: Algorithms summary korean

병합 정렬 -보장된 계산복잡도

• 알고리즘

• 루프 1

• 리스트를 반으로 쪼갠다

• 모든 리스트가 더이상 쪼개질 수 없을 때까지 루프 1 반복

• 루프 2

• 인접한 두 리스트를 병합하여 더 큰 정렬리스트를 만든다

• 모두 병합되어 하나의 리스트가 될 때까지 루프 2 반복

O(n lg n)

Page 18: Algorithms summary korean

탐색(SEARCH)

• 순차(sequential) 탐색

• O(n)

• 좀 더 효율적인 방법 필요

• 자기 조직화(self-organising) 리스트

• 자주 접근되는 원소를 리스트의 앞으로 옮겨 놓음

• 언제나 운이 좋지는 않을 것이다

Page 19: Algorithms summary korean

이진 탐색(BINARY SEARCH)

• 규칙

• 찾으려는 키: k, 검색을 하려는 대상은 정렬된 배열 array

• 위치 i의 값이 v라는 것을 알 수 있다: array[i] = v

• k=v이면 키를 발견했고 위치는 i가 됨

• k>v라면 array[i]보다 왼쪽 영역은 더이상 고려할 필요 없음

• k<v라면 오른쪽이 고려할 필요가 없어짐

• 알고리즘

• 1. 키 k와 리스트의 가운데 원소를 비교한다

• 2.

• 일치하면 가운데 원소의 인덱스를 리턴 (종료)

• 일치하지 않으면 왼쪽, 오른쪽 가운데 한 쪽을 규칙에 따라 버린다

• 3. 리스트가 남아 있다면 다시 1로 돌아간다

Page 20: Algorithms summary korean

이진 탐색 트리 (BINARY SEARCH TREE)• 노드에 적용되는 간단한 규칙

• 나의 왼쪽 부트리(subtree)에 있는 모든 원소는 나보다 작은 값

• 나의 오른쪽 부트리(subtree)에 있는 모든 원소는 나보다 큰 값

• 작업

• 운이 좋을 때 (트리가 균형잡혀 있을 때)

• 탐색: O(lgn)

• 노드 추가: O(lgn)

• 삭제 (다음 슬라이드 상세 설명)

• 사소한 경우

• 잎(leaf)를 지우거나 하나의 부트리(subtree)를 가진 노드를 지울 때

• 사소하지 않은 경우

• 지울 노드의 왼쪽 부트리에서 제일 큰 원소 혹은 오른쪽 부트리에서 제일 작은 원소와 교체

Page 21: Algorithms summary korean

이진탐색트리 노드 삭제

• 사소한 경우

• 잎 노드인 경우

• 그냥 지우면 됨

• 내부 노드이지만 사소한 경우

• 가진 부트리가 하나인 경우

• 지울 노드의 부모와 자식을 연결해 줌

• 사소하지 않은 경우

• 지우려는 노드 x가 두 개의 부트리를 가지는 경우

• 오른쪽 부트리에서 가작 작은 원소 ‘min’을 찾음

• ‘min’을 x에 복사함

• 재귀적으로 원래의 ‘min’을 삭제하는 작업을 수행

Page 22: Algorithms summary korean

2-3-4 트리

• 왜 필요한가

• BST는 균형이 잡히지 않을 수 있음

• 어떻게 균형을 잡을 것인가? 답: 2-3-4 트리

• 노드의 종류 = 3 종

• 2 노드

• 1개 키와 2 개의 링크 (이진 트리 노드와 동일)

• 3 노드

• 2개의 키와 3 개의 링크

• 4 노드

• 3개의 키와 4 개의 링크 Patrick Prosser, 2-3-4 trees and red-black tree, course slide, http://www.dcs.gla.ac.uk/~pat/52233/slides/234_RB_trees1x1.pdf

Page 23: Algorithms summary korean

2-3-4 트리: 어떻게 동작하나

• BST와 같은 방식으로 잎 노드를 찾는다

• 삽입시 대상 노드가 2-, 3- 노드인 경우 각각을 3-,4- 노드로 키워서 새 아이템 삽입

• 잎 노드가 4 노드라면?

• 4-노드를 쪼개어 두 개의 2 노드를 만든다

• 가운데 원소를 위로 올린다

• 새 노드를 추가한다

• 4노드 분할이 연쇄적으로 일어날 수도?

• 잎 노드를 찾아 내려가면서 4-노드가 발견되면 미리 쪼갬

• 노드 삭제: 다소 복잡

2-3-4 트리는 균형잡힌 트리 O(lg n) 탐색이 언제나 가능

Patrick Prosser, 2-3-4 trees and red-black tree, course slide, http://www.dcs.gla.ac.uk/~pat/52233/slides/234_RB_trees1x1.pdf

Page 24: Algorithms summary korean

흑적(RED-BLACK) 트리

• 2-3-4 트리의 문제: 각각의 노드가 서로 다른 구조를 가짐

• 더 나은 구현법

• 흑적 트리 - 모든 노드는 이진트리 노드, 간선은 흑, 적 두 종류

• 2-노드

• 3-노드

• 4-노드

붉은 간선이 상하로 두 개 연속 나타날 수는 없다 (따라서, 검은 간선의 수는 언제나 균형이 잡혀 있다)

Patrick Prosser, 2-3-4 trees and red-black tree, course slide, http://www.dcs.gla.ac.uk/~pat/52233/slides/234_RB_trees1x1.pdf

제한조건

Page 25: Algorithms summary korean

흑적 트리

• 삽입

• 2진 탐색 트리처럼 새 아이템을 삽입할 위치를 찾는다

• 새 아이템이 달리게 되는 부모 노드에서 새 노드로 오는 간선을 붉은 색으로 칠한다

• 연속적으로 붉은 간선이 나타날 수 없다는 규칙을 지킨다

• 실제 삽입시 발생하는 경우들

right rotation left rotation left-right double rotation right-left double rotation

승진규칙(promotion rule) 부모 노드 p로 들어오는 간선과 p의 형제 노드로 들어오는 간선이 모두 붉은 색이라면 이들 간선을 검정으로 바꾸고, 할아버지 노드로 들어오는 간선을 붉은 색으로 바꾼다.

Patrick Prosser, 2-3-4 trees and red-black tree, course slide, http://www.dcs.gla.ac.uk/~pat/52233/slides/234_RB_trees1x1.pdf

Page 26: Algorithms summary korean

우선 순위 큐 - HEAP

• 종류

• 맥스 힙(max-heap): 어떤 노드 x 아래의 모든 노드는 이 x보다 크다

• 민-힙(min-heap): 어떤 노드 x 아래의 모든 노느는 이 x보다 작다

• 힙(heap)은 완전이진트리

• 언제나 균형잡힌 트리

• 배열로 구현 가능

• i-번째 노드

• 자식: 2*i 번째와 2*i+1 번째

• 부모: �i

2

Page 27: Algorithms summary korean

우선순위 큐 - HEAP

• 삽입

Page 28: Algorithms summary korean

• 삭제

우선순위 큐 - HEAP

Page 29: Algorithms summary korean

해시(HASH)

• 해시 함수

• 임의 크기를 가진 데이터를 고정된 크기의 데이터로 매핑(mapping)하는 함수로서 입력 데이터가 조금만 달라져도 출력 데이터는 상당히 큰 차이가 나야 한다 (Wikipedia, http://en.wikipedia.org/wiki/Hash_function)

• 이 함수는 일반적으로 역함수가 없는 함수이다.

• 해시 테이블

• data 는 hash(data)-th 번째 원소로 해시 테이블에 저장된다

• 충돌

• 해시 함수가 완전하지 않음

• 해법

• 체이닝

• 개방 주소형

• 선형 탐사, 제곱 탐사, 이중 해싱, 임의 주소

Page 30: Algorithms summary korean

해시 함수들

• 해시 함수의 예

• 곱셈법

!

• Knuth의 제안

!

• 나눗셈법: hash(k) = k mod m

• 제곱의 가운데

• 입력된 값을 제곱한 의 가운데 p-비트를 사용

• 폴딩

• 입력 키를 몇 개의 조각으로 나누어 더하거나 뒤집는 방식으로 하나로 합침

0 hash(k) < m

k2

A =

p5� 1

2

hash(k) = m · (k ·A� bk ·Ac)

황금비율

Page 31: Algorithms summary korean

그래프(GRAPH)

• 그래프 G = {V,E}

• V: 정점의 집합

• E: 두 정점을 연결하는 간선의 집합

• 인접

• 두 노드가 간선으로 연결되어 있으면 두 노드가 인접하다라고 함

• 그래프를 표현하는 자료구조

• 인접 행렬, 인접 리스트

• 그래프의 종류

• 유향과 무향 그래프

• 가중치가 있는 것과 없는 것

undirected vs. directed

weighted vs. non-weighted

Page 32: Algorithms summary korean

그래프 순회(TRAVERSAL)

• 깊이 우선 탐색(DFS, depth-first-search)과 너비 우선 탐색 (BFS, breadth-first-search)

• DFS와 BFS는 각각 스택과 큐를 활용

A

B

C

D

E

F

G

HI

DFSStack

[A] [AB] [ABC] [AB] [ABD] [ABDE] [ABDEF] [ABDE] [ABDEG] [ABDEGH] [ABDEG] [ABDGI]

Traversal: A, B, C, D, E, F, G, H, I

BFS

Queue

Traversal: A, B, C, D, E, G, F, H, I

[A] [B] [CD] [D] [EGH] [GHF] [HFI]

A

B

C

DE

F

G

HI

A

B

C

DE

F

G

H I

DFS tree

BFS tree

Page 33: Algorithms summary korean

최소비용 신장 트리 (MINIMUM COST SPANNING TREE)

• 탐욕 기법

• 프림의 기법

• 두 개의 정점 집합을 준비: V, U

• v0 노드를 선택하고 V={v0}로 설정

• U = { 다른 모든 정점}

• V와 U를 연결하는 최소비용 간선 (v in V, u in U)를 찾는다

• 싸이클이 만들어지지 않으면 u를 V에 넣는다

• 크루스칼(Kruskal’s) 알고리즘

• 간선의 리스트를 비용에 따라 정렬한다.

• 간선을 오름차순으로 선택하여 스패닝 트리에 포함

• 싸이클을 만들면 포기

Page 34: Algorithms summary korean

다익스트라(DIJKSTRA)의 최단경로

• 하나의 시작점 - 모든 지점으로의 경로

subgraph with vertices of which shortest path was found

subgraph with vertices of which shortes paths are not known yet

G

+

G

start

u : newly added vertex

d

+= 0

d

+u : found

v1

v2

vn

.

.

.

c1

c2

cn

d

�v2

d

�v1

d

�vn

initialisation

d

+start = 0

d

�vi =1

G

+= start

G

�= G� start

u = start

Loop

d

+u + ci < d

�vi ) d

�vi d

+u + ci

for all i

find minimum d

�v in G

add v into G

+, remove it from G

fix d

�v to be d

+v

u v

While G

�is not empty

Page 35: Algorithms summary korean

문자열 탐색 라빈 카프(RABIN-KARP) 기법• 라빈-카프

• T: m 개의 글자를 가진 텍스트

• p: n 개의 글자를 가진 text

• h = hash(p)

• hi: T[i]에서 시작하는 n 개 글자의 해시값

• h = hi이면, 문자열 “T[i]…T[i+n-1]”가 p일 수 있음

• i=0 에서 m-n까지 검사 수행

• 해쉬hi =

n�1X

j=0

T [i+ j] · 2n�1�j

hi+1 = hi � T [i] · 2n�1 + T [i+ n]

abcdefghijklmnopqrstuvwxyz

hash value = h1

hash value = h2

h2 = h1 � b · 210 +m

Page 36: Algorithms summary korean

문자열 탐색 KMP(KNUTH-MORRIS-PRATT) 기법

text

pattern mismatch

1 character shift

naive approach

text

pattern mismatch

jump to the mismatched location?

we want...

ANY PROBLEM?

Sometimes we cannot jump that far... Why?

text

pattern mismatch

identical

”Jump Table” is required

border

Page 37: Algorithms summary korean

문자열 탐색 보이어-무어(BOYER-MOORE) 기법• 오른쪽에서 왼쪽으로 검사

• 나쁜 캐릭터 이동

• 좋은 접미부 이동text

pattern

mismatch

comparison direction

bad character

bad character shift

text

pattern

mismatch

comparison direction

good su�x

case 1

case 2

good su�x is found in the left

su�x of good su�x matches the prefix of pattern

Page 38: Algorithms summary korean

동적계획법(DYNAMIC PROGRAMMING) 최장 공통 부분서열 (LONGEST COMMON SUBSEQUENCE)

• 부분서열(subsequence)

• 다른 서열의 원소들이 가진 순서를 변경하지 않고 일부 원소를 삭제함으로서 얻을 수 있는 서열

• 공통 부분서열

• 만약 G가 X의 부분서열이면서 동시에 Y의 부분서열이라면 G는 X와 Y의 공통 부분서열이다.

• 최장 공통 부분서열

• 최적 부분구조

Xi =< x1, x2, · · · , xi >

Yj =< y1, y2, · · · , yj >

|LCS(Xi, Yi)| =

0

@0 , if i = 0 or j = 0

|LCS(Xi�1, Yj�1)|+ 1 , if xi = yj

max(|LCS(Xi�1, Yj)|, |LCS(Xi, Yj�1)|) , if xi 6= yj and i, j > 0

1

A

Page 39: Algorithms summary korean

문제 해결 기법들

• 분할 정복(divide and conquer)

• 퀵 정렬, 합병 정렬

• 탐욕 기법

• 최적 부분 구조

• 최소비용 신장 트리

• 구현이 쉽다. 탐욕 기법으로 풀 수 있는지를 증명해야 함

• 동적 계획법

• 최적 부분 구조

• 큰 문제를 작고 쉬운 문제로 쪼개의 풀어 그 결과를 활용하여 큰 문제의 해를 구함