Python:简化布朗数字代码

时间:2016-11-11 23:38:58

标签: python python-3.x math

我很好奇,如果你们中的任何一个人想出一个更简化的代码来计算布朗数字。截至目前,此代码可以在进行爬网之前执行~650!。布朗数的计算方法是n! + 1 = m**(2)其中M是一个整数

brownNum = 8
import math
def squareNum(n):
        x = n // 2
        seen = set([x])
        while x * x != n:
                x = (x + (n // x)) // 2
                if x in seen: return False
                seen.add(x)
        return True
while True:
        for i in range(math.factorial(brownNum)+1,math.factorial(brownNum)+2):
                if squareNum(i) is True:
                        print("pass")
                        print(brownNum)
                        print(math.factorial(brownNum)+1)
                        break
                else:
                        print(brownNum)
                        print(math.factorial(brownNum)+1)
                        brownNum = brownNum + 1
                        continue

                break
print(input(" "))

4 个答案:

答案 0 :(得分:3)

抱歉,我不明白你的代码背后的逻辑。

我不明白为什么每次通过math.factorial(brownNum)循环使用相同的brownNum值计算while True 4次。在for循环中:

for i in range(math.factorial(brownNum)+1,math.factorial(brownNum)+2):

i 取值math.factorial(brownNum)+1

无论如何,这是我的Python 3代码,用于强力搜索Brown numbers。它很快找到了只有3对已知对,然后在这台2GHz 32位机器上大约1.8秒内测试1000以下的所有其他数字。在那一点之后你可以看到它放慢速度(它在20秒左右达到2000点)但是它会快乐地突然行进,直到因子太大而你的机器不能容纳。

我将进度信息打印到stderr,以便它可以与Brown_number对输出分开。此外,与stdout不同,stderr在不打印换行符时不需要刷新(至少,它不在Linux上)。

import sys

# Calculate the integer square root of `m` using Newton's method.
# Returns r: r**2 <= m < (r+1)**2
def int_sqrt(m):
    if m <= 0:
        return 0
    n = m << 2
    r = n >> (n.bit_length() // 2)
    while True:
        d = (n // r - r) >> 1
        r += d
        if -1 <= d <= 1:
            break
    return r >> 1

# Search for Browns numbers
fac = i = 1
while True:
    if i % 100 == 0: 
        print('\r', i, file=sys.stderr, end='')
    fac *= i
    n = fac + 1
    r = int_sqrt(n)
    if r*r == n:
        print('\nFound', i, r)
    i += 1

答案 1 :(得分:2)

您可能想要:

  • 预先计算你的平方码,而不是动态测试它们
  • 预先计算每次循环迭代num_fac = math.factorial(brownNum)而不是多次调用
  • 的阶乘
  • 实施您自己的,已记住的,因子的

应该让你跑到机器的硬限制

答案 2 :(得分:1)

我要做的一个优化就是实现一个&#39;包装器&#39; math.factorial周围的函数缓存了之前的阶乘值,因此当你的brownNum增加时,阶乘没有那么多的工作要做。这被称为&#39; memoization&#39;在计算机科学。

编辑:找到了另一个具有相似意图的答案:Python: Is math.factorial memoized?

答案 3 :(得分:1)

您还应该更准确地将平方根初始化为根。

e = int(math.log(n,4))
x = n//2**e

由于4**e <= n <= 4**(e+1),平方根将介于x/2x之间,这应该会产生第一次迭代时Heron公式的二次收敛。