使用恒定空间迭代所有互质对?

时间:2017-01-14 20:35:29

标签: python algorithm primes ternary-tree

我可以按照维基百科上列出的三元树算法生成所有互质对: https://en.wikipedia.org/wiki/Coprime_integers

快速:

int longestSequence(int a[], int n ,int* begin)
{
    int oldlength=1,length=1,i,maxvalue=0;
    for(i=0; i<n; i++)
    {
        if(a[i+1]==a[i])
        {
            length++;
            if(length>oldlength)
            {

                oldlength=length;
                *begin=i;

            }
        }
        else
        {
            oldlength=length;
            length=1;
        }

然而,每对产生的空间使用的空间将增加三倍(并且说打印,或者不保留在内存中)。

这可能是haskell的解决方案: Generating sorted list of all possible coprimes

但是我在python中寻找一些东西,它没有懒惰的评估或无限的列表。

3 个答案:

答案 0 :(得分:5)

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

def coprimes():
    yield (2, 1)
    yield (3, 1)
    for m, n in coprimes():
        yield (2*m - n, m)
        yield (2*m + n, m)
        yield (m + 2*n, n)

你可以在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)

演示显示第十亿对,这使得我的PC大约需要4分钟,而Python进程的内存使用率保持在任何Python进程至少占用我的9.5 MB基线。

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

答案 1 :(得分:1)

接受的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

只获得几个:

iterator = find_coprimes()
for i in range(10):
    print(next(iterator))

输出:

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

答案 2 :(得分:1)

该问题未说明生成的互质对的条件(例如,是特定范围内的数字之一吗?)。不过,我发现以下两个示例很有趣(都需要恒定的空间)。

首先考虑Farey sequence,这是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)

它将枚举具有1 <= a <= b <= n的所有互质对a,b。

第二个例子有点古怪,使用基于Calkin–Wilf tree的想法,您可以无限制地枚举所有互素对。好吧,至少在数学上,实际上,您仅受能够在内存中表示的数字数量的限制。无论如何,这是一个Python 3示例:

a, b = 0, 1
while True:
    a, b = b, 2*(a//b) * b - a + b
    print(a, b)

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