Python - 使用更改变量值的递归函数调用

时间:2017-11-14 01:53:20

标签: python python-3.x recursion montecarlo

我正在尝试创建一个函数,该函数使用蒙特卡罗近似方法计算给定精度的pi值(小数位数)。我试图通过比较近似值和pi的文字值来做到这一点,如果它们不匹配,递归调用自身的函数再次尝试更多的试验。 这就是我到目前为止所做的:

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)

我遇到了麻烦,因为变量x(应该控制近似的试验次数)在每次调用函数时都会初始化为1。我不知道该怎么办,请帮忙!

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

这个递归序列需要一个辅助方法。这是您当前的方法

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)

我将用

替换它
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)

我修复你的x是你的试炼。我还添加了一个辅助方法,它将试验作为参数来保持运行计数。最后,你的命中和总数被传入以保持运行计数,我的印象是这是蒙特卡罗模拟的完成方式,尽管我可能错了。如果您在每次运行中需要一组新的命中数和总数,请相应地更改它。

对于缩进问题,我们深表歉意。 IDE应该很容易解决它