Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加快搜索卡迈克尔号码的速度?_Python_Python 3.x_Primes - Fatal编程技术网

Python 加快搜索卡迈克尔号码的速度?

Python 加快搜索卡迈克尔号码的速度?,python,python-3.x,primes,Python,Python 3.x,Primes,这里的主要问题是:有没有更好的方法在Python中使用“all”? 我读过,它经历了每一个条件,然后回来看看是否有任何是真的。我想一次检查一个条件,然后一旦一个条件不起作用就退出。我相信这就是所谓的“短路……”。我不能使用一系列的“和”,因为它们会随着输入而改变,并且可能有数百万个条件 我在找。卡迈克尔数的一个定义是,对于所有1

这里的主要问题是:有没有更好的方法在Python中使用“all”? 我读过,它经历了每一个条件,然后回来看看是否有任何是真的。我想一次检查一个条件,然后一旦一个条件不起作用就退出。我相信这就是所谓的“短路……”。我不能使用一系列的“和”,因为它们会随着输入而改变,并且可能有数百万个条件

我在找。卡迈克尔数的一个定义是,对于所有1 我使用了代码:

def Carm(num):
    if all(gcd(k,num) == 1 for k in range(3,int(round(num**0.5)),2)) and gcd(2,num) == 1:
        print(num,'is a Prime Number')
    elif all(pow(b,num,num)==b for b in range(1,num)) and gcd(num,2)==1:
        print(num,'is a Carmichael Number')
    else:
        print(num,'is not a Carmichael Number')
对原问题的答复 我所能得到的最好结果是,通过重新排列您的条件(速度将取决于您输入的数字是否通过第一个条件)并使用
math.gcd()
代替
fracts.gcd()
,大约提高了4.5倍

我还让他们返回字符串,而不是打印字符串。这应该更快,但我之所以这么做,主要是因为它更容易测试计时。然后可以使用字符串执行任何操作:

def carm_math_reorder(num):
    if math.gcd(2,num) == 1 and all(math.gcd(k,num) == 1 for k in
                                    range(3, int(round(num**0.5)), 2)):
        return 'Prime'
    elif math.gcd(num, 2) == 1 and all(pow(b, num, num)==b for b in
                                       range(1, num)):
        return 'Carmichael'
    return 'Composite'  # implicit "else" return

% timeit [Carm(num) for num in range(1000)]  # your implementation
16.9 ms ± 89.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

% timeit [carm_math_reorder(num) for num in range(1000)]
3.71 ms ± 45.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
重新排列条件是有效的,因为
短路(实际上
所有的
),所以如果第一个条件没有通过,Python将忽略第二个条件,然后继续。在您的Carmichael测试中,检查单个
gcd()
的条件比检查
pow(b,n,n)==1的条件快,至少在我的测试中是这样。因此,应该首先进行
gcd()
测试。这可能与测试数字是否为素数的行无关。在我的测试中,这个变化导致了大约2倍的加速

我收到警告说
fracts.gcd()
已被弃用,因此我改为使用
math.gcd()
,这会更快地启动!这让我看到了其余的加速

当然,如果您需要一次检查许多数字,那么最好使用
numpy
并将其矢量化。让我知道这是否是你的用例,我会看看我是否能想出一个很好的优化版本

校正卡迈克尔试验 我很确定你的卡迈克尔号码支票被取消了。如果对所有整数
b
,而不是对所有
b
,则一个数字是Carmichael。你不能这样检查,所以你需要一个不同的规则

如果
pow(b,n-1)%n==1,
b=1,2,…,n
的所有
b
n
都是同素数,那么看起来你可以使用一个数字是Carmichael的事实,以及上述示例中的代码(或多或少):


这比上面的选项慢,但我相信它在技术上是正确的:最好的一种是正确的。

所有的
都已经短路了。无论什么来源使你认为它不是,要么是来源是错误的,要么是你误解了它。我们不知道

不过,加快速度仍然很容易。例如,您的
gcd
调用正在测试
num
是否与所有这些数字都是互质的,但这既昂贵又不必要。我们只需要检查整除性,这可以通过更快的
num%k!=0
。此外,2的可除性排除了比任何其他检查更多的数字,因此将其放在第一位将节省一些工作。另外,在
elif
中的
gcd(num,2)==1
检查也是多余的

def is_carmichael(n):
    # Requires a positive integer.
    if n == 1:
        return '1'
    elif n % 2 != 0 and all(n % k != 0 for k in range(3, math.ceil(n**0.5), 2)):
        return 'prime'
    elif all(pow(k, n, n) == k for k in range(1, n)):
        return 'carmichael'
    else:
        return 'non-carmichael composite'

首先,我会把你的条件颠倒过来
短路:如果第一个条件为
False
,则不检查第二个条件。如果你的一个条件比另一个条件慢很多,它应该排在最后。另外,你能发布你的
gcd()
代码吗?非常感谢你的回复!我应该交换哪些条件?你能推荐最好的订单吗?gcd是从“分数”中导入的:
从分数导入gcd
为什么您要通过所有的gcd计算来检查整除性?这非常有效,谢谢!!!另一种定义是,pow(b,n-1,n)=1表示所有bI认为您的第一次检查不正确。对于所有整数
b
,而不是所有整数
b
,至少,
pow(b,n,n)=1
!这是不可能签入代码的。我想你必须检查使用情况,但我甚至不知道p-1 | n-1
是什么意思……我只是用我认为更正确的东西更新了答案。我敢肯定原来的支票有瑕疵。
def is_carmichael(n):
    # Requires a positive integer.
    if n == 1:
        return '1'
    elif n % 2 != 0 and all(n % k != 0 for k in range(3, math.ceil(n**0.5), 2)):
        return 'prime'
    elif all(pow(k, n, n) == k for k in range(1, n)):
        return 'carmichael'
    else:
        return 'non-carmichael composite'