Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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_Python 3.x_Primes_Prime Factoring - Fatal编程技术网

Python 如何为一个数字生成所有可能的除数积?

Python 如何为一个数字生成所有可能的除数积?,python,algorithm,python-3.x,primes,prime-factoring,Python,Algorithm,Python 3.x,Primes,Prime Factoring,我正在努力实现一个算法,它可以为我提供一个数字的可能结果。例如,对于N=24,这些是: 24*1, 12*2, 8*3, 6*4, 4*3*2, 3*2*2*2 我已经实现了一个函数,它可以计算给定数字的素数因子及其幂,例如N=24时的2^3和3^1。但我不知道如何从素因子中得到除数组合 编辑:以下是我尝试过的: def divisors(factors): # prime factors, e.g. [2,2,2,3] for 24 yield list(factors)

我正在努力实现一个算法,它可以为我提供一个数字的可能结果。例如,对于N=24,这些是:

24*1, 12*2, 8*3, 6*4, 4*3*2, 3*2*2*2
我已经实现了一个函数,它可以计算给定数字的素数因子及其幂,例如N=24时的2^3和3^1。但我不知道如何从素因子中得到除数组合

编辑:以下是我尝试过的:

def divisors(factors): # prime factors, e.g. [2,2,2,3] for 24
    yield list(factors)

    d = factors.pop()

    for i in range(len(factors)):
        m = [d*factors[i]] + factors[:i] + factors[i+1:]
        yield from divisors(m)

以下是您问题的最简单解决方案:

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

以下是您问题的最简单解决方案:

def prime_factors(n):
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return factors

你不会说你需要它来处理什么大小的数字,或者速度是否是一个问题,但是这里有一个非常简单的未优化的解决方案,对于小于10**7的小输入n应该可以正常工作

要解释代码,请考虑如何手动系统地执行此操作。您可以从包含2的产品开始。如果n是奇数,则没有。如果n是偶数,那么我们可以做一个简单的递归:找到n//2的所有可能分解,然后为每个分解输出分解*2。一旦我们用完了所有包含2的产品,我们就转到包含3的产品。但这里还有一个额外的复杂问题:在第一步中,我们已经找到了所有涉及a 2的乘积,因此为了避免重复解,我们想限制到每个除数至少为3的乘积。因此,我们的递归调用需要跟踪允许的最小除数,上面的最小除数。最后,我们需要一个基本情况:1可以表示为空产品

这是n=24的输出,包括您遗漏的6*2*2情况:

>>> for product in products(24):
...     print('*'.join(map(str, product)))
... 
3*2*2*2
6*2*2
4*3*2
12*2
8*3
6*4
24
然而,这并不令人满意:正如其他评论者所指出的,应该可以从素因子分解计算n的乘法分区,甚至仅仅从素因子分解中的指数列表计算n的乘法分区,只有在需要重构因子时才使用素。这是上面的一个变体,它与现有的素因子分解一起工作。效率仍有很大的提高空间:特别是,itertools.product调用和随后的过滤(忽略所有按字典顺序小于min_指数的内容)应替换为从min_指数开始的自定义迭代器。但这应该作为一个起点

import itertools

def exponent_partitions(exponents, min_exponents):
    """Generate all vector partitions of 'exponents', each of whose
    entries is lexicographically at least 'min_exponents'."""
    if all(exponent == 0 for exponent in exponents):
        yield []
    else:
        for vector in itertools.product(*(range(v+1) for v in exponents)):
            if vector >= min_exponents:
                remainder = tuple(x - y for x, y in zip(exponents, vector))
                for partition in exponent_partitions(remainder, vector):
                    yield partition + [vector]


def divisor_from_exponents(primes, exponent_vector):
    """Reconstruct divisor from the list of exponents."""
    divisor = 1
    for p, e in zip(primes, exponent_vector):
        divisor *= p**e
    return divisor


def multiplicative_partitions(primes, exponents):
    """Generate all multiplication partitions of
    product(p**e for p, e in zip(primes, exponents))"""
    if len(exponents) == 0:
        # Corner case for partitions of 1.
        yield []
    else:
        initial_vector = (0,) * (len(exponents) - 1) + (1,)
        for partition in exponent_partitions(exponents, initial_vector):
            yield [divisor_from_exponents(primes, vector) for vector in partition]
24的输出,同样:我们把24写成2**3*3**1,所以素数的元组是2,3,相应的指数元组是3,1


关于生成和计算整数的乘法分区,有很多文献。例如,请参阅中的链接,以及用于计算向量分区的链接。

您并没有说需要使用该方法来计算多大的数字,或者速度是否是一个问题,但这里有一个非常简单的未优化解决方案,对于小于10**7的小输入n应该可以正常工作

要解释代码,请考虑如何手动系统地执行此操作。您可以从包含2的产品开始。如果n是奇数,则没有。如果n是偶数,那么我们可以做一个简单的递归:找到n//2的所有可能分解,然后为每个分解输出分解*2。一旦我们用完了所有包含2的产品,我们就转到包含3的产品。但这里还有一个额外的复杂问题:在第一步中,我们已经找到了所有涉及a 2的乘积,因此为了避免重复解,我们想限制到每个除数至少为3的乘积。因此,我们的递归调用需要跟踪允许的最小除数,上面的最小除数。最后,我们需要一个基本情况:1可以表示为空产品

这是n=24的输出,包括您遗漏的6*2*2情况:

>>> for product in products(24):
...     print('*'.join(map(str, product)))
... 
3*2*2*2
6*2*2
4*3*2
12*2
8*3
6*4
24
然而,这并不令人满意:正如其他评论者所指出的,应该可以从素因子分解计算n的乘法分区,甚至仅仅从素因子分解中的指数列表计算n的乘法分区,只有在需要重构因子时才使用素。这是上面的一个变体,它与现有的素因子分解一起工作。效率仍有很大的提高空间:特别是,itertools.product调用和随后的过滤(忽略所有按字典顺序小于min_指数的内容)应替换为从min_指数开始的自定义迭代器。但这应该作为一个起点

import itertools

def exponent_partitions(exponents, min_exponents):
    """Generate all vector partitions of 'exponents', each of whose
    entries is lexicographically at least 'min_exponents'."""
    if all(exponent == 0 for exponent in exponents):
        yield []
    else:
        for vector in itertools.product(*(range(v+1) for v in exponents)):
            if vector >= min_exponents:
                remainder = tuple(x - y for x, y in zip(exponents, vector))
                for partition in exponent_partitions(remainder, vector):
                    yield partition + [vector]


def divisor_from_exponents(primes, exponent_vector):
    """Reconstruct divisor from the list of exponents."""
    divisor = 1
    for p, e in zip(primes, exponent_vector):
        divisor *= p**e
    return divisor


def multiplicative_partitions(primes, exponents):
    """Generate all multiplication partitions of
    product(p**e for p, e in zip(primes, exponents))"""
    if len(exponents) == 0:
        # Corner case for partitions of 1.
        yield []
    else:
        initial_vector = (0,) * (len(exponents) - 1) + (1,)
        for partition in exponent_partitions(exponents, initial_vector):
            yield [divisor_from_exponents(primes, vector) for vector in partition]
24的输出,同样:我们把24写成2**3*3**1,所以素数的元组是2,3,相应的指数元组是3,1


关于生成和计算整数的乘法分区,有很多文献。例如,请参阅中的链接以及计算向量分区的链接。

向我们展示您尝试过的Python代码。告诉人们,包括任何失败尝试的片段,以便他们了解您错过了哪些途径,这一点始终很重要。这很重要
这是因为它激励人们回答问题,这一点很重要,因为它使人们更容易给出高质量、相关的答案。就目前的状况而言,这一目标尚未实现。如果编辑该问题,可能会阻止该问题被关闭,并且您得到的答案的数量、质量和清晰度也会提高。请注意,这实际上是一个分区问题:您希望依次选择所有可能的唯一素数组合,以将集合拆分为,并获取产品。希望这有助于搜索。我希望你不必对大数字这样做,因为乘积的数量随着因子分解中素数的指数之和增长得非常快。你确定需要列出乘积吗,不只是数一数有多少条?向我们展示您尝试过的Python代码。告诉人们,包括任何失败尝试的片段,让他们了解您错过了哪些途径,这一点非常重要。这一点很重要,因为它激励人们回答问题,这一点很重要,因为它使人们更容易给出高质量、相关的答案。就目前的状况而言,这一目标尚未实现。如果编辑该问题,可能会阻止该问题被关闭,并且您得到的答案的数量、质量和清晰度也会提高。请注意,这实际上是一个分区问题:您希望依次选择所有可能的唯一素数组合,以将集合拆分为,并获取产品。希望这有助于搜索。我希望你不必对大数字这样做,因为乘积的数量随着因子分解中素数的指数之和增长得非常快。你确定你需要列出乘积,而不仅仅是计算有多少个吗?不,不是。我需要的是除数组合,比如OP中列出的除数组合,而不是素数。对不起!让我来研究一下!不,不是。我需要的是除数组合,比如OP中列出的除数组合,而不是素数。对不起!让我来研究一下吧!。。。现在我已经找到了SAGE的VectorPartitions的源代码,我有点不安,因为我的代码离源代码有多近:。我发誓这是我自己想出来的!。。。现在我已经找到了SAGE的VectorPartitions的源代码,我有点不安,因为我的代码离源代码有多近:。我发誓这是我自己想出来的!