창조론 이야기 - 실패의 의의

깊은 정글에서 일군의 탐험가들이 보물을 찾고 있습니다. 그들은 어느새 수십개의 동굴이 늘어서 있는 절벽에 도착했습니다. 그들중 절반은 주저앉아서 말합니다.
"여기가 끝이야. 여기에 보물이 있을 리가 없어."
그러나 나머지 사람들은 동굴 몇 곳으로 나뉘어 들어갑니다. 그중 한 동굴에서 사람들이 나와서 보고합니다.
"이 동굴에는 아무것도 없습니다."
그들은 그 동굴에 ×팻말을 붙여놓고는, 천막으로 와 물을 마십니다.
그것을 보고 주저앉아 있던 사람들이 말합니다.
"거봐, 여기는 아무것도 없다니까..."
"맞아, 빨리 집에 가서 하나님께 기도나 하자구..."

창조론자들에게 커다란 떡밥이 제공된 것 같습니다. 과일 파리의 진화실험이 실패했다는 내용이군요

창조론자들은 진화가 불가능함이 입증되었다고 좋아하는 것 같습니다만, 이 실험이 입증한 것은 '진화가 불가능함'이 아닙니다. '이런 식으로의 진화는 일어나지 않는다', 그러므로 '다른 방식으로 진화를 실험해 보자'는 것이 이 실험 실패의 의의입니다.

창조론자들이 뭐라고 하든 진화론자들은 여러가지 방법을 동원해서 과일파리의 진화를 성공시킬 것입니다. 그렇게 되면 아무 일도 하지 않던 창조론자들은 '파리의 소진화일 뿐이다'라고 주장하겠죠(박테리아의 진화실험에서처럼 말입니다).

그렇게 주저앉아 있는 탐험대원들을 보며 탐험대장이 물을 마시고 있는 신입대원에게 말합니다.
"예전에 에디슨이라는 탐험대장과 함께 '전구'라는 보물을 찾으러 간 적이 있었지. 그때도 지금과 같은 상황이었어. 수천개의 동굴을 뒤져야 했다고.
그때도 저치들은 '전구같은 게 여기 있을리가 없다'면서 주저앉아 있었지. 하지만 에디슨대장은 수천개의 동굴을 모두 뒤져서 전구를 찾아냈지 뭔가."
"그 보물은 어떻게 됐나요?"
"탐험대 전원이 나눠가졌지. 주저앉아있던 저치들을 포함해서 말일세"
"그런데 여기 정말 '진화'라는 보물이 있을까요?"
"나도 알 수 없다. 하지만 체념은 저 동굴들을 모두 뒤져본 후에 해도 늦지 않아. 그리고 보물이 없다고 해도 '진화란 보물은 없다'는 사실을 알았다는 자체가 우리에게는 보물이지"
"그런데 정말 '진화'란 보물이 나온다면, 저 아무일도 하지 않은 사람들과 나누어가져야만 하나요?"
"자, 쓸데없는 말 그만하고 다시 시작하자구."
대장은 신입대원을 데리고 ×팻말이 붙어있지 않은 동굴을 향해 발걸음을 옮깁니다.

진화론 이야기 - 어류는 양서류로 진화하지 않는다.

제목보고 의아하게 생각하시는 분들 많을지도... 어류가 양서류로 진화했다는 것은 정설인데 무슨 소리? 얘가 진화교에 심취하더니, 드디어 정신이 나갔구나...

진화가 뭔지 제대로 모르는 창조론자들이 흔히 이런 말을 하죠.
어류가 양서류로 진화했다고 하는데 왜 지금은 양서류로 진화하는 어류를 볼 수가 없냐? 이것만 봐도 진화론은 거짓이다.

결론부터 말하자면 어류는 양서류로 진화했습니다. 그러나 어류는 양서류로 진화하지 않습니다. 여전히 정신나간 소린가요?^^

Tiktaalik
약 3억 6천만년 전, 어류들은 얕은 여울가까지 진출했습니다. 얕은 물에 몸을 반쯤 담그고, 헤엄치는 대신 바닥을 기어다닐 수 있는 틱타알릭류(?)로 진화한 것입니다
.

이러한 육지로의 진출시도는 쉽게 성공하지 않았습니다. 수많은 어류들이 육상으로 오르려다 실패를 거듭한 끝에 마침내 한 종이 육상으로의 진출에 성공한 것입니다.

그들이 뭍에 올랐을때, 뭍은 텅 비어 있는 상황이었습니다. 이렇게 생태적으로 비어 있는 공간에 어느 한 종이 진출했을 때 그들은 급속하게 종분화를 하게 됩니다. 그들 역시 비어있는 뭍으로 퍼져나가며 다양하게 종분화를 하게 됩니다.

이렇게 최초로 뭍에 진출한 어류의 후손이 '양서류'입니다.이들은 하나의 조상에서 분화했기에 동일한 특성 - 축축한 피부, 피부호흡, 껍질없는 알을 물 속에 낳기 등 - 을 가지고 있고, 그때문에 '양서류(양서강 - Amphibia)'라는 분류체계를 형성하게 된 것입니다.

그렇다면 지금도 어류가 양서류로 진화할 수 있을까요?
① 다시한번 말하지만 3억 6천만년 전 뭍은 텅 비어 있었습니다. 갓 뭍으로 올라와 비틀거리는 틱타알릭류가 뭍에 익숙해질 때까지 그들을 방해할 만한 천적들이 없었습니다.
만약 지금 다시 어류의 일부가 뭍으로 올라가겠다고 짧은 지느러미로 버둥거린다면 어떨까요? 뭍에서 기다리고 있던 육상동물들의 맛있는 먹이가 되어 도태될 뿐입니다.
② 혹시나, 태평양 한가운데에 화산섬이 생긴다면, 그리고 수천만년동안 외부 동물들이 이 섬에 들어오지 못한다면 그 섬에서 다시한번 어류가 육상으로 진출하는 진화가 일어날지도 모르겠습니다. 하지만 그곳에서 육상으로 진화한 생물이 과연 양서류일까요?

그들은 양서강(Amphibia)이 아닐 것입니다. 파충강(Sauropsida)도 아닐 테고, 포유강(Mammalia)이나 조강(Avian)은 더욱 아니겠죠. 이들은 새로운 분류체계를 만들어서 제 5의 강으로 분류해야 할 것입니다. 왜냐하면 현재의 양서류들과는 전혀 다른 조상에서 발생했기 때문입니다.

진화에는 정해진 길이란 없습니다. 까마득한 과거에 어류가 양서류로 진화했다어류는 양서류로 진화한다고 할 수는 없습니다.

진화론 이야기 - 몸의 탄생

지구상에 최초의 생명이 탄생한 것은 약 30~40억년 전으로 생각되고 있습니다. 그 후 약 30억년동안 지구상의 생물들은 단세포생물들 뿐이었습니다.
그러다가 약 6억년전, 선캄브리아기를 전후해서 생물들은 앞다투어 '몸'을 만들기 시작했습니다. 바로 다세포생물의 탄생이었죠.
어떤 이유로 인해 30억년동안 단세포로 지냈던 생물들이 갑자기 몸을 만들기 시작했을까요?

1. 세포의 동아줄
다세포생물의 경우 세포들 사이의 접착제는 오른쪽 그림과 같은 콜라겐입니다(그림출처) 이렇게 밧줄처럼 생긴 콜라겐에 의해 세포들이 접착되는 것이죠. 노화가 진행될 때 피부가 푸석푸석해지는 것 역시 피부속에 들어있던 콜라겐이 분해되면서 피부세포들간의 접착력이 줄어들기 때문입니다.

최초의 다세포생물들 역시 이런 콜라겐을 만듦으로써 이분법에 의한 무성생식 후 완전히 떨어지지 않게 된 것이라 생각하고 있습니다.

2. 다세포가 되기 위한 선택압
만약 일부 세포가 콜라겐에 의해 다세포를 이루었다면, 그러한 다세포생물이 자연선택에서 살아남기 위한 선택압이 있어야 합니다. 그렇지 않다면 결국 다세포생물은 도태되고 말 것입니다.

이에 대한 실험결과1)가 있습니다.
단세포로 존재하는 조류(藻類 : algae)를 수천세대 배양한 후, 그 조류를 먹는 포식자를 풀어놓았습니다. 그 포식자는 편모로 조류들을 추적하며 잡아먹어 소화시키는 녀석들이었죠.
그러자 불과 200세대만에 조류들은 서로 뭉치기 시작했습니다. 혼자서 다니는 조류보다는 뭉쳐서 존재하는 조류들이 이 포식자를 피하기가 용이했기 때문이었죠. 조류들은 수천개의 세포로 이루어진 덩어리가 되었습니다.
그러나 이렇게 수천개 덩어리의 중심부에 있는 조류들은 햇빛을 받을 수 없었기에 도태되기 시작했습니다. 시간이 지나면서 조류들이 이루는 덩어리는 점점 작아지기 시작했습니다.
그리하여 마침내 조류는 세포 8개로 이루어진 덩어리로 존재하기 시작했습니다. 즉 단세포생물에서 군체생물로의 진화가 일어난 것이죠. 게다가 포식자를 제거한 후에도 이 8개세포의 군체는 흩어지지 않고 군체로서의 삶을 계속하게 되었습니다.

3. 그렇다면 왜 30억년이 걸렸을까?
위의 실험에서 보듯이 포식자가 있다면 다세포생물(정확히는 군체생물)로의 진화는 매우 쉽게 일어납니다. 그렇다면 왜 저런 진화가 더 일찍 일어나지 않았을까요? 왜 최초의 다세포생물의 화석이 6억년 전의 지층에서발견되기 시작했을까요?

그것은 지구의 환경 때문입니다. 콜라겐을 합성하기 위해서는 상당히 많은 산소가 필요합니다. 그런데 초기 지구에는 산소가 거의 없었습니다.
즉, 몸을 만들기 위해서는 먼저 광합성을 하는 생명체가 탄생하고, 그 후에 산소가 지구에 가득 차게 되고, 또 그 산소를 이용할 수 있는 생명체가 탄생한 후에야 몸을 만들 수 있었던 것입니다.

4. 그렇다면 왜 단세포생물이 남아 있을까?
창조론자들의 성향으로 보아 틀림없이 이런 질문이 나올 듯 합니다. '다세포가 되면서 포식의 위험에서 벗어났다면 왜 단세포동물들이 남아 있느냐?'
먹이인 단세포동물이 모여 거대해진다면 포식자는 가만히 있을까요? 그것은 역시 포식자에 대한 선택압으로 작용하여 포식자들 역시 다세포생물이 되어야 합니다. 그러나 포식자들 역시 거대해진다면 오히려 단세포인 생물들이 다세포포식자를 피해 살아남을 수 있게 되죠.
결국 생태계는 다세포생물과 단세포생물이 균형을 이루게 되고, 그것이 현재까지 유지되고 있는 것입니다.


reference
1) Boraas. M. E., Seale. D. B., Boxhom. J. (1998) Phagotrophy by a flagelate selects for colonial prey : A possible origin of multicellularity, Evolutionary Ecology 12:153~164

출처 : 내 안의 물고기(닐 슈빈 저)

요리하는 여자

한 연인이 있었습니다.
어느날 여자는 남자친구를 저녁식사에 초대했습니다.

남자친구가 도착하자, 여자는 준비했던 스테이크를 만들기 시작했습니다. 그녀는 손질되어 있는 고기 한귀퉁이를 잘라내고 큼지막한 프라이팬에 올렸습니다.
그것을 보고 남자는 물었습니다.
"고기 한쪽은 왜 잘라냈어? 상한 부분이었나?"
"아니, 엄마가 요리할 때마다 고기 한쪽을 자르고 하셔서 그냥..."

그 말을 듣고 보니 그녀도 어머니가 왜 고기를 잘라냈는지 궁금해졌습니다. 그래서 어머니에게 전화를 걸었습니다.
"엄마, 엄마가 스테이크 만들때 늘 고기 한쪽을 잘라내잖아, 왜그런거야?"
"갑자기 그건 왜 묻니? 네 외할머니가 스테이크 만들때마다 잘라내서 그냥 따라한 건데..."

그녀는 더욱 궁금증이 생겼습니다. 결국 그녀는 외할머니에게까지 전화를 걸었습니다.
외할머니의 대답은 이랬습니다.
"그거? 그때 집에 있던 프라이팬이 너무 작아서 고기가 다 안들어갔었거든. 그래서 조금 잘라내고 구웠지."

스스로 이유를 찾지 않으면 이렇게 쓸데없는 삽질을 하게 되는 경우가 있습니다.

- 출처 : 리더스 다이제스트

진화론 이야기 - 단속평형설(Punctuated Equilibrium)의 오해

진화론에서 이야기하는 다른 많은 이론들도 마찬가지겠지만, 1972년 엘드리지와 굴드가 발표한 단속평형설은 특히나 더 창조론자들의 오해를 많이 받고 있습니다. 물론 그 이유는 진화론을 비난하는 창조론자들이 단속평형설을 전혀 모르고 있기 때문, 그리고 절대 알려고 하지 않기 때문이죠.

100만년전 지층에서 몸길이 10cm의 화석이 발견되었습니다. 그리고 1만년전 지층에서는 몸길이 1m인 또다른 화석이 발견되었습니다. 두 화석의 골격을 비교해본 결과 두 화석은 같은 계통으로 100만년전 10cm에 불과했던 동물이 1만년전에는 1m까지 커지는 진화가 일어났다는 결론을 내립니다.
이때 창조론자들은 다음과 같은 그래프를 내밀며 주장합니다.


[진화론이 맞다면 이 그래프처럼 점진적으로 진화해 왔다는 것인데,그렇다면 30cm, 50cm, 60cm짜리 화석은 왜 안나오느냐?]


단속평형론에 대한 창조론자들의 오해는 다음과 같은 것이 있습니다.


1. 단속평형설은 바람직한 괴물 이론이다. - 단속평형설에 의하면 10cm짜리 동물이 어느날 갑자기 1m짜리 새끼를 낳기 시작했다는 이야기인데 말이 됩니까?
원래 '바람직한 괴물 이론'을 주창한 것은 굴드가 아니라 골드슈미트(Richard Goldschmidt, 1878-1958)입니다. 골드슈미트는 때때로 일어나는 거대돌연변이가 생존에 유리할 경우(즉 괴물이 태어났는데 그것이 '바람직한 괴물'일 경우) 그것이 새로운 종이 된다고 주장했습니다. 단속평형설은 골드슈미트의 이론과 전혀 관계가 없습니다. 단지 변화가 급격하게 일어난다는 공통점만으로 단속평형설과 바람직한 괴물 이론을 헷갈리는 것입니다.

단속평형설은 일반적인 진화론과 마찬가지로 '점진적 변화'를 말합니다. 다만 단속평형설에서 주장하는 것은 '변화의 속도가 일정치 않다'는 것입니다. 마치 다음 그림과 마찬가지입니다.



즉 일반적인 진화론이 '이 동물의 크기가 99만년동안 1년에 약 0.001mm씩 점진적으로 변화해 왔다'는 것에 비해 단속평형설은 '이 동물의 크기는 '45만년동안 거의 변화가 없다가 10만년에 걸쳐 1년에 약 0.01mm씩 점진적으로 변화한 후 다시 45만년동안 거의 변화가 없다'는 것입니다. 그에 의하면 50cm짜리 화석이 발견될 가능성은 10%로 감소하게 됩니다.
만약 그러한 변화가 1000년에 걸쳐 점진적으로 일어났다고 해도 이 동물의 크기변화는 1년에 1mm 증가라는, 말이 안되지 않는 변화입니다. 그리고 이렇게 된다면 50cm짜리 화석이 발견될 가능성은 0.1%밖에 안되는 것이죠.


2. 단속평형설은 중간화석의 부재를 설명하기 위해 억지로 만든 가설이다. - 이렇게 중간화석이 발견되지 않으니까 굴드 같은 진화설자들은 단속평형설을 대충 만들어서 주장하고 있습니다.
일단 단속평형설은 중간화석의 부재를 설명하기 위해 만들어진 것은 맞습니다. 하지만 '대충 만든 가설'은 아닙니다.

1960년대 이후 생물학은 새로운 강력한 도구를 얻게 되었습니다. 바로 컴퓨터였죠. 컴퓨터 시뮬레이션을 통해서 수천년 걸릴 변화도 며칠 안에 알 수 있게 되었습니다. 그에 따라 진화론에서 나왔던 여러 이론들을 실험실은 아니지만 컴퓨터 가상세계 안에서 시뮬레이션이 가능해졌습니다.

단속평형설 역시 실험실에서 실험하기에는 쉽지 않은 이론입니다. 하지만 컴퓨터 안에서 실험하기는 어렵지 않죠.
생물학자들은 컴퓨터 내부에서 유전자의 움직임을 시뮬레이션했습니다. 그 결과 단속평형설에서 예측했던 '적응성의 도약'현상이 발견되었습니다. 생물의 적응성이 한동안 정체하다가 마치 위 그래프처럼 짧은 시간에 높은 적응성으로 뛰어오르는 현상이 발견된 것입니다.


유전자를 검사해본 결과는, 유전자는 꾸준한 변화(진화)를 보이고 있었습니다. 그러나 그 무리의 적응도는 그다지 큰변화가 없는 상황이 한동안 계속되었습니다. 그러다가 유전자의 진화가 어느 임계점을 넘었을때 그 유전자가 무리 전체로 퍼지면서 비교적 짧은 시간내에 전체 적응성이 올라가는 현상이 발견된 것이죠.(인공생명<스티븐 레빈> 참조)

<2010.11.5일 본문 수정>

창조론 이야기 - 선무당이 사람 잡는다.

어느 신학자가 있습니다. 그의 주장은 '물리학은 거짓이다. 이 세상은 오로지 신의 뜻대로 움직일 뿐이다.물리학에서 말하는 각종 이론과 법칙들은 모두 사탄의 수작이다'입니다.

물론 그의 이론은 많은 사람들이 반론합니다. 개중에는 '물리학책 한권이라도 보고 이야기하는 것이냐'라는 반론도 있습니다.
이 신학자는, 그 말에 반론하기 위해 물리학책을 삽니다. 그리고 아무데나 펼칩니다. 마침 '부력'에 대한 설명이 있군요. 여러가지 실험결과와 함께 결론이 있습니다.
[그러므로 유체 내의 고체는 고체가 밀어낸 유체의 무게만큼의 부력을 받게 되며, 물체가 이보다 가벼우면 물에 뜨게 된다]
그러나 그의 눈의 필터가 작동, 이 글은 다음과 같이 보이게 됩니다.
[그러므로 유체 내의 고체는 고체가 밀어낸 유체의 무게만큼의 부력을 받게 되며, 물체가 이보다 가벼우면 물에 뜨게 된다]
그는 책을 덮고는 신나게 컴퓨터로 달려가 다음과 같은 글을  올립니다.

'저도 물리학 공부를 할만큼 했습니다. 그런데도 물리학은 오류 투성이더군요. 말하자면 물리학의 부력 설명은 물체가 가벼우면 물에 뜬다고 되어 있습니다. 그렇다면 물에 가라앉는 바둑돌과 물에 뜨는 항공모함과 어느쪽이 가벼운가요?'

GA - 미로 속 슬라임 - 흠뻑 젖은 슬라임

8. 젖은 슬라임
앞과 같은 미로를 통과하기 위해서는, 슬라임이 과거에 어디를 통과했는지에 관한 기억이 필요합니다. 그래서 왔던길로 돌아가지 말아야 하는 것이죠.

내가 어디서 왔는지를 표시하기 위해 슬라임이 수액을 분비한다고 해 봅시다. 슬라임은 이동할 때마다 자신이 있는 위치를 수액으로 흠뻑 적십니다. 슬라임의 이동경로를 따라 수액의 흔적이 남을 겁니다. 이 수액은 시간이 갈수록 조금씩 말라갑니다.
그와 함께 슬라임은 자기 주위의 습기를 알 수 있는 감지기를 가지고 있습니다. 이것으로 자기가 어디서 왔는지 알 수 있겠죠.

이 젖은슬라임을 만들기 위해서는 약간의 변형이 필요합니다. 먼저 미로에 습기를 저장할 수 있도록 해야 합니다.

procedure MazeProcess(slime, maze)
   // 슬라임을 출발점에 세움
   slime.LocX := 1
   slime.LocY := 1
   maze.Clear() // 미로 안의 모든 습기 제거

   // 미로 안에서 슬라임 움직임
   for k := 0, 900 do // 미로 안에서 슬라임이 움직이는 횟수
                     // 미로가 클수록 커져야 함
      // 미로 안의 습기 말리기
      for x := 0, 15 do
         for y := 0, 15 do
            if maze.Wet[x][y] > 0 then
               maze.Wet[x][y] := maze.Wet[x][y] - 1
            end
         end
      end

      // 슬라임이 수액 분비
      maze.Wet[slime.LocX][slime.LocY] := 100

      // 어디로 움직일지 생각
      movedirect = SlimeThink(slime, maze)

      // 이동할 위치
      if movedirect == 'E' then
         newx := slime.LocX + 1
         newy := slime.LocY
      elseif movedirect == 'W' then
         newx := slime.LocX - 1
         newy := slime.LocY
      elseif movedirect == 'S' then
         newx := slime.LocX
         newy := slime.LocY + 1
      elseif movedirect == 'N' then
         newx := slime.LocX
         newy := slime.LocY - 1
      end

      // 이동한 결과 계산
      if maze.IsBlock(newx, newy) then // 블럭에 충돌
         slime.Fitness := slime.Fitness - 10 // 적응도 감소
      else // 충돌하지 않을 경우
         slime.LocX := newx
         slime.LocY := newy
         slime.Fitness := slime.Fitness - 1 // 적응도 감소

         // 목적지에 도착했나?
         if maze.IsGoal(slime.LocX, slime.LocY) then
            slime.Fitness := slime.Fitness + 1000 // 적응도 대폭 증가
            break // for 루프 탈출
         end
      end
   end
end


즉 슬라임이 있는 위치의 습도는 100, 슬라임이 떠난 후 1씩 감소합니다.

function SlimeThink(slime, maze)
   // 슬라임 동서남북의 블럭정보 얻기
   curstate.detect.EastBlock := maze.IsBlock(slime.LocX + 1, slime.LocY)
   curstate.detect.WestBlock := maze.IsBlock(slime.LocX - 1, slime.LocY)
   curstate.detect.SouthBlock := maze.IsBlock(slime.LocX, slime.LocY + 1)
   curstate.detect.NorthBlock := maze.IsBlock(slime.LocX, slime.LocY - 1)

   // 사방의 습기 찾기
   curstate.detect.EastWet := maze.WetOrder(slime.LocX + 1, slime.LocY)
   curstate.detect.WestWet := maze.WetOrder(slime.LocX - 1, slime.LocY)
   curstate.detect.SouthWet := maze.WetOrder(slime.LocX, slime.LocY + 1)
   curstate.detect.NorthWet := maze.WetOrder(slime.LocX, slime.LocY - 1)

   // 나갈 입구의 방향 찾기
   curstate.detect.ExitEast := maze.IsExitEast(slime.LocX, slime.LocY)
   curstate.detect.ExitWest := maze.IsExitWest(slime.LocX, slime.LocY)
   curstate.detect.ExitSouth := maze.IsExitSouth(slime.LocX, slime.LocY)
   curstate.detect.ExitNorth := maze.IsExitNorth(slime.LocX, slime.LocY)
   // GeneList(유전자들의 묶음)에서 curstate 찾기
   fnd := slimt.GeneList.Find(curstat)
   if fnd == nil then // 처음 만나는 상황
      // effect부분을 랜덤으로 만듦
      for k := 0, 10 do
         curstate.effect[k] = Random("EWSN") // EWSN 중에서 하나 선택
      end
      slime.GeneList.Append(curstate) // 현재 상황 추가
      fnd = curstate
   end
   // 여기까지 해서 fnd에는 현재상황에 맞는 유전자가 들어있음

   return fnd.effect[Random(0, 9)]
end

이때 EastWet~NorthWet을 설정하는 데는 각 방향의 습기를 그대로 저장할 수도 있지만, 그렇게 된다면 유전자 수가 너무 많아질 수 있습니다. 동서남북 최대 100단계이니 100000000개 가까이 유전자가 늘어날 수 있죠(물론 불가능한 조합도 있습니다만)
그러므로 여기서는 각 방향의 습기 등수를 가져오도록 했습니다(가장 많이 젖은 곳이 0, 그다음 젖은 순서대로 1, 2, 3). 그 외는 앞의 슬라임과 동일합니다.

9. 젖은 슬라임의 결과
'수액에 젖은' 슬라임으로 100세대를 진화시킨 결과입니다.


그리고 앞의 슬라임이 통과하지 못했던 미로를 통과한 결과입니다.


두 개의 미로 모두 최적의 슬라임이 탄생했습니다. 단, 두개의 미로를 모두 통과할 수 있는 슬라임이 태어난 것은 아닙니다. 첫째 미로를 돌파하는 슬라임을 둘째 미로에 넣는다면 제대로 못찾을 것입니다.
이러한 현상을 막기 위해서는 미로 자체를 변화시켜야겠죠.

GA - 미로 속 슬라임 - 결과

3. 재생산
재생산루틴은 오델로의 경우와 거의 동일합니다.
3.1 선택
재생산 대상 선택은, 여기서는 T=0.9, num=2(4개를 뽑아 2회 겨루기)인 토너먼트법을 사용했습니다.
3.2 교차
오델로의 경우와 비슷합니다. 두 슬라임의 유전자리스트를 동기화시킨 후 일정한 확률로 동일한 두 유전자를 교환합니다.
3.3 돌연변이
역시 detect부분은 건드리지 않고 effect부분 10개의 방향비트들을 일정한 확률로 바꿉니다.

procedure Mutantation(slime)
   for k := 0, size(slime.GeneList) do
      if RandomRate then
         // 모든 비트 돌연변이
         for b := 0, 10 do
            slime.GeneList[k].effect[b] := Random("EWSN")
         end
      else
         // 비트 하나하나 돌연변이
         for b := 0, 10 do
            if RandomRate then
               slime.GeneList[k].effect[b] := Random("EWSN")
            end
         end
      end
   end
end

4. 결과 1
우선은 위와 같은 방식으로 100세대를 진화시켰습니다. 각 세대마다 최고 적응도를 얻은 슬라임을 찾아 100번의 시도 중 성공횟수와 이동횟수, 충돌횟수를 그래프로 그린 것입니다.


그래프에서 잘 보이지는 않지만 성공횟수는 가장 밑에 깔려 있습니다(모두 0). 충돌횟수는 점점 줄어들고 반면 이동횟수는 늘어나지만, 정작 중요한 성공횟수에서는 좌절할 수밖에 없습니다. 즉, 슬라임의 진화는 대실패란 뜻이죠.ㅡㅡ;


5. 용불용설(用不用說 : Use Disuse Theory)
용불용설은 과학적으로 폐기된 이론입니다. 용불용설이 설득력을 가지려면 외부 환경이 유전자에 직접 영향을 미치는 메커니즘이 밝혀져야 합니다. 그러나 환경이 유전자에 영향을 미치는 그러한 메커니즘은 자연계에서 발견되지 않았습니다.
하지만 이 슬라임의 창조주(?)는 프로그래머입니다. 이 슬라임에 용불용설을 설계해 놓는 것은 프로그래머 마음이죠(어째 창조론/지적설계론자가 된듯....)
여기서는 슬라임이 장애물에 충돌한다면, 슬라임을 충돌시킨 유전자를 수정하는 식으로 코딩했습니다.


function SlimeThink(slime, maze)
   // 슬라임 동서남북의 블럭정보 얻기
   curstate.detect.EastBlock := maze.IsBlock(slime.LocX + 1, slime.LocY)
   curstate.detect.WestBlock := maze.IsBlock(slime.LocX - 1, slime.LocY)
   curstate.detect.SouthBlock := maze.IsBlock(slime.LocX, slime.LocY + 1)
   curstate.detect.NorthBlock := maze.IsBlock(slime.LocX, slime.LocY - 1)

   // 나갈 입구의 방향 찾기
   curstate.detect.ExitEast := maze.IsExitEast(slime.LocX, slime.LocY)
   curstate.detect.ExitWest := maze.IsExitWest(slime.LocX, slime.LocY)
   curstate.detect.ExitSouth := maze.IsExitSouth(slime.LocX, slime.LocY)
   curstate.detect.ExitNorth := maze.IsExitNorth(slime.LocX, slime.LocY)

   // GeneList(유전자들의 묶음)에서 curstate 찾기
   GeneFind := slimt.GeneList.Find(curstat)
   if GeneFind == nil then // 처음 만나는 상황
      // effect부분을 랜덤으로 만듦
      for k := 0, 10 do
         curstate.effect[k] = Random("EWSN") // EWSN 중에서 하나 선택
      end
      slime.GeneList.Append(curstate) // 현재 상황 추가
      GeneFind = curstate
   end
   // 여기까지 해서 fnd에는 현재상황에 맞는 유전자가 들어있음

   GeneSlot = Random(0, 9)
   return GeneFind.effect[GeneSlot]
end

여기서 GeneFind와 GeneSlot은 전역변수입니다. 즉 이번 슬라임의 이동에 영향을 준 유전자를 저장하고 있습니다. 그리고

procedure MazeProcess(slime, maze)
   // 슬라임을 출발점에 세움
   slime.LocX := 1
   slime.LocY := 1

   ........

      // 이동한 결과 계산
      if maze.IsBlock(newx, newy) then // 블럭에 충돌
         slime.Fitness := slime.Fitness - 10 // 적응도 감소
         GeneFind.effect[GeneSlot] := Random("EWSN")// 충돌시킨 유전자 수정
      else // 충돌하지 않을 경우
         slime.LocX := newx
         slime.LocY := newy
         slime.Fitness := slime.Fitness - 1 // 적응도 감소

         // 목적지에 도착했나?
         if maze.IsGoal(slime.LocX, slime.LocY) then
            slime.Fitness := slime.Fitness + 1000 // 적응도 대폭 증가
            break // for 루프 탈출
         end
      end
   end
end

즉,돌연변이에 의해 장애물에 충돌하는 슬라임이라도 이후에는 그 유전자를 수정하여 더이상 충돌하지 않도록 만드는 것입니다.

6. 결과 2
용불용설까지 적용한 결과는 다음과 같습니다.


하나의 그래프로 나타내기 위해 적당히 배율을 조정했습니다. 여기서 뚜렷이 알 수 있듯 충돌횟수는 급격히 줄어들었습니다. 무엇보다 성공횟수가 불과 7세대만에 만점(100번 시도에 100번 성공)에 도달했으며, 그 후에도 이동횟수도 점차 감소하는(헤매지 않고 목적지로 이동하는) 현상을 보이고 있습니다. 아까의 대실패에 비하면 성공인듯 싶군요.

그런데 과연 성공일까요?

7. 이 슬라임의 약점
이번에는 이 슬라임을 다음과 같은 미로에 넣어 보도록 합시다.

@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
@ S                         @
@ @ @ @ @ @ @ @ @ @ @ @ @   @
@                           @
@   @ @ @ @ @ @ @ @ @ @ @ @ @
@                           @
@ @ @ @ @ @ @ @ @ @ @ @ @   @
@                           @
@   @ @ @ @ @ @ @ @ @ @ @ @ @
@                           @
@ @ @ @ @ @ @ @ @ @ @ @ @   @
@                           @
@   @ @ @ @ @ @ @ @ @ @ @ @ @
@                         E @
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @

이러한 미로에서 100세대동안 진화시킨 결과는 다음과 같습니다.


미로만 바꾸었을 뿐인데 성공률은 뚝 떨어지고 말았습니다. 왜 이런 결과가 나왔을까요.
다음과 같이 슬라임이 1번위치에 있을 때와 2번위치에 있을 때를 비교해 봅시다.

@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
@                           @
@ @ @ @ @ @ @ @ @ @ @ @ @   @
@     1                     @
@   @ @ @ @ @ @ @ @ @ @ @ @ @
@         2                 @
@ @ @ @ @ @ @ @ @ @ @ @ @   @
@                           @
@   @ @ @ @ @ @ @ @ @ @ @ @ @
@                           @
@ @ @ @ @ @ @ @ @ @ @ @ @   @
@                           @
@   @ @ @ @ @ @ @ @ @ @ @ @ @
@                         E @
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @


두 위치에 있을 때 주위의 장애물 구조는 동일합니다(남북에만 장애물). 또한 목적지의 방향 역시 동일합니다(남서쪽). 그럼에도 불구하고, 두 위치에 있을때 슬라임이 가야 할 방향은 반대입니다(1번일 경우는 서쪽으로, 2번에서는 동쪽으로).
그러므로 최초에 설계한 유전자로는 이 두 경우를 나눌 수 없고, 결국 이런 종류의 미로는 찾을 수 없다는 결론이 나옵니다.
과연 이러한 미로를 통과할 수 있는 슬라임은 탄생할 수 있을까요?

GA - 미로 속 슬라임 - 개요

"찾았다"
어느 병사의 외침에 다른 병사들이 달려왔다. 그들 한가운데에는 슬라임 한마리가 반투명한 몸체를 흔들며 서 있었다. 병사들은 슬라임을 둘러싸고 무기를 슬라임에게 향했다.
그것은 창 같지만 창이 아니었다. 창날이 있어야 할 곳에 넓적한 판자가 달려 있었다.
"시작하십시오"
대장이 옆에 있는 노마법사에게 말하자, 다섯명의 젊은 마법사들이 슬라임을 중심으로 오망성을 이루었다.
"자, 모두들 주의하시오. 저놈이 포위망을 뚫으면 안됩니다"
노마법사의 명령에 이어 젊은 마법사들은 주문을 읇기 시작했다. 갑자기 슬라임이 붉은 빛에 휩싸이는 듯 싶더니 몸부림을 쳤다. 그와 함께 병사들의 판자에서는 룬문자가 빛나기 시작했다. 그 판자에 닿은 슬라임은 감전이라도 된 듯 물러났다. 하지만 그와 함께 병사들 역시 몇걸음씩 뒤로 물러나곤 했다.
"힘내라, 밀리면 안된다!"
주문이 끝나갈 동안 병사들은 슬라임을 버티고 있었다. 마침내 붉은 빛이 잦아들면서 슬라임은 주먹만한 크기로 줄어들었다. 노마법사는 그제서야 유리병을 꺼내 슬라임을 넣었다.
"됐다. 성공이다."
"잘 됐다니 다행이군요. 그런데 그 슬라임을 뭐에 쓰려고 잡는 겁니까?
"보시겠습니까?"
대장과 함께 텐트로 돌아온 노마법사는 탁자 위의 천을 걷었다. 그곳에는 다음과 같은 미로가 있었다.

@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
@ S @           @           @
@   @   @ @ @   @ @ @     @ @
@       @       @           @
@ @ @ @ @   @ @       @     @
@           @   @ @ @       @
@   @ @ @ @ @       @   @ @ @
@   @           @ @ @       @
@   @   @ @ @       @ @     @
@   @   @         @         @
@       @     @ @     @     @
@ @ @ @     @       @       @
@   @       @   @ @     @ @ @
@               @         E @
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @

노마법사는 슬라임을 왼쪽 위에 넣고는 뚜껑을 닫았다. 그리고 오른쪽 아래에 있는 문을 열었다. 노마법사가 잠시 슬라임에게 주문을 걸자 슬라임은 미로를 돌아다니기 시작했다
"지금 저 슬라임은 자기 주위에 장애물이 있는지 없는지와, 출구의 방향만을 알 수 있습니다. 그것만으로 이 미로를 빠져나와야 합니다. 조금이라도 미로를 더 잘 찾는 슬라임들만 골라서 번식시키면 마침내는 미로를 빠져나오는 슬라임이 만들어질 겁니다. 저는 그런 슬라임을 만들려는 것입니다."
"호오.. 그래요? 그런데 미로찾는 슬라임은 뭐에 쓰실려구요?"
"예? 뭐에 쓸 거냐구요? 저... 그러니까... 글쎄요... 어디에 쓰면 좋을까요?"

1. 유전자 설계
다른 것도 마찬가지지만, 일반적으로 유전자는 어떤 상황에서 어떻게 행동할까로 정의하는 것이 쉽습니다.

1.1 상황패턴
위에서도 말했지만 슬라임이 알 수 있는 것은 동서남북에 장애물이 있는가와 출구의 방향입니다.
슬라임의 현 상황을 묘사하기 위해서는 8개의 숫자가 필요합니다. 만약 윗 그림의 슬라임이 S위치에 있다면


1101 1010

이 될 것입니다. 이때 앞 4자리는 동서남북의 장애물 유무(동, 서, 북쪽에 장애물이 있고 남쪽에는 없다), 뒤 4자리는 출구가 동서남북 어느 쪽에 있는지(출구는 동남쪽이 있음)를 의미합니다.

1.2 행동패턴
다음에는 이 슬라임이 어떻게 행동할까(어떤 방향으로 움직일까)입니다. 간단히 하자면, 동서남북 중 어느쪽으로 갈지만 묘사하면 됩니다. 그러므로 오델로의 경우와 마찬가지로 다음과 같은 상황과 행동의 묶음을 유전자로 할 수 있습니다.

(1101 1010 - S)
(1001 1101 - E)
(0011 1000 - N)
...


즉, 슬라임이 출발점에 있다면 그 슬라임은 남쪽으로 이동하게 될 것입니다.

그러나 만약 이 슬라임이 다음과 같이

@ @ @ @ @ @ @ @ @ @ @ @ @ @ @
@   @           @           @
@   @   @ @ @   @ @ @     @ @
@       @       @           @
@ @ @ @ @   @ @       @     @
@           @   @ @ @       @
@   @ @ @ @ @       @   @ @ @
@   @           @ @ @       @
@   @   @ @ @       @ @     @
@   @   @         @         @
@       @     @ @     @     @
@ @ @ @     @       @       @
@   @       @   @ @     @ @ @
@               @       S E @
@ @ @ @ @ @ @ @ @ @ @ @ @ @ @

출구 바로 앞까지 도착했다면 어떻게 될까요? 이때의 상황은 0011 1000이며, 유전자 묶음에서의 행동은 N, 북쪽으로 이동하는 것입니다. 결국 이 슬라임은 출구 바로 앞에서 좌절하겠죠.
그러므로 여기서는 행동패턴은 단일한 방향이 아닌 10% 단위의 확률로 나타내기로 했습니다. 이를테면


(0011 1000 - ENNENENNEW)

와 같이 할 수 있습니다. 여기서 E가 3개, W가 2개, N이 5개이므로 이 경우에는 동쪽으로 갈 확률 30%, 북쪽 50%, 서쪽 20%, 남쪽으로 갈 일은 없게 되겠죠. 이 슬라임은 30%확률로 동쪽으로 갈 것이며 목적지에 도착할 것입니다(물론 20% 확률로 서쪽으로 가겠지만, 그래도 목적지에 도착할 가능성이 0%는 아닙니다).

2. 미로찾기
전체적으로, 이 슬라임은 오델로와 비슷한 루틴을 가지고 있습니다. 각 슬라임은 최초에 아무것도 없는 상태에서 시작하며, 자신이 있는 위치에서 현재 상태를 감지, 유전자리스트에서 유전자를 찾습니다.
다음 함수는 현 위치에서 슬라임이 어느 위치로 이동할지 생각하는 함수입니다.

function SlimeThink(slime, maze)
   // 슬라임 동서남북의 블럭정보 얻기
   curstate.detect.EastBlock := maze.IsBlock(slime.LocX + 1, slime.LocY)
   curstate.detect.WestBlock := maze.IsBlock(slime.LocX - 1, slime.LocY)
   curstate.detect.SouthBlock := maze.IsBlock(slime.LocX, slime.LocY + 1)
   curstate.detect.NorthBlock := maze.IsBlock(slime.LocX, slime.LocY - 1)

   // 나갈 입구의 방향 찾기
   curstate.detect.ExitEast := maze.IsExitEast(slime.LocX, slime.LocY)
   curstate.detect.ExitWest := maze.IsExitWest(slime.LocX, slime.LocY)
   curstate.detect.ExitSouth := maze.IsExitSouth(slime.LocX, slime.LocY)
   curstate.detect.ExitNorth := maze.IsExitNorth(slime.LocX, slime.LocY)

   // GeneList(유전자들의 묶음)에서 curstate 찾기
   fnd := slimt.GeneList.Find(curstat)
   if fnd == nil then // 처음 만나는 상황
      // effect부분을 랜덤으로 만듦
      for k := 0, 10 do
         curstate.effect[k] = Random("EWSN") // EWSN 중에서 하나 선택
      end
      slime.GeneList.Append(curstate) // 현재 상황 추가
      fnd = curstate
   end
   // 여기까지 해서 fnd에는 현재상황에 맞는 유전자가 들어있음

   return fnd.effect[Random(0, 9)]
end

최초에 슬라임을 초기위치(1, 1)에 넣은 후 SlimeThink()를 실행, 미로를 진행하게 됩니다.

procedure MazeProcess(slime, maze)
   // 슬라임을 출발점에 세움
   slime.LocX := 1
   slime.LocY := 1

   // 미로 안에서 슬라임 움직임
   for k := 0, 900 do // 미로 안에서 슬라임이 움직이는 횟수
               // 미로가 클수록 커져야 함
      // 어디로 움직일지 생각
      movedirect = SlimeThink(slime, maze)

      // 이동할 위치
      if movedirect == 'E' then
         newx := slime.LocX + 1
         newy := slime.LocY
      elseif movedirect == 'W' then
         newx := slime.LocX - 1
         newy := slime.LocY
      elseif movedirect == 'S' then
         newx := slime.LocX
         newy := slime.LocY + 1
      elseif movedirect == 'N' then
         newx := slime.LocX
         newy := slime.LocY - 1
      end

      // 이동한 결과 계산
      if maze.IsBlock(newx, newy) then // 블럭에 충돌
         slime.Fitness := slime.Fitness - 10 // 적응도 감소
      else // 충돌하지 않을 경우
         slime.LocX := newx
         slime.LocY := newy
         slime.Fitness := slime.Fitness - 1 // 적응도 감소

         // 목적지에 도착했나?
         if maze.IsGoal(slime.LocX, slime.LocY) then
            slime.Fitness := slime.Fitness + 1000 // 적응도 대폭 증가
            break // for 루프 탈출
         end
      end
   end
end

여기서 충돌하지 않고 이동했을 때도 적응도를 감소시키는 것은, 목적지에 빨리 도달한 슬라임에게 적응도를 높여주기 위함입니다.
이런 식으로 각각의 슬라임은 저 미로를 100회씩 돌게 됩니다.

procedure MainRoutine
   for generation := 0, 100 do
      for k := 0, 4096 do
         SlimeList[k].Fitness := 0
         for m := 0, 100 do
            MazeProcess(SlimeList[k], Maze)
         end
      end
      Rebirth Next  Generation
   end
end