토끼와 거북이 알고리즘

영어 질문 하나. 우리가 잘 아는 이솝 우화, '토끼와 거북이'를 영어로 하면은? 학교에서 거북이는 Turtle로 배웠고 토끼는 Rabbit으로 배웠으니...

Rabbit and Turtle ?

안타깝게도 이것은 정답이 아니다. 토끼와 거북이는 영어로

Tortoise and Hare

로 쓴다. 내가 Rabbit and Turtle라는 말을 쓰자 인도친구가 웃으면서 Tortoise and Hare로 고쳐주더라.

그런데 정작 하고 싶은 이야기는...

Tortoise and Hare, 즉 토끼와 거북이 알고리즘이라는 것이 있다. 주어진 리스트에 싸이클이 있는지 없는지를, 보다 일반적으로 표현하면 주어진 함수에서 싸이클이 있는지 없는지를 알려주는 알고리즘이다. 이 알고리즘을 고안한 사람은 Floyd라는 사람이다. 알고리즘 책에서 본, 그 짧은 코드에도 불구 오묘한 기능을 하는 All Shortest Path 알고리즘을 만든 그 Floyd이다.

그림을 그려서 다시 이 문제를 설명하면,

 image

링크드 리스트에서 O(n) 시간과 O(1) 저장 공간을 이용해서 싸이클이 있는지 없는지를 알아내어라.

만약 시간과 저장 공간의 제약이 없다면, 노드마다 방문 되었는지 기억하는 변수를 하나 두고 돌아다니면 될 것이다. 그러나 문제에서는 O(1)의 공간, 즉 이런 추가적인 변수를 둘 수 없다. 그렇다면 일반적인 방법으로는 풀기가 어렵다. 여기서 아주 기발하게 토끼와 거북이가 등장해서 싸이클 유무를 판단할 수 있다.

  1. 거북이는 리스트를 한 번에 한 노드씩 앞으로 나아간다.
  2. 반면에 토끼는 두 걸음씩 움직인다.
  3. 이런 과정을 계속 반복한다.

만약 리스트에 싸이클이 있다면? 그렇다면 이 둘은 언젠가 만나게 될 것이다.

그림을 그려서 확인해보자. (PowerPoint 2007 만세~)

image 

이렇게 보다시피 언젠가는 만나게 됨을 직관적으로 알 수 있다. Wiki에는 리스트가 아닌 함수에서 싸이클 찾는 알고리즘을 Python으로 기술하고 있다. (리스트일 경우에는 단순히 함수 f를 다음 노드를 반환해주는 것으로 만들면 될 것이다.)

def floyd(f, x0):
# The main phase of the algorithm, finding a repetition x_nu = x_2nu
# The hare moves twice as quickly as the tortoise
tortoise, hare = f(x0), f(f(x0))
while tortoise != hare:
tortoise = f(tortoise)
hare = f(f(hare))

Floyd의 논문에는 단순히 싸이클의 존재 유무를 떠나 모든 싸이클 (보다 엄밀하게는 simple cycle)을 다 찾고 나열할 수 있는 알고리즘이 나와있다 (Fig. 5~8). 그러나 정확히 위의 pseudo code처럼 토끼와 거북이를 명시한 알고리즘은 아니다.

Floyd는 이런 알고리즘을 Back-tracking 알고리즘과 구분하여 Nondeterministic 알고리즘이라고 부른다. 흔히 우리가 알고 있는 Nondeterministic Turing Machine의 행동과 비슷하다. NTM에서는 다음 스텝으로 갈 때, 일반적인 Deterministic TM처럼 한 곳으로만 가는 것이 아니라 (확률에 의존적이지가 않고) 여러 군데로 가는 것을 허용한다. Floyd가 제안한 Nondeterministic 알고리즘은 이와 유사하게 multivalued function (아래 참고)을 도입하여 비결정성을 구현하고 있다. 그러나 결국 컴퓨터로 돌리기 위해서는 deterministic 해야 하니 실제 모든 루프(=싸이클)를 찾는 알고리즘을 보면 (컴파일러 최적화에서 쓰이는 것) Floyd가 제시한 알고리즘과 매우 유사하지만 모든 스텝이 결정적으로 이루어져있다. 더 이상 쓰려니 머리가 아파서 그만...

암튼 결론은 리스트에서 싸이클을 찾고 싶을 때 토끼와 거북이를 이용하라는 것.


@ Multivalued function: 간단하게 말하면, 함수는 x원소에 대응되는 y 원소가 오직 하나 뿐임에 비해 이 multivalued function은 f(x)가 여러 개의 y 값을 가지고 있음. 즉, 일반적인 함수의 정의에는 위배됨.

@ 그냥 관심있으면 보시라고 Floyd의 논문을 직접 다운 받아 여기에 올렸는데 설마 잡아가지는 않겠지...

p636-floyd.pdf
by object | 2008/01/07 17:21 | 컴퓨터 | 트랙백(1) | 덧글(15)
트랙백 주소 : http://minjang.egloos.com/tb/1687021
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from Xeraph Online at 2008/01/30 15:16

제목 : SICP 연습문제 3.19 토끼와 거북이
리스트를 살펴보고 그 속에 고리가 들어 있는지 살펴보는 프로시저를 만들어라. 리스트 속에 고리가 있다면, 리스트 끝을 cdr 연산으로 찾으려 해도 끝이 나지 않는다. 딱 정해진 만큼의 공간만 쓰는 알고리즘을 만들어 풀어 보아라. (define (cycle? lst) (define (race tortoise hair) (cond ((eq? tortoise hair) #t) &nb......more

Commented by 파파울프 at 2008/01/07 17:27
허윽... @@ 눈이 핑핑 돕니다. 저도 나름 이학 출신인데... 으...
Commented by codewiz at 2008/01/07 17:38
기가 막힌 방법이네요...
두번째 그림을 보면서 탄식했습니다... 흐흐~~
어떻게 저런 방법을 생각해 냈는지 ...
Commented by object at 2008/01/07 17:40
천재들만이 할 수 있는 영역이죠 ㅎ
Commented by 4four at 2008/01/07 17:44
O(1) 공간만을 이용해서 싸이클을 찾는 방법이라.. 아이디어가 참 재미있네요. 그리고 글을 읽다보니 리스트를 함수로 일반화할 수가 있군요. 토끼와 거북이의 영어 표현도 그렇고.. 여러가지로 배우고 갑니다.
Commented by kc at 2008/01/07 17:54
PowerPoint2007에서는 저런 다이어그램을 그냥 그릴 수 있단 말입니까?
쉐이딩도 그렇고 사람들을 홀리기에는 딱 좋은 다이어그램 스타일인데요... ^^
Commented by object at 2008/01/07 18:00
네.. 오피스 2007에서는 그리기가 매우 강력해졌습니다. 토끼와 거북이 그림도 그냥 파워포인트에서 바로 찾아서 넣었습니다.
Commented by xeraph at 2008/01/07 19:07
오.. (..감탄) 한 번 리스트 순회하면서 중간 노드를 찾아내는거랑 비슷한 방법이군요.
Commented by 머스타드 at 2008/01/07 19:33
O(n) 시간에 O(1) 공간이라니... ㄷㄷㄷ
Commented by 수아기 at 2008/01/08 00:03
멋진걸요. 역시 천재들의 영역이란...
사이클 찾기가 은근히 쉬운것은 아니였는데 저렇게 딱 주어진 조건에서는 특히나 말이죠
우왕~~ 잘 보고 갑니다.
Commented by object at 2008/01/08 02:49
xeraph님.. "한 번 리스트 순회하면서 중간 노드를 찾아내는거"는 어떤 것이죠? 좀 알려주세요~
Commented by felucca at 2008/01/08 03:32
논문 한글로 번역해서 올려놓으면 못 잡아갈껄요 ㅋㅋㅋ
Commented by 박상민 at 2008/01/08 07:38
예전에 동아리형이 구글 면접문제라면서 알려주신 것이네요.
그 때에는 이걸 보고 정말 신기하다고 생각했었는데,
이름도 있는 알고리즘이었군요. ㅎㅎ
Commented by 박상민 at 2008/01/08 07:39
리스트를 한 번 순회하면서 중간노드를 찾는것도 똑같이 하면 될 것 같은데요.
포인터 한개는 두 칸씩 움직이고, 한개는 한칸씩 움직이면
먼저가는 포인터가 끝에 닿는 시점에, 뒤쳐지는 포인터는 중간을 가르키겠네용. ㅎㅎ
Commented by object at 2008/01/08 12:20
훌륭하다 역시...
Commented by Sungbae at 2008/01/08 16:30
리스트에서 사이클 있는지 찾는 문제는 면접에 자주 나오나봐요. 저번에 저도 N사 인터뷰에서 나왔던 문제였습니다. 구체적으로 이 알고리즘을 물은 건 아니고 어떻게 찾을 수 있을지 물어봤었어요.

:         :

:

비공개 덧글

<< 이전 페이지 다음 페이지 >>





by 김민장 2008 이글루스 TOP 100
최근 등록된 덧글
개발자 입장에서의 수많은 ..
by Jiyoon at 02/04
저도 아들 돌잔치때 돌잡이 ..
by 박상욱 at 01/18
미국 대학원 원서 작성중에 p..
by 태클사이야 at 01/13
TO: 박PD 로그인 하지 않아..
by 박응용 at 01/10
http://gigglehd.com/zbx..
by dhunter at 12/28
우와.. 좋네요. 태반이 ..
by 윤광배 at 12/17
항상 좋은 글 잘 보고 있습니..
by y2k at 11/23
글이 좋아서 제 블로그에 담..
by 쏭섭 at 11/23
최근 등록된 트랙백
조엘 스폴스키의 강연 (Sta..
by 인덕원칸타타
[Redis] sds.c를 분..
by 조급하지말고 천천히
메뉴릿
이글루 파인더

website counter

Add to Google

rss

skin by 이글루스