Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.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_Algorithm_Primes_Ternary Tree - Fatal编程技术网

Python 使用常量空间迭代所有互质对?

Python 使用常量空间迭代所有互质对?,python,algorithm,primes,ternary-tree,Python,Algorithm,Primes,Ternary Tree,我可以按照维基百科上列出的三元树算法生成所有互质对: 很快: Start with two coprime branches: (2,1), (3,1), then iterate: Branch 1: (2m-n,m) Branch 2: (2m+n,m) Branch 3: (m+2n,n) 然而,每生产一对(比如说打印的,或者没有保存在内存中的),所使用的空间将增加三倍 在haskell中可能有一个解决方案: 但是我在python中寻找一些东西,它没有惰性求值或无限列表。公认的Has

我可以按照维基百科上列出的三元树算法生成所有互质对:

很快:

Start with two coprime branches: (2,1), (3,1), then iterate:
Branch 1: (2m-n,m)
Branch 2: (2m+n,m)
Branch 3: (m+2n,n)
然而,每生产一对(比如说打印的,或者没有保存在内存中的),所使用的空间将增加三倍

在haskell中可能有一个解决方案:


但是我在python中寻找一些东西,它没有惰性求值或无限列表。

公认的Haskell解决方案的python版本

def find_coprimes():
    l = 1
    while True:
        i = 2
        while i < l-i:
            if gcd(i, l-i) == 1:
                yield i, l-i
            i += 1
        l += 1
输出:

(2, 3)
(2, 5)
(3, 4)
(3, 5)
(2, 7)
(4, 5)
(3, 7)
(2, 9)
(3, 8)
(4, 7)

公认的Haskell解决方案的Python版本

def find_coprimes():
    l = 1
    while True:
        i = 2
        while i < l-i:
            if gcd(i, l-i) == 1:
                yield i, l-i
            i += 1
        l += 1
输出:

(2, 3)
(2, 5)
(3, 4)
(3, 5)
(2, 7)
(4, 5)
(3, 7)
(2, 9)
(3, 8)
(4, 7)

这使用对数空间,也许这就足够了?它是线性时间(使用O(k)时间产生前k对)

在David Eppstein的这些文章中,您可以阅读有关此类自递归生成器的更多信息:

演示显示前20对:

>>> pairs = coprimes()
>>> for _ in range(20):
        print(next(pairs))

(2, 1)
(3, 1)
(3, 2)
(5, 2)
(4, 1)
(5, 3)
(7, 3)
(5, 1)
(4, 3)
(8, 3)
(7, 2)
(8, 5)
(12, 5)
(9, 2)
(7, 4)
(9, 4)
(6, 1)
(7, 5)
(13, 5)
(11, 3)
演示显示了第十亿对的内存,这需要我的电脑大约4分钟,而Python进程的内存使用量保持在任何Python进程至少需要9.5 MB的基线

>>> from itertools import islice
>>> next(islice(coprimes(), 10**9-1, None))
(175577, 63087)

这使用对数空间,也许这就足够了?它是线性时间(使用O(k)时间产生前k对)

在David Eppstein的这些文章中,您可以阅读有关此类自递归生成器的更多信息:

演示显示前20对:

>>> pairs = coprimes()
>>> for _ in range(20):
        print(next(pairs))

(2, 1)
(3, 1)
(3, 2)
(5, 2)
(4, 1)
(5, 3)
(7, 3)
(5, 1)
(4, 3)
(8, 3)
(7, 2)
(8, 5)
(12, 5)
(9, 2)
(7, 4)
(9, 4)
(6, 1)
(7, 5)
(13, 5)
(11, 3)
演示显示了第十亿对的内存,这需要我的电脑大约4分钟,而Python进程的内存使用量保持在任何Python进程至少需要9.5 MB的基线

>>> from itertools import islice
>>> next(islice(coprimes(), 10**9-1, None))
(175577, 63087)

该问题没有说明生成的互质对的条件(例如,其中一个数是否在特定范围内?)。然而,我发现下面两个例子很有趣(都需要恒定的空间)

首先考虑,这里是Python 3中的一个例子:

a, b, c, d = 0, 1, 1, n
while c <= n:
    k = (n + b) // d
    a, b, c, d = c, d, k * c - a, k * d - b
    print(a, b)

如果你想找到一个满足某些性质的有理数的例子,但你不知道它的边界,这可能很方便。当然,您可以尝试所有可能的自然数对,但这会直接生成互质对。

问题不会说明生成的互质对的条件(例如,其中一个数是否在特定范围内?)。然而,我发现下面两个例子很有趣(都需要恒定的空间)

首先考虑,这里是Python 3中的一个例子:

a, b, c, d = 0, 1, 1, n
while c <= n:
    k = (n + b) // d
    a, b, c, d = c, d, k * c - a, k * d - b
    print(a, b)

如果你想找到一个满足某些性质的有理数的例子,但你不知道它的边界,这可能很方便。当然,您可以尝试所有可能的自然数对,但这会直接生成互质对。

请澄清:您想要与Haskell问题相同的限制吗<代码>每对中的第一个元素必须小于第二个元素。排序必须按升序进行——按对的元素之和;如果两个和相等,则通过对的第一个元素进行交换。如果是,则要在算法中交换这些对。Python确实有无限的生成器,这可能与您的“无限列表”类似。您是在试图避免“增长三倍”的问题,还是只需要简单的Python代码?“但我在Python中寻找一些东西,它没有惰性求值或无限列表。”Python有生成器(惰性地生成值)和函数(尤其是在
itertools
中),它们产生潜在的无限序列。我不是在寻找haskell解决方案的限制,我应该说。任何惯用的python解决方案都可以工作,而不管懒惰/无限的术语如何<代码>每对中的第一个元素必须小于第二个元素。排序必须按升序进行——按对的元素之和;如果两个和相等,则通过对的第一个元素进行交换。如果是,则要在算法中交换这些对。Python确实有无限的生成器,这可能与您的“无限列表”类似。您是在试图避免“增长三倍”的问题,还是只需要简单的Python代码?“但我在Python中寻找一些东西,它没有惰性求值或无限列表。”Python有生成器(惰性地生成值)和函数(尤其是在
itertools
中),它们产生潜在的无限序列。我不是在寻找haskell解决方案的限制,我应该说。而且任何惯用的python解决方案都可以工作,不管懒惰/无限的术语是什么。这要优雅得多,应该被接受!信息链接。是的,谢谢,这是一个优雅的解决方案,我不知道你能用迭代器做到这一点。很漂亮。我高兴得流下了眼泪。这更优雅,应该被接受!信息链接。是的,谢谢,这是一个优雅的解决方案,我不知道你能用迭代器做到这一点。很漂亮。我高兴得流下了眼泪。