【发布时间】:2017-09-23 08:17:59
【问题描述】:
所以我实现了自己的小型 RSA 算法,并在此过程中编写了一个函数来查找大素数。
首先,我编写了一个测试素数的函数prime?,然后我编写了两个版本的素数搜索函数。在第一个版本中,我只是测试随机 BigIntegers,直到我遇到一个素数。在第二个版本中,我对一个随机 BigInteger 进行采样,然后将其递增,直到找到一个素数。
(defn resampling []
(let [rnd (Random.)]
(->> (repeatedly #(BigInteger. 512 rnd))
(take-while (comp not prime?))
(count))))
(defn incrementing []
(->> (BigInteger. 512 (Random.))
(iterate inc)
(take-while (comp not prime?))
(count)))
(let [n 100]
{:resampling (/ (reduce + (repeatedly n resampling)) n)
:incrementing (/ (reduce + (repeatedly n incrementing)) n)})
运行此代码会产生两个平均值:重采样函数为 332.41,递增函数为 310.74。
现在第一个数字对我来说完全有意义。 prime number theorem 表示n'th 素数的大小约为n*ln(n)(其中ln 是自然对数)。所以相邻素数之间的距离约为n*ln(n) - (n-1)*ln(n-1) ≈ (n - (n - 1))*ln(n) = ln(n)(对于n 的大值ln(n) ≈ ln(n - 1))。由于我正在采样 512 位整数,因此我希望素数之间的距离在 ln(2^512) = 354.89 附近。因此,随机抽样在达到素数之前平均需要大约 354.89 次尝试,结果非常好。
我的困惑是为什么递增函数要采取同样多的步骤。如果我想象在素数相距 355 个单位的网格上投掷飞镖,则平均只需大约一半的步数即可走到下一个更高的素数,因为平均而言,我会在两个素数之间击中中心。
(prime?的代码有点长,大家可以看一下here。)
【问题讨论】:
-
也许是因为你用增量方法测试的数字有一半是偶数?
-
@rossum 与
resampling方法相同,所以我认为这不是原因 -
检查它我得到了一个相似的号码。我的数学很生疏,从一开始就没有那么好,但据我所知,素数的分布是en.wikipedia.org/wiki/Poisson_distribution,这意味着这些数字从这里是有意义的:phillipmfeldman.org/mathematics/primes.html“任何两个独立泊松的总和随机变量产生另一个泊松随机变量。”这个问题可能更适合cs或数学网站之一。
标签: java random clojure primes