C++ 特殊的简单随机数发生器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3062746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:56:48  来源:igfitidea点击:

Special simple random number generator

c++calgorithmmath

提问by psihodelia

How to create a function, which on every call generates a random integer number? This number must be most random as possible (according to uniform distribution). It is only allowed to use one static variable and at most 3 elementary steps, where each step consists of only one basic arithmetic operation of arity1 or 2.

如何创建一个函数,每次调用都会生成一个随机整数?这个数字必须尽可能随机(根据均匀分布)。只允许使用一个静态变量和最多 3 个基本步骤,其中每个步骤仅包含一个1 或 2元的基本算术运算。

Example:

例子:

int myrandom(void){
  static int x;
  x = some_step1;
  x = some_step2;
  x = some_step3;
  return x;
}

Basic arithmetic operations are +,-,%,and, not, xor, or, left shift, right shift, multiplication and division. Of course, no rand(), random() or similar stuff is allowed.

基本算术运算有+、-、%、and、not、xor、or、左移、右移、乘法和除法。当然,不允许使用 rand()、random() 或类似的东西。

回答by Hyman

Linear congruential generatorsare one of the oldest and simplest methods:

线性同余生成器是最古老和最简单的方法之一:

int seed = 123456789;

int rand()
{
  seed = (a * seed + c) % m;
  return seed;
}

Only a few instruction with basic arithmetic operations, that's all you need.

只有一些基本算术运算的指令,这就是你所需要的。

Mind that this algorithm works fine only if a, cand mare chosen in a particular way!

请注意,只有在以特定方式选择acm 时,此算法才能正常工作!

To guarantee the longest possible period of this sequence, cand mshould be coprime, a???1 should be divisible by all prime factors of m, and also for 4 if mis divisible by 4.

为了保证这个序列的最长可能周期,cm应该是互质的,a???1 应该可以被m的所有质因子整除,如果m可以被 4 整除,那么对于 4 也是如此。

Some examples of parametersare shown on Wikipedia: for example ANSI C for some compilers proposes m?=?2?31, a?=?1103515245 and c?=?12345.

维基百科上显示了一些参数示例:例如,某些编译器的 ANSI C 建议m?=?2?31、a?=?1103515245 和c?=?12345。

回答by misioptysio

public long randomLong() {
  x ^= (x << 21);
  x ^= (x >>> 35);
  x ^= (x << 4);
  return x;
}

Seed cannot be 0. Source: http://www.javamex.com/tutorials/random_numbers/xorshift.shtml#.VlcaYzKwEV8

种子不能为 0。来源:http: //www.javamex.com/tutorials/random_numbers/xorshift.shtml#.VlcaYzKwEV8

Additional info in wiki: https://en.wikipedia.org/wiki/Xorshift

维基中的其他信息:https: //en.wikipedia.org/wiki/Xorshift

回答by phimuemue

You might have a look at this. It's far from beeing a "perfect" random number generator, but it does fulfil your requirements as far as i can see.

你可以看看这个。它远非“完美”的随机数生成器,但据我所知,它确实满足了您的要求。

Hereyou can find some additional information about random number generation.

在这里您可以找到一些关于随机数生成的附加信息。

回答by andand

Boost has a very nice random number library, and the source code is available, so you could try looking there and using what you need (i.e. cut and paste).

Boost 有一个非常好的随机数库,并且源代码可用,因此您可以尝试查看那里并使用您需要的内容(即剪切和粘贴)。

回答by ShinTakezou

If I write man rand, I can read a possible example, given in POSIX.1-2001, for implementing rand() and srand(). See e.g. here. If you need something more sophisticated, take a look at GNU Scientific Library; you can of course download the code and see the implementation(s).

如果我写man rand,我可以阅读 POSIX.1-2001 中给出的一个可能的例子,用于实现 rand() 和 srand()。参见这里。如果您需要更复杂的东西,请查看GNU Scientific Library;您当然可以下载代码并查看实现。

回答by Ghost Rider

I use this

我用这个

SUBROUTINE GNA(iiseed)
    USE Variaveis
    parameter (ia=843314861,ib=453816693,m=1073741824, r231=1./2147483648.)
    INTEGER :: iiseed

    iiseed = ib + ia*iiseed
    if (iiseed.lt.0) iiseed = (iiseed+m) + m
    RndNum = iiseed*r231

END SUBROUTINE GNA

A big gain of randomness can be achieved without spending more computational time creating a random number generator for each call the random number generator made in the program.

无需花费更多的计算时间为程序中的随机数生成器的每次调用创建一个随机数生成器,即可获得很大的随机性。

This is a very good trick!

这是一个非常好的技巧!

回答by Bill

Here's a function with uniform distribution over the entire range of int:

这是一个在整个 int 范围内均匀分布的函数:

int rand()
{
  static int random = 0;
  return random++;
}