简体   繁体   English

如何随机生成一个数字,其条件与其他两个随机生成的数字没有共同因素

[英]How can I randomly generate a number with a condition that is shares NO common factors with two other randomly generated numbers

p1 = 1097
p2 = 1279
p = p1*p2
phi = (p1-1)*(p1-1)

I want to randomly generate a number >phi that does not share common factors between "p" and "phi"我想随机生成一个数字>phi,它在“p”和“phi”之间不共享公因数

Constructing the numbers from known primes so they do not share the same primes (as factors) in them should be faster then creating random numbers, factorizing them and checking them for non-overlapping factors.从已知素数构造数字以使它们不共享相同的素数(作为因子)应该比创建随机数、分解它们并检查它们的非重叠因子更快。

Algo:算法:

  • calculate/provide enough primes to work with (that start with your lower bound)计算/提供足够的素数(从你的下限开始)
  • then create 2 lists of random indexes into the primes list然后在素数列表中创建 2 个随机索引列表
    • first list draw how many numbers you want as factors第一个列表画出你想要多少个数字作为因素
    • remove any indexes from the 2nd list that are already in the 1st list until both lists confirm to your wanted number of factors从第二个列表中删除已经在第一个列表中的任何索引,直到两个列表都确认您想要的因素数量
  • then multpiply the primes together然后将素数相乘

could be done like so:可以这样做:

# get or calculate some primes that are big enough
# starting with 
primes = [1097,1103,1109,1117,1123,1129,1151,
  1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,
  1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,
  1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,
  1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,
  1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,
  1597,1601,1607,1609,1613,1619,1621,1627,1637,1657,1663,1667,
  1669,1693,1697,1699,1709,1721,1723,1733,1741,1747,1753,1759,
  1777,1783,1787,1789,1801,1811,1823,1831,1847,1861,1867,1871,
  1873,1877,1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,
  1979,1987,1993,1997,1999,2003,2011,2017,2027,2029,2039,2053,
  2063,2069,2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,
  2141,2143,2153,2161,2179,2203,2207,2213,2221,2237,2239,2243,
  2251,2267,2269,2273,2281,2287]

then choose indexes into them and multiply them to get your result:然后在其中选择索引并将它们相乘以获得结果:

import random
from operator import mul
from functools import reduce

random.seed(42)
choices = random.choices

def m(numbers):
    return reduce(mul, numbers, 1)

# how many numbers to use to factorize the number you want    
size = 5

# draw f.e. 5 factors from then
p1 = [primes[i] for i in choices(range(len(primes)), k=size)]

# draw 5 others that are not in p1
p2 = []
while len(p2) != size:
  p2 = [primes[i] for i in choices(range(len(primes)), k=3 * size) if i not in p1][:size]

# calculate them 
print( m(p1), m(p2)) # 8058608274530453 8642866553052643

Your choice of primes to be used should be bigger then twice the numbers you want to use to multiply out your results else you might hang in an long running loop.您选择的要使用的素数应该大于您想要用来乘以结果的数字的两倍,否则您可能会陷入长时间运行的循环中。 Providing about 5 to 10 times the primes that you want to use as factors should be plenty.提供大约 5 到 10 倍的要用作因子的素数应该足够了。

Not sure what you mean by "don't sharing common factors between p and phi", as p and phi won't have common factors不确定“不要在 p 和 phi 之间共享公因数”是什么意思,因为 p 和 phi 不会有公因数

One of the "bruteforce" ways to do it would be to run a Poisson random variable to get an integer n, then to compute the decomposition of each integer bigger than psi until you get the n-th integer bigger than psi satisfying your condition. One of the "bruteforce" ways to do it would be to run a Poisson random variable to get an integer n, then to compute the decomposition of each integer bigger than psi until you get the n-th integer bigger than psi satisfying your condition.

Another way I would see would be to take a random integer bigger than psi (with for instance a Poisson random variable) and check if they satisfy your condition.我会看到的另一种方法是采用大于 psi 的随机 integer (例如泊松随机变量)并检查它们是否满足您的条件。

Depends on what you mean and the size of your numbers.取决于你的意思和你的数字的大小。

EDIT: I suggest Poisson variables as they allow you to avoid setting an arbitrary hardcoded upper bound for your random number编辑:我建议泊松变量,因为它们允许您避免为随机数设置任意硬编码上限

You can generate random numbers using random module in python.您可以使用 python 中的random模块生成随机数。

To find that there is no common factors with p and phi , you can check greatest common divisor (GCD) with p*phi .要发现pphi没有公因数,您可以使用p*phi检查最大公约数 (GCD)。

from math import gcd as calcGcd
from random import randint

def getRandom(lower, upper, *noFacWithThese):
    for _ in range(upper - lower): # to avoid infinite loop
        randNum = randint(lower, upper)
        if noCommonFactors(randNum, noFacWithThese):
            return randNum
    return None

def noCommonFactors(base, withThese):
    withThis = 1
    for n in withThese: # find mutiplication of numbers inside 'withThese' list
        withThis *= n
    return calcGcd(base, withThis) == 1

p1 = 1097
p2 = 1279
p = p1*p2
phi = (p1-1)*(p1-1)

while True:
    print( getRandom(1, 10000, p, phi) )
    input()
    

Make sure to use necessary lower and upper limits for randint function.确保为randint function 使用必要的下限和上限。

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

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