[이계대학생 응원] 몬테카를로법으로 원주율을 구한다

기사 업데이트
2019 Aug. 30: 그림 추가

이계 대학생 (마음대로) 응원 기획



이 기사는 자신이 날마다 Python 스크립트를 쓰고 있을 때 깨달은 비망록이면서도 "이계 대학생이지만 프로그래밍 지식 별로 없고, 과제 제출이 트라이"등의 학생을 지원하는 기사입니다.

이번은 타이틀에 있는 대로 「몬테카를로법을 이용해 원주율 3.141592...를 구하십시오」라고 하는 과제 응원입니다.

몬테카를로법이란?



확률을 사용하여 어떤 값을 추정하는 방법 (그리고 나는 해석하고있다).

원주율 구하기 (알고리즘)



지금의 경우, $x\in[0, 1]$, $y\in[0, 1]$의 영역에 점을 랜덤하게 묘화해 가고, 그것이 원의 1/4안에 존재한다 확률에서 원주율을 구합니다(아래 그림 참조).



원주율 구하기 (Python 스크립트)



pi_estimate.py
#!/usr/bin/env python


import numpy as np


class PiEstimate:
    def __init__(self):
        self.NRAND = 10000

    def pi_estimate(self):
        # set (x, y)
        x = np.random.rand(self.NRAND)
        y = np.random.rand(self.NRAND)
        # compute distance from origin
        dist = x * x + y * y
        # count sum of the number of distance < 1
        under = np.count_nonzero(dist<1)
        # estimate PI
        pi = 4 * under / self.NRAND
        # print result
        print(pi)

    def run(self):
        self.pi_estimate()

if __name__ == '__main__':
    a = PiEstimate()
    a.run()

스크립트 상세



__init__


self.NRAND 에서 무작위로 치는 점의 수를 지정합니다. 위의 스크립트에서는 10000으로 하고 있습니다만, 이 값을 다양하게 바꾸어, 계산 결과가 어떻게 변화하는지 고찰해 보는 것도 재미있을 것입니다.

pi_estimate


np.random.rand(self.NRAND)

그리고 0~1의 랜덤한 값이 들어간 요소수 self.NRAND개의 리스트를 작성하고 있습니다.
dist = x * x + y * y

그리고, 그 점의 원점으로부터의 거리의 제곱을 요구하고 있습니다.
np.count_nonzero(dist<1)

에서 조건 dist < 1의 조건을 충족하는 요소 수의 합계를 계산합니다. 자세히 설명하면 np.count_nonzero는 True의 요소 수를 계산하는 함수입니다. True는 1, False는 0으로 처리되므로 np.sum 함수를 사용해도 비슷한 결과를 얻을 수 있습니다.

마지막으로 얻은 결과 under/self.NRAND 는 원의 1/4의 면적 안에 점이 들어갈 확률을 나타내므로, 이것을 4배함으로써 원주율을 구할 수 있습니다.

결언



이것을 응용하면 다양한 적분과 물리 문제를 풀 수 있습니다. 알고리즘을 이해하는 여러 가지에 응용해 갑시다. 무엇보다 이 기사가 이계 학생의 프로그래밍의 뒷받침이 되면 이것 다행입니다.

좋은 웹페이지 즐겨찾기