我编写了一个python程序,该程序可以在特定范围内找到友好对。我认为有很多更好的方法可以做到这一点,并且正在寻找有关如何改进我的代码的反馈。
def d(n):
x = []
for i in range(1, n):
if n % i == 0:
x.append(i)
return sum(x)
def amicable(z,y):
if d(z) == y and d(y) == z:
print(z, y)
for z in range(0, 10000, 2):
for y in range(0, 10000, 2):
if z != y:
amicable(z, y)
此代码实际上执行了应有的功能,但效率不高。我要等一会儿结果。
答案 0 :(得分:0)
不幸的是,我的箱子里所有我的项目Euclid的东西都在存储中,所以我将为您模拟一些东西。有机会计算一些素数时,我将对此进行测试。
通常,查找数字除数的最佳方法是仅检查素数。另外,您只需要检查数字的平方根即可。另外,存储素数列表很方便,因为它们需要很长时间才能计算出来。
您还可以使用一些嵌套循环魔术来检查配对的一半。
这是一个通用方案:
def save_primes(primes):
#save your primes file, they take a long time to compute
pass
def load_primes(fname):
#load your primes file
....
return primes
def compute_primes(n):
#get the prime numbers up to n
primes = []
...
save_primes(primes, "my_primes")
def get_prime_divisors(n):
#return prime divisors and their multiplicity
global PRIMES
prime_divisors = []
prime_divisor_multiplicities = []
j = 0
if "PRIMES" not in globals():
PRIMES = load_primes("my_primes")
while PRIMES[j] < n**0.5:
prime = PRIMES[j]
if n % prime == 0:
k = 0
while n % prime == 0:
n = n//prime
k += 1
prime_divisors.append(prime)
prime_divisor_multiplicities.append(k)
return prime_divisors, prime_divisor_multiplicities
def d(n):
import itertools
prime_divisors, multiplicities = get_prime_divisors(n)
sum_divisors = 0
for powers in itertools.product(map(range, multiplicities))):
for i, prime in enumerate(prime_divisors):
sum_divisors += prime**powers[i]
sum_divisors -= n #only proper divisors
return sum_divisors
def amicable(z,y):
if d(z) == y and d(y) == z:
return True
return False
for z in range(0, 10000-1, 2):
for y in range(z+1, 10000, 2):
if amicable(z, y):
print(z,y)
答案 1 :(得分:0)
我可以使用numpy
来加快您的代码速度,并避免对同一对计算两次。
import numpy as np
def divisors_sum(n):
x = np.arange(1, n)
return np.sum(x[(n % x) == 0])
def is_amicable(z,y):
if divisors_sum(z) == y and divisors_sum(y) == z:
return True
return False
def amicable_pairs(N):
for z in range(0, N, 2):
for y in range(z+2, N, 2):
if is_amicable(z, y) is True:
print(z,y)
如果我与您的代码进行比较
def d(n):
x = []
for i in range(1, n):
if n % i == 0:
x.append(i)
return sum(x)
def is_amicable_old(z,y):
if d(z) == y and d(y) == z:
return True
return False
def amicable_pairs_old(N):
for z in range(0, N, 2):
for y in range(0, N, 2):
if z!=y:
if is_amicable_old(z, y) is True:
print(z, y)
我知道了
%%time
amicable_pairs(1000)
220 284
CPU times: user 1.69 s, sys: 28 ms, total: 1.72 s
Wall time: 1.69 s
同时
%%time
amicable_pairs_old(1000)
220 284
284 220
CPU times: user 7.35 s, sys: 7.85 ms, total: 7.35 s
Wall time: 7.35 s