快速素因数分解模块

2023-11-29

我正在寻找一个执行 or 清晰的算法为了得到的素因数N用 python、伪代码或其他易读的内容。有一些要求/限制:

  • N介于 1 到 ~20 位数字之间
  • 没有预先计算的查找表,但记忆功能很好
  • 无需数学证明(例如,如果需要,可以依赖哥德巴赫猜想)
  • 无需精确,如果需要,可以是概率性/确定性的

我需要一个快速素因数分解算法,不仅适用于它本身,而且适用于许多其他算法,例如计算欧拉phi(n).

我尝试过维基百科等的其他算法,但要么我无法理解它们(ECM),要么我无法从该算法(Pollard-Brent)创建一个有效的实现。

我对 Pollard-Brent 算法非常感兴趣,所以任何更多关于它的信息/实现都会非常好。

Thanks!

EDIT

经过一番折腾后,我创建了一个相当快的素数/因式分解模块。它结合了优化的试除算法、Pollard-Brent 算法、米勒-拉宾素性测试和我在互联网上找到的最快的素数筛。 gcd 是常规 Euclid 的 GCD 实现(二进制 Euclid 的 GCD 是much比普通的慢)。

Bounty

哦,高兴,可以获得赏金!但我怎样才能赢呢?

  • 在我的模块中查找优化或错误。
  • 提供替代/更好的算法/实现。

最完整/有建设性的答案将获得赏金。

最后是模块本身:

import random

def primesbelow(N):
    # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188
    #""" Input N>=6, Returns a list of primes, 2 <= p < N """
    correction = N % 6 > 1
    N = {0:N, 1:N-1, 2:N+4, 3:N+3, 4:N+2, 5:N+1}[N%6]
    sieve = [True] * (N // 3)
    sieve[0] = False
    for i in range(int(N ** .5) // 3 + 1):
        if sieve[i]:
            k = (3 * i + 1) | 1
            sieve[k*k // 3::2*k] = [False] * ((N//6 - (k*k)//6 - 1)//k + 1)
            sieve[(k*k + 4*k - 2*k*(i%2)) // 3::2*k] = [False] * ((N // 6 - (k*k + 4*k - 2*k*(i%2))//6 - 1) // k + 1)
    return [2, 3] + [(3 * i + 1) | 1 for i in range(1, N//3 - correction) if sieve[i]]

smallprimeset = set(primesbelow(100000))
_smallprimeset = 100000
def isprime(n, precision=7):
    # http://en.wikipedia.org/wiki/Miller-Rabin_primality_test#Algorithm_and_running_time
    if n < 1:
        raise ValueError("Out of bounds, first argument must be > 0")
    elif n <= 3:
        return n >= 2
    elif n % 2 == 0:
        return False
    elif n < _smallprimeset:
        return n in smallprimeset


    d = n - 1
    s = 0
    while d % 2 == 0:
        d //= 2
        s += 1

    for repeat in range(precision):
        a = random.randrange(2, n - 2)
        x = pow(a, d, n)
    
        if x == 1 or x == n - 1: continue
    
        for r in range(s - 1):
            x = pow(x, 2, n)
            if x == 1: return False
            if x == n - 1: break
        else: return False

    return True

# https://comeoncodeon.wordpress.com/2010/09/18/pollard-rho-brent-integer-factorization/
def pollard_brent(n):
    if n % 2 == 0: return 2
    if n % 3 == 0: return 3

    y, c, m = random.randint(1, n-1), random.randint(1, n-1), random.randint(1, n-1)
    g, r, q = 1, 1, 1
    while g == 1:
        x = y
        for i in range(r):
            y = (pow(y, 2, n) + c) % n

        k = 0
        while k < r and g==1:
            ys = y
            for i in range(min(m, r-k)):
                y = (pow(y, 2, n) + c) % n
                q = q * abs(x-y) % n
            g = gcd(q, n)
            k += m
        r *= 2
    if g == n:
        while True:
            ys = (pow(ys, 2, n) + c) % n
            g = gcd(abs(x - ys), n)
            if g > 1:
                break

    return g

smallprimes = primesbelow(1000) # might seem low, but 1000*1000 = 1000000, so this will fully factor every composite < 1000000
def primefactors(n, sort=False):
    factors = []

    for checker in smallprimes:
        while n % checker == 0:
            factors.append(checker)
            n //= checker
        if checker > n: break

    if n < 2: return factors

    while n > 1:
        if isprime(n):
            factors.append(n)
            break
        factor = pollard_brent(n) # trial division did not fully factor, switch to pollard-brent
        factors.extend(primefactors(factor)) # recurse to factor the not necessarily prime factor returned by pollard-brent
        n //= factor

    if sort: factors.sort()

    return factors

def factorization(n):
    factors = {}
    for p1 in primefactors(n):
        try:
            factors[p1] += 1
        except KeyError:
            factors[p1] = 1
    return factors

totients = {}
def totient(n):
    if n == 0: return 1

    try: return totients[n]
    except KeyError: pass

    tot = 1
    for p, exp in factorization(n).items():
        tot *= (p - 1)  *  p ** (exp - 1)

    totients[n] = tot
    return tot

def gcd(a, b):
    if a == b: return a
    while b > 0: a, b = b, a % b
    return a

def lcm(a, b):
    return abs((a // gcd(a, b)) * b)

如果您不想重新发明轮子,请使用库sympy

pip install sympy

使用功能sympy.ntheory.factorint

给定一个正整数n, factorint(n)返回一个包含以下内容的字典 的主要因素n作为键及其各自的重数 作为价值观。例如:

Example:

>>> from sympy.ntheory import factorint
>>> factorint(10**20+1)
{73: 1, 5964848081: 1, 1676321: 1, 137: 1}

您可以分解一些非常大的数字:

>>> factorint(10**100+1)
{401: 1, 5964848081: 1, 1676321: 1, 1601: 1, 1201: 1, 137: 1, 73: 1, 129694419029057750551385771184564274499075700947656757821537291527196801: 1}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

快速素因数分解模块 的相关文章

  • pydev 断点不起作用

    我正在使用 python 2 7 2 sqlalchemy 0 7 unittest eclipse 3 7 2 和 pydev 2 4 开发一个项目 我在 python 文件 单元测 试文件 中设置断点 但它们被完全忽略 之前 在某些时候
  • 如何使用playsound模块停止音频?

    如何在Python代码中通过playaudio模块停止音频播放 我播放过音乐 但我无法停止音乐 我怎样才能阻止它 playsound playsound name of file 您可以使用多处理模块将声音作为后台进程播放 然后随时终止它
  • 在 Django 中使用 prefetch_lated 连接 ManyToMany 字段

    我可能遗漏了一些明显的东西 但我在连接 ManyToMany 字段以在 Django 应用程序中工作时遇到问题 我有两个模型 class Area models Model name CharField class Role models
  • python中嵌套字典值的总和

    我有一本这样的字典 data 11L a 2 b 1 a 2 b 3 22L a 3 b 2 a 2 b 5 a 4 b 2 a 1 b 5 a 1 b 0 33L a 1 b 2 a 3 b 5 a 5 b 2 a 1 b 3 a 1 b
  • 将 2D Panda 的 DataFrame 列表转换为 3D DataFrame

    我正在尝试创建一个将标签值保存到 2D DataFrame 的 Pandas DataFrame 这是我到目前为止所做的 我正在使用读取 csv 文件pd read csv并将它们附加到列表中 出于这个问题的目的 让我们考虑以下代码 imp
  • 正则表达式等价

    有没有办法找出两个任意正则表达式是否等价 对我来说看起来很复杂的问题 但可能有一些 DFA 简化机制之类的 要测试等价性 您可以计算的表达式并进行比较
  • Tensorflow 训练期间 GPU 使用率非常低

    我正在尝试为 10 类图像分类任务训练一个简单的多层感知器 这是 Udacity 深度学习课程作业的一部分 更准确地说 任务是对各种字体呈现的字母进行分类 数据集称为 notMNIST 我最终得到的代码看起来相当简单 但无论如何我在训练期间
  • 如何使用appium自动化Android手机后退按钮

    我正在使用 Appium python 客户端库 对 Android 上的混合移动应用程序进行测试自动化 我无法找到任何方法来自动化或创建手势以使用 电话后退 按钮返回到应用程序的上一页 有没有可以使用的驱动函数 我尝试了 self dri
  • 使用 argparse 指定默认文件名,但不使用 --help 打开它们?

    假设我有一个对文件执行一些操作的脚本 它在命令行上获取此文件的名称 但如果未提供 则默认为已知文件名 content txt 说 与蟒蛇的argparse 我使用以下内容 parser argparse ArgumentParser des
  • 如何使直方图列的宽度都相同

    我在操作直方图时遇到了一些麻烦 我有一个包含两列的 df 我将它们绘制为堆叠直方图 我将它们放入特定的垃圾箱中 请参阅下面的代码 但我想在最后制作一个大垃圾箱 4000 10000 但是 默认情况下 大垃圾箱的列宽很大 有没有办法让这个大垃
  • 自适应支付 API 错误 580001

    我正在 python 中向 paypal 自适应支付 API 发出 PAY 请求 并收到通用错误 id 580001 没有其他信息 headers API credentials for the API caller business ac
  • 收到“/:未找到事件。”使用 PyCharm 远程调试器时

    当我使用 PyCharm 通过 ssh 进行远程调试时tcsh shell 服务器 很多时候它停止工作 并显示 未找到事件 更具体地说 我在 pycharm 调试控制台中遇到以下内容 ssh username hostserver 22 p
  • 尝试将 cuda 与 pytorch 一起使用时出现运行时错误 999

    我为我的 Geforce 2080 ti 安装了 Cuda 10 1 和最新的 Nvidia 驱动程序 我尝试运行一个基本脚本来测试 pytorch 是否正常工作 但出现以下错误 RuntimeError cuda runtime erro
  • 如何连接多个字符串? [复制]

    这个问题在这里已经有答案了 如何将 stringList 中的所有字符串合并为一个而不打印它 例如 s joinStrings very hot day returns string print s Veryhotday 感觉有点倒退 但是
  • 如何在 matplotlib 中第一个 x 轴的底部添加第二个 x 轴?

    我指的是已经提出的问题here https stackoverflow com questions 10514315 how to add a second x axis in matplotlib 在此示例中 用户通过将第二个轴添加到与标
  • 如何从 IDLE 命令行运行 Python 脚本?

    在 bash shell 中 我可以使用 bash 或 source 手动调用脚本 我可以在 Python IDLE 的交互式 shell 中做类似的事情吗 我知道我可以转到文件 gt gt 打开模块 然后在单独的窗口中运行它 但这很麻烦
  • Pandas:按日历周分组,然后绘制真实日期时间的分组条形图

    EDIT 我找到了一个非常好的解决方案并将其发布在下面作为答案 结果将如下所示 您可以为此问题生成一些示例数据 codes list ABCDEFGH dates pd Series pd date range 2013 11 01 201
  • PyMC3 和 Theano - 导入 pymc3 后,有效的 Theano 代码停止工作

    一些简单的 theano 代码可以完美运行 当我导入 pymc3 时停止工作 这里有一些片段可以重现错误 Initial Theano Code this works import theano tensor as tsr x tsr ds
  • 将同一 numpy 数组的两个视图组合成单个视图而不复制数组?

    我有一个大型 2d numpy 数组 我想删除它的子集并处理函数剩下的内容 我需要对许多子集执行此操作 因此理想情况下我不想每次都创建数组的副本 该函数不会更改数组中的任何值 mat np load filename mat 1 mat i
  • 使用 TkInter 绑定设置不可交互(点击)覆盖

    我已经浏览了其他几篇关于类似问题的帖子 所有这些似乎都指向this https stackoverflow com questions 29458775 tkinter see through window not affected by

随机推荐