1. 알고리즘의 정의(레시피의 비유)
- 알고리즘은 문제를 해결하기 위한 방법, '레시피'
- 레시피의 실행 주체는 사람, 알고리즘의 실행 주체는 컴퓨터(기계)
-> 구체적 기술이 필요
* 안 중요한 내용
영어: Algorithm
'thm'이니까 따지면 알고리'듬'이 맞는데 일본의 영향을 받아 알고리즘이라고 하는 듯.
(일본에서는 Algorithm을 アルゴリズム(아르고리즈무)라고 읽는다.)
2. 문제
- 주어진 입력에 대한 출력의 명확하고 정확한 명세
Ex) 자연수 x와 y가 주어질 때 x×y
3. 컴퓨터
- '컴퓨터'를 하나의 Computation model로 생각할 수 있다.
- 컴퓨터마다 연산 속도(또는 performance)는 다르지만 제공되는 연산은 거기서 거기
4. 문제를 해결하려면(알고리즘을 구상하려면)
① 해결해야 하는 문제가 무엇인지 명확하고 정확히 주어져야 함
② 어떤 computation model을 사용해 문제를 해결할 것인지 명확히 정해져야 함
- 알고리즘을 기술하기 전에 문제를 명확히 서술할 수 있어야 함
- 알고리즘은 주어진 입력에 대해 올바른(문제를 해결하는) 출력을 하게 되는 연산들의 sequence(와 제어문)
- "주어진 값 -> 결과"라는 면에서 '함수'의 관점으로도 이해해볼 수 있다.
Ex) f(x,y)=xy가 나오려면 함수 f안에서 어떤 일이 일어나야 할까?
5. Example: 곱셈, 정렬
① Long mutiplcation problem
- (한 자리 수) X (한 자리 수) 하는 법(구구단)을 배우면 10000자리 수의 곱셈도 할 수 있다(자릿수가 늘어나도 적용 가능).
- 구구단도 '알고리즘'이다.
② 다른 곱셈의 방법
x=∑m−1i=0X[i]⋅10iandy=∑n−1j=0Y[j]⋅10j
z=xy=∑m+n−1k=0X[k]⋅10k
x⋅y=∑m−1i=0∑n−1j=0X[i]⋅Y[j]⋅10i+j
Ex) 386×504
386×504
=(3×102+8×101+6×1)⋅(5×102+0×101+4×1)
=15×104+0+12×102+40×1030+32×101+30×102+0+24
③ Lattice mutiplication(<L'Arte dell'Abbaco>(1458) 참고)


ⅰ) 피제수는 표의 위에, 제수는 오른쪽에 한 칸에 한 자리씩 쓴다
ⅱ) 각 행렬의 칸을 나눈 후 i열과 j행의 수를 곱해 십의 자리 수는 빗금의 위에, 일의 자리 수는 빗금의 아래에 쓴다.
Ex) 행렬의 1행 1열에는 9×3=27에서 빗금의 위는 2, 아래는 7이 된다.
ⅲ) 대각선 기준으로 맨 끝 칸(3행 3열)부터 시작해 더해 나간다.
위 그림에서는 6부터 시작해 (6),(4,1,2),(2,0,3,1,6),⋯,(2)의 각 대각선 합을 대각선의 끝에 쓴다.
즉 다음과 같이 된다.

더해서 두 자리수가 되는 경우 십의 자리 수는 그 다음으로 넘긴다.
즉 위 그림에서 (2,0,3,1,6)의 합은 12이므로 이는 그 다음 합인 (1,9,0,9,3)으로 넘긴다.
그러면 (1,9,0,9,3)의 합은 1+9+0+9+3+1=23이 되므로 2를 다음 합인 (0,7,0)으로 넘긴다.
이 과정을 반복한 후 왼쪽부터 아래의 수를 차례로 읽으면 곱셈의 결과인 293276이 된다.
④ Peasant multiplication
xy를 구할 때 x는 계속 2로 나누고 y는 2로 곱하되 x가 홀수면 y를 축적해 구하는 방법

x가 홀수일 때 x를 2로 나누고 나머지를 버리면 (y+y)×0.5=y를 버리게 되므로
홀수일 때는 ⌞x/2⌟⋅(y+y)+y가 된다.
⑤ 곱셈 알고리즘
- Long multiplication
- Lattice multiplication
- Peasant multiplication
이외에도 수많은 곱셈 알고리즘이 알려져 있다.
-> 어떤 방법으로 목적을 해결했다고 해서 그 방법이 유일한 것이 아니다.
: 한 가지 문제에 대해 여러 개의 알고리즘이 존재한다.
⑥ 정렬
- Insertion sort
- Selection sort
- Bubble sort
- Merge sort
- Quick sort
- ...
->곱셈과 마찬가지로 어떤 방법으로 목적을 해결했다고 해서 그 방법이 유일한 것이 아니다.
7. 알고리즘 기술(記述)
알고리즘에 대한 충분한 설명은
- What: 어떤 문제를 해결하는가?
- How: 어떻게 문제를 해결하는가? (알고리즘의 절차가 무엇인가?) (★ 이 항목이 핵심이긴 함)
- Why: 왜 그렇게 해결되는가? (실제로 그 문제가 정확히 해결됨을 증명한다)
- How fast: 시간이 얼마나 걸리는가? (효율성)
를 포함해야 한다.
알고리즘은 여러 방식으로 기술할 수 있다.
- 자연어: 사람의 언어 Ex) 수식: 수학 공식도 간단한 알고리즘(식 하나로 나타낼 수 있는 알고리즘)이다!
- pseudocode: 프로그래밍 언어를 닮아 직관적, 특정 언어에 얽매이지 않고 자유롭게
- Programming language(C, Java, ...): 가장 형식적이고 정확하나 이해하기 어려움
- 보고 코드로 짤 수 있으면 ㅇㅋ -> 짜여진 코드도 하나의 알고리즘이라고 할 수 있다
목적에 맞게 골라 쓰자.
* 왜 유사코드를 자주 쓰는가?
- 어느 부분은 대충 말로, 어느 부분은 코드처럼 쓴 유사코드는 프로그래밍 언어로 옮기기 쉬워진다.
- 자연어와 코드 사이의 가교 역할: 말로 'xy 값을 구해라'라고만 하면 코드로 옮기기가 어려워짐
- 이해하기 쉽지만 코드로 옮기기 어려운 자연어와 정확하지만 이해하기 어려운 프로그래밍 언어의 중간다리 역할
유사코드는 여러 언어로 바꿔 쓸 수 있다. 그러나 언어 A로 작성한 코드를 언어 B로 바꾸려면 '번역'이 필요하다.
그래서 프로그래밍 언어보다는 유사코드를 자주 쓴다.
8. 알고리즘 분석
"알고리즘 분석"이라 하면 보통 다음의 두 가지를 의미
① Correctness Proof
- 증명: 주어진 알고리즘이 정말 목적으로 하는 문제를 올바른 출력을 도출하는가?
주로 수학적 귀납법을 활용
② Running Time Analysis - 시간복잡도 분석
알고리즘을 짤 때 보통 효율성(어떻게 하면 더 빨리 해결할 수 있는가)을 고민한다.
-> 그 알고리즘을 실행해 문제를 해결하기까지 얼마나 걸리는가?
* 왜 시간복잡도 분석인가?
가장 좋은 건 코드를 짜서 돌려보고 시간을 측정하는 것이나 한계가 있다.
Ex) 10만 개의 data를 정렬하는 시간은 얼마나 걸릴까?
하지만 실행 시간을 알고 코드를 돌리는 것과 모르고 돌리는 것은 좀 다름
시간복잡도 분석: 코드를 짜지 않고 분석한다.
- 특정 문제에 대한 해결방법은 여러 가지가 존재한다.
-> 그 중 최선을 무엇인가?
- 시간복잡도: 소요 시간
- 공간복잡도: 메모리 사용량
- 그 외: Cache fault, IO 연산 횟수 등
구현해서 실제로 돌리면 분석 시간이 너무 오래 걸림...
-> '이 코드는 이 정도 걸리겠구나'를 이론적으로 분석
Ex) n자리 정수 x와 m자리 정수 y의 곱을 계산할 때 Long multiplication은 총 몇 번의 자리 수 곱셈을 해야 하는가?
-> 대략 n×m회 -> O(nm)
Ex) Bubble sort는 총 몇 번의 비교 및 대입 연산을 해야 하는가?(정렬에서 제일 중요한 연산)
-> O(n2) (n2에 비례)
요약)
Problem
Algorithm for a problem
Describing and algorithm: Recursion, Divide-and-conquer, Dynamic programming, Greedy, ...
- 무슨 문제에 관한 것인가
- 어떻게 동작하는가
Analysis of an algorithm: 시간 복잡도 분석, Induction(수학적 귀납법), ...
- Correntness: 올바르게 동작하는가
- Complexity: 얼마나 효율적인가
'강의노트 > 알고리듬' 카테고리의 다른 글
[알고리듬] 4주차: Divide-and-Conquer (0) | 2021.03.24 |
---|---|
[알고리듬] 3주차: Homework#1 (0) | 2021.03.21 |
[알고리듬] 3주차: Recursion - Mergesort, Quicksort (0) | 2021.03.17 |
[알고리듬] 2주차: 정렬 (0) | 2021.03.15 |
[알고리듬] 2주차: 시간복잡도 (0) | 2021.03.15 |