6.1 하노이 타워
하노이 타워는 대표적인 재귀 알고리즘입니다.
하노이 타워 알고리즘은 n 개의 돌을 이동시키는 문제입니다. 세 개의 기둥이 있고 하나의 기둥에 n 개의 돌이 크기 순으로 있습니다. 한 번에 하나의 돌을 이동할 수 있고 작은 돌 위에 큰 돌이 올 수 없습니다. 이와 같은 규칙을 이용하여 n 개의 돌이 있는 기둥에서 다른 기둥으로 모든 돌을 옮기는 문제입니다.
이 문제를 재귀적으로 해결하면 다음처럼 해결할 수 있습니다.
가정: n-1개의 돌을 옮길 수 있다.
가정에 의해 먼저 A에 있는 n-1개의 돌을 C를 이용하여 B로 옮깁니다.
규칙에 의해 1개의 돌을 A에서 C로 옮깁니다.
가정에 의해 B에 있는 n-1개의 돌을 A를 이용하여 C로 옮깁니다.
따라서 n개의 돌을 옮길 수 있습니다.
의사코드(pseudo code)로 나타내면 다음처럼 표현할 수 있습니다. 탈출 조건을 표현하고 있음을 확인하세요.
Hanoi(src, use, dest, n)
조건 n<=0
종료
Hanoi(src,dest,use,n-1)
Move(src,dest)
Hanoi(use,src,dest,n-1)
재귀 호출하면 이전보다 n을 1 감소하므로 탈출 조건에 근접함을 알 수 있습니다.
하노이 타워 알고리즘을 구현합시다.
#include <iostream>
#include <string>
using namespace std;
알고리즘은 입력 인자로 세 개의 기둥과 돌의 개수를 받아야 합니다.
void Hanoi(string src, string use, string dest, int n)
{
돌이 없을 때는 아무것도 수해하지 않고 알고리즘을 끝냅니다. 즉 탈출 조건입니다.
if(n<=0) //돌이 없을 때
{
return;
}
n-1개의 돌을 src에서 dest를 이용하여 use로 옮깁니다.
Hanoi(src,dest,use,n-1); //n-1 개의 돌을 src에서 dest를 이용하여 use로 이동
src에 있는 돌을 dest로 옮깁니다.
cout<<"move "<<src<<" -> "<<dest<<endl; //scr에서 dest로 이동
use에 있는 n-1개의 돌을 src를 이용하여 dest로 옮깁니다.
Hanoi(use,src,dest,n-1); //n-1개의 돌을 use에서 src를 이용하여 dest로 이둉
}
int main()
{
Hanoi("a","b","c",3);
return 0;
}
▷ 실행 결과
move a -> c
move a -> b
move c -> b
move a -> c
move b -> a
move b -> c
move a -> c
6.1.1 하노이 타워 성능 분석
하노이 타워 알고리즘 성능을 분석해 보기로 해요. n개 돌을 옮기는 데 걸리는 시간을 T(n)이라고 합시다.
하노이 타워 알고리즘의 수행 시간 T(n)은 T(n-1) 2번과 Move 1번으로 진행합니다.
T(n) = 2*T(n-1) + 1 = 2 *T(n-2) + 2 +1 = 2^2*T(n-3) +4+2+1 = ... = 2^n -1
따라서 하노이 타워 알고리즘 수행 시간은 O(2^n)이라고 말할 수 있습니다.
다음은 속도를 측정하기 위해 수정한 코드입니다.
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
void Hanoi(string src, string use, string dest, int n)
{
if(n<=0) //돌이 없을 때
{
return;
}
Hanoi(src,dest,use,n-1); //n-1 개의 돌을 src에서 dest를 이용하여 use로 이동
cout<<"move "<<src<<" -> "<<dest<<endl; //scr에서 dest로 이동
Hanoi(use,src,dest,n-1); //n-1개의 돌을 use에서 src를 이용하여 dest로 이둉
}
int main()
{
clock_t st,et;
알고리즘을 수행 전 시간을 측정하세요.
st = clock();
Hanoi("a","b","c",5);
알고리즘을 수행 후 시간을 측정한 후에 수행 전과의 차이를 계산하세요.
et = clock();
cout<<"5 개일 때 걸린 시간:"<<et-st<<endl;
똑같은 방법으로 수행 시간을 측정하세요. 이번에는 8개의 돌을 옮기게 할게요.
st = clock();
Hanoi("a","b","c",8);
et = clock();
cout<<"8 개일 때 걸린 시간:"<<et-st<<endl;
return 0;
}
▷ 실행 결과
move a -> c
...중략...
move a -> c
5 개일 때 걸린 시간:44
move a -> b
...중략...
move b -> c
8 개일 때 걸린 시간:364
결과를 보면 돌의 개수가 3개 늘었을 때 걸린 시간은 8배 이상 차이가 나는 것을 확인할 수 있습니다.
'언어 자료구조 알고리즘 > [C++]디딤돌 자료구조와 알고리즘' 카테고리의 다른 글
7.2 이진 탐색 트리(Binary Search Tree) 개요 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
---|---|
7.1 트리의 용어 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
7. 이진 탐색 트리 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
6.3 이진 탐색(Binary Search) [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
6.2 퀵 정렬(Quick Sort) [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
6. 재귀 알고리즘 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
5. list 만들기 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
4. vector 만들기 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
3.5 큐를 이용한 스케쥴러 시뮬레이션 [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |
3.4 큐(Queue) [디딤돌 자료구조와 알고리즘 with C++] (0) | 2016.04.04 |