Python用58秒算一亿质数,多进程,PC端

我觉得在有限的硬件资源中,提升算法能最大限度的利用资源,节省时间

以下是我的代码,如果有毛病请指正,谢谢大佬!!

质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数

我说一下思路:

1.已知质数分布在(x+1)/6==0或者(x-1)/6==0中,2,3除外

2.如果要计算100内的质数,那么只需要先知道100^0.5=10以内的素数,即s=[2,3,5,7]

用它来排除素数的倍数,其他的就不用管了,按照流程来,不断更新这个列表s

3.一亿的平方根10000内的底数先单独用此的方式算出,然后每个进程都依次为底计算,可以减少计算时间。

4.我统计了时间,最后的验证因为我没有将许多独立的文件合并,所以,用另一段代码统计。

以下是第一段:

import math
import multiprocessing
import os
import time


# 融合了复用算法
def plus(z=100000, num='0', dirname=None):
    _time3 = time.time()
    sss = [2, 3]
    for x in range(2, z + 1):
        n = None
        if (x - 1) % 6 == 0 or (x + 1) % 6 == 0:
            w1 = math.sqrt(x + 1)
            for y in sss:
                if y >= w1:
                    n = 1
                    break
                if x % y == 0:
                    break
            else:
                n = 1
        if n:
            sss.append(x)
    with open(f'{dirname}/{num}.txt', 'w+', encoding='utf-8') as d:
        for _s in iter(sss):
            d.write(f'{_s}\n')
    _time2 = time.time()
    print(f'plus 耗时--->{_time2 - _time3},all={len(sss)}')


def zhi_mun(lists, num, dirname, ppp):
    pid = os.getpid()
    _time1 = time.time()
    sss = []
    for _x in iter(lists):
        n = 0
        if (_x - 1) % 6 == 0 or (_x + 1) % 6 == 0:
            w1 = math.sqrt(_x + 1)
            for y in ppp:
                if y >= w1:
                    n = 1
                    break
                if _x % y == 0:
                    break
            else:
                n = 1
        if n:
            sss.append(_x)
    _time2 = time.time()

    with open(f'{dirname}/{num}.txt', 'w+', encoding='utf-8') as d:
        for _s in iter(sss):
            d.write(f'{_s}\n')
    print(f"pid:{pid},底数为{len(ppp)}个,计算出{len(sss)}个,耗时{_time2 - _time1}")
    quit(0)


if __name__ == '__main__':
    time1 = time.time()
    s = {}
    print(os.getpid())
    # u = int(input('='))
    u = 100000000
    allas = [d for d in range(1, u + 1)]
    cpu_count = os.cpu_count()
    cpu_count = 50
    print(f"cpu_count:{cpu_count}")
    newdir = 'math3'
    if not os.path.exists(newdir):
        os.mkdir(newdir)
    stop = int(math.sqrt(u)) + 1  # 作为底数
    music_process = multiprocessing.Process(target=plus, kwargs={'z': stop, 'num': 0, 'dirname': newdir})
    music_process.start()
    music_process.join()
    print('firstfile is OK')
    long = int((len(allas) - stop) / cpu_count)
    end_long = len(allas) - long * cpu_count - stop
    print(f"long:{long}", f'end_long:{end_long}')
    for i in range(cpu_count):
        start = stop + i * long
        ends = stop + (i + 1) * long
        if i == cpu_count - 1:
            ends = stop + (i + 1) * long + end_long
        # print(start, ends)
        one = allas[start:ends]
        pp = []
        with open(f'{newdir}/0.txt', 'r', encoding='utf-8') as d:
            for l in d:
                pp.append(int(l))
        music_process = multiprocessing.Process(target=zhi_mun,
                                                kwargs={'lists': one, 'num': i + 1, 'dirname': newdir, 'ppp': pp})
        music_process.start()
        # print(music_process)
        # music_process.join()
        x = music_process.pid
        s[i] = x
        # music_process.join()
    music_process.join()
    time2 = time.time()
    print(f'共耗时{time2 - time1}')
    print(len(allas), len(s), s)
    with open(f'{newdir}/end.txt', 'w+', encoding='utf-8') as d:
        d.write(f'计算{len(allas)}个,耗时{time2 - time1},共{-1}个')

以下是第二段:

import os
import sys
def makedirs(keyword):
    if not os.path.exists(keyword):
        os.makedirs(keyword)
def tj_all(dir_name=["math3"], target_dir=["自动拼接"], rules=r"(.+)"):
    """
    :param dir_name: 寻找路径
    :param target_dir: 储存路径
    :param rules: 寻找规则
    :return:
    """
    nowpath = sys.path[0]
    if nowpath.find('\\') != -1:
        print('PC端')
        suffix = '\\'
    elif nowpath.find('/') != -1:
        print('手机端')
        suffix = '/'
    else:
        print('识别错误')
        quit()
   
    name = nowpath + suffix + suffix.join(dir_name) + suffix
    tarname = nowpath + suffix + suffix.join(target_dir) + suffix
    makedirs(tarname)
    all_s = os.listdir(name)
    print('all_s', all_s)
    num = 0
    first_path = name
    if os.path.isdir(first_path):
        for one_ in all_s:
            se = 0
            with open(first_path + one_, 'r', encoding='utf-8') as g:
                for j in g.readlines():
                    j=j.replace('\n','')
                    if j.isdigit():
                        se += 1
            num += se
            print(one_, se)

    # delete_list(h=one, target_dir=name)
    print(f"统计结束!{num}")


tj_all()

有点小问题,有时间再更,相信大佬们随便就能看懂!

哈哈,先闪一步~~

 

 

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值