이 메시지는 외부 자료를 칸아카데미에 로딩하는 데 문제가 있는 경우에 표시됩니다.

If you're behind a web filter, please make sure that the domains *.kastatic.org and *.kasandbox.org are unblocked.

주요 내용

확률 & 비균일 분포

여기서 프로그래밍을 갓 시작했을 때를 기억하시나요? 화면에 원을 여러개 그리고 싶었을 겁니다. 그래서 대충 임의의 색과 크기로 아무곳에나 그리려고 했을 겁니다. 컴퓨터 그래픽 시스템에서 난수성을 갖는 시스템만들기는 매우 쉽습니다. 그러나 이 수업에서는 우리가 자연에서 보는 것을 토대로 한 시스템을 구축하는 방법을 배우게 될겁니다. 난수성을 기본으로 하는 것은 문제를 설계하기에 그다지 좋은 해결책은 아닙니다. 특히 유기적이거나 자연스러운 시뮬레이션을 생성할 때는 더더욱 좋지 않은 해결책입니다.
약간의 요령으로 random()을 조금 다르게 써서 “균일하지 않은” 분포의 난수를 생성하도록 만들 수 있습니다. 이 과정에서 여러 가지 시나리오를 살펴보며 그 활용성을 깨닫게 될 겁니다. 예를 들어 유전 알고리즘을 실험할 때 “선택”을 수행하는 방법론이 필요할 것입니다. 전체 인구 중에서 다음 세대에 DNA를 물려줄 수 있는 개체는 어떻게 선택해야 할까요? 적자생존의 개념을 기억하고 있나요? 어떤 진화하고 있는 원숭이 집단이 있다고 가정합시다. 모든 원숭이에게 번식 기회가 똑같이 주어지지는 않습니다. 다윈 진화(Darwinian evolution)를 모사하려면 두 마리의 원숭이를 임의로 선택하여 부모로 만들 수는 없습니다. 선택될 가능성이 많은 좀 더 “적합한” 원숭이들이 필요합니다. 따라서 “적자 선택 확률”을 정의해야 합니다. 예를 들어, 유별나게 빠르고 강한 원숭이의 번식 기회는 90%인 반면 보다 약한 원숭이는 10%입니다.
여기서 잠시 멈추고 확률의 기본 원칙에 대해 살펴봅시다. 먼저 단일 사건 확률 즉, 한 사건이 발생할 가능성에 대해 분석해 봅시다.
경우의 수가 특정한 수로 정해져 있는 어떤 시스템이 있다고 가정합시다. 각 경우의 수가 일어날 확률은 서로 같습니다. 특정 사건이 발생할 확률은 사건이 되는 경우의 수를 가능한 모든 경우의 수로 나눈 것과 같습니다. 동전 던지는 간단한 예제를 봅시다. 이 경우 앞면과 뒷면, 즉 두 가지 경우의 수가 있습니다. 뒤집어서 앞면이 나올 수 있는 방법은 오직 하나입니다. 그러므로 앞면이 나올 확률은 1 나누기 2 즉, 1/2 혹은 50%입니다.
52개 들이 카드 팩을 생각해 보겠습니다. 팩에서 에이스를 선택할 확률은 다음과 같습니다.
에이스의 수 / 카드 수 = 4 / 52 = 0.077 = ~8%
다이아몬드를 선택할 확률은 다음과 같습니다.
다이아몬드의 수 / 카드 수 = 13 / 52 = 0.25 = 25%
또한 연속적으로 발생하는 다중 사건의 확률을 계산할 수 있습니다. 이를 위해 각 사건의 개별 확률을 곱하면 됩니다.
연속으로 3번 동전 던기기를 해서 앞면이 나올 확률은 다음과 같습니다.
(1/2) * (1/2) * (1/2) = 1/8 (or 0.125)
이것은 8번 중 한 번만 연속으로 3회 앞면이 나올 가능성이 높다는 것을 의미합니다. (3 “회”는 동전을 3회 던진다는 뜻)
계속하기 전에 확률에 대해 알아보고 싶나요? 복사건(compound events)조건부 확률(dependent probability)을 공부해 보세요.
코드에서 확률을 갖는 random() 함수를 이용하는 방법이 몇 가지 있습니다. 그 중 하나는 선택한 수로 배열을 채우고 (반복될 수 있음) 해당 배열로부터 난수를 선택합니다. 그리고 이 선택한 난수를 기반으로 사건을 생성하는 것입니다.
이 코드를 실행하면 1, 2와 3을 출력할 확률은 각각 40%, 20%와 40%가 됩니다.
또한, 임의의 수를 요청하고(단순하게 만들기 위해 0과 1 사이의 소수를 선택합시다) 그 수가 특정 범위에 있을 때만 사건이 발생하도록 할 수도 있습니다. 아래 예제를 한 번 보세요. 임의로 선택된 수가 결과적으로 임계치보다 작아질 때까지 다시 시작을 계속 클릭해 보세요.
그리고 이 메소드는 여러 결과값에 적용될 수도 있습니다. A가 발생할 확률은 60%이고 B가 발생할 확률은 10%이고 C가 발생할 확률은 30%라고 가정해 봅시다. 이를 코드에 적용시키기 위해 먼저 난수를 선택하고 들어가는 범위를 살펴봅시다.
  • 0.00과 0.60 (60%) 사이 –> 결과 A
  • 0.60과 0.70 (10%) 사이 –> 결과 B
  • 0.70과 1.00 (30%) 사이 –> 결과 C
다시 시작 버튼을 클릭해 다른 결과를 몇 번이나 얻는지를 확인해 보세요:
위 방법을 이용하여 오른쪽으로 이동하는 경향을 가진 임의의 walker를 생성할 수 있습니다. 다음과 같은 확률로 움직이는 Walker를 살펴봅시다.
  • 위로 갈 확률: 20%
  • 아래로 갈 확률: 20%
  • 왼쪽으로 갈 확률: 20%
  • 오른쪽으로 갈 확률: 40%
본 "내추럴 시뮬레이션" 과정은 다니엘 쉬프만(Daniel Shiffman)이 저술한 "The Nature of Code"의 내용을 차용한 것이며, 본 내용물의 저작권은 Creative Commons Attribution-NonCommercial 3.0 Unported License를 적용합니다.