简体   繁体   English

从素数计算非素数除数

[英]Calculating non-prime divisors from primes

Having a number eg 510510 有一个号码,例如510510

The prime divisors are: [2, 3, 5, 7, 11, 13, 17] 主要除数是: [2, 3, 5, 7, 11, 13, 17] 2、3、5、7、11、13、17 [2, 3, 5, 7, 11, 13, 17]

Using the list of primes, what could an efficient way to calculate the non-prime divisors be? 使用素数列表,计算非素数除数的有效方法是什么?

Assuming that the list of prime factors contains all factors according to there multiplicity, you can use 假设主要因子列表包含根据那里的多重性的所有因子,则可以使用

prime_factors = [2, 3, 5, 7, 11, 13, 17]
non_prime_factors = [reduce(operator.mul, f)
                     for k in range(2, len(prime_factors) + 1)
                     for f in itertools.combinations(prime_factors, k)]

to get all the non-prime factors. 获得所有非主要因素。 Note that you might get duplicates if some prime factors have a greater multiplicity than one -- these can be filtered out using set(non_prime_factors) . 请注意,如果某些素因子的多重性大于一个,则可能会出现重复-可以使用set(non_prime_factors)过滤掉set(non_prime_factors)

(NumPy wouldn't help too much in this context.) (在这种情况下,NumPy不会提供太多帮助。)

Edit: By "contains all factors according to there multiplicity" above I mean that (say) 2 should appear twice in the list if it is a prime factor of multiplicity 2, ie 4 is the highest power of 2 which is a factor of the number. 编辑:上面的“根据那里的多重性包含所有因子”,我的意思是,(说)如果2是多重性的素数,则2应该在列表中出现两次,即4是2的最高幂,这是2的幂。数。

Edit 2: If there are prime factors with a high multiplicity, the above code is inefficient. 编辑2:如果存在具有高多重性的素因,则上述代码效率不高。 So just in case you need this, here is efficient code for this case also. 因此,以防万一您需要它,这也是这种情况下的有效代码。

primes = [2, 3, 5]
multiplicities = [3, 4, 5]
exponents = itertools.product(*(range(n + 1) for n in multiplicities))
factors = (itertools.izip(primes, e) for e in exponents if sum(e) >= 2)
non_prime_factors = [reduce(operator.mul, (p ** e for p, e in f))
                     for f in factors]

Here is something get you started. 这是一些让您入门的东西。 In this method factors is a map of primes to their occurance in your number. 在这种方法中,因数是素数与其在您的数字中出现的映射。 So, for your case it would look like [2 : 1, 3 : 1, 5 : 1, 7 : 1, 11 : 1, 13 : 1, 17 : 1] . 因此,对于您的情况,它看起来像[2 : 1, 3 : 1, 5 : 1, 7 : 1, 11 : 1, 13 : 1, 17 : 1] Note this finds all divisors but the modification should be trivial. 请注意,这会找到所有除数,但修改应该是微不足道的。

def findAllD(factors):
    pCount = [0 for p in factors.keys()]
    pVals  = [p for p in factors.keys()]
    iters  = reduce(lambda x, y: x*y, [c+1 for c in factors.values()])
    ret    = []

    for i in xrange(0, iters):
        num = 1
        for j in range(0, len(pCount)):
            num *= pVals[j]**pCount[j]

        ret.append(num)

        for j in range(0, len(pCount)):
            pCount[j] = pCount[j] + 1

            if pCount[j] > factors[pVals[j]]:
                pCount[j] = 0
            else:
                break;

    return ret

Since the number 510510 equals 2 * 3 * 5 * 7 * 11 * 13 * 17 , every pair of those primes multiplied are also non-prime divisors: 由于数字510510等于2 * 3 * 5 * 7 * 11 * 13 * 17 ,因此,每个与这些素数相乘的对也是非素数除数:

>>> divmod(510510, 2*3)
(85085, 0)
>>> divmod(510510, 11*17)
(2730, 0)

6 (=2*3) and 187 (=11*17) are non primes, and are propper divisors to 510510. 6(= 2 * 3)和187(= 11 * 17)是非质数,是510510的适当除数。

You can easily find all the pairs of numbers using itertools: 您可以使用itertools轻松找到所有数字对:

>>> a=[2, 3, 5, 7, 11, 13, 17]
>>> list(itertools.combinations(a, 2))
[(2, 3), (2, 5), (2, 7), (2, 11), (2, 13), (2, 17), (3, 5), (3, 7), (3, 11), (3,
 13), (3, 17), (5, 7), (5, 11), (5, 13), (5, 17), (7, 11), (7, 13), (7, 17), (11
, 13), (11, 17), (13, 17)]

All you need to do then is to multiply the first number of the pair to the second one: 然后,您需要做的就是将该对的第一个数字乘以第二个:

>>> a
[2, 3, 5, 7, 11, 13, 17]
>>> b=list(itertools.combinations(a, 2))
>>> [d*e for d,e in b]
[6, 10, 14, 22, 26, 34, 15, 21, 33, 39, 51, 35, 55, 65, 85, 77, 91, 119, 143, 187, 221]

Finally, you need to repeat the same procedure to triples, four-touples, etc. passing the appropiate number as the secondth parameter to combinations(): 最后,您需要重复相同的过程以将三元组,四元组等重复,将适当的数字作为第二个参数传递给combinations():

>>> b=[reduce((lambda o, p: o*p), y, 1) for x in xrange(2, len(a)) for y in itertools.combinations(a, x)]
>>> b
[6, 10, 14, 22, 26, 34, 15, 21, 33, 39, 51, 35, 55, 65, 85, 77, 91, 119, 143, 187, 221, 30, 42, 66, 78, 102, 70, 110, 130, 170, 154, 182, 238, 286, 374, 442, 105, 165, 195, 255, 231, 273, 357, 429, 561, 663, 385, 455, 595, 715, 935, 1105, 1001, 1309, 1547, 2431, 210, 330, 390, 510, 462, 546, 714, 858, 1122, 1326, 770, 910, 1190, 1430, 1870, 2210, 2002, 2618, 3094, 4862, 1155, 1365, 1785, 2145, 2805, 3315, 3003, 3927, 4641, 7293, 5005, 6545, 7735, 12155, 17017, 2310, 2730, 3570, 4290, 5610, 6630, 6006, 7854, 9282, 14586, 10010, 13090, 15470, 24310, 34034, 15015, 19635, 23205, 36465, 51051, 85085, 30030, 39270, 46410, 72930, 102102, 170170, 255255]

If D is the set of prime divisors of N and d = |D| 如果D是N的素数除数的集合,则d = |D| than N = \\prod_i=1^d(D[i]^p[i]) for some p[i] (where p[i] is a natural number > 0). 对于某些p[i] ,其中N = \\prod_i=1^d(D[i]^p[i]) (其中p [i]是自然数> 0)。

From this point of view you can use a bit mask to go through all possible combinations of elements from D and generate partial products, which will divide N . 从这个角度来看,您可以使用位掩码来遍历D中元素的所有可能组合,并生成部分乘积,该乘积将除以N And of course go through all powers 1...p[i] for each element. 当然,每个元素都要经过所有幂1...p[i]

In this case you'll get all possible non-prime divisors of N. 在这种情况下,您将获得N的所有可能的非素数除数。

If you mean you want to generate ALL the divisors of 510510: 如果您要生成510510的所有除数:

Each prime divisor appears just once in the product. 每个主要除数在产品中仅出现一次。

Each prime divisor could be used or not used. 每个主要除数可以使用也可以不使用。 So think of it as a binary set from 0 to 127 and look at the bits. 因此,将其视为从0到127的二进制集,并查看这些位。 Iterate through the numbers and if the bit relating to the prime divisor is set, include that prime. 遍历数字,并且如果设置了与素数除数有关的位,则包括该素数。

eg binary 1011010 means use numbers 17, 11, 7 and 3 so multiply these to get 3927 例如二进制1011010表示使用数字17、11、7和3,因此将它们相乘得到3927

Of course 0000000 relates to 1 and 1111111 to 510510, so you might not want to count "1 and itself". 当然,0000000与1和1111111至510510有关,因此您可能不想将“ 1及其本身”计算在内。

If you have a number that has multiple factors you have to count 0 to n on that factor, eg 60 is 2 * 2 * 3 * 5 so 0-2 uses of 2, 0-1 use of 3, 0-1 use of 5, total of 12 possible factors (including 1 and 60). 如果您有一个具有多个因子的数字,则必须在该因子上计算0到n,例如60为2 * 2 * 3 * 5,因此0-2使用2,0-1使用3,0-1使用5,总共12个可能的因素(包括1和60)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM