简体   繁体   English

使用 c++11 std::uniform_int_distribution 生成随机素数

[英]Generate a random prime using c++11 std::uniform_int_distribution

Trying to generate a random prime p in the range [2,2147483647] using the C++11 std::uniform_int_distribution .尝试使用 C++11 std::uniform_int_distribution在 [2,2147483647] 范围内生成随机素数p

It's been commented that this approach might not be correct:有人评论说这种方法可能不正确:

It is not immediately obvious that this p is uniformly distributed over the set of all primes <= 2^31 - 1. Whatever uniformity and bias guarantees the random-number generator has, they refer to all integers within the range, but the code is "sieving" just the primes out of it.这个p是否均匀分布在所有素数 <= 2^31 - 1 的集合上并不是很明显。无论随机数生成器具有什么均匀性和偏差保证,它们都指范围内的所有整数,但代码是“筛选”只是其中的素数。

However, from another similar SO article, it notes但是,从另一篇类似的SO文章中,它指出

As long as the input random numbers are uniformly distributed in the range, the primes chosen by this method will be uniformly distributed among the primes in that range, too.只要输入的随机数均匀分布在该范围内,通过这种方法选择的素数也将均匀分布在该范围内的素数中。

Question问题

Is this code truly correct to generate a random prime?这段代码真的正确生成随机素数吗?

https://onlinegdb.com/FMzz78LBq https://onlinegdb.com/FMzz78LBq

#include <stdio.h>
#include <stdint.h>
#include <math.h>
#include <time.h>
#include <random>


int isPrimeNumber (int num)
{
  if (num == 1) return 0;

  for (int i = 2; i <= sqrt (num); i++)
  {
      if (num % i == 0)
      {
        // not prime
        return 0;
      }
  }

  // prime
  return 1;
}

int main ()
{
  std::random_device rd;
  std::mt19937 rng (rd ());
  // Define prime range from 2 to 2^31 - 1.
  std::uniform_int_distribution<int>uni (2, 2147483647);

  int prime;

  // Generate a random prime.
  do { prime = uni(rng); } while (!isPrimeNumber(prime));

  printf ("prime = %d", prime);

  return 0;
}

The code you presented:您提供的代码:

  1. Uniformly picks a random prime number in the range.在范围内统一选择一个随机素数。 Any given prime number in the range will have the same probability of coming up as any other prime in the range.该范围内的任何给定素数都将具有与该范围内的任何其他素数相同的概率。
  2. will not produce numbers that are uniformly distributed around the range of integers.不会产生整数范围内均匀分布的数字。 Eg there will be much more numbers in the range 1-1000 than there will be in the range 1000001-1001000.例如,1-1000 范围内的数字将比 1000001-1001000 范围内的数字多得多。
  3. is extremely inefficient (if you were to generate many numbers)效率极低(如果您要生成很多数字)

You should get clarity on exactly what you want.你应该清楚你想要什么。 If you wanted 2. above you need something different.如果你想要上面的 2. 你需要一些不同的东西。

A sketch for a proof:证明草图:

Assume for the purpose of contradiction that the algorithm produces a non-uniform distribution over the primes.出于矛盾的目的,假设该算法在素数上产生非均匀分布。 Then there must be a prime p that has a higher probability than a prime q.那么一定有一个素数 p 比素数 q 具有更高的概率。 As these are also integers, that means that in the larger range from 2 to N, sieving out non-primes had no effect on either p or q, hence the uniform distribution had to produce p with a higher probability than q, which is a direct contradiction.由于这些也是整数,这意味着在从 2 到 N 的较大范围内,筛选出非素数对 p 或 q 都没有影响,因此均匀分布产生 p 的概率必须高于 q,即直接矛盾。

Note: Observe that this proof would not hold if you compute a random number and search for the next prime after that number.注意:请注意,如果您计算一个随机数并搜索该数之后的下一个素数,则该证明将不成立。

However, as pointed out by Jeffrey, this algorithm is rather inefficient.然而,正如 Jeffrey 所指出的,这种算法效率相当低。 One alternative comes to mind: In the range up to 2**31 you have about 10**8 primes , according to the pi function.想到一个替代方案:根据pi function,在 2**31 范围内,您有大约10**8 个素数 So it is close to feasible to just create a lookup table with all those primes and store it, if not in your binary, in a separate file (I expect about 400 MB), and just compute a uniform random number in the appropriate interval and pick that number out of the lookup table.因此,只需创建一个包含所有这些素数的查找表并将其存储在一个单独的文件(我预计大约 400 MB)中(我预计大约 400 MB)中,并在适当的时间间隔内计算一个统一的随机数和从查找表中选择该数字。


However, just to be safe, be aware that for any purpose close to security, std::mt19937 is not a cryptographically secure PRNG.但是,为了安全起见,请注意,对于任何接近安全的目的, std::mt19937都不是加密安全的 PRNG。

暂无
暂无

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

相关问题 c ++ 11随机数生成:如何使用`mt19937`重新实现`uniform_int_distribution`而不使用模板 - c++11 random number generation: how to re-implement `uniform_int_distribution` with `mt19937` without templates std::uniform_int_distribution 不够随机 - std::uniform_int_distribution isn't random enough 为什么是 <random> 每次使用std :: uniform_int_distribution时,库都会产生相同的结果 - Why is <random> library producing the same results every time when using std::uniform_int_distribution std::uniform_int_distribution 的分段错误 - Segmentation fault with std::uniform_int_distribution 使用 Rcpp 从 std::uniform_int_distribution 采样时出现“来自 C 堆栈溢出的段错误” - Getting "segfault from C stack overflow" when using Rcpp to sample from std::uniform_int_distribution c ++ 11使用uniform_real_distribution随机双打 - c++11 random doubles using uniform_real_distribution C ++ 11 std :: generate和std :: uniform_real_distribution调用两次给出奇怪的结果 - C++11 std::generate and std::uniform_real_distribution called two times gives strange results C ++数值库:std :: uniform_int_distribution &lt;&gt;,更改两次调用之间的分配范围 - C++ numerics lib: std::uniform_int_distribution<>, change bounds of distribution between calls 的std :: uniform_int_distribution <int> g ++和msvc的范围 - std::uniform_int_distribution<int> range in g++ and msvc 为什么不是`std::uniform_int_distribution<uint8_t> ` 和 `std::uniform_int_distribution<int8_t> ` 允许吗? - Why Aren't `std::uniform_int_distribution<uint8_t>` and `std::uniform_int_distribution<int8_t>` Allowed?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM