在python中执行素数值对

在python中执行素数值对,python,primes,Python,Primes,我目前被困在欧拉计划问题60上。问题是这样的: 素数3、7、109和673是非常显著的。通过取任意两个素数并以任意顺序连接它们,结果将始终是素数。例如,取7和109,7109和1097都是素数。这四个素数之和792表示具有此属性的四个素数集合的最小和 求一组五个素数的最小和,其中任意两个素数连接起来生成另一个素数 在Python中,我使用并创建了以下函数 def isprime(n): """Primality test using 6k+-1 optimi

我目前被困在欧拉计划问题60上。问题是这样的:

素数3、7、109和673是非常显著的。通过取任意两个素数并以任意顺序连接它们,结果将始终是素数。例如,取7和109,7109和1097都是素数。这四个素数之和792表示具有此属性的四个素数集合的最小和

求一组五个素数的最小和,其中任意两个素数连接起来生成另一个素数

在Python中,我使用并创建了以下函数

def isprime(n):
    """Primality test using 6k+-1 optimization."""
    if n <= 3:
        return n > 1
    elif n % 2 == 0 or n % 3 == 0:
        return False
    i = 5
    while i * i <= n:
        if n % i == 0 or n % (i + 2) == 0:
            return False
        i += 6
    return True

def prime_pair_sets(n):
    heap = [[3,7]]
    x = 11
    #Phase 1: Create a list of length n.
    while getMaxLength(heap)<n:
        if isprime(x):
            m = [x]
            for lst in heap:
                tmplst = [x]
                for p in lst:
                    if primePair(x,p):
                        tmplst.append(p)
                if len(tmplst)>len(m):
                    m=tmplst
            heap.append(m)
        x+=2
    s = sum(maxList(heap))
    #Phase 2: Find the lowest sum.
    for li in heap:
        y=x
        while s>(sum(li)+y) and len(li)<n:
            b = True
            for k in li:
                if not primePair(k,y):
                    b = False
            if b == True:
                li.append(y)
            y+=2
        if len(li)>=n:
            s = sum(li)
    return s

def getMaxLength(h):
    m = 0
    for s in h:
        if len(s) > m:
            m = len(s)
    return m

def primePair(x, y):
    return isprime(int(str(x)+str(y))) and isprime(int(str(y)+str(x)))

def maxList(h):
    result = []
    for s in h:
        if len(s)> len(result):
            result = s
    return result
我仅使用第一阶段执行primePairSets函数。经过大约一个小时的等待,我得到了7461733647+23003+16451+1493+23的总数。事实证明,这不是我们想要的金额。我用两个阶段再次尝试了这个问题。大约两个小时后,我得到了同样的错误结果。显然,答案不到74617。有人能帮我找到一个更有效的方法来解决这个问题吗。请告诉我如何解决它。

找到解决方案

素数:135197570167338389 总数:26033 运行时间减少到约10秒,而OP solution报告的运行时间为1-2小时。 接近

基于扩展包含素数列表路径的回溯算法 如果一个素数与路径中已有的所有素数成对,则可以将其添加到路径中 使用Eratosthenes筛预先计算素数,直到达到我们预期需要的最大值 对于每个素数,预先计算它与哪个素数成对 代码

运行时间

n  max_prime    Primes Found                      Run Time (secs)
2  1000         (3, 7)                            0.1280
3  1000         (3, 37, 67)                       0.1240
4  1000         (3, 7, 109, 673)                  0.1233
5  40,000       (13, 5197, 5701, 6733, 8389)      7.1142
注意:上面的计时在较旧的Windows桌面计算机上执行, 即: 约7岁的HP Pavilion台式机i7 CPU 920@2.67 GHz

解决方案

素数:135197570167338389 总数:26033 运行时间减少到约10秒,而OP solution报告的运行时间为1-2小时。 接近

基于扩展包含素数列表路径的回溯算法 如果一个素数与路径中已有的所有素数成对,则可以将其添加到路径中 使用Eratosthenes筛预先计算素数,直到达到我们预期需要的最大值 对于每个素数,预先计算它与哪个素数成对 代码

运行时间

n  max_prime    Primes Found                      Run Time (secs)
2  1000         (3, 7)                            0.1280
3  1000         (3, 37, 67)                       0.1240
4  1000         (3, 7, 109, 673)                  0.1233
5  40,000       (13, 5197, 5701, 6733, 8389)      7.1142
注意:上面的计时在较旧的Windows桌面计算机上执行, 即: 约7岁的HP Pavilion台式机i7 CPU 920@2.67 GHz


我写这段代码是基于一个Eratosthenes筛,它只存储数字1 mod 6和-1 mod 6。它非常快

def find_lowest_sum (pmax,num):
    n=int(str(pmax)+str(pmax))
    sieve5m6 = [True] * (n//6+1)
    sieve1m6 = [True] * (n//6+1)
    for i in range(1,int((n**0.5+1)/6)+1):
        if sieve5m6[i]:
            sieve5m6[6*i*i::6*i-1]=[False]*(((n//6+1)-6*i*i-1)//(6*i-1)+1)
            sieve1m6[6*i*i-2*i::6*i-1]=[False]*(((n//6+1)-6*i*i+2*i-1)//(6*i-1)+1)
        if sieve1m6[i]:
            sieve5m6[6*i*i::6*i+1]=[False]*(((n//6+1)-6*i*i-1)//(6*i+1)+1)
            sieve1m6[6*i*i+2*i::6*i+1]=[False]*(((n//6+1)-6*i*i-2*i-1)//(6*i+1)+1)

    
    def test_concatenate (p1,p2):
        ck=0
        p3=int(str(p1)+str(p2)) 
        if  sieve1m6[(p3-1)//6] and p3%6==1:
            ck=1
        elif  sieve5m6[(p3+1)//6]and p3%6==5:
            ck=1 
        if ck==1:
            p3=int(str(p2)+str(p1))
            if  sieve1m6[(p3-1)//6] and p3%6==1:
                ck=2
            elif  sieve5m6[(p3+1)//6]and p3%6==5:
                ck=2 
        if ck==2:
             return True
        else: 
             return False

    kmax=(pmax+1)//6
    s1=5*pmax
    P1=[]
    P2=[]
    p=3
    kmin=0
    while p<s1//5:
        if p==3 or(p%6==1 and sieve1m6[(p-1)//6])or(p%6==5 and sieve5m6[(p+1)//6]):
            P=[]
            if p%6==1:
                kmin=p//6
            elif p%6==5:
                kmin=(p+1)//6
                if  sieve1m6[kmin]:
                    if test_concatenate(p,6*kmin+1):
                        P.append(6*kmin+1) 

            for  k in range(kmin+1,kmax):
                if  sieve5m6[k]:
                    if test_concatenate(p,6*k-1):
                        P.append(6*k-1) 
                if  sieve1m6[k]:
                    if test_concatenate(p,6*k+1):
                        P.append(6*k+1) 

            i1=0
            while i1<len(P) and P[i1]<s1:
                P1=[p]
                s=p
                P1.append(P[i1])
                s+=P[i1]

                for i2 in range(i1+1,len(P)):
                    for i3 in range(1,len(P1)):
                        ck=test_concatenate(P[i2],P1[i3])
                        if  ck==False:
                            break
                    if len(P1)-1==i3 and ck==True:
                        P1.append(P[i2])
                        s+=P[i2]
                    if len(P1)==num:
                        if s<s1:
                            P2=P1
                            s1=s
                        break
 
                i1+=1
        p+=2
    return P2



P=find_lowest_sum(9001,5)


print(P)
s=0
for i in range(0,len(P)):
    s+=P[i]
print(s)

我写这段代码是基于一个Eratosthenes筛,它只存储数字1 mod 6和-1 mod 6。它非常快

def find_lowest_sum (pmax,num):
    n=int(str(pmax)+str(pmax))
    sieve5m6 = [True] * (n//6+1)
    sieve1m6 = [True] * (n//6+1)
    for i in range(1,int((n**0.5+1)/6)+1):
        if sieve5m6[i]:
            sieve5m6[6*i*i::6*i-1]=[False]*(((n//6+1)-6*i*i-1)//(6*i-1)+1)
            sieve1m6[6*i*i-2*i::6*i-1]=[False]*(((n//6+1)-6*i*i+2*i-1)//(6*i-1)+1)
        if sieve1m6[i]:
            sieve5m6[6*i*i::6*i+1]=[False]*(((n//6+1)-6*i*i-1)//(6*i+1)+1)
            sieve1m6[6*i*i+2*i::6*i+1]=[False]*(((n//6+1)-6*i*i-2*i-1)//(6*i+1)+1)

    
    def test_concatenate (p1,p2):
        ck=0
        p3=int(str(p1)+str(p2)) 
        if  sieve1m6[(p3-1)//6] and p3%6==1:
            ck=1
        elif  sieve5m6[(p3+1)//6]and p3%6==5:
            ck=1 
        if ck==1:
            p3=int(str(p2)+str(p1))
            if  sieve1m6[(p3-1)//6] and p3%6==1:
                ck=2
            elif  sieve5m6[(p3+1)//6]and p3%6==5:
                ck=2 
        if ck==2:
             return True
        else: 
             return False

    kmax=(pmax+1)//6
    s1=5*pmax
    P1=[]
    P2=[]
    p=3
    kmin=0
    while p<s1//5:
        if p==3 or(p%6==1 and sieve1m6[(p-1)//6])or(p%6==5 and sieve5m6[(p+1)//6]):
            P=[]
            if p%6==1:
                kmin=p//6
            elif p%6==5:
                kmin=(p+1)//6
                if  sieve1m6[kmin]:
                    if test_concatenate(p,6*kmin+1):
                        P.append(6*kmin+1) 

            for  k in range(kmin+1,kmax):
                if  sieve5m6[k]:
                    if test_concatenate(p,6*k-1):
                        P.append(6*k-1) 
                if  sieve1m6[k]:
                    if test_concatenate(p,6*k+1):
                        P.append(6*k+1) 

            i1=0
            while i1<len(P) and P[i1]<s1:
                P1=[p]
                s=p
                P1.append(P[i1])
                s+=P[i1]

                for i2 in range(i1+1,len(P)):
                    for i3 in range(1,len(P1)):
                        ck=test_concatenate(P[i2],P1[i3])
                        if  ck==False:
                            break
                    if len(P1)-1==i3 and ck==True:
                        P1.append(P[i2])
                        s+=P[i2]
                    if len(P1)==num:
                        if s<s1:
                            P2=P1
                            s1=s
                        break
 
                i1+=1
        p+=2
    return P2



P=find_lowest_sum(9001,5)


print(P)
s=0
for i in range(0,len(P)):
    s+=P[i]
print(s)

使用埃拉托斯烯筛进行初步检查,这将节省大量时间。如果部分列表中有3个元素,则需要将任何新候选元素与所有3个现有元素(前缀和后缀)进行对比检查。使用Eratosthenes筛选进行基本检查,这将节省大量时间。如果部分列表中有3个元素,则需要将任何新候选元素与所有3个现有元素(前缀和后缀)进行对比。