몬테카를로 방법은 과학과 공학 전 영역에 걸쳐 널리 사용되는 방법이다. 확률적인 해석을 요구하는 문제를 풀고싶을 때, 이 방법이 주로 쓰인다. 역사적으로는 물리학에서 자주 사용되었다고 전해진다. 1940년도에 원자로의 연쇄 반응 제어를 최초로 실현한 물리학자 엔리코 페르미는 중성자 확산(Neutron Diffusion)을 연구하면서, 이 방법을 자주 사용하였고, 로스앨러모스에서 맨하탄 프로젝트가 수행될 때 현대적인 버전의 몬테카를로 방법이 개발되었다고 전해진다.
참고 Montecarlo
몬테카를로 방법의 가장 간단한 예시로는 원주율(π)의 값을 추정하는 것이다.
넓이가 1인 정사각형을 생각하자. 정사각형의 한 꼭지점을 중심으로 반지름이 1인 사분원을 정사각형 안에 그린다. 그러면 사분원이 차지하는 넓이는 π/4가 될 것이다. 이제, 0 <= x <= 1인 x를 임의로 가져오고, 독립적으로 0 <= y <= 1인 y를 임의로 가져온 후, x^2 + y^2 <= 1일 확률은 사분원이 차지하는 넓이와 같은 값인 π/4가 된다.
이 과정을 여러 번 수행하는 알고리즘을 작성하고, 원주율의 값을 추정하시오.

93개의 풀이가 있습니다.
import random
n=int(input("반복 횟수"))
count=0
for i in range(n):
x=random.uniform(0,1.0)
y=random.uniform(0,1.0)
if (x**2+y**2)<=1:
count=count+1
print("파이값은? ",4*count/n)
double pi=0;
@Test
public void 몬테카를로() {
LongStream.rangeClosed(1l, 100l).forEach(v -> {
pi=pi+BigDecimal.valueOf(LongStream.rangeClosed(0, v*3000).filter(x -> (Math.pow(Math.random(), 2) + Math.pow(Math.random(), 2)) <= 1).count()).divide(BigDecimal.valueOf(v*3000), MathContext.DECIMAL128).multiply(BigDecimal.valueOf(4)).doubleValue();
logger.debug("{} : {}", v*3000, pi / v);
});
}
@Test
public void 원주율추정() {
double pi = 0;
for (int i = 1; i < 100; i++) {
pi = pi + reckoningPi(i * 3000);
logger.debug("{} : {}", i * 3000, pi / i);
}
}
private double reckoningPi(int limited) {
double count = 0;
for (double c = 0; c < limited; c++) {
if (Math.pow(Math.random(), 2) + Math.pow(Math.random(), 2) <= 1) {
count++;
}
}
return count / limited * 4;
}
Ruby
m_pi = ->n { (1..n).reduce {|_,e|_+(rand(0..1.0)**2+rand(0..1.0)**2>1? 0:1) }*4.0/n }
Test
expect(m_pi[10000]).to be_within(0.1).of(3.1415)
expect(m_pi[20000]).to be_within(0.1).of(3.1415)
expect(m_pi[30000]).to be_within(0.1).of(3.1415)
Out
#=> p m_pi[30000]
3.1489333333333334
#파이썬3.5.1
from random import *
from decimal import *
def montecarlo(n):
points = []
for i in range(n):
points.append((Decimal(uniform(0,1)),Decimal(uniform(0,1))))
c = 0
for p in points:
if p[0]**2 + p[1]**2 <= Decimal(1):
c += 1
return Decimal(c)/Decimal(n) * Decimal(4)
while True:
n = input('How many repeat this program(If you want to stop, input nothing). : ')
if n == '':
break
print('ㅠ will be',montecarlo(int(n))) # 파이를 ㅠ로 표기
public double getProbability(int repeat){
int total = 0, count = 0;
double x=0.0, y=0.0 , result = 0.0;
total = repeat;
while(repeat > 0 ){
repeat--;
x = (double) Math.random()* 1.0;
y = (double) Math.random()* 1.0;
result = x * x + y * y;
if(result <= 1.0){
count++;
}
System.out.println("x : " + x +"," + "y:"+ y + " = " +result + "count : " + count);
}
return (double)count / (double) total;
}
import random
import math
N=100000
N_in_C=0
for i in range(N):
x=random.random()
y=random.random()
if (x**2+y**2)<1 : N_in_C+=1
Pi_cal=((N_in_C/N)*4)
error=(abs(Pi_cal-math.pi)/math.pi)*100
print("Pi is %f" % Pi_cal)
print("Error rate = %f%%" % error)
dic = {}
for x in range(0, 1, 0.0001)
for y in range(0, 1, 0.0001)
if x**2 + y**2 =< 1:
dic.append{x:y}
len(dic)/10**8 = pi/4
print(pi)
파이썬 처음인데 이게 맞을까요? ㅠㅠ
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <math.h>
using namespace std;
#define PI 3.141592
int main()
{
srand((unsigned int)time(NULL));
int n;
float x, y;
float mypi;
float count = 0;
cout << "몇 번?"; cin >> n;
for (int i = 1; i <= n; i++)
{
x = (float)rand() / RAND_MAX;
y = (float)rand() / RAND_MAX;
if (pow(x, 2) + pow(y, 2) <= 1)
{
count++;
}
}
mypi = count / n;
cout << mypi * 4<< endl;
return 0;
}
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <math.h>
using namespace std;
#define PI 3.141592
int main()
{
srand((unsigned int)time(NULL));
int n;
float x, y;
float mypi;
float count = 0;
cout << "몇 번?"; cin >> n;
for (int i = 1; i <= n; i++)
{
x = (float)rand() / RAND_MAX;
y = (float)rand() / RAND_MAX;
if (pow(x, 2) + pow(y, 2) <= 1)
{
count++;
}
}
mypi = count / n;
cout << mypi * 4<< endl;
return 0;
}
import random
count = 10000
def getPi(count):
undercnt = 0
for cnt in range(count):
x = random.uniform(0,1.0)
y = random.uniform(0,1.0)
if x**2 + y**2 <= 1:
undercnt +=1
return (float(undercnt) / float(count))*4
if __name__ == '__main__':
print getPi(count)
python 2.7
import random
try:
n = int(raw_input('how many times ? : '))
print n
except:
print 'not integer'
cnt = 0
for i in range(n):
x = random.uniform(0,1.0)
y = random.uniform(0,1.0)
if(x*x + y*y)<=1:
cnt+=1
pi = 4.0*cnt/n
print pi
위에분꺼 참고해서 작성하다가 추가함 실수로 출력이 안되서
import random
def pi(n):
count = 0
for i in range(n):
x = random.uniform(0, 1)
y = random.uniform(0, 1)
if (x**2 + y**2) <= 1:
count += 1
return 4 * count / n
print(pi(56000))
print(pi(10000))
package main
import (
"fmt"
"math/rand"
)
func main() {
for j := 1; j < 10; j++ {
count := 3000 * j
small := 0
for i := 0; i < count; i++ {
x := rand.Float64()
y := rand.Float64()
calc := x * x + y * y
if calc <= 1 {
small++
}
}
fmt.Println(float64(small) / float64(count))
}
}
import random as rd
from ctypes import *
from multiprocessing import Process, Queue
PROCESS = 8
MULTIPLY = 2**20 #동기화 간격. 적으면 병목 발생.
n = i = 0
def f(q):
while 1:
li = []
for x in range(MULTIPLY):
li.append((rd.random()**2+rd.random()**2<=1))
q.put([li.count(True), len(li)])
if __name__ == '__main__':
proc = []
q = Queue(maxsize = 1000)
for x in range(PROCESS):
proc.append(Process(target = f, args = (q,)))
proc[x].start()
while 1:
temp = q.get()
i += temp[0]; n += temp[1]
print(4*i/n)
멀티프로세스로 계산했습니다. 병목 현상 발생해서 나름 고쳐보았습니다. 파이썬 3.5.1 64
from random import random
count = 0
for i in range(30000):
if random()**2+random()**2 <= 1:
count += 1
print(4*count/i)
짧게 짰습니다
GCC
i;
main(j){
srand(time(0));
for(i=10000;i--;pow(rand(),2)+pow(rand(),2)<1073676290&&j++);
printf("%f",j/2500.);
}
import random
n=int(input('몇 회 반복할까요? '))
count=0
for k in range(n):
x=random.random()
y=random.random()
if x**2+y**2<=1:
count+=1
pi=(count/(k+1))*4
if (k+1)%10000==0:
print('%d회 실시 결과 pi=%0.10f' %(k+1, pi))
print('추정된 pi=%0.10f' %pi)
import random
count = int(input("수행횟수 : "))
stack=0
for i in range(count):
ii=random.random()
jj=random.random()
if ii**2 + jj**2 <=1 :
stack+=1
pi=stack*4/count
print("%d 의 수행으로 얻을 수 있는 pi값 : %f"%(count,pi))
Python 3.5.2
matrix_size = 10000
x = 0
y = 0
in_num = 0
for i in range(matrix_size) :
for j in range(matrix_size) :
if (x**2 + y**2) <= 1 : in_num +=1
x = x + (1 / matrix_size)
y = y + (1 / matrix_size)
x = 0
print(in_num / matrix_size**2 * 4)
코드 정리는 하지 아니하였습니다. 처음 Random 함수를 이용하여 풀어 봤지만 시행 횟수가 많아지면 질수록 중복값의 우려 때문에..
저 도표를 보니 더 규칙적이고 조밀하게 만들면 더 좋을꺼 같아 이렇게 해봤습니다. 행렬 사이즈가 커지면 커질 수록 더 값이 정교하게 나오네요
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(0));
double x = 0;
double y = 0;
double circle = 0;
double total = 0;
for(int i = 0; i < 100000; i++) {
x = (double)rand() / (double)RAND_MAX;
y = (double)rand() / (double)RAND_MAX;
total++;
if((x * x) + (y * y) <= 1) {
circle++;
}
}
printf("%f\n", (circle / total) * 4);
}
Java
import java.util.Random;
public class PiTest {
public static void main(String[] args) {
Random RANDOM = new Random();
int withinCircleCount = 0;
int totalCount = Integer.MAX_VALUE;
for (int i = 0; i < totalCount; i++) {
if (Math.pow(RANDOM.nextDouble(), 2) + Math.pow(RANDOM.nextDouble(), 2) <= 1d) {
withinCircleCount++;
}
}
System.out.println(4*(double)withinCircleCount / (double)totalCount);
}
}
결과 : 3.141641342612748
랜덤이 아닌 x, y 값을 조금씩 늘여서 계산
public class PiTest2 {
public static void main(String[] args) {
double accuracy = 0.000003;
double withinCircleCount = 0, totalCount = 0;
for (double i = 0; i <= 1; i += accuracy) {
for (double j = 0; j <= 1; j += accuracy) {
totalCount++;
if (Math.pow(i, 2) + Math.pow(j, 2) <= 1d) {
withinCircleCount++;
}
}
}
System.out.println(4*withinCircleCount / totalCount);
}
}
결과 : 3.1415920915270674
C#
public double SimpleMontecarloMethod(int nTimes)
{
double x = 0;
double y = 0;
Random rnd = new Random();
double Count = 0;
for (int i = 0; i < nTimes; i++)
{
x = rnd.NextDouble();
y = rnd.NextDouble();
if ((x * x + y * y) <= 1)
{
Count++;
}
}
return 4 * (Count / nTimes);
}
이걸 몇 번 시행해서 평균값 같은 걸 내고.. 그런 과정도 필요한건가요?
import random
def test(n=1000000):
t = 0
for _ in range(n):
x, y = random.random(), random.random()
if not (x**2 + y**2)**0.5 > 1:
t += 1
return t / n * 4
print("{:0.9f}".format(test()))
안녕하세요 c++로 풀어봤습니다.
#include<iostream>
#include<time.h>
using namespace std;
void main()
{
cout<<"Hello Stranger!?"<<endl;
int n = 0;
double s = 0;
cout<<"input N"<<endl;
cin>>n;
srand(time(0));
for(int i=0; i<n; i++)
{
double x = (double)rand()/RAND_MAX;
double y = (double)rand()/RAND_MAX;
double res = x*x + y*y;
if(res <= 1)
s++;
}
s = s/n*4;
cout<<s;
}
import random
def do(n):
p = 0
for i in range(n):
x = random.random()
y = random.random()
p+=1 if x**2 + y**2 <=1 else 0
return n, p / n * 4
print(do(6000))
print(do(12000))
print(do(24000))
print(do(27000))
print(do(30000))
print(do(60000))
print(do(120000))
Python 3.5.2에서 작성하였습니다.
import random
result, count, p_count = 0,1,0
tmp = list()
while p_count < 30000:
x = random.random()
y = random.random()
result = x**2+y**2
if result <= 1:
p_count += 1
count += 1
print('%.5f' % (p_count/count*4))
#### 2017.01.24 D-394 ####
import random
result, count, p_count = 0,1,0
tmp = list()
while p_count < 30000:
x = random.random()
y = random.random()
result = x**2+y**2
if result <= 1:
p_count += 1
count += 1
print('%.5f' % (p_count/count*4))
#### 2017.01.24 D-394 ####
import random
def pi_cal(n):
print(sum((random.uniform(0,1)**2+random.uniform(0,1)**2<=1) for i in range(n))/n*4)
pi_cal(500000)
import random
n=1000000
n1=0
for i in range(n):
x=random.random()
y=random.random()
if (x**2+y**2)<=1:
n1+=1
pi=(n1/n)*4
print('n={0}, pi={1:0.5f}'.format(n,pi))
MATLAB으로 짜보았습니다. 1천만번 (1e7) 테스트입니다. 만번 (1e4) 때부터 거의 수렴하는 것 같네요.
N_max=1e7;
n=0;
sol_cnt=0;
converge_check=zeros(N_max,1);
while n < N_max
n=n+1;
x=rand(1,1);
y=rand(1,1);
if (x^2+y^2) < 1^2
sol_cnt=sol_cnt+1;
end
if mod(n,100000)==0
disp([num2str(n) 'th trial -> ' num2str(sol_cnt/n*4)]);
end
converge_check(n)=sol_cnt/n*4;
end
%%
figure;
semilogx((1:N_max),pi*ones(1,N_max),':k');
hold on;
semilogx((1:N_max),converge_check);
axis([1 N_max 3-1.5 3+1.5]);
```{.python} import random while(True): number = int(input('반복하는횟수: ')) j = 0 for i in range(1,number+1): x=random.random() y=random.random() if((x2)+(y2)<=1): j=j+1 print((j/number)*4)
```3.6 python
Python 3.6 using random.random()
from random import random
def monte_pi(n):
inner, total = 0, 0
while total <= n:
total += 1
if random()**2 + random()**2 <= 1:
inner +=1
return 4 * (inner/total)
>>> monte_pi(30000)
3.1413619546015132
javascript
var distance = (x, y) => Math.sqrt(x * x + y * y);
var guessPI = function(r) {
return Array.from(Array(r)).reduce(v => v + (distance(Math.random(), Math.random()) <= 1 ? 1 : 0), 0) / r * 4
}
var repeat = [3000, 4000, 5000, 6500, 8500, 10000, 15000, 18000, 24000, 30000, 300000, 999999];
for (r of repeat) {
console.log(`${r} : ${guessPI(r)}`);
}
아래는 guessPI 의 loop 버전
코딩도장에서 loop 를 functional 로 배우는 기법을 많이 배우네요.
아직 모르는 언어이지만, Ruby 나 python 코드를 훔쳐보고 있어요.
그리고 javascript ES6 스타일로 많이 적용해보고 있습니다.
var guessPI = function (repeat) {
var inner = 0;
for (let i = 0; i < repeat; i++) {
if (distance(Math.random(), Math.random()) <= 1) inner++;
}
return inner / repeat * 4;
};
저장용
def prob(n):
import random
count=0
for i in range(n):
x, y = random.random(), random.random()
if x**2+y**2<=1:
count += 1
return print('pi ~',4*count / n)
from random import uniform as U
def Montecarlo(n):
p = [(U(0,1), U(0,1)) for _ in range(n)]
cnt = sum([x*x+y*y <= 1 for (x, y) in p])
return 4 * cnt / n
print(Montecarlo(1000000))
여러 수학공식들이 많네요 !
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#define ele int
using namespace std;
double random(void) {
return pow(rand() / (double)RAND_MAX,2);
}
int main() {
ele chk = 0, cnt;
srand(time(NULL));
cout << " 반복 횟수 : "; cin >> cnt;
for(ele i=0;i<cnt;i++) random() + random() <= 1 ? chk++ : 0;
// 확률 = 파이/4 , 원주율 = 파이 = 확률*4
cout << " 원주율(파이) : " << (double)chk / cnt * 4 << endl;
return 0;
}
from random import random
def pi(n):
return 4.0 * sum([1 for x in range(n) if random()**2 + random()**2 < 1]) / n
print(pi(10000))
x제곱 + y제곱이 1보다 작은 확률을 사각형의 넓이와 곱하여 원의 넓이를 계산하고 원의 크기의 4분의 1인 pi/4가 같다고 놓고 계산함
import random
def pi(n):
shot = 0
for i in range(n):
x = random.random()
y = random.random()
if x*x + y*y < 1:
shot += 1
return shot/n*4
print(pi(100000))
import random as rd
def findpi(n):
tmp=0
for i in range(n):
x,y=rd.uniform(0,1),rd.uniform(0,1)
if x**2+y**2<=1: tmp+=1
return(tmp*4/n)
num=int(input())
print(findpi(num))
Java 입니다.
public class level_2_Montecarlo_Method {
public static void main(String[] args) {
System.out.println("몬테카를로 방법을 수행할 횟수를 입력하세요. (횟수는 적당히.)");
Scanner sc = new Scanner(System.in);
double number = sc.nextDouble();
sc.close();
double count = 0;
for(int i = 0; i < number; i++)
{
double x = 0;
double y = 0;
x = Math.pow(Math.random(), 2); // 0이상 1미만의 무작위 실수들.
y = Math.pow(Math.random(), 2); // 0이상 1미만의 무작위 실수들.
if(x + y <= 1)
{
count++;
}
}
System.out.println("x^2 + y^2 <= 1일 확률 : " + count / number);
System.out.println("추정되는 원주율의 값은 약 : " + (count / number) * 4);
}
}
파이썬 3.6
import math
def calpai(n):
a,π = 0,0
t = round(math.sqrt(n))
for i in range(0,t+1):
for h in range(0,t+1):
x = i/t
y = h/t
if 0 <= x <= 1 and 0 <= y <= 1:
if x**2 + y**2 <= 1: a += 1
else: break
# 확률(P) = 사건A(x^2 + y^2 <= 1)가 일어나는 경우의 수(a) / 모든 경우의 수(n)
# π = 4 * (a / n)( ∵ π/4 = a / n)
print("n = %d, π ≈ %.4f" %(n,4 * (a/n)))
if __name__ == "__main__":
data = [3000,5000,6500,8500,15000,18000,24000,30000,1000000]
for n in data:
calpai(n)
n = 3000, π ≈ 3.2333
n = 5000, π ≈ 3.2200
n = 6500, π ≈ 3.2185
n = 8500, π ≈ 3.1689
n = 15000, π ≈ 3.1469
n = 18000, π ≈ 3.1633
n = 24000, π ≈ 3.1703
n = 30000, π ≈ 3.1559
n = 1000000, π ≈ 3.1456
랜덤 쓰지 않고 쌩으로 점하나 하나 찍어 면적 구하기
# 파이썬
in_circle = 0
n = 2000
for x in range(0, n):
for y in range(n, x, -1):
if x**2 + y**2 <= (n)**2:
in_circle += 1
print(4*in_circle / (n**2/2))
# 3.142172
랜덤 썼을 때.
import random
random.seed(0)
in_circle = 0
n = 2000000
for _ in range(n):
x = random.uniform(0, 1)
y = random.uniform(0, 1)
if x**2 + y**2 <= 1:
in_circle += 1
print((in_circle/(n+1))*4)
# 3.1416324291837854
import random
i = j = 0
n = int(input("반복 횟수 :"))
while i <= n:
i += 1
x = random.random()
y = random.random()
if x*x+y*y <= 1:
j +=1
print(4*j/i)
import numpy
AttempN = [50000, 100000, 500000]
for i in AttempN:
print("pi ~ ", sum(1 for j in range(i) if numpy.linalg.norm(numpy.random.rand(1,2)) <=1)/i*4)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int attemp_n, count=0;
float x, y;
while (1) {
printf("실행 횟수를 입력하시오. ");
scanf_s("%d", &attemp_n);
for (int i = 1; i < attemp_n + 1; i++) {
x = (float)rand()/RAND_MAX; y = (float)rand()/RAND_MAX;
if ((x*x) + (y*y) <= 1) count++;
}
printf("%d회 실행의 Pi의 추정치는 %f입니다.\n", attemp_n, (float)count / (float)attemp_n * 4.0f);
count = 0;
}
return 0;
}
Python
import random
n = 10000000
prob = 0
for i in range(n):
x = random.random()
y = random.random()
if x**2 + y**2 <= 1:
prob += 1
if i%100000 == 0 and i != 0:
print("N = {}, pi = {}".format(i, 4*prob/i))
ans = 4*prob/n
print(ans)
import sys
import random as rd
test_count = int(sys.argv[1])
in_circle = 0
for i in range(test_count):
x = rd.uniform(0,1.0)
y = rd.uniform(0,1.0)
if x**2 + y**2 < 1:
in_circle += 1
pi = (in_circle / test_count) * 4
print(pi)
public class Main {
public static void main(String[] args) {
int count = 0, total = 100000000;
for (int i = 0; i < total; i++)
if (Math.pow(Math.random(), 2) + Math.pow(Math.random(), 2) <= 1)
count++;
System.out.println(count * 4 / total);
}
}
파이썬 3.
from random import random
total_count = 0
inside_count = 0
while total_count < 1000000:
total_count += 1
x, y = (random(), random())
if x**2 + y**2 <= 1:
inside_count += 1
pie = (inside_count / total_count) * 4
print(pie)
from random import *
for n in range(5000,100001,1000):
noc = 0
for i in range(n):
if random()**2+random()**2 <= 1: noc += 1
print('n = {:6}, π ≒ {:.7}'.format(n,4*noc/n))
C#
using System;
namespace CD108
{
class Program
{
static Random position = new Random();
static void Main()
{
int tryCase = 5_000_000;
Console.WriteLine($"n = {tryCase}, pi = {GetPiValue(tryCase)}");
}
static double GetPiValue(int tryCase)
{
double posX, posY;
int count = 0;
for (int i = 0; i < tryCase; i++)
{
posX = position.NextDouble();
posY = position.NextDouble();
if (posX * posX + posY * posY <= 1.0) { count++; }
}
return (double)count / tryCase * 4.0;
}
}
}
import java.util.Random;
public class KimSanghyeop
{
public static void main(String[] args)
{
double x;
double y;
Random rd = new Random();
int f1;
int f1_max= 100000;
int cnt=0;
for(f1=0;f1<f1_max;f1++)
{
x=rd.nextDouble();
y=rd.nextDouble();
if(x*x + y*y <=1)
{
cnt+=1;
}
if(f1 % 2000 ==0)
{
System.out.println(f1+" : "+ 4.0*cnt/f1);
}
}
}
}
n <- 1000000
ct <- 0
for (i in 1:n){
x <- runif(1, min = 0 , max = 1)
y <- runif(1, min = 0 , max = 1)
if(x ^ 2 + y ^ 2 <= 1){
ct <- ct + 1
}
}
pi <- 4 * ct / n
def find_pi(repeats):
import random
area_square = 0
area_circle = 0
for rep in range(repeats):
x = random.random()
y = random.random()
if x ** 2 + y ** 2 <= 1:
area_circle += 1
area_square += 1
return area_circle * 4 / area_square
print(find_pi(1000000))
from random import random
def montecarlo(n):
per = 0
for i in range(n):
if random()**2+random()**2 <= 1:
per += 1
return per/n*4
>>> montecarlo(10)
3.2
>>> montecarlo(100)
3.16
>>> montecarlo(1000)
3.252
>>> montecarlo(10000)
3.1288
>>> montecarlo(100000)
3.14824
>>> montecarlo(1000000)
3.14236
>>> montecarlo(10000000)
3.1415864
import random
n= int(input())
count = 0
for i in range(n):
x = random.uniform(0, 1.0)
y = random.uniform(0, 1.0)
if (x*x + y*y) <= 1:
count += 1
print(4*count/n)
import random
piData = []
for i in range(1, 30000 + 1) :
x = random.random()
y = random.random()
won = x**2 + y**2
if won <= 1 :
pi = len(piData) / i * 4
piData.append(pi)
if i % 5000 == 0 :
print("n = %d, π ≒ %0.4f"%(i, pi))
# 파이썬 3
i = 0
z = 0
for i in range(10000000):
x = random.uniform(0,1)
y = random.uniform(0,1)
if x**2 + y**2 <= 1:
i += 1
else:
z += 1
print(i / (i+z) * 4)
import random
count=0
for i in range(10000000):
x = float(random.random())
y = float(random.random())
if (x**2 + y**2)**0.5 <=1:
count += 1
else:
pass
print(count / 10000000 * 4)
import random
def Monte(n): #n은 알고리즘을 수행하는 횟수
t = 0
for i in range(n):
x, y = random.random(), random.random()
if x**2 + y**2 <= 1: t += 1 #t는 사분원에 들어간 횟수
return 4 * (t/n)
>>> print(Monte(10)) #10번
2.0
>>> print(Monte(100)) #100번
3.28
>>> print(Monte(1000)) #1000번
3.224
>>> print(Monte(10000)) #10000번
3.1404
>>>
from random import *
n=int(input());p=0
for i in range(n):
x=random();y=random()
if x*x+y*y<=1:
p+=1
print("π="+str(4*p/n))
확률이라고 해서 무슨 말인가 했읍니다 .이번 문제는 랜덤모듈을 끌어와서 실용하여 본 좋은 예제였읍니다.^^
python
import random as rd
n = int(input())
count = 0
for i in range(n):
x = rd.uniform(0,1)
y = rd.uniform(0,1)
if x**2 + y**2 <= 1:
count += 1
print("π = ",4*count/n)
cnt =0
for n in range(1,50001):
x,y = np.random.rand((2))
if x**2 + y**2 <= 1:
cnt+=1
if n%1000==0:
print("n={0}, pi={1}".format(n,(4*cnt/n)))
var 총횟수 = 1000;
var 원내부위치 =0;
for (var i = 0; i < 총횟수; i++) {
var x = Math.random();
var y = Math.random();
if (x**2+y**2<1) {
원내부위치++
}
}
console.log('pi/4=',원내부위치/총횟수)
console.log('pi=',원내부위치/총횟수*4)
number = 0
m = 1000
for x in range(0, m): for y in range(0, m): if (x2 + y2) <= (m*m) : number += 1
ramnum = number / (m*m) print(ramnum) result = (ramnum) * 4 print(result)
import time
import random
def pi_MontecarloMethod(randtime):
start = time.time()
cin = 1
for cnt in range(randtime):
x = random.uniform(0, 1)
y = random.uniform(0, 1)
if (x**2 + y**2) <= 1:
cin += 1
res = cin*4 / randtime
runtime = time.time()-start
return res, str(runtime)[0:10]
if __name__ == '__main__':
cnt = int(input('input count time : '))
print()
print('calculating...\n')
pi = pi_MontecarloMethod(cnt)
print('pi : ', pi[0])
print('runtime :', pi[1], 'seconds')
public class 간단한몬테카를로방법 {
public static void main(String[] args){
double count = 0.0;
for(double i=1; i<30001; i++) { //예제에서와 같이 30000번 실행
double x = Math.random(); //x에 난수 0.0~1.0사이의 난수 생성
double y = Math.random(); //y에 난수 생성
if(x*x+y*y<=1) { //x^2 + y^2의 값이 1보다 작거나 같으면 count++;
count++;
}
if(i%1000==0) { //1000 단위로 값을 출력
System.out.printf("%.4f\n", (count/i)*4); //소수점 4번째 자리까지 출력
}
}
}
}
import random
x_list, y_list, count = [], [], 0
for n in range(int(input("N : "))) :
x_list.append(random.uniform(0, 1))
y_list.append(random.uniform(0, 1))
if (x_list[n])**2+(y_list[n])**2 <= 1 :
count +=1
else : continue
print((count/n)*4)
결과
N : 100000
3.142111421114211
파이썬3입니다.
import random
a = int(input('몇번 반복하시겠습니까?'))
result = 0
for i in range(a):
x, y = random.uniform(0, 1), random.uniform(0, 1)
if x**2 + y**2 <= 1:
result += 1
print('파이값은 {:0.4f} 입니다.'.format(4*result/a))
mport random
count = int(input("반복 횟수 : "))
num = 0
for i in range(count):
x = random.random() #random 모듈의 random() 0 이상 1 미만
y = random.random()
if (x**2 + y**2) <= 1:
num +=1
print("PIE : ", num/count * 4)
문제를 이해를 못해서 다른사람 풀이 과정을 모방했습니다.
import random
repeat = 10000000
in_circle = 0
for i in range(repeat):
x = random.random()
y = random.random()
t = x**2 + y**2
if t <= 1:
in_circle +=1
print(in_circle/repeat*4)
import random
yes=0
for i in range (1,50000000):
x=random.random()
y=random.random()
if(x**2+y**2<=1):
yes=yes+1
print ((yes/i)*4 )
파이썬 3.8로 작성했습니다.
# http://codingdojang.com/scode/507#answer-filter-area
n=int(input("반복 횟수를 입력해 주세요"))
import random
count=0
# a2+b2<=1이면 count+1
for i in range(n):
a=random.random()
b=random.random()
if a**2+b**2<=1:
count+=1
print(4*count/n)
import random
n=100000
count=0
for i in range(n):
x=random.random()
y=random.random()
if(x*x+y*y<1):
count=count+1
a=4*count/n
print(a)
from random import *
def monte_carlo():
trial = 1000000
count = 0
for i in range(trial):
count += 1 if random() ** 2 + random() ** 2 <= 1 else 0
return 4 * count / trial
from random import *
n = int(input())
algogo = []
cnt = 0
for i in range(n):
x = uniform(0,1)
y = uniform(0,1)
if x**2+y**2 <= 1:
cnt += 1
else:
continue
print(4*cnt/n)
import random
t = 0
f = 0
for i in range(1, 100001):
x = random.uniform(0, 1)
y = random.uniform(0, 1)
if x ** 2 + y ** 2 <= 1:
t += 1
else:
f += 1
if i % 1000 == 0:
print("n = {},pi = {}".format(i, t / (t + f) * 4))
import random as r
def Montecarlo_Method(number):
count=0
for i in range(number):
x=r.uniform(0,1.0)
y=r.uniform(0,1.0)
if x*x+y*y<=1:
count+=1
return str(4*(count/number))
def main():
numbers=int(input("wirte number"))
print(Montecarlo_Method(numbers))
main()
import random
def monte(n):
count = 0
for i in range(1, n+1):
x = random.uniform(0, 1)
y = random.uniform(0, 1)
if x**2 + y **2 <= 1:
count+=1
pi = (count/i)*4
return pi
print(f'1000: {monte(1000)}')
print(f'10000: {monte(10000)}')
print(f'100000: {monte(100000)}')
print(f'1000000: {monte(1000000)}')
import random
loop = int(input("반복횟수를 입력하세요 : "))
count=0
i=0
while i<loop:
x = random.uniform(0,1.0)
y = random.uniform(0,1.0)
if x**2+y**2<=1:
count+=1
i+=1
print("원주율은 {}".format(count/loop*4))
import random
def monte(n):
n_inside = 0
for i in range(n):
x = random.uniform(0, 1.0)
y = random.uniform(0, 1.0)
if x**2 + y**2 <= 1:
n_inside += 1
return n_inside/n
print(monte(10000))
print(monte(100000))
print(monte(1000000))
python 3.9.4로, 원주율의 값을 15회마다 출력하는 것을 1000번 반복하였습니다.
import random
x = 0
y = 0
dots_in_square = 0
dots_in_circle = 0
pi = 0
for i in range(1, 1001):
for j in range(15):
x = random.random()
y = random.random()
distance_from_origin = x**2 + y**2
dots_in_square += 1
if distance_from_origin <= 1:
dots_in_circle += 1
pi = (dots_in_circle / dots_in_square) * 4
print("====================%sth generation====================" % i)
print("pi is %s" % pi)
결과는 다음과 같습니다.
====================1th generation====================
pi is 2.933333333333333
====================2th generation====================
pi is 3.2
====================3th generation====================
pi is 3.3777777777777778
====================4th generation====================
pi is 3.3333333333333335
====================5th generation====================
pi is 3.2
(...생략...)
====================996th generation====================
pi is 3.1386880856760375
====================997th generation====================
pi is 3.1384821130056837
====================998th generation====================
pi is 3.1382765531062122
====================999th generation====================
pi is 3.1383383383383383
====================1000th generation====================
pi is 3.1386666666666665
import random, math
def is_in(r):
x = random.random()*r
y = random.random()*r
return (x-r)**2 + (y-r)**2 <= r**2
run = int(input('실행할 회수를 입력하세요.: '))
cnt = 0
for _ in range(run):
if is_in(1):
cnt += 1
estimate_pi = (cnt/run)*4
print(f'pi 추정치:', round(estimate_pi, 5))
print(f'pi = ' , round(math.pi, 5))
#codingdojing_montecarlo_method
# x^2 + y^2 = 1
# y = (1-x^2)*(1/2)
from random import random
def monte(n):
cnt = 0
for i in range(n):
x = random()
y = random()
if x**2 + y**2 <= 1: cnt += 1
# percentage = pi/4
pi = 4*(cnt/n)
return pi
print(monte(1000))
print(monte(10000))
print(monte(30000))
print(monte(100000))
print(monte(1000000))
print(monte(10000000))
print(monte(100000000))
3.284 3.1276 3.1544 3.13748 3.139796 3.1408744 3.14154508
import random
def Montecarlo_Method(a):
cnt = 0
for i in range(a):
b = random.uniform(0,1)
c = random.uniform(0,1)
if b*b + c*c <= 1:
cnt += 1
π = (4*cnt)/a
return π
if __name__ == '__main__':
a = int(input("반복횟수입력:"))
print(Montecarlo_Method(a))
import random
n = int(input("수행 횟수"))
p= 0
for i in range(1,n+1):
x = random.random()
y = random.random()
if x**2 +y**2 <=1:
p +=1
probabilty = p/n
pi = probabilty*4
print(probabilty)
print(pi)
import random
import math
import matplotlib as mpl
import matplotlib.pylab as plt
def mcr(n):
a=[random.random() for x in range(n)]
b=[random.random() for x in range(n)]
c=[math.sqrt(a[x]**2+b[x]**2) < 1 for x in range(n)]
#print(c)
return c.count(True)/n*4
mcr(1000000)
z = 7
x = [10**i for i in range(2, z)]
y = [mcr(j) for j in x ]
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(x, y, '-o', mfc='orange');
from random import random
n=10000
num=0
for rep in range(1,n):
x, y=random(), random()
if x**2+y**2<=1:
num+=1
print(num/n*4)
import random
n = int(input("수행할 횟수 입력 :"))
count = 0
n_count = 0
while count + n_count != n:
x = random.random()
y = random.random()
if (x ** 2) + (y ** 2) <= 1:
count += 1
else:
n_count += 1
result = count / n * 4
print(result)
import random
def monte(n):
count = 0
for i in range(0,n):
x = random.random()
y = random.random()
if x**2 + y**2 <= 1:
count += 1
return count/n
print(monte(100000)*4)
import random
cmd = int(input("반복할 횟수를 입력하시오: "))
count = 0
for i in range(cmd):
x = random.random()
y = random.random()
PI = x * x + y * y
if PI <= 1:
count += 1
print(f"파이값은 {4*count/cmd}이다")
``````{.python}
import random
cmd = int(input("반복할 횟수를 입력하시오: "))
count = 0
for i in range(cmd):
x = random.random()
y = random.random()
PI = x * x + y * y
if PI <= 1:
count += 1
print(f"파이값은 {4*count/cmd}이다")
import random
n = input('몬테카를로 방법을 통해 원주율의 값을 추정하는 함수 입니다. \n반복할 숫자를 입력해주세요 : ')
in_circle = [1 for i in range(int(n)) if random.random()**2 + random.random()**2 <= 1]
print(4*len(in_circle)/int(n))
import random
n = 0
count = 0
cnt = 0
res = 0
while True:
n += 1
x = random.uniform(0, 1.0)
y = random.uniform(0, 1.0)
if (x**2 + y**2) <= 1:
count += 1
a = random.random()
b = random.random()
if (a**2 + b**2) < 1:
cnt += 1
if n > 5000 + res * 5000 and 3.14 < 4 * count / n < 3.145:
print(n, "번 시행: 파이값은? ", 4 * count / n, '\n\t\t\t\t: pi = ', 4 * cnt / n)
res += 1
if res > 2:
break