私は再帰とキャッシングを理解しようとしていますが、まだまだ私は興味深い進歩を遂げています。私はこのコードを理解するのに少し問題があります:フィボナッチコードからの再帰とキャッシングを理解できない
# Fibonacci recursive with result storage
class FibonacciStorage:
_storage = { 0:1, 1:1 }
@staticmethod
def _fib(number):
try: # is this already calculated
return FibonacciStorage._storage[number] #searches dict, and if value exists then return it
except KeyError:
result = FibonacciStorage._fib(number-1) + FibonacciStorage._fib(number-2) #this is the actual Fibonacci Formula
FibonacciStorage._storage[number] = result #adds result to dictionary
#print FibonacciStorage._storage #this shows the storage list growing with each iteration.
return result
@staticmethod
def fib(number): #first function, it has two asserts to basically make sure number is whole/positive and if its okay passes it to _fib(where the real work is done)
# only do the assert statements once
assert(isinstance(number,int)),"Needs a whole number"
assert(number>0),"Needs a positive whole number"
return FibonacciStorage._fib(number)
# use a more readable name
getFib = FibonacciStorage.fib
print getFib(50)
私はこのコードをネットで見つけて、実際に何をしているのかを理解するために各行にコメントしようとしました。私はこれがどのように再帰であるのか分かりませんが、正しい結果が得られるまでコードをループしますが、その呼び出し自体は見えません。
私はそれがこの行だと思っていましたが、私のprint FibonacciStorage._storage
行はストレージキャッシュの成長と成長を示していますが、その下の行はリターン関数なので混乱します。 return result
がどういうふうに再帰を再び引き起こしているのか分かりません。
また、ストレージ辞書がこのプログラムを非常に速くしているかどうかもわかりません。ファイブシーケンスの単純な再帰は(データを保存しても)長い時間がかかりますが、この場合はprint getFib(200)
の瞬間があります。キャッシングはどのように高速化していますか?
だからまとめるために、二つの質問は:
1)どのように再帰は実際にトリガされていますか?私のprintステートメントが各ループでアクセスされている場合?
2)キャッシングは他のフィブスシーケンスよりもどのように高速化されますか?クラス構造や@staticmethodが違いを生み出していますか?例えば、これは瞬間的で、http://en.literateprograms.org/Fibonacci_numbers_(Pythonのものは少し遅れているようです。
3)おそらくintrestから出て、ちょうどintrestから出ているfibnocciタイプのalgoスケール(分割して並行して実行できますか?
洞察力があれば助かります。
再帰を理解するには良い試みです。フィボナッチシリーズの定義は再帰的ですが、再帰的な実装は非常に無駄であるため、パターンパターンです。 'fib(7)'が24回の呼び出しを行い、 'fib(3)' _five_ timesの値を独立して計算することを考慮してください。実際、 'fib(n)'に対する呼び出しの総数は '2 * fib(n) - 1'です。 'fib(20)'(6765)を計算するには13,529回の呼び出しが必要です。 –
Python 2.xを使用している場合は、常にクラスを 'object'から継承します。そうでなければ微妙なエラーが発生します(例えば、" staticmethod "がクラスで動作しないなど) – jsbueno
@JimGarrisonは再帰上記のようにキャッシュすれば悪いですか?私はそれを理解しようとしていますが、これまでのところ理解していないので、ほとんどのものはキャッシュに対してルックアップされているので、20回以上しかループしません。 –