如何创建一个函数,在每个调用中生成一个随机整数?这个数字必须尽可能最随机(根据uniform distribution)。它只允许使用一个静态变量和最多3个基本步骤,其中每个步骤只包含arity 1或2的一个基本算术运算。
示例:
int myrandom(void){
static int x;
x = some_step1;
x = some_step2;
x = some_step3;
return x;
}
基本算术运算是+, - ,%,而不是xor,或左移,右移,乘法和除法。当然,不允许使用rand(),random()或类似的东西。
答案 0 :(得分:45)
Linear congruential generators是最古老,最简单的方法之一:
int seed = 123456789;
int rand()
{
seed = (a * seed + c) % m;
return seed;
}
只有少数基本算术运算指令,这就是你所需要的。
请注意,只有在以特定方式选择 a , c 和 m 时,此算法才能正常工作!
为了保证此序列的最长可能时间段, c 和 m 应该是互质的, a -1应该可以被所有素数整除 m 的因子,以及4如果 m 可以被4整除。
维基百科上显示了一些examples of parameters:例如某些编译器的ANSI C建议 m =2³¹, a = 1103515245和 c < / EM> = 12345。
答案 1 :(得分:9)
public long randomLong() {
x ^= (x << 21);
x ^= (x >>> 35);
x ^= (x << 4);
return x;
}
种子不能为0.来源:http://www.javamex.com/tutorials/random_numbers/xorshift.shtml#.VlcaYzKwEV8
wiki中的其他信息:https://en.wikipedia.org/wiki/Xorshift
答案 2 :(得分:3)
答案 3 :(得分:0)
Boost有一个非常好的随机数字库,并且源代码可用,因此您可以尝试查看并使用您需要的内容(即剪切和粘贴)。
答案 4 :(得分:0)
如果我写man rand
,我可以阅读一个可能的例子,在POSIX.1-2001中给出,用于实现rand()和srand()。参见例如here。如果您需要更复杂的东西,请查看GNU Scientific Library;你当然可以下载代码并查看实现。
答案 5 :(得分:0)
我想这对于大范围来说已经足够了,但我还没有使用过。两个数必须互质。
u32 rand()
{
static u32 seed = 3459173429;
seed = 910230123 + seed ;
return seed;
}
工作示例
int printf(char* , ...);
typedef unsigned int u32;
typedef signed int i32;
u32 rand()
{
static u32 seed = 3459173429;
seed = 910230123 + seed ;
return seed;
}
i32 randInt(i32 a, i32 b)
{
return (rand() % (b - a)) + a;
}
void main()
{
for(int i = 0 ; i < 10000 ; i += 1)
{
printf("%d\n", randInt(-50, 50));
}
}
答案 6 :(得分:-3)
我用这个
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
可以实现随机性的大增益,而无需花费更多的计算时间为程序中的随机数生成器创建随机数生成器。
这是一个非常好的技巧!
答案 7 :(得分:-5)
这是一个在整个int范围内均匀分布的函数:
int rand()
{
static int random = 0;
return random++;
}