2017-11-14 12 views
1

몬테카를로 근사법을 사용하여 pi의 정밀도 (소수점 이하 자릿수)를 계산하는 함수를 만들려고합니다. 근사값을 파이의 리터럴 값과 비교하고 일치하지 않는 경우 재귀 적으로 많은 수의 재판으로 다시 시도하기 위해 함수를 재귀 호출합니다. 근사에 대한 임상 시험의 수를 제어하도록되어 변수 x가 1로 함수가 호출 될 때마다 초기화됩니다 때문에이 문제가있어Python - 변수 값을 변경하는 순환 함수 호출

def estimate_pi(precision): 

    x = 1 

    N_tot = 0 
    N_hits = 0 

    for i in range(0,trials*10**x): 
     if(inside_circle(random.random(),random.random())==True): 
      N_hits = N_hits+1 
      N_tot = N_tot+1 
     else: 
      N_tot = N_tot+1 

    result = 4.0*N_hits/N_tot 

    if compare_to_pi(result,precision)==True: 
     print(result) 
    else: 
     x++ 
     estimate_pi(precision) 

     if trials>999999: 
      raise Error('approximation not converging to given precision') 
      print(result) 

: 이것은 내가 지금까지 가지고있는 것입니다. 나는 무엇을해야할지 모르겠다. 제발 도와주세요!

+0

평가판은 어디에 정의되어 있습니까? 글로벌 변수입니까? – UnsignedByte

+1

'x'를 디폴트 값 1로 만든 다음'x + 1'을 재귀 호출에 전달하십시오. 초기 호출은 'x'에 대한 명시적인 인수없이 이루어질 수 있습니다. – chepner

+1

그러나이 유형의 재귀는 일반 루프로 대체하는 것이 더 좋습니다. – chepner

답변

0

당신은 클래스에서 함수를 래핑하고 클래스 인스턴스가 시간의 경과에 따라 x의 값을 저장하도록함으로써이를 해결할 수 있습니다.

class foo(): 
    def __init__(self, precision, trials): 
     self.x = 1 
     self.precision = precision 
     self.trials = trials 
     .... 

    def compare_to_pi(self, ...): 
     .... 

    def inside_circle(self, ...): 
     .... 

    def estimate_pi(self, precision): 
     N_tot = 0 
     N_hits = 0 

     for i in range(0, self.trials*10**self.x): 
      if(inside_circle(random.random(),random.random())==True): 
       N_hits = N_hits+1 
       N_tot = N_tot+1 
      else: 
       N_tot = N_tot+1 

     result = 4.0*N_hits/N_tot 

     if compare_to_pi(result, self.precision)==True: 
      print(result) 
     else: 
      self.x += 1 
      self.estimate_pi(self.precision) 

     if self.trials > 999999: 
     raise Error('approximation not converging to given precision') 
     print(result) 
0

이 재귀 시퀀스에는 도우미 메서드가 필요합니다. 이것은 내가 시련으로 당신의 X를 고정

def estimate_pi(precision): 
x = 1 

N_tot = 0 
N_hits = 0 

for i in range(0,trials*10**x): 
    if(inside_circle(random.random(),random.random())==True): 
     N_hits = N_hits+1 
     N_tot = N_tot+1 
    else: 
     N_tot = N_tot+1 

result = 4.0*N_hits/N_tot 

if compare_to_pi(result,precision)==True: 
    print(result) 
else: 
    x++ 
    estimate_pi_helper(precision, 2) #we are on our second trial 


def estimate_pi_helper(precision,trials, N_tot, N_hits): 
    if trials>999999: #if we reach our 1000000'th trial we throw an error 
     raise Error('approximation not converging to given precision') 
     print(result) 



for i in range(0,trials*10**x): 
    if(inside_circle(random.random(),random.random())==True): 
     N_hits = N_hits+1 
     N_tot = N_tot+1 
    else: 
     N_tot = N_tot+1 

result = 4.0*N_hits/N_tot 

if compare_to_pi(result,precision)==True: 
    print(result) 
else: 
    x++ 
    estimate_pi_helper(precision,trials+1, N_tot, N_hits) 

와 이것을 대체 할 수 있습니다 현재의 방법

def estimate_pi(precision): 

    x = 1 

    N_tot = 0 
    N_hits = 0 

    for i in range(0,trials*10**x): 
     if(inside_circle(random.random(),random.random())==True): 
      N_hits = N_hits+1 
      N_tot = N_tot+1 
     else: 
      N_tot = N_tot+1 

    result = 4.0*N_hits/N_tot 

    if compare_to_pi(result,precision)==True: 
     print(result) 
    else: 
     x++ 
     estimate_pi(precision) 

     if trials>999999: 
      raise Error('approximation not converging to given precision') 
      print(result) 

입니다. 필자는 실행 횟수를 유지하기 위해 시행 착오를 매개 변수로 사용하는 도우미 메서드도 추가했습니다. 마지막으로, 히트 수와 합계가 계속 카운트를 유지하기 위해 전달되었습니다. 아마도 이것이 잘못된 것 일지라도 몬테카를로 시뮬레이션이 수행되는 방식입니다. 당신이 각 뛰기에 새로운 명중 세트 및 합계를 필요로하는 경우에 따라서 적절하게 그것을 바꾸십시오.

들여 쓰기 문제로 불편을 끼쳐 드려 죄송합니다. IDE가 쉽게 고쳐야합니다.