コードを分割して、かなりの時間を費やしているコード部分を改善できます。
の1-
あなたはif m != n and amicable(m, n) == True:
とif amicable(m, n) == True and m != n:
を交換した場合、それはあなたのm != n
がfalse
されるために友好的な方法(最も高価なメソッド)に10000回のコールを保存します。
amicable
メソッドでは、両方の数値のすべての要素を見つけるために1からnをループしています。要因を見つけるにはより良いアルゴリズムが必要です。あなたは上記のhereを使用することができます。ファクタを見つけるためにO(n)
の複雑さがO(sqrt(n))
に減少します。この最終的なコードは、あなたが言及した半分の時間である、私のために実行するために10分を取っ考慮すると、両方のあなたのコード上のポイントが
def amicable(a, b):
if sum(factors(a) - {a}) == b and sum(factors(b) - {b}) == a:
return True
return False
sum_of_amicables = 0
for m in range (1, 10001):
for n in range (1, 10001):
if m!= n and amicable(m, n) == True:
sum_of_amicables = sum_of_amicables + m + n
なります
def factors(n):
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
。
Iはfactors
方法を最適化することによって一時30分にそれを最適化するようにさらにできました。
factors
メソッドに10000 * 10000コールがあります。そして、数字のそれぞれについて、factors
が10000回呼び出されます。つまり、同じ数に対して10000回の係数を計算します。したがって、コールごとに計算するのではなく、以前の要因計算の結果をキャッシュすることで最適化することができます。
factors
を変更して結果をキャッシュする方法は次のとおりです。
def factors(n, cache={}):
if cache.get(n) is not None:
return cache[n]
cache[n] = set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
return cache[n]
全コード:(ランタイム午前1時30分)
だから、完全かつ最終的なコードは、あなたはまだそれをさらに向上させることができます
def factors(n, cache={}):
if cache.get(n) is not None:
return cache[n]
cache[n] = set(reduce(list.__add__,
([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))
return cache[n]
def amicable(a, b):
if sum(factors(a) - {a}) == b and sum(factors(b) - {b}) == a:
return True
return False
sum_of_amicables = 0
for m in range (1, 10001):
for n in range (1, 10001):
if m!= n and amicable(m, n) == True:
sum_of_amicables = sum_of_amicables + m + n
になります。
ヒント:sum
は、それぞれの数値に対して10000回とも呼ばれます。
多くのネストされたループでは、そのようなパフォーマンスの低下が予想されます。どの部品が最も遅いかを見るには、[Profile it](http://stackoverflow.com/questions/582336/how-can-you-profile-a-python-script)を参照してください。とにかく、あなたの問題を解決するにはより良いアルゴリズム**を見つける必要があります。 Pythonの速度自体はここでは問題になりません。 –