300 000 000 000 的质因数?
我需要找出超过3000亿的素因数。 我有一个函数正在添加到它们的列表中......非常缓慢! 现在它已经运行了大约一个小时,我认为它还有相当长的距离要静止。 我这样做是完全错误的还是这是预期的?
编辑:我试图找到数字 600851475143 的最大质因数。
编辑: 结果:
{
List<Int64> ListOfPrimeFactors = new List<Int64>();
Int64 Number = 600851475143;
Int64 DividingNumber = 2;
while (DividingNumber < Number / DividingNumber)
{
if (Number % DividingNumber == 0)
{
ListOfPrimeFactors.Add(DividingNumber);
Number = Number/DividingNumber;
}
else
DividingNumber++;
}
ListOfPrimeFactors.Add(Number);
listBox1.DataSource = ListOfPrimeFactors;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
您只需要检查它的余数 mod(n),其中 n 是素数 <= sqrt(N),其中 N 是您要分解的数字。 即使在非常慢的计算机或 TI-85 上,它实际上也不应该花费一个多小时。
You only need to check it's remainder mod(n) where n is a prime <= sqrt(N) where N is the number you are trying to factor. It really shouldn't take over an hour, even on a really slow computer or a TI-85.
你的算法必须是FUBAR。 在我使用 Python 的 1.6 GHz 上网本上,这只需要大约 0.1 秒。 Python 并不以其惊人的速度而闻名。 然而,它确实具有任意精度的整数......
(这段代码似乎无视我对数论的了解不足以填充顶针这一事实。)
Your algorithm must be FUBAR. This only takes about 0.1s on my 1.6 GHz netbook in Python. Python isn't known for its blazing speed. It does, however, have arbitrary precision integers...
(This code seems to work in defiance of the fact that I don't know enough about number theory to fill a thimble.)
只是为了稍微扩展/改进“仅测试不以 5 结尾的奇数”建议...
所有大于 3 的素数要么比 6 的倍数多一或少一(6x + 1 或 6x - 1)对于 x 的整数值)。
Just to expand/improve slightly on the "only test odd numbers that don't end in 5" suggestions...
All primes greater than 3 are either one more or one less than a multiple of 6 (6x + 1 or 6x - 1 for integer values of x).
即使使用相对简单的蛮力,也不应该花那么长时间。 对于这个具体数字,我可以在大约一秒钟的时间内在脑海中将其分解。
你说你不需要解决方案(?),但这是你的“微妙”提示。 该数字的唯一质因数是最低的三个质数。
It shouldn't take that long, even with a relatively naive brute force. For that specific number, I can factor it in my head in about one second.
You say you don't want solutions(?), but here's your "subtle" hint. The only prime factors of the number are the lowest three primes.
该大小的半素数用于加密,所以我很好奇你到底想用它们做什么。
除此之外,目前还没有好的方法可以在相对较短的时间内找到大数的素因数分解。
Semi-prime numbers of that size are used for encryption, so I am curious as to what you exactly want to use them for.
That aside, there currently are not good ways to find the prime factorization of large numbers in a relatively small amount of time.
您是否记得将要因式分解的数字除以找到的每个因数?
举例来说,您发现 2 是一个因数。 您可以将其添加到因子列表中,但然后将尝试分解的数字除以该值。
现在您只需搜索 1500 亿的因数。 每次你都应该从你刚刚找到的因素开始。 因此,如果 2 是一个因素,请再次测试 2。 如果您找到的下一个因子是 3,则无需再次从 2 进行测试。
等等...
Are you remembering to divide the number that you're factorizing by each factor as you find them?
Say, for example, you find that 2 is a factor. You can add that to your list of factors, but then you divide the number that you're trying to factorise by that value.
Now you're only searching for the factors of 150 billion. Each time around you should start from the factor you just found. So if 2 was a factor, test 2 again. If the next factor you find is 3, there's no point testing from 2 again.
And so on...
使用蛮力查找素因数很困难,这听起来像是您正在使用的技术。
这里有一些加快速度的技巧:
编辑:一个简单的例子:
您正在查找 275 的因数。
那么 275 = 5 * 5 * 11
更有意义吗?
Finding prime factors is difficult using brute force, which sounds like the technique you are using.
Here are a few tips to speed it up somewhat:
Edit: A simple example:
You are finding the factors of 275.
So 275 = 5 * 5 * 11
Make more sense?
对大数进行因式分解是一个难题。 事实上,如此困难以至于我们依赖它来保证 RSA 的安全。 但请查看维基百科页面,了解一些可以提供帮助的算法指针。 但对于这么小的数字,确实不应该花那么长时间,除非您一遍又一遍地重复工作,而不必在某个地方做。
对于暴力解决方案,请记住您可以进行一些小型优化:
Factoring big numbers is a hard problem. So hard, in fact, that we rely on it to keep RSA secure. But take a look at the wikipedia page for some pointers to algorithms that can help. But for a number that small, it really shouldn't be taking that long, unless you are re-doing work over and over again that you don't have to somewhere.
For the brute-force solution, remember that you can do some mini-optimizations:
这是一个 XSLT 解决方案!
此 XSLT 转换需要 0.109 秒。
此转换只需 0.109 秒即可产生正确的结果(最大质因数 600851475143)。:
6857
该转换使用
f:sqrt()
和f:isPrime()
定义于FXSL 2.0
—— XSLT。FXSL
本身完全是用 XSLT。f:isPrime()
使用< strong>费马小定理,从而可以高效地确定素性。Here is an XSLT solution!
This XSLT transformation takes 0.109 sec.
This transformation produces the correct result (the maximum prime factor of 600851475143) in just 0.109 sec.:
6857
The transformation uses the
f:sqrt()
andf:isPrime()
defined inFXSL 2.0
-- a library for functional programming in XSLT.FXSL
is itself written entirely in XSLT.f:isPrime()
uses Fermat's little theorem so that it is efficient to determine primeality.最后一件事没有人提到,也许是因为它看起来很明显。 每次找到一个因子并将其除掉时,不断尝试该因子,直到失败为止。
64 只有一个质因数 2。如果你不断地除 2 直到你不能除为止,你会发现这个结果非常微不足道。
One last thing nobody has mentioned, perhaps because it seems obvious. Every time you find a factor and divide it out, keep trying the factor until it fails.
64 only has one prime factor, 2. You will find that out pretty trivially if you keep dividing out the 2 until you can't anymore.
如果需要一个小时,你就做错了什么。 您甚至可能在某个地方有无限循环 - 确保您没有使用 32 位整数。
You're doing something wrong if it's taking an hour. You might even have an infinite loop somewhere - make sure you're not using 32-bit ints.
理解平方根为何如此重要的关键在于,考虑到 n 的每个因子低于 n 的平方根都有一个对应的因子高于。 要了解这一点,请考虑如果 x 是 n 的因子,则 x/n = m,这意味着 x/m = n,因此 m 也是一个因子。
The key to understanding why the square root is important, consider that each factor of n below the square root of n has a corresponding factor above it. To see this, consider that if x is factor of n, then x/n = m which means that x/m = n, hence m is also a factor.
我根本不认为它会花费很长时间——这并不是一个特别大的数字。
您能给我们一个导致您的代码困难的示例编号吗?
I wouldn't expect it to take very long at all - that's not a particularly large number.
Could you give us an example number which is causing your code difficulties?
您可以在以下网站上获得答案:Factoris - 在线分解服务。 它可以计算非常大的数字,但它也可以分解代数表达式。
Here's one site where you can get answers: Factoris - Online factorization service. It can do really big numbers, but it also can factorize algebraic expressions.
最快的算法是筛算法,并且基于离散数学的神秘领域(至少在我的头脑中),实现和测试很复杂。
最简单的因式分解算法可能是(正如其他人所说的)埃拉托斯特尼筛法。 使用此方法来分解数字
N
时需要记住的事情:x
的递增序列,看看它们是否能均匀地划分您的候选数字N
(在 C/Java/Javascript 中检查是否N % x == 0
),在这种情况下 N 不是素数。sqrt(N)
,但实际上并不计算sqrt(N)
:只要您的测试因子 x 通过测试即可循环x*x
P*P > ; N_max
因为你永远不会再使用它们x
只需检查 2 和所有奇数 是的,它会花费。更长,但对于合理大小的数字来说,时间不会太长。它的近似值可以告诉您哪些数字是质数;即使对于 264 = 大约 1.8x1019,该分数的减小也非常。每 43 个数字中就有一个是素数(= 每 21.5 个奇数中就有一个是素数)对于小于 264 的因数,这些因数x
小于。 232 其中大约每 20 个数字中有一个是质数 = 每 10 个奇数中有一个是质数。 因此,您必须测试 10 倍的数字,但循环应该更快一些,而且您不必费力存储所有这些素数。还有一些较旧且更简单的筛选算法,它们稍微复杂一些,但仍然相当容易理解。 请参阅迪克森,Shanks' 和 费马的< /a> 因式分解算法。 我读过一篇关于其中一篇的文章,不记得是哪一篇了,但它们都相当简单,并且使用平方差的代数性质。
如果您只是测试数字
N
是否是素数,并且实际上并不关心因子本身,请使用 概率素性测试。 我认为 Miller-Rabin 是最标准的。The fastest algorithms are sieve algorithms, and are based on arcane areas of discrete mathematics (over my head at least), complicated to implement and test.
The simplest algorithm for factoring is probably (as others have said) the Sieve of Eratosthenes. Things to remember about using this to factor a number
N
:x
to see if they evenly divide your candidate numberN
(in C/Java/Javascript check whetherN % x == 0
) in which case N is not prime.sqrt(N)
, but don't actually calculatesqrt(N)
: loop as long as your test factor x passes the testx*x<N
P*P > N_max
since you'll never use them againx
just check 2 and all the odd numbers. Yes, it will take longer, but not that much longer for reasonable sized numbers. The prime-counting function and its approximations can tell you what fraction of numbers are prime; this fraction decreases very slowly. Even for 264 = approx 1.8x1019, roughly one out of every 43 numbers is prime (= one out of every 21.5 odd numbers is prime). For factors of numbers less than 264, those factorsx
are less than 232 where about one out of every 20 numbers is prime = one out of every 10 odd numbers is prime. So you'll have to test 10 times as many numbers, but the loop should be a bit faster and you don't have to mess around with storing all those primes.There are also some older and simpler sieve algorithms that a little bit more complex but still fairly understandable. See Dixon's, Shanks' and Fermat's factoring algorithms. I read an article about one of these once, can't remember which one, but they're all fairly straightforward and use algebraic properties of the differences of squares.
If you're just testing whether a number
N
is prime, and you don't actually care about the factors themselves, use a probabilistic primality test. Miller-Rabin is the most standard one, I think.我花了一些时间在这上面,因为它让我着迷。我暂时不会将代码粘贴到这里。 如果您好奇的话,请参阅this Factors.py gist。
请注意,在阅读这个问题之前,我对因式分解一无所知(现在仍然不知道)。 这只是 BradC 上面答案的 Python 实现。
在我的 MacBook 上,需要 0.002 秒来分解问题中提到的数字 (600851475143)。
显然必须有更多、更快的方法来做到这一点。 我的程序需要 19 秒来计算 6008514751431331 的因子。但是 Factoris 服务立即给出答案。
I spent some time on this since it just sucked me in. I won't paste the code here just yet. Instead see this factors.py gist if you're curious.
Mind you, I didn't know anything about factoring (still don't) before reading this question. It's just a Python implementation of BradC's answer above.
On my MacBook it takes 0.002 secs to factor the number mentioned in the question (600851475143).
There must obviously be much, much faster ways of doing this. My program takes 19 secs to compute the factors of 6008514751431331. But the Factoris service just spits out the answer in no-time.
具体号码是300425737571? 它很简单地分解为 131 * 151 * 673 * 22567。
我不明白有什么大惊小怪的...
The specific number is 300425737571? It trivially factors into 131 * 151 * 673 * 22567.
I don't see what all the fuss is...
这里有一些 Haskell 的好处给你们:)
花了大约 0.5 秒找到它们,所以我认为这是成功的。
Here's some Haskell goodness for you guys :)
Took it about .5 seconds to find them, so I'd call that a success.
您可以使用埃拉托斯特尼筛来查找素数,看看您的数字是否能被这些素数整除你发现。
You could use the sieve of Eratosthenes to find the primes and see if your number is divisible by those you find.