2017-11-14 13 views
1

私は、Monte Carlo近似法を使って、与えられた精度(小数点以下の桁数)にpiの値を計算する関数を作成しようとしています。近似値をpiのリテラル値と比較し、一致しない場合は、再帰的にその関数を呼び出して、より多くの試行で再試行することでこれを実行しようとしていました。 これは私がこれまで持っているものです。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) 

近似のための試行回数を制御することになっている変数xは、1に関数が呼び出されるたびに初期化されますので、私はトラブルを抱えています。私は何をすべきかわからない、助けてください!

+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で簡単に修正する必要があります

関連する問題