You are looking for information, articles, knowledge about the topic nail salons open on sunday near me 하노이 탑 알고리즘 on Google, you do not find the information you need! Here are the best content compiled and compiled by the toplist.fordvinhnghean.com team, along with other related topics such as: 하노이 탑 알고리즘 하노이탑 알고리즘 재귀, 하노이의 탑 게임, 하노이탑 규칙, 하노이탑 재귀, 하노이탑 코딩, 하노이탑 문제, 하노이 탑 전설, 하노이탑 점화식
Table of Contents
‘하노이의 탑’ 이해하기 – Parkito’s on the way
- Article author: shoark7.github.io
- Reviews from users: 1443
Ratings
- Top rated: 4.0
- Lowest rated: 1
- Summary of article content: Articles about ‘하노이의 탑’ 이해하기 – Parkito’s on the way 개인적으로 재귀 를 사용한 프로그래밍을 매우 좋아하는데, ‘하노이의 탑’은 재귀를 연습하기에 매우 좋은 연습문제다. 아마 학교에서도 알고리즘 초급 … …
- Most searched keywords: Whether you are looking for ‘하노이의 탑’ 이해하기 – Parkito’s on the way 개인적으로 재귀 를 사용한 프로그래밍을 매우 좋아하는데, ‘하노이의 탑’은 재귀를 연습하기에 매우 좋은 연습문제다. 아마 학교에서도 알고리즘 초급 … ‘하노이의 탑’ 문제를 이해하고 문제 해결을 위한 핵심 통찰을 살핀 뒤 코드로 작성합니다. 이후 탑의 개수에 따른 총 이동 횟수를 구하는 일반항까지 수학적으로 유도합니다.
- Table of Contents:
0 Index
1 들어가며
2 하노이의 탑
3 아이디어 얻기
4 실제 코드
5 번외 원반의 개수에 따른 총 이동횟수 구하기
6 마치며
7 자료 출처

하노이탑 알고리즘
- Article author: brunch.co.kr
- Reviews from users: 15423
Ratings
- Top rated: 3.6
- Lowest rated: 1
- Summary of article content: Articles about 하노이탑 알고리즘 원반이 3개라면 총 7번을 옮겨야 한다. 마찬가지로 n이 커지면 -1은 큰 의미가 없으므로 하노이탑 알고리즘의 계산 복잡도는 O(2n)으로 표현할 수 있다. …
- Most searched keywords: Whether you are looking for 하노이탑 알고리즘 원반이 3개라면 총 7번을 옮겨야 한다. 마찬가지로 n이 커지면 -1은 큰 의미가 없으므로 하노이탑 알고리즘의 계산 복잡도는 O(2n)으로 표현할 수 있다. 30층짜리 하노이탑을 옮기려면 무려 34년간을 쉬지도 않고 옮겨야 한다. | 하노이탑을 옮기려면 원반을 모두 (2의 n승)-1번만큼 옮겨야 한다. 원반이 3개라면 총 7번을 옮겨야 한다. 마찬가지로 n이 커지면 -1은 큰 의미가 없으므로 하노이탑 알고리즘의 계산 복잡도는 O(2n)으로 표현할 수 있다. 이는 2를 n번 제곱한 값이므로 n이 커짐에 따라 값이 기하급수적으로 증가한다. 그래서 원반 하나를 옮기는 데 1초가 걸린다고 가정
- Table of Contents:
‘하노이의 탑’ 이해하기 (feat. 재귀 함수)
- Article author: mgyo.tistory.com
- Reviews from users: 33580
Ratings
- Top rated: 4.2
- Lowest rated: 1
- Summary of article content: Articles about ‘하노이의 탑’ 이해하기 (feat. 재귀 함수) 백준 11729번 문제에 관한 내용으로, 이번 내용은 ‘하노이의 탑’ 알고리즘이다. ‘하노이 의 탑’은 재귀를 연습하기에 매우 좋은 연습문제다. …
- Most searched keywords: Whether you are looking for ‘하노이의 탑’ 이해하기 (feat. 재귀 함수) 백준 11729번 문제에 관한 내용으로, 이번 내용은 ‘하노이의 탑’ 알고리즘이다. ‘하노이 의 탑’은 재귀를 연습하기에 매우 좋은 연습문제다. 들어가며 하노이의 탑 문제 소개 문제 정의 아이디어 얻기 아이디어 재귀 출발점, 도착점, 경유점 문제 분해 실제 코드 번외 : 원반의 개수에 따른 총 이동횟수 구하기 마무리 자료 출처 https://www.acmicpc.net/..
- Table of Contents:
댓글
이 글 공유하기
다른 글
[이코테] Chapter3-4 1이 될 때까지(그리디) [이코테] Chapter3-3 숫자 카드 게임(그리디)파이썬 변수의 유효 범위 (전역 변수 지역 변수) – global
[백준] 2447번 별찍기 문제 재귀 함수 이용해서 풀기티스토리툴바

하노이의 탑 (개념 이해하기) | 알고리즘 | Khan Academy
- Article author: ko.khanacademy.org
- Reviews from users: 44816
Ratings
- Top rated: 4.7
- Lowest rated: 1
- Summary of article content: Articles about 하노이의 탑 (개념 이해하기) | 알고리즘 | Khan Academy 재귀에 관한 수업을 다 마쳤다면 이제 재귀 과정을 여러번 거쳐 푸는 다른 문제에 대해 알아봅시다. 이는 하노이 탑이라고 불리는 문제입니다. …
- Most searched keywords: Whether you are looking for 하노이의 탑 (개념 이해하기) | 알고리즘 | Khan Academy 재귀에 관한 수업을 다 마쳤다면 이제 재귀 과정을 여러번 거쳐 푸는 다른 문제에 대해 알아봅시다. 이는 하노이 탑이라고 불리는 문제입니다.
- Table of Contents:
하노이의 탑
하노이의 탑
사이트 탐색
[알고리즘 기본] 하노이 탑 알고리즘
- Article author: velog.io
- Reviews from users: 34201
Ratings
- Top rated: 4.1
- Lowest rated: 1
- Summary of article content: Articles about [알고리즘 기본] 하노이 탑 알고리즘 세부 규칙 · 크기가 다른 원반 n개를 시작 기둥에서 도착 기둥으로 모두 옮겨야 한다. · 원반은 한 번에 한 개씩만 옮길 수 있다. · 원반을 뽑을 땐 기둥의 … …
- Most searched keywords: Whether you are looking for [알고리즘 기본] 하노이 탑 알고리즘 세부 규칙 · 크기가 다른 원반 n개를 시작 기둥에서 도착 기둥으로 모두 옮겨야 한다. · 원반은 한 번에 한 개씩만 옮길 수 있다. · 원반을 뽑을 땐 기둥의 … 하노이 탑 알고리즘
- Table of Contents:
알고리즘 기본
게임 설명
세부 규칙
풀이
파이썬 코드 구현 및 실행
점화식
시간 복잡도
관련 문제
![[알고리즘 기본] 하노이 탑 알고리즘](https://velog.velcdn.com/images/bky373/post/44da1063-89bd-4b2a-9fe7-b774fa701306/Algorithm._basics_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98_%EA%B8%B0%EC%B4%88.png)
재귀 (3) – 하노이 탑 (Tower of Hanoi)
- Article author: gusdnd852.tistory.com
- Reviews from users: 15278
Ratings
- Top rated: 4.7
- Lowest rated: 1
- Summary of article content: Articles about 재귀 (3) – 하노이 탑 (Tower of Hanoi) 1. 알고리즘 개요 … 하노이의 탑은 3개의 기둥과 크기가 각각 다른 N개의 원판이 주어졌을 때 1번 기둥의 모든 원판을 3번 기둥으로 옮기는 일종의 퍼즐 … …
- Most searched keywords: Whether you are looking for 재귀 (3) – 하노이 탑 (Tower of Hanoi) 1. 알고리즘 개요 … 하노이의 탑은 3개의 기둥과 크기가 각각 다른 N개의 원판이 주어졌을 때 1번 기둥의 모든 원판을 3번 기둥으로 옮기는 일종의 퍼즐 … 1. 알고리즘 개요 하노이의 탑은 3개의 기둥과 크기가 각각 다른 N개의 원판이 주어졌을 때 1번 기둥의 모든 원판을 3번 기둥으로 옮기는 일종의 퍼즐게임이다. 원판을 옮기기 위해 2번 기둥을 사용할 수 있고, 작..
- Table of Contents:
재귀 (3) – 하노이 탑 (Tower of Hanoi)
티스토리툴바

자꾸 생각나는 체리쥬빌레 :: [알고리즘] 하노이의 탑 알고리즘 이해 돕기 | 재귀함수 과정
- Article author: splendidlolli.tistory.com
- Reviews from users: 13125
Ratings
- Top rated: 4.2
- Lowest rated: 1
- Summary of article content: Articles about 자꾸 생각나는 체리쥬빌레 :: [알고리즘] 하노이의 탑 알고리즘 이해 돕기 | 재귀함수 과정 하노이의 탑 알고리즘 이해 돕기 하노이의 탑은 크게 어렵지 않고 간단해서 초보자도 설명을 차근히 읽어본다면 이해하기 어렵지 않다. …
- Most searched keywords: Whether you are looking for 자꾸 생각나는 체리쥬빌레 :: [알고리즘] 하노이의 탑 알고리즘 이해 돕기 | 재귀함수 과정 하노이의 탑 알고리즘 이해 돕기 하노이의 탑은 크게 어렵지 않고 간단해서 초보자도 설명을 차근히 읽어본다면 이해하기 어렵지 않다. 하노이의 탑 알고리즘 이해 돕기 하노이의 탑은 크게 어렵지 않고 간단해서 초보자도 설명을 차근히 읽어본다면 이해하기 어렵지 않다. 하지만 내 기준에서 ‘코드를 이렇게 설명하면 더 좋은 이해가 될 것 같다’라..
- Table of Contents:
네비게이션
[알고리즘] 하노이의 탑 알고리즘 이해 돕기 재귀함수 과정사이드바
검색
티스토리툴바
![자꾸 생각나는 체리쥬빌레 :: [알고리즘] 하노이의 탑 알고리즘 이해 돕기 | 재귀함수 과정](https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeaXzo3%2Fbtq895rA1hv%2FmlmqBV915JZKT3PbnbZKy1%2Fimg.png)
[ 알고리즘 ] 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 (C언어)
- Article author: bite-sized-learning.tistory.com
- Reviews from users: 46345
Ratings
- Top rated: 4.9
- Lowest rated: 1
- Summary of article content: Articles about [ 알고리즘 ] 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 (C언어) [ 알고리즘 ] 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 (C언어). hahehohoo 2020. 7. 9. 00:04. 320×100. …
- Most searched keywords: Whether you are looking for [ 알고리즘 ] 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 (C언어) [ 알고리즘 ] 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 (C언어). hahehohoo 2020. 7. 9. 00:04. 320×100. C언어로 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 하노이 타워 문제는 1883년 프랑스 수학자에 의해 처음 소개되었습니다. 하나의 막대에 쌓여 있는 원반을 다른 막대에 그대로 옮겨야 하는..프로그래밍
- Table of Contents:
태그
관련글
댓글1
최근글
인기글
전체 방문자
최근댓글
태그
티스토리툴바
![[ 알고리즘 ] 하노이 타워(The Tower of Hanoi) 재귀 함수로 구현하기 (C언어)](https://img1.daumcdn.net/thumb/R800x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2ZF1e%2FbtqFuiH4nIB%2FFUbsqmj1qOSpjUO4wX2nkK%2Fimg.png)
See more articles in the same category here: 852+ tips for you.
‘하노이의 탑’ 이해하기
‘하노이의 탑’ 이해하기
0. Index
1. 들어가며
오늘 다룰 포스트는 ‘하노이의 탑’ 알고리즘이다. 개인적으로 재귀 를 사용한 프로그래밍을 매우 좋아하는데, ‘하노이의 탑’은 재귀를 연습하기에 매우 좋은 연습문제다. 아마 학교에서도 알고리즘 초급 수업에서 재귀 입문으로 이 문제를 많이 다루는 것으로 아는데 이에 대한 내 이해를 공유하면 좋을 것 같다.
언제나 그렇듯 나는 단순히 정답 코드를 찍 적고 휑하니 끝내는 것을 좋아하지 않는다. 코드 자체보다 코드에 이르는 과정이 더 중요한데, 먼저 이 문제를 우리가 원하는 방식으로 정의한다. 그 다음 이 문제를 풀기 위한 핵심 아이디어를 살펴본다. 이후 이 통찰력을 사용해 코드를 곧바로 유도한다.
코드를 살펴본 후 바로 마치지 않고, 탑의 개수에 따른 총 이동횟수 자체를 구해본다. 이때 단순히 재귀식이 아닌, 일반항을 유도해보자.
2. 하노이의 탑
먼저 문제를 이해해보자. 이 문제가 무엇을 요구하는지 확인하고, 우리는 그중 어떤 출력을 선택할 것인지 정한다. 어떤 출력을 선택하는지에 따라 코드 형태가 달리지기 때문에 확실히 하고 간다.
2.1. 문제 소개
‘하노이의 탑’(Tower of Hanoi)은 프랑스의 수학자 에두아르 뤼카가 1883년 소개한 유명한 문제로, 다음과 같은 그림으로 표현할 수 있다.
3개의 막대가 있고, 첫 번째 막대(여기서는 ‘A’)에 5개의 원반이 쌓여 있다. 각 원반의 크기는 모두 다르고, 아래에서부터 위로 갈수록 점점 작아진다.
우리의 목표는 막대 ‘A’에 쌓여 있는 원반들을 그 순서를 지키면서 그대로 ‘C’로 옮기는 것이다.(‘B’도 상관 없다.)
이때 원반을 옮기는 몇 가지 조건이 따른다.
한 번에 움직일 수 있는 원반은 기둥 위에 놓인 원반 하나뿐이다.
어떤 원반 위에 그보다 더 큰 원반을 쌓을 수 없다.
이 조건 하에서 ‘최소의 이동횟수로 옮기는 가짓수’를 구하거나, ‘최소의 이동횟수로 옮길 때 각 원반을 옮기는 순서’ 등을 구하는 것이 하노이의 탑 문제가 된다.
2.2. 문제 정의
이제 문제 자체는 알았으니 문제를 보다 체계적으로 정의하자. 내가 말하는 체계적 이라함은 문제의 입력과 출력을 보다 함수에 가깝게 정의하자는 것이다. 앞서 하노이의 탑과 관련된 여러 문제를 만들 수 있다고 했는데 우리는 원반의 이동횟수를 최소화하고자 할 때, 각 원반을 옮기는 모든 순서를 출력하는 것으로 한다. 이때 각 이동의 출력은 ‘3번 원반을 A에서 C’와 같이로 정하며, 입력은 원반의 개수로 받는다.
이를 구현하는 함수 hanoi 를 대략적으로 정의하면 다음과 같다.
hanoi(N): 원반의 개수 N을 입력 받아 모든 원반을 ‘C’ 막대에 옮기는 각 움직임을 출력한다.
3. 아이디어 얻기
위에서 문제를 대략적으로, 사실 매우 러프하게 정의했다. 우리는 여기서 시작해서 각 원반을 어디에서 어디로 옮기는지를 모두 출력해야 하며 그를 위해서는 실제 움직임을 추적하고 문제해결을 위한 핵심 아이디어를 포착해야 한다.
어떻게 아이디어를 포착할까? 어떤 알고리즘 문제든 감각적으로 아이디어가 안 떠오를 때 가장 해볼법한 것은 실제로 원반을 하나씩 옮겨보는 것이다. 우리도 그렇게 해보자. 그리고 중요한 것은 언제나 문제를 작게 만들어 해결하고 이후 확대하는 것이다. 그런 의미에서 원반을 3개에서 시작해보자. 이렇게 그려본 후, 문제 해결을 위해 내가 선택한 세 가지 통찰을 확인한다.
와… 이거 그리는 거 힘들었다. 원반의 개수가 3개일 때, 각 움직임을 표현하고 있다. 이동횟수를 최소로 할 때 총 7번을 이동해야 하며 정해진 규칙을 지키면서 최종적으로 ‘C’ 막대에 모든 원반이 위치하게 된다. 각 움직임을 눈으로 쫓기 바란다. 원반이 2개, 4개일 때 직접 그려보는 것도 매우 도움이 된다.
이때 우리는 각 움직임을 한 문장씩 출력한다고 했다. 우리가 원하는 함수(\(hanoi(3)\))의 실행결과는 다음과 같을 것이다.
1번 원반을 A에서 C로 이동 2번 원반을 A에서 B로 이동 1번 원반을 C에서 B로 이동 3번 원반을 A에서 C로 이동 1번 원반을 B에서 A로 이동 2번 원반을 B에서 C로 이동 1번 원반을 A에서 C로 이동 # 여기까지 7번
자, 이제 우리가 할 것은 작은 입력을 통해 문제를 직접 풀어본 뒤 이를 통해 문제 해결을 위한 통찰, 즉 핵심 아이디어를 얻는 것이다. 그를 바탕으로 문제를 프로그래밍 가능하게 보다 구체적으로 재정의할 것이다.
3.1. 재귀
앞서 여러 번 언급했지만 재귀는 이 문제의 성패를 가르는 통찰이다. 재귀(recursion)란 같은 형태의 보다 작은 입력을 지닌 자기 자신을 호출하는 것이고, 이렇게 재귀적인 호출을 사용하는 함수를 재귀함수라고 한다. 재귀함수의 활용은 내 알고리즘 포스트에서 많이 사용됐기 때문에 이쯤 넘어가도록 하자.
이 문제 어디에서 재귀의 여지가 있을까? 일단 우리가 정의한 함수의 명세를 다시 보자.
hanoi(N): N개의 원반을 어쩌고 저쩌고 해서 다른 곳으로 옮겨라.
이때 위의 7번의 움직임은 모두 hanoi(N) 의 과정이다. 그러면 hanoi(N-1) 은 뭘까? 정의에 따라 다음과 같을 것이다:
hanoi(N-1): (N-1)개의 원반을 어쩌고 저쩌고 해서 다른 곳으로 옮겨라.
뭐 충분히 가능한 해석이다. 원반을 100개를 옮길 수도 있고, 그보다 1개 작은 99개 옮기는 것도 얼마든지 가능할테니까. 내가 원하는 것은 hanoi(N) 에서 hanoi(N-1) 가 발견되냐는 것이다. 이를 현재 문제에 적용하면 hanoi(3) 이니 hanoi(2) 가 발견되는지가 될 것이다.
이 조건을 충족할 때 재귀를 전략적으로 사용할 수 있다. 위 그림에서 찾아보자.
단서는 start와 4번째 움직임 후. 먼저 맨 처음을 보자. 규칙에 따라 3번째 원반을 ‘A’에서 ‘C’로 옮기려면 위의 두 원반은 ‘B’ 원반에 이미 꽂혀 있어야 한다. 즉 여기서 hanoi(2) 가 보인다.
또 4번째 그림. 2개의 원반을 ‘B’에 꽂은 후 3번째 원반을 ‘C’로 옮겼다. 이제 2개의 원반을 다시 ‘B’에서 ‘C’로 옮겨야 한다. 여기서도 hanoi(2) 가 쓰이고 있다.
여기서 알 수 있는 것은 hanoi(N) 은 두 번의 hanoi(N-1) 재귀 과정을 수반한다는 것이다. 한 번의 재귀 후 가장 큰 원반(N번째 원반)을 목적지로 옮기고, 다시 마지막 재귀를 통해 나머지 N-1개의 원반을 목적지에 옮긴다. 즉, hanoi(N)은 세 번의 과정으로 나눌 수 있다.
3.2. 출발점, 도착점, 경유점
좋아, 재귀의 가능성을 찾은 것은 큰 성과다. hanoi(N) 함수를 어떻게든 hanoi(N-1) 를 활용한 형태로 표현가능할 것이라는 단서를 찾았다. 근데 여기서 다가 아니고 추가적인 정보가 필요하다.
앞서 N개의 원반을 옮기는 작업에는 두 번의 재귀 과정이 있다고 했다. 이때 각 재귀 과정이 의도하는 바가 조금씩 다르다. 위의 그림을 참고하면 다음과 같이 구분할 수 있다.
첫 번째 재귀: N-1 개의 원반을 ‘A’에서 ‘B’로 옮긴다.(start)
두 번째 재귀: N-1 개의 원반을 ‘B’에서 ‘C’로 옮긴다.(4번)
두 재귀는 옮기는 원반의 개수는 같지만 원반을 움직이는 출발지와 목적지가 다르다. 그리고 이 정보는 현재 러프하게 정의한 hanoi 함수에서 추적하지 않고 있는 정보이기도 하다. 우리의 문제 정의에서 출력은 각 움직임의 출발지와 목적지도 같이 기술해야 하기 때문에 함수에서 이 두 정보를 같이 추적해줘야 한다. 따라서 원 함수의 입력이 원반의 개수만 받았다면 이제는 최소 출발지, 도착지의 변수까지 추가로 받아야 한다.
여기에 더해 경유점 이라는 개념도 사용하자. 만약 ‘A’에서 ‘C’로 3개의 원반을 이동할 때 ‘B’ 막대도 결국 사용해야 한다. 이렇게 세 개의 입력을 같이 입력해줘야 원반을 하나씩 이동할 때 경유점을 지날 때도 문제없이 출력할 수 있다.
3.2. 문제 분해
이제 문제 해결과 관련된 핵심 재귀식을 만들어보자. 앞선 그림에서 순차적으로 얻을 수 있다. 먼저 보다 구체화된 문제를 다시 한 번 정의해보자.
hanoi(N, start, to, via): start에서 to로 via를 거쳐 총 N개의 원반을 운반할 때 각 이동 과정을 출력하라
앞선 문제보다 훨씬 구체화됐다. 그러면 위의 3개의 원반을 옮기는 과정은 다음 함수로 표현할 수 있다.
hanoi(3, ‘A’, ‘C’, ‘B’)
그리고 hanoi 함수는 두 번의 재귀와 한 번의 가장 큰 원반을 옮기는 과정이 필요하다고 했다. 즉, 전체 과정을 세 과정의 연속으로 분해가능한 것이다. 이때 각 과정은 순차적으로 이루어지는데 그 순서는 다음과 같다. 이 과정은 그림과 같이 확인하라.
hanoi(2, ‘A’, ‘B’, ‘C’) : start에서 3번까지 3번 원반을 ‘C’로 옮기기 위해서는 먼저 위의 두 원반을 ‘B’로 옮겨야 한다. 이후 3번 원반을 ‘C’로 옮긴다 : 4번 hanoi(2, ‘B’, ‘C’, ‘A’) : 5번 ~ 3번을 ‘C’로 옮긴 후 ‘B’에 있는 두 개의 원반을 ‘C’로 옮긴다. 이때 ‘A’를 경유한다.
원반의 개수(\(N\))가 몇 개가 되든 결국 이 과정을 거친다. 한 번의 재귀, 가장 큰 원반 옮기기 이후 다시 한 번의 재귀. 물론 이때 예외가 있다. \(N\)이 1일 때는 자신의 위에 원반이 없기 때문에 재귀가 필요없고 바로 원반을 옮기고 종료한다. 이것이 곧 재귀함수의 탈출 조건, 또는 기저 사례(base case)가 된다. 이제 이 식을 실제 수식으로 표현해보자.
\[ move(N, from, to): \text{N번 원반을 from에서 to로 옮긴다.(우리는 print로 출력함)} \]
\[ \text{hanoi}(N, start, to, via) = \displaylines{ \begin{cases} move(1, start, to) & \quad \text{1. if N == 1}, \\ hanoi(N-1, start, via, to) + move(N, start, to) + hanoi(N-1, via, to, start) & \quad \text{2. else} \end{cases} } \]
각 재귀함수에서 인자의 순서가 헷갈리기 쉽다. 헷갈리지 말자.
첫 번째 재귀에서는 맨 밑의 N번째 원반을 목적지로 옮기기 위해 위의 N-1 개의 원반을 경유지로 옮긴다. 그 다음 N 번째 원반을 목적지로 옮긴다. 경유지에 있는 N-1 개의 원반을 to로 옮긴다.
이게 핵심이다. 그러면 이제 할 수 있는 질문은 ‘이러면 진짜 풀려??’ 일 수 있는데, 코드를 짜고 실행시켜 보면 알 수 있겠다.
4. 실제 코드
재귀함수는 많은 경우 재귀식을 표현만 할 수 있으면 그대로 풀린다. 위에서 정의한 함수 그대로 코드를 작성해보자.
MSG_FORMAT = “{}번 원반을 {}에서 {}로 이동” def move ( N , start , to ): print ( MSG_FORMAT . format ( N , start , to ))
먼저 실제로 원반을 옮기는 move 함수를 정의한다. 메시지 형식은 위에서 정의한 그대로 사용한다. 이때 기억하자. 실제 데이터와 데이터를 표현하는 형식은 별개의 것이므로, 이 둘을 분리하면 좋다. MSG_FORMAT 은 형식에 불과하고, 실제 데이터는 N, start, to 다. 이렇게 역할에 맞게 분리하는 습관은 결국 정답이다.
def hanoi ( N , start , to , via ): if N == 1 : move ( 1 , start , to ) else : hanoi ( N – 1 , start , via , to ) move ( N , start , to ) hanoi ( N – 1 , via , to , start )
정말 위에서 정의한 재귀식 그대로 함수를 만들었다. 기억하자. 설계가 코딩에 앞선다는 것. 설계 없는 코딩은 전기와 노동력, 시간을 잡아먹는 바보 같은 짓이다.
이제 함수가 돌아가는지 실행해볼까?
hanoi ( 3 , ‘A’ , ‘C’ , ‘B’ ) 1 번 원반을 A에서 C로 이동 2 번 원반을 A에서 B로 이동 1 번 원반을 C에서 B로 이동 3 번 원반을 A에서 C로 이동 1 번 원반을 B에서 A로 이동 2 번 원반을 B에서 C로 이동 1 번 원반을 A에서 C로 이동
따라가 보라. 정말 기가 막히게, 다시 말해 이 문제의 조건을 어기지 않으며 원반을 옮긴다. 시간과 용기가 허락한다면 \(N\)을 4, 5로 키워서 실행해보라. 문제없이 동작할 것이다.
이렇게 원반을 옮기는 각 과정을 추적하는 형태의 하노이의 탑 문제는 해결이 됐다.
5. 번외: 원반의 개수에 따른 총 이동횟수 구하기
앞선 ‘문제 정의’ 절에서 우리는 원반을 움직이는 각 이동의 과정을 출력하도록 하노이의 탑 문제를 정의했다. 하지만 이번에는 조금 다른, 상대적으로 수학적인 하노이의 탑 문제를 풀어보려고 한다. 원반의 개수가 N일 때, 원반을 모두 옮기는 데 드는 이동 횟수는 몇 번일까?
확실히 앞선 문제와는 궤를 달리 한다. 앞서 작성한 함수는 원반의 개수가 3일 때 7번의 print 문이 실행되는데 이번 문제에서는 이렇게 7을 구하면 된다. 즉, 이번 문제는 원반의 개수 N에 따른 하노이의 탑 이동횟수에 대한 일반식을 구할 수 있을까?이고, 확실히 앞선 문제에 비해 수학적이다.
천천히 접근해서 먼저 함수를 정의하고 시작하자. 앞선 함수는 원반의 개수(N)뿐 아니라 출발지와 목적지에 대한 정보도 필요했다. 어디에서 어디로 옮기는지를 모두 출력해야 했기에 당연하다. 하지만 이 문제에서는 구체적인 출발지와 목적지에 대한 정보는 필요없다. 단순히 총 이동횟수만 구하면 되기 때문이고 따라서 이번 함수에서는 이 정보들을 무시한다. 결국 함수를 정의하면 다음과 같다.
hanoi(N): N개의 원반을 옮기는 하노이의 탑 문제의 총 이동 횟수를 구하라
이때 각 함수는 마찬가지로 재귀식으로 짤 수 있다.
\[ \text{hanoi}(N) = \displaylines{ \begin{cases} 1 & \quad \text{1. if N == 1}, \\ 2 \times hanoi(N-1) + 1 & \quad \text{2. else} \end{cases} } \]
앞선 함수와 핵심 재귀 논리는 동일하다. 원반의 개수가 1개일 때는 눈치보지 않고 바로 옮기면 되고, 아니면 위의 원반을 옮기고 자신을 옮긴 뒤 다시 남은 원반을 목적지로 옮긴다.
이제 문제는 이 재귀식에서 일반항을 어떻게 도출할 수 있는가이다. 그 과정이 결코 어렵지 않으니 따라가보자.
\[ \displaylines{ hanoi_n = hanoi_{n-1} \times 2 + 1 \\ \text{양변에 1을 더하면} \\ hanoi_n + 1 = 2 \times (hanoi_{n-1} + 1) \\ hanoi_{n-1} + 1 = 2 \times (hanoi_{n-2} + 1) \\ hanoi_{n-2} + 1 = 2 \times (hanoi_{n-3} + 1) \\ \vdots \\ hanoi_2 + 1 = 2 \times (hanoi_1 + 1) } \]
\[ \displaylines{ \text{이때 좌변과 우변을 각각 곱하면…} \\ (hanoi_n + 1)(hanoi_{n-1} + 1) \cdots (hanoi_2 + 1) = 2^{n-1}(hanoi_{n-1} + 1) \cdots (hanoi_1 + 1) \\ \text{양변의 공통된 인자들을 나눈다.} \\ (hanoi_n + 1) = 2^{n-1} \times (hanoi_1 + 1) \\ hanoi_1 \text{은 1이기 때문에 결국} \\ (hanoi_n + 1) = 2^n } \]
\[ \therefore \mathbf{hanoi_n = 2^n – 1} \]
이렇게 N개의 원반을 옮기는 하노이의 탑 문제의 이동횟수의 일반항을 구할 수 있었다. 결국 2의 지수식이 나오는데 각 함수가 두 번의 재귀식을 실행시킨다는 것을 알면 감각적인 사람들은 대충이라도 유추할 수도 있었을 것이다. 나는 못했다. ㅋㅋ
6. 마치며
오늘은 그 유명한 하노이의 탑 문제를 풀어봤다. 이 문제는 병합정렬과 마찬가지로 재귀 를 연습하는 데 정말 좋은 문제로 재귀가 익숙하지 않은 분들은 꼭 복기하시면 좋겠다. 우리는 이 문제를 해결하기 위한
재귀 출발점, 도착점, 경유 문제 분해
이상 세 개의 통찰을 발견할 수 있었고 이를 통해 각 움직임을 포착하는 함수를 작성할 수 있었다.
번외로 각 움직임을 포착하는 것이 아닌, 총 이동횟수를 구하는 일반항까지 구할 수 있었다. 문제는 정하기 나름이라는 것, ‘주제’와 ‘문제’는 구분할 필요가 있다는 것을 기억하자.
현재 재미있는 알고리즘 주제들이 준비되어 있다. 아마 빠른 주기로 작성될 것 같다. 다시 가보자.
7. 자료 출처
하노이탑 알고리즘
30층짜리 하노이탑을 옮기려면 무려 34년간을 쉬지도 않고 옮겨야 한다.
하노이탑을 옮기려면 원반을 모두 (2의 n승)-1번만큼 옮겨야 한다. 원반이 3개라면 총 7번을 옮겨야 한다. 마찬가지로 n이 커지면 -1은 큰 의미가 없으므로 하노이탑 알고리즘의 계산 복잡도는 O(2n)으로 표현할 수 있다. 이는 2를 n번 제곱한 값이므로 n이 커짐에 따라 값이 기하급수적으로 증가한다. 그래서 원반 하나를 옮기는 데 1초가 걸린다고 가정하더라도 30층짜리 하노이 탑을 옮기려면 무려 34년간 먹지도 쉬지도 않고 원반만 옮겨야 한다(이승찬, 2017).
재귀 호출을 이용한 하노이탑 알고리즘 함수의 작성은 간단하나, 직접 순서를 짜는 것은 일련의 과정을 머릿속에서 그릴 수 없다면 시도조차 하기 어려울 것이다. 그래서 머릿속에서 먼저 처음 그림의 과정을 하나씩 그려보고 수식으로 표현할 줄 아는 단계를 거쳐야 원반 세 개를 옮기는 것의 일반적인 경우(원반이 n개일 때)도 생각할 수 있다.
알고리즘을 적어보면 아래와 같다.
1. 원반이 한 개면 그냥 옮기면 끝이다(종료 조건).
2. 원반이 n개일 때
1) 1번 기둥에 있는 n개 원반 중 n-1개를 2번 기둥으로 옮긴다(3번 기둥을 보조 기둥으로 사용).
2) 1번 기둥에 남아 있는 가장 큰 원반을 3번 기둥으로 옮긴다.
3) 2번 기둥에 있는 n-1개 원반을 다시 3번 기둥으로 옮긴다(1번 기둥을 보조 기둥으로 사용).
원반이 한 개일 때가 ‘종료 조건’에 해당한다. 원반 n개 문제를 풀려면 n-1개 원반 문제를 풀어야 하는데, 이는 바로 ‘좀 더 작은 값으로 자기 자신을 호출하는 과정’이다. 따라서 이 문제는 전형적인 재귀 호출 알고리즘에 해당한다(이승찬, 2017).
같은 과정의 반복이 이루어지는 하노이탑 옮기기의 재귀(Recusion)
참조
1) 이승찬 저. (2017). 모두의 알고리즘 with 파이썬, 서울:(주)도서출판 길벗.
2) Towers Of Hanoi. (2018, May 28). Retrieved from https://algorithms.tutorialhorizon.com/towers-of-hanoi/
‘하노이의 탑’ 이해하기 (feat. 재귀 함수)
반응형
들어가며 하노이의 탑 문제 소개 문제 정의 아이디어 얻기 아이디어 재귀 출발점, 도착점, 경유점 문제 분해 실제 코드 번외 : 원반의 개수에 따른 총 이동횟수 구하기 마무리 자료 출처
https://www.acmicpc.net/problem/11729
1. 들어가며
백준 11729번 문제에 관한 내용으로, 이번 내용은 ‘하노이의 탑’ 알고리즘이다. ‘하노이 의 탑’은 재귀를 연습하기에 매우 좋은 연습문제다.
코드 자체보다 코드에 이르는 과정이 더 중요하다. 문제를 정의하고, 문제를 풀기 위한 핵심 아이디어를 살펴보자.
그리고나서 이 통찰력을 사용해서 코드로 유도하자. 그리고 코드를 살펴본 후 탑의 개수에 따른 총 이동횟수를 구해보자.
이때는 단순히 재귀식이 아닌, 일반항을 유도해 보도록 하자.
2. 하노이의 탑
먼저 문제를 이해해 보자. 이 문제가 요구하는 바를 파악하고, 어떤 것을 출력할 것인지 정해보자.
어떤 것을 출력할 것인지에 따라 코드 형태가 달라지기 때문에, 이점을 확실히 생각하고 가자.
2.1 문제 소개
‘하노이의 탑'(Tower of Hanoi)은 프랑스의 수학자 에두아르 뤼카가 1883년 소개한 문제이다.
아래 그림으로 표현할 수 있다.
하노이의 탑
3개의 막대(기둥)가 있고, 첫 번째 막대에 5개의 원반이 쌓여있다. 각 원반의 크기는 모두 다르고, 아래에서부터 위로 갈수록 점점 작아진다.
우리의 목표는 막대 ‘A’에 쌓여있는 원반들을 그 순서를 지키면서 그대로 ‘C’로 옮기는 것이다. (‘B’로 옮겨도 상관은 없다)
하노이의 탑
이때 원반을 옮기는 몇 가지 조건이 따른다.
한 번에 움직일 수 있는 원반은 기둥 위에 놓인 원반 하나뿐이다.
어떤 원반 위에 그보다 더 큰 원반을 쌓을 수 없다.
이 조건 하에서 ‘최소의 이동횟수로 옮기는 가짓수’를 구하거나, ‘최소의 이동횟수로 옮길 때 각 원반을 옮기는 순서’등을 구하는 것이 하노이의 탑 문제가 된다.
2.2 문제 정의
이제 문제 자체는 이해했으니, 이를 체계적으로 정의해보자. “체계적”이라함은, 문제의 입력과 출력을 보다 함수에 가깝게 정의하자는 것이다. 우리는 “원반의 이동횟수를 최소화하고자 할 때, 각 원반을 옮기는 모든 순서를 출력하는 것”으로 한다. 이때 각 이동의 출력은 ‘3번 원반을 A에서 C와 같이로 정하며, 입력은 원반의 개수로 받는다.
이를 구현하는 함수 hanoi를 대략적으로 정의하면 다음과 같다.
hanoi(N): 원반의 개수 N을 입력 받아 모든 원반을 “C” 막대에 옮기는 각 움직임을 출력한다.
3. 아이디어 얻기
위에서 문제를 매우 러프하게(대략적으로) 정의했다.
각 원반을 어디에서 어디로 옮기는지를 모두 출력해야 하며 그를 위해서는 실제 움직임을 추적하고 문제해결을 위한 핵심 아이디어를 포착해야 한다.
어떻게 아이디어를 포착할까? 어떤 알고리즘 문제라도, 감각적으로 아이디어가 안 떠오를 때 가장 먼저 시도해 볼 수 있는 것은, 실제로 하나씩 해보는 것이다. 이 문제에서는 실제로 원반을 하나씩 옮겨보는 것이다.
중요한 것은, 문제를 작게 축소해서 시도해서 해결해보고, 그것을 확대하는 것이다.
한번 해보자. 우선 원반(n) 3개로 시작해보자. 그리고 나서 얻은 통찰을 확인해 보자.
원반의 개수가 3개일 때, 각 움직임을 표현하는 그림이다. 이동횟수를 최소로 할 때 총 7번을 이동해야 하며 정해진 규칙을 지키면서 최종적으로 ‘C’막대에 모든 원반이 위치하게 된다. 각 움직임을 눈으로 쫓아 생각해보기 바란다. 원반이 2개, 4개일 때를 직접 그려보는 것도 좋다.
앞서 hanoi(N) 함수는 각 움직임을 한 문장씩 출력한다고 했다. 우리가 원하는 함수 hanoi(3)의 실행결과는 다음과 같을 것이다.
1번 원반을 A에서 C로 이동 2번 원반을 A에서 B로 이동 1번 원반을 C에서 B로 이동 3번 원반을 A에서 C로 이동 1번 원반을 B에서 A로 이동 2번 원반을 B에서 C로 이동 1번 원반을 A에서 C로 이동
이제, 우리가 할 것은 작은 입력을 통해 문제를 직접 풀어본 뒤, 이를 통해 문제 해결을 위한 통찰, 즉 핵심 아이디어를 얻는 것이다.
그 아이디어를 바탕으로 문제를 프로그래밍 가능하게 보다 구체적으로 재정의 할 것이다.
3.1 문제 풀이 접근(아이디어)
원판이 n개일떄를 생각해보자.
출처: 밤샘공부
우리는 n개의 원판을 세번째 기둥에 옮겨야 한다.
편의상 아래와 같이, 1번막대, 2번막대, 3번막대로 칭하겠다.
출처: 밤샘공부
이제 n개의 원판을 1번막대에서 3번막대로 옮기는 것을 각 단계로 나누어 생각해 보자.
총 3단계로 나눌 수 있다. (변화가 있는 원판은 노란색)
1단계에서는 n-1 개의 원판을 1번 막대에서 2번막대로 옮긴다.
2단계에서는 남은 1개의 원판을 1번 막대에서 3번 막대로 옮긴다.
3단계에서는 다시 n-1개의 원판을 2번 막대에서 3번 막대로 옮긴다.
이렇게 총 3단계로 구성되있는 루프가 이 문제를 푸는 핵심 아이디어이다.
3.2 재귀
재귀는 이 문제의 성패를 가르는 통찰이다. 재귀(recursion)란 같은 형태의 보다 작은 입력을 지닌 자기 자신을 호출하는 것이고, 이렇게 재귀적인 호출을 사용하는 함수를 재귀함수라고 한다.
이 문제에서 재귀의 여지가 있을까? 우선, 우리가 앞서 정의한 함수의 정의를 다시 보자.
hanoi(N) : N개의원반을 어쩌고 저쩌고 해서 다른 곳으로 옮겨라.
이때 위의 7번 움직임은 모두 hanoi(N)의 과정이다. 그러면 hanoi(N-1)은 뭘까? 정의에 따라 다음과 같을 것이다.
hanoi(N) : (N-1)개 원반을 어쩌고 저쩌고 해서 다른 곳으로 옮겨라.
충분히 가능한 해석이다. 내가 원하는 것은 재귀를 사용할 수 있도록,
hanoi(N)에서 hanoi(N-1)이 발견되냐는 것이다. 이를 현재 문제에 적용하면 hanoi(3)이니, hanoi(2)가 발견되는지가 될 것이다.
이 조건이 충족될 때 재귀를 전략적으로 사용할 수 있다.
단서는 2번 찾을 수 있다.
우선, 맨 처음을 보자. 규칙에 따라 3번째 원반을 “A에서 C”로 옮기려면 위의 두 원반은 ‘B’에 이미 꽂혀 있어야 한다. 즉, 이때 hanoi(2)가 필요하다고 보여진다.
두번째 단서는, 위 그림의 4번째 움직임에서 찾을 수 있다. 2개의 원반을 “B”에 꽂은 후 3번째 원반을 “C”로 옮겼다. 이제 2개의 원반을을 “B”에서 “C”로 옮겨야 한다. 여기서도 hanoi(2)가 보인다.
여기서 알 수 있는 것은 hanoi(N)은 두 번의 hanoi(N-1) 재귀 과정을 수반한다는 것이다.
3.3 출발점, 도착점, 경유점
재귀의 가능성을 찾은 것은 큰 성과다. hanoi(N)함수를 어떻게든 hanoi(N-1)를 활용한 형태로 표현 가능할 것 이라는 단서를 찾았다. 근데 추가적인 정보가 필요하다.
앞서 N개의 원반을 옮기는 작업에는 두 번의 재귀 과정이 있다고 했다. 이때 각 재귀 과정이 의도하는 바가 조금씩 다르다. 위의 그림을 참고하면 다음과 같이 구분할 수 있다.
첫 번째 재귀 : N-1 개의 원반을 “A”에서 “B”로 옮긴다.
두 번쨰 재귀 : N-1 개의 원반을 “B”에서 “C”로 옮긴다.
두 재귀는 옮기는 원반의 개수는 같지만 원반을 움직이는 출발지와 목적지가 다르다. 그리고 이 정보는 현재 러프하게 정의한 hanoi(함수에서 추적하지 않고 있는 정보이기도 하다. 우리의 문제 정의에서 출력은 각 움직임의 출발지와 목적지도 같이 기술해야 하기 때문에 함수에서 이 두 정보를 같이 추적해 주어야 한다. 따라서 원 함수의 입력이 원반의 개수만 받았다면 이제는 최소 출발지, 도착지의 변수까지 추가로 받아야 한다.
여기에 더해 “경유점” 이라는 개념도 사용하자. 만약 “A”에서 “C”로 3개의 원반을 이동할 때 “B”막대도 결국 사용해야 한다. 이렇게 세 개의 입력을 같이 입력해줘야 원반을 하나씩 이동할 때 경유점을 지날 때도 문제없이 출력할 수 있다.
3.4 문제 분해
이제 문제 해결과 관련된 핵심 재귀식을 만들어 보자. 앞선 그림에서 순차적으로 얻을 수 있다.
먼저, 보다 구체화된 문제를 다시 한 번 정의해보자.
hanoi(N, start, end, sub): start에서 sub를 거쳐 end로 총N개의 원반을 운반할 때 각 이동 과정을 출력하라
앞선 문제보다 훨씬 구체화 됐다. 그러면 위의 3개의원반을 옮기는 과정은 다음 함수로 표현할 수 있다.
hanoi(3, “A”, “C”, “B”)
그리고 hanoi함수는 두 번의 재귀와 한 번의 가장 큰 원반을 옮기는 과정이 필요하다고 했다.
즉, 전체 과정을 세 과정의 연속으로 분해가능하다. (위에서 언급했음)
1. hanoi(2, “A”, “B”, “C”): “A”에서 “C”를 거쳐 “B”에 1번 2번 원반을 옮긴다.
2. 이후, start에 있는 3번원반을 “C”지점으로 옮긴다.
3.hanoi(2, “B”, “C”, “A”) : “B”에 있는 두개의 원반을 “A”를 거쳐 “C”로 옮긴다.
원반의 개수(N)가 몇 개가 되든, 결국 이 과정을 거친다. 한 번의 재귀, 가장 큰 원반 옮기기 이후 다시 한번의 재귀, 물론 종료구문이 필요하다. N이 1일 때는 자신의 위 원반이 없기 때문에 재귀가 필요없고, 바로 원반을 옮기고 종료한다.
(hanoi(N, start, end, sub) == hanoi(N, start, to, via)임을 감안하고 아래 수식을 볼 것.)
각 재귀함수에서 인자의 순서를 햇갈리시 쉽다. 햇갈리지 말자.
1. 첫 번쨰 재귀에서는 맨 밑의 N번째 원반을 목적지로 옮기기 위해 위에 있는 N-1개의 원반을 경유지로 옮긴다.
2. 그 다음 N번째 원반을 목적지로 옮긴다.
3. 경유지에 있는 N-1개의 원반을 목적지로 옮긴다.
hanoi 함수의 파라미터중에 start, end, sub는 각각, 촐발기둥, 목표기둥, 보조기둥을 의미한다.
hanoi라는 재귀 함수를 이용하여 원판을 앞서 설명한 3단계의 방식으로 옮긴다.
해당 3단계의 방식을 1번 이상 거치면서 3번기둥으로 완전히 동일한 순서로 원판이 놓아지도록 옮겨지게 되는데,
이때 1단계와 3단계에서는 , 출발기둥, 목표기둥, 보조기둥이 바뀌게 된다.
처음에는 문제에 주어진 출발지점과 목표지점을 고려하여 1번기둥이 start, 2번기둥이 sub, 3번기둥이 end다.
즉, 함수는 처음에 hanoi(원판의 개수(n), 출발 기둥(start), 목표 기둥(end), 보조기둥(sub)) 의 형태로 파라미터를 받게 된다.
1단계에서는 start에 있는 n-1개의 원판을 모두 sub기둥으로 옮겨야 한다. 즉 1단계의 묙표기둥은 2번기둥이다.
그리고 보조기둥은 end기둥이 된다. 따라서 재귀를 이용할 때, 함수 인자로는 (n-1, start, sub, end)를 받게 된다.
이때 재귀 종료문으로 n이 1일때 종료 되도록 설정하고 return을 한다. 왜냐하면 n이 1개라면 재귀를 이용하지 않아도 되기 때문이다.
1단계를 거치고 나면 2번기둥(sub)에 n-1개의 원판이 모두 옮겨진다.
2단계에서는 비어있는 3번 기둥(end)기둥에 1번에 남은 기둥(가장 큰 원판)을 옮긴다.
3단계에서는 2번기둥으로 옮긴 n-1개의 원판을 3번기둥으로 옮기게되는데,
이때는 2번기둥이 출발기둥이 되고, 1번기둥이 보조기둥, 3번기둥에 목표기둥이 된다.
따라서 재귀를 호출 할 때 삽입되는 인자는 (n-1, sub, end, start)를 받게 된다.
이것이 핵심이다. 이러면 정말 풀릴까? 라는 생각이 들 수도 있다.
코드를 짜고 실행시켜 보자.
문제 풀이 코드
재귀함수는 많은 경우 재귀식을 표현 할 수 있으면 그대로 풀린다. 위에서 정의한 함수 그대로 코드를 작성해 보자.
MSG_FORMAT = “{}번 원반을 {}에서 {}로 이동” def move(N, start, end): # 원반을 실제로 옮기는 함수(출력) print(MSG_FORMAT.format(N, start, end))
먼저, 실제로 원반을 옮기는 move 함수를 정의한다. 메시지 형식은 위에서 정의한 그대로 사용한다.
이때 기억해야 할 것은, 실제 데이터와 데이터를 표현하는 형식은 별개이므로, 이 둘을 분리하면 좋다. MSG_FORMAT 은 형식에 불과하고, 실제 데이터는 N, start, end다. 이렇게 역할에 맞게 분리하는 습관을 들이자.
def hanoi(N, start, end, sub): if N == 1: move(1, start, end) return else: hanoi(N-1, start, sub, end) move(N, start, end) hanoi(N-1, sub, end, start) hanoi(3, “A”, “C”, “B”)
정말로 위에서 정의한 재귀식 그대로 함수를 만들었다. 기억하자. 설계가 코딩에 앞선다. 설계 없는 코딩은, 전기와 노동력, 시간을 잡아먹는 어리석은 짓이다.
[출력 결과]1번 원반을 A에서 C로 이동 2번 원반을 A에서 B로 이동 1번 원반을 C에서 B로 이동 3번 원반을 A에서 C로 이동 1번 원반을 B에서 A로 이동 2번 원반을 B에서 C로 이동 1번 원반을 A에서 C로 이동
이렇게 원반을 옮기는 각 과정을 추적하는 형태의 하노이 탑 알고리즘 문제는 해결했다.
5. 번외 : 원반의 개수에 따른 총 이동횟수 구하기
앞선 ‘문제 정의’ 절에서 우리는 원반을 움직이는 각 이동의 과정을 출력하도록 하노이의 탑 문제를 정워했다.
하지만, 이번에는 조금 다른, 상대적으로 수하적인 하노이의 탑 문제를 풀어볼 것이다.
원반의 개수가 N일 때, 원반을 모두 옮기는 데 드는 이동 횟수는 몇 번일까?
확실히 앞선 문제와는 결을 달리 한다. 앞서 작성한 함수는 원반의 개수가 3일 때, 7번의 print문이 실행되는데 이번 문제에서는 이렇게 7을 구하면 된다. 즉, 이번 문제는 원반의 개수 N에 따른 하노이의 탑 이동횟수에 대한 일반식을 구할 수 있을까? 이고, 확실히 앞선 문제에 비해 수학적이다.
천천히 접근해서 먼저 함수를 정의하고 시작하자. 앞선 함수는 원반의 개수(N뿐 아니라 출발지와 목적지에 대한 정보도 필요했다. 어디에서 어디로 옮기는지를 모두 출력해야 했기에 당연하다. 하지만 이 문제에서는 구체적인 출발지와 목적지에 대한 정보는 필요없다. 단순히 총 이동횟수만 구하면 되기 떄문이고 따라서 이번 함수에서는 이 정보들은 무시한다. 결국 함수를 정의하면 다음과 같을 것이다.
hanoi(N): N개의 원반을 옮기는 하노이의 탑 문제의 총 이동 횟수를 구하라
이때 각 함수는 마찬가지로 재귀식으로 짤 수 있다.
앞선 함수와 핵심 재귀 논리는 동일하다.
원반의 개수가 1개일 때는 바로 옮기면 되고, 그렇지 않다면, 위의 원반을 옮기고 자신을 옮긴 뒤 다시 남은 원반을 목적지로 옮긴다.
이 재귀식에서 일반항을 어떻게 도출할 수 있을까?
이렇게 N개의 원반을 옮기는 하노이의 탑 문제의 이동횟수의 일반항을 구했다.
결국 2의 지수식이 나오는데, 각 함수가 두번의 재귀식을 실행시킨다는 것을 알면 대충 유추할 수도 있었을 것이다.
문제에 대한 감각이 중요..
6. 마무리
하노이의 탑 문제를 풀어보았다.
이 문제는 병합정렬과 마찬가지로 “재귀” 를 연습하는 데 정말 좋은 문제이다.
이 문제를 해결하면서,
재귀 출발점, 도착점, 경유 문제 분해
세 개의 인사이트를 발견했고, 이를 통해 각 움직임을 포착하는 함수를 작성 할 수 있었다.
번외로, 각 움직임을 포착하는 것이 아닌, 총 이동 횟수를 구하는 일반항까지 구할 수 있었다.
7. 자료 출처
하노이의 탑
반응형
So you have finished reading the 하노이 탑 알고리즘 topic article, if you find this article useful, please share it. Thank you very much. See more: 하노이탑 알고리즘 재귀, 하노이의 탑 게임, 하노이탑 규칙, 하노이탑 재귀, 하노이탑 코딩, 하노이탑 문제, 하노이 탑 전설, 하노이탑 점화식