ALGORITHM - CBNU › course › 2019.2 › cs › 06.algorithm.pdf · 4...

Post on 06-Jul-2020

8 views 0 download

Transcript of ALGORITHM - CBNU › course › 2019.2 › cs › 06.algorithm.pdf · 4...

ALGORITHM

Jo, Heeseung

2

이번 chapter에서 배우는 것들

6.1 알고리즘의 개념 및 표현

• 알고리즘의 개념, 알고리즘의 표현

6.2 반복구조

• 루프 제어, 순차 검색 알고리즘, 삽입 정렬 알고리즘

6.3 재귀구조

6.4 정확성과 효율성

6.1 알고리즘 개념 및 표현

4

알고리즘의 정형적 정의

An ordered set of unambiguous, executable steps, defining a terminating process

모호하지 않고

실행 가능한 단계들의 집합이며,

단계들에는 순서가 정해져 있고

종료되는 프로세스이다.

5

알고리즘의 추상적 특성

하나의 알고리즘은 여러 방식으로 표현 가능

스토리(story)와 책(book)을 통해 본 알고리즘과 표현의 차이?

• 스토리 : 본질적으로 추상적이거나 개념적

• 책 : 스토리에 대한 물리적인 표현

- 책을 다른 언어로 재 출판할 경우, 변하는 것은 스토리의 표현

- 스토리 자체는 변하지 않음

6

여러 가지 알고리즘의 표현

여러 가지 알고리즘의 표현

• 예) 섭씨온도를 화씨온도로 변환하기 위한 알고리즘

- 공식으로 표현

- 지시사항으로 표현

"섭씨온도에 5/9를 곱한 다음 그 결과에 32를 더하라"

바탕이 되는 알고리즘은 동일하며, 표현만 다름

• 알고리즘을 표현으로 바꿀 때 문제가 생길 수 있다!

• 알고리즘을 얼마나 자세히 기술해야 하나?

- 기상학자? 일반인?

7

알고리즘, 프로그램, 프로세스

알고리즘(algorithm)

• 주어진 일(또는 문제)을 처리하여원하는 결과(output)를 얻기까지의 과정을명확(明確)하고 단계(段階)적으로 서술한 것

프로그램(program)

• (컴퓨터가 이해할 수 있는) 알고리즘의 표현

프로세스(process)

• 프로그램의 실제 수행 중인 상태로 알고리즘의 실행 상태

8

알고리즘의 표현 - 프리미티브

자연 언어(natural language)

• 해석이 모호할 우려

• 얼마나 자세히 기술해야 하나

알고리즘의 표현에 사용될 언어가 정확히 정의되지 않거나 정보가충분히 자세하게 기술되지 않을 경우 의사소통 문제가 발생함!

프리미티브(primitive)

• 명확하게 잘 정의된 기초 요소의 집합

• 프리미티브를 정확히 정의하면 많은 모호성 문제 해결

• 프리미티브의 집합이 프로그래밍 언어를 형성

잘 정의된 프리미티브(primitive)들을 필요로 한다

9

종이접기 프리미티브

10

구문 vs. 의미

구문(syntax) : 프리미티브의 기호 표현

• 'air'의 구문 요소 : 3개의 기호

의미(semantics) : 프리미티브가 나타내는 개념

• 'air'의 의미 : 지구를 둘러싼 대기의 하층부를 구성하는 무색, 무취의투명한 기체

프로그래밍 언어

• 구문을 철저히 체크

• 왜? 컴퓨터가 해석해야

11

의사코드

의사코드(pseudo code)

• 프로그래밍 언어보다 직관적이고 형식이 자유로운 표기 체계(가공의 언어)

• 알고리즘 개발 과정에서 생각들을 보다 자유로운 형식으로 표현할 수있는 표기 체계

• 사람만 이해할 수 있으면 된다

알고리즘 표기 시에는 주로 의사코드 사용 -> 왜?

• 프로그래밍 언어로 쓰면 너무 힘들다

- 생각을 방해한다

• 특정 프로그래밍 언어에 종속되지 않으면서 여러 프로그래밍 언어에서구현 가능

12

의사코드 프리미티브

배정문

• 이름 = 식

조건선택

• if (조건):활동

• if (조건):활동

else:활동

-

if (해당 연도가 윤년):1일 합계 = 합 / 366

else:1일 합계 = 합 / 365

if (판매액이 감소하였음):가격을 5%만큼 낮추어라

RemainingFunds = CheckingBalance + SavingsBalance

13

의사코드 프리미티브

들여쓰기는 중첩된 조건을 표시한다

반복실행

• while (조건): 본체

while (판매할 티켓이 남아있음):한 장의 티켓을 판다

if (비가 오지 않음):if (기온 == 높음):

수영하러 간다else:

골프를 한다else:

TV를 본다

14

의사코드 프리미티브

함수 정의

• def 이름():

함수 실행

def ProcessLoan():

if (...):ProcessLoan()

else:RejectApplication()

15

의사코드 프리미티브

의사코드로 작성된 Greetings 함수

def Hello():Count = 3while (Count > 0):

print('Hello')Count = Count - 1

16

의사코드 프리미티브

매개변수

• def Sort(List):..

// 각기 다른 리스트에 대한 Sort 실행

Sort(단체의 회원 명부)

Sort(결혼식 하객 명부)

6.2 반복 구조

18

반복 구조

사전 테스트 루프:

while (조건):본체

19

반복 구조

사후 테스트 루프:

repeat:본체until (조건)

20

루프 제어의 구성요소들

초기화

• 종료 조건으로 이행되어갈 초기 상태를 확립

테스트

• 현재 상태와 종료 조건을 비교하고 이들이 같으면 반복을 종료

변경

• 종료 조건을 향해 이행되도록 상태를 변화

count = 1;

while (count != 5)

print(count)

count = count + 1

21

순차 검색 알고리즘

순차 검색(Sequential Search) 알고리즘

• 리스트에서 특정 값이 나타나는지 검색하는 알고리즘

• 항목들을 리스트에 나타나는 순서대로 비교

문제) n개의 항목을 가지고 있는 배열 L 에서 값 x 검색

• 이 때 값은 오름차순으로 정렬되어 있다고 가정

• x 를 성공적으로 찾으면 x 의 인덱스를 리턴x 를 찾지 못하면 -1 리턴

• x = 8이면? return 3

• x = 2이면? return -1

1 3 6 8 9L : n = 5

0 1 2 3 4

22

순차 검색 알고리즘

가장 간단한 방법: 하나하나 비교한다

• 주의: n은 정해진 값이 아니다

input: array L, integer n, integer xoutput: integer indexindex := 0; while (index < n and L[index] x) do

(index := index + 1)if (index = n) then (index := -1)return index

23

순차 검색 알고리즘

x = 8일 경우

index = 0L[index] = 1index = 1L[index] = 3 index = 2L[index] = 6index = 3 L[index] = 8

while loop 끝return 3

1 3 6 8 9L : n = 5

0 1 2 3 4

24

순차 검색 알고리즘

x = 2일 경우

1 3 6 8 9L : n = 5

0 1 2 3 4index = 0L[index] = 1index = 1 L[index] = 3 index = 2L[index] = 6index = 3L[index] = 8index = 4L[index] = 9index = 5

while loop 끝index = n 이므로,return -1

25

순차 검색 알고리즘

앞의 방법은 L의 특성을 사용하지 못함

• 그래서, 비효율적

• L에는 숫자가 순서대로 들어 있음

반면에, 무작위로 나열된 숫자에 대해서도 쓸 수 있는 장점

• ⇒ 실제로 순차 검색이 쓰이는 이유

또, L이 비어 있는 경우도 체크해야

26

순차 검색 알고리즘

A better version

if (n < 1) then (return -1)index := 0;while (index < n and L[index] x) do

if (x = L[index]) then (return index)index := index + 1

return -1

27

순차 검색 알고리즘

x = 8일 경우

index = 0L[index] = 1index = 1L[index] = 3 index = 2L[index] = 6 index = 3 L[index] = 8

return 3

1 3 6 8 9L : n = 5

0 1 2 3 4

28

순차 검색 알고리즘

x = 2일 경우

index = 0L[index] = 1index = 1L[index] = 3L[index] > x 이므로,

return -1

1 3 6 8 9L : n = 5

0 1 2 3 4

29

순차 검색 알고리즘

x = 2일 경우

index = 0L[index] = 1index = 1L[index] = 3L[index] > x 이므로,

return -1

1 3 6 8 9L : n = 5

0 1 2 3 4

30

순차 검색 알고리즘

순차 검색 알고리즘을 나타내는 의사코드

def Search(List, TargetValue):

if (List가 비어 있음):

검색의 실패를 선언한다.

else:

List 안의 첫 번째 항목을 TestEntry로 선택한다.

while (TargetValue > TestEntry이고 비교할 항목이 남아있음):

List 안의 다음 항목을 TestEntry로 선택한다.

if (TargetValue == TestEntry):

검색의 성공을 선언한다.

else:

검색의 실패를 선언한다.

31

Sort 정렬(整列)

문제 정의

• 데이타들이 주어졌을 때, 전체 데이타를 순서대로 배치

주어진 단어들을 사전 순으로 정렬(sort)

• 시작: Fred Alex Diana Byron Carol

• 완료: Alex Byron Carol Diana Fred

순서?

• 두 개의 데이터가 주어지면, 어느 쪽이 큰 지를 정의해야

• 사전 순서: A < B < C < D ...

32

삽입 정렬 알고리즘

리스트(list) 항목을알파벳 순으로정렬하기

33

삽입 정렬 알고리즘

일반화시키면..

• 리스트에서 정렬되지 않은 부분의 첫 번째 이름을 꺼내고,

• 이 이름보다 큰 이름들을 아래쪽으로 이동하고,

• 아까 꺼낸 이름을 빈자리에 다시 삽입

의사코드로 나타내면..

이를 반복적으로 실행

기준 항목을 임시 공간에 옮겨 List에 빈자리를 만든다

while (빈자리 위쪽에 이름이 있고 그 이름은 기준 항목보다 큼):

빈자리 위쪽의 이름을 빈자리로 옮겨 그 이름 위에 빈자리를 만든다

기준 항목을 List 의 빈자리로 옮긴다

34

삽입 정렬 알고리즘

의사코드로 표현된 삽입 정렬 알고리즘

def Sort (List):

N = 2

while (N의 값이 List의 길이 이하임):

List의 N 번째 항목을 기준 항목으로 선택

기준 항목을 임시 공간에 옮겨 List에 빈자리를 만든다

while (빈자리 위쪽에 이름이 있고 그 이름은 기준 항목보다 큼):

빈자리 위쪽의 이름을 옮겨 그 이름 위에 빈자리를 만든다

기준 항목을 List의 빈자리로 옮긴다

N = N + 1

6.3 재귀 구조

36

재귀 구조

재귀법(recursion)

• 한 프로시저를 실행하면 그 안에서 다시 동일한 프로시저의 실행으로이어짐

• 동일한 프로시저에 대한 여러 개의 호출이 중첩되며, 이 중 한 개의호출본에 대해 진행이 이루어지고, 나머지 호출본들은 다른 호출본들이완료되기를 기다림

루프와 재귀

• 루프 : 반복되는 명령 집합을 끝내고 다시 반복하는 방식

• 재귀에서는 명령 집합을 원래 작업의 부분 작업으로서 반복

재귀 시스템

• 일종의 반복적인 프로세스

• 적절한 제어가 중요!

• 종료조건에 대한 테스트와 종료조건에 도달하도록 보장하는 설계가 중요!

37

이진 검색 알고리즘

리스트가 정렬되어 있을 때 특정 항목을 찾는 문제

• 리스트에서 John이라는 항목을 검색하기 위한 전략의 적용

문제 해결의 발판

• 사전을 검색할 때사용되는 프로시저를생각해본다

38

이진 검색 알고리즘

방법

• 항상 리스트의 "중앙"에서 검색 시작

- 이 문제에서 "중앙"은 리스트 후반부의 첫번째 항목이라 가정

• 리스트 중앙 항목이 목표값일 경우, 검색 성공!

• 그렇지 않으면,

- 목표값이 지금 비교한 항목보다 작은지 또는 큰지에 따라 리스트의 전반부또는 후반부로 검색 범위를 제한

- 리스트의 남은 부분에 대하여서도 남은 리스트 부분의 "중앙" 항목을 다음검사 항목으로 선택

- 목표값이 원래 리스트에 들어 있지 않을 경우 검색범위가 리스트의 구간으로좁혀질 때까지 문제의 리스트를 작은 구간으로 계속 분할

- 빈구간이 될 때까지 반복 : 빈 구간이 나타나면 검색은 실패!

39

이진 검색 알고리즘

0 n-1index = (n-1)/2

x = L[index] ?x < L[index] x > L[index]

0 (n-1)/2-1index (n-1)/2+1 n-1index

40

이진 검색 알고리즘

이 과정을 되풀이하다가, 하나만 남았을 때:

• array의 시작도 끝도 모두 index와 일치

• x = L[index] : 찾았다!

• x < L[index] : array끝을 index-1로 -> 빈 array

• x > L[index] : array시작을 index+1로 -> 빈 array

index index index

41

이진 검색 알고리즘

의사코드로 표현한 이진 검색 알고리즘 초안

if (List가 비어 있음):

검색 실패를 보고한다.

else:

TestEntry = List 안의 "중앙" 항목

if (TargetValue == TestEntry):

검색 성공을 보고

if (TargetValue < TestEntry):

TargetValue에 대해 TestEntry 앞의 List 부분에 Search()를적용하고, 검색 결과를 보고

if (TargetValue > TestEntry):

TargetValue에 대해 TestEntry 뒤의 List 부분에 Search()를적용하고, 검색 결과를 보고

42

이진 검색 알고리즘을 재귀로 풀기

TestEntry = List 내의 "중앙" 항목

TargetValue < TestEntry

TestEntry

Search(List, TargetValue)

Search(Sublist, TargetValue) Search(Sublist, TargetValue)

Sublist = TestEntry 앞의 List 부분 Sublist = TestEntry 뒤의 List 부분

TargetValue > TestEntry

TestEntry

43

이진 검색 알고리즘을 재귀로 풀기

의사코드로 표현한 재귀구조인 이진 검색 알고리즘

def Search (List, TargetValue):

if (List가 비어 있음):

검색 실패를 보고

else:

TestEntry = List 안의 “중앙” 항목

if (TargetValue == TestEntry):

검색 성공을 보고

if (TargetValue < TestEntry):

Sublist = TestEntry 앞의 List 부분

Search(Sublist, TargetValue)

if (TargetValue > TestEntry):

Sublist = TestEntry 뒤의 List 부분

Search(Sublist, TargetValue)

6.4 효율성과 정확성

45

알고리즘 효율성

효율성(efficiency) : 알고리즘이 얼마나 좋은가의 척도

• 끊임없이 알고리즘을 개발하는 이유

• 당연히 더 효율적인(efficient) 알고리즘 사용

예: 100명의 이름 중에서 검색(search)하라

• 순차 검색(sequential search): 평균 50개는 찾아야

• 이진 검색(binary search): 7번만에 찾는다

46

알고리즘 효율성

최악의 상황에서의 삽입정렬의 적용

47

알고리즘 효율성

삽입 정렬 알고리즘에 대한 최악 경우 분석 그래프

48

알고리즘 효율성

이진 검색 알고리즘에 대한 최악 경우 분석 그래프

49

소프트웨어 검증

검증(Verification) : 과연 좋은 알고리즘인가 검사

• 예: 금 목걸이 문제

- 한 번은 반드시 끊어야 한다

- 세 번 끊었다. : 더 좋은 알고리즘이 가능

- 한 번만 끊었다. : 가장 좋은 알고리즘

✓ 어떤 여행자가 7개의 고리로 된 황금 사슬을 가지고 있다

✓ 이 여행자가 외딴 호텔에서 7일 밤을 지내야 한다

✓ 매일 밤 숙박료로 사슬 고리 한 개를 주어야 한다

✓ 숙박료를 미리 내는 일 없이 매일 아침 호텔에 숙박료를 내기 위해 끊어야 할 고리의 최소 개수는 몇 개인가?

50

소프트웨어 검증

3번 끊어 사슬 분리하기

1번만 끊는 사슬 문제 해법

51

소프트웨어 검증

정확성에 대한 증명

• 명제(assertion)

- 디버깅(debugging)의 한 방법

- 프로그램 내에서 어느 위치에서는 꼭 성립해야 하는 expression을 넣는 기법

• 참고: C의 <assert.h>

- assert(first < last);

- first < last 이면: nothing

- first >= last 이면: error message 출력Assertion failed: 'first < last'

테스트 : error가 없는가 검사

• 흔히, 프로그램을 작성하지 않은 사람이 검사

• 예: alpha version, beta version