from random import random, seed
from math import sqrt

Monte Carlo Method

난수를 이용해 함수의 값을 확률적으로 계산하는 알고리즘
참고 url
몬테카를로 법을 이용해 pi의 근사값을 구해보자

  1. 반지름이 1인 원이 있다고 생각하자 ( $x^2 + y^2 = 1$ )
  2. 이제 그 원안에 점들을 찍는다.
    • 이때 난수가 사용된다. (점의 좌표 범위 : $ 0 \leq x \leq 1 , 0 \leq y \leq 1 $ )
    • random 함수의 값은 float으로 0~1 사이의 값이 리턴된다.
  3. 원의 넓이는 $\pi r^2$이고 정사각형의 넓이는 $4r^2$이다.
    따라서 원의 넓이를 정사각형의 넓이로 나누게 되면 $\frac{\pi}{4}$가 된다.

  4. 3번에서 구한 값에 4배를 해주면 원주율의 근사값이 나온다

#n은 점을 몇개 찍을것 인지를 지정해주는 변수 (n이 클수록 정확한 근사값을 얻을 수 있다.)
n = 10000
#inside, outside는 각각 원안에 원밖에 찍힌 점들을 저장해두는 list이다.
inside = []
outside = []
#n번 반복하면서 x, y에 random함수에서 나온 난수를 대입하고
#원안에 있는지 밖에 있는지 체크해서 넣어준다
for i in range(n):
    x = random()
    y = random()
    if sqrt(x*x + y*y) <= 1:
        inside.append([x, y])
    else:
        outside.append([x, y])
#원안에 찍힌 점들의 갯수 / 총 점의 갯수
pi = 4 * len(inside) / n
print('pi ≈ ', pi)
pi ≈  3.1436
#여기서부터는 찍힌 점을 그래프로 보여주는 코드이다. (읽을 필요 x)
import plotly.plotly as py
import plotly.graph_objs as go
inx, iny = zip(*inside)
outx, outy = zip(*outside)
inner_plot = go.Scatter (
    x = inx,
    y = iny,
    mode = 'markers',
    name = 'inCircle'
)

outter_plot = go.Scatter(
    x = outx,
    y = outy,
    mode = 'markers',
    name = 'outCircle'
)

data = [inner_plot, outter_plot]

layout = {
    'xaxis' : {
        'range' : [0, 1],
        'zeroline' : False,
        },
    'yaxis' : {
        'range' : [0, 1]
        },
    'shapes' : [
        {
            'type' : 'circle',
            'xref' : 'x',
            'yref' : 'y',
            'x0' : -1,
            'y0' : -1,
            'x1' : 1,
            'y1' : 1,
            'line' : {
                'color': 'rgba(0, 0, 0, 1)',
                'width' : 3,
            },
        },
    ]
}



fig = {
    'data' : data,
    'layout' : layout,
}
py.iplot(fig, filename='MonteCarlo_PI')
저작자 표시 비영리 변경 금지
신고
Creative Commons License
Creative Commons License

WRITTEN BY
Jen6
jen6의 개발, 보안 블로그 까끔가다 쓸대 있는걸 올리려고 노력중

받은 트랙백이 없고 , 댓글이 없습니다.
secret