是否可以查看下一个兰特值
Is it possible to peek at the next rand value
假设生成器已播种,是否可以在不更改的情况下查看下一个随机值?
即给定:
#include <stdlib.h>
int r;
r = rand(); // say this is 99
r = rand(); // say this is 80
这可能吗
#include <stdlib.h>
int r;
r = peekAtRand(); // this will give 99
r = rand(); // but this still gives 99
r = peekAtRand(); // this will give 80
r = rand(); // but this still gives 80
此外,这是否可以扩展为偷看接下来的 n 个数字?
大多数随机数生成器的当前实现是不可能的。但是有两种解决方法。
解决方案 1
如果您使用srand()
函数将随机数生成器的起始值设置为相同的值,您将始终得到相同的数字序列。这样你就可以很容易地预测第二遍的数字。
解决方案 2
简单地为数字写一个小缓冲区。
const int randBufferSize = 1024;
int randBuffer[randBufferSize];
int randBufferPosition = 0;
// Initialise the buffer with random data.
void initRandBuffer() {
for (int i = 0; i < randBufferSize; ++i) {
randBuffer[i] = rand();
}
}
// Peek at the n'th random number (starting from 0).
int peekAtRand(int n) {
int peekIndex = randBufferPosition + n;
if (peekIndex >= randBufferSize) {
peekIndex -= randBufferSize;
}
return randBuffer[peekIndex];
}
// Get the next random number.
int getRand() {
int result = randBuffer[randBufferPosition];
randBuffer[randBufferPosition] = rand();
++randBufferPosition;
if (randBufferPosition >= randBufferPosition) {
randBufferPosition = 0;
}
}
int peek;
int r;
peek = rand();
doPeekyThings(peek);
r = peek;
您可以按如下方式实施peekAtRand
:
int peekAtRand()
{
int r,s;
s = rand();
srand(s);
r = rand();
srand(s);
return r;
}
要使其成为 "worthy",请在程序开头调用 srand((unsigned int)time(NULL))
。
Assuming the generator has been seeded, it is possible to peek at the next random value without changing it?
不单独使用 rand()
。你需要缓冲它。
Furthermore, can this be extended to peeking at the next n numbers?
如果你缓冲它,那么是的:
const int bufsize = 15;
int randarr[bufsize];
int cur_rand = 0;
int my_srand(int seed) {
srand(seed);
for (int i=0;i<bufsize;++i) {
randarr[i] = rand();
}
}
int my_rand() {
int r = randarr[cur_rand];
randarr[cur_rand] = rand();
++cur_rand;
if (cur_rand >= bufsize) cur_rand = 0;
return r;
}
int peek_my_rand(int n = 0) {
return randarr[(cur_rand + n)%bufsize];
}
使用此实现,您始终可以查看 bufsize
个数字,并且查看永远不会干扰实际的生成器,这意味着它永远不会改变其内部状态。
假设生成器已播种,是否可以在不更改的情况下查看下一个随机值?
即给定:
#include <stdlib.h>
int r;
r = rand(); // say this is 99
r = rand(); // say this is 80
这可能吗
#include <stdlib.h>
int r;
r = peekAtRand(); // this will give 99
r = rand(); // but this still gives 99
r = peekAtRand(); // this will give 80
r = rand(); // but this still gives 80
此外,这是否可以扩展为偷看接下来的 n 个数字?
大多数随机数生成器的当前实现是不可能的。但是有两种解决方法。
解决方案 1
如果您使用srand()
函数将随机数生成器的起始值设置为相同的值,您将始终得到相同的数字序列。这样你就可以很容易地预测第二遍的数字。
解决方案 2
简单地为数字写一个小缓冲区。
const int randBufferSize = 1024;
int randBuffer[randBufferSize];
int randBufferPosition = 0;
// Initialise the buffer with random data.
void initRandBuffer() {
for (int i = 0; i < randBufferSize; ++i) {
randBuffer[i] = rand();
}
}
// Peek at the n'th random number (starting from 0).
int peekAtRand(int n) {
int peekIndex = randBufferPosition + n;
if (peekIndex >= randBufferSize) {
peekIndex -= randBufferSize;
}
return randBuffer[peekIndex];
}
// Get the next random number.
int getRand() {
int result = randBuffer[randBufferPosition];
randBuffer[randBufferPosition] = rand();
++randBufferPosition;
if (randBufferPosition >= randBufferPosition) {
randBufferPosition = 0;
}
}
int peek;
int r;
peek = rand();
doPeekyThings(peek);
r = peek;
您可以按如下方式实施peekAtRand
:
int peekAtRand()
{
int r,s;
s = rand();
srand(s);
r = rand();
srand(s);
return r;
}
要使其成为 "worthy",请在程序开头调用 srand((unsigned int)time(NULL))
。
Assuming the generator has been seeded, it is possible to peek at the next random value without changing it?
不单独使用 rand()
。你需要缓冲它。
Furthermore, can this be extended to peeking at the next n numbers?
如果你缓冲它,那么是的:
const int bufsize = 15;
int randarr[bufsize];
int cur_rand = 0;
int my_srand(int seed) {
srand(seed);
for (int i=0;i<bufsize;++i) {
randarr[i] = rand();
}
}
int my_rand() {
int r = randarr[cur_rand];
randarr[cur_rand] = rand();
++cur_rand;
if (cur_rand >= bufsize) cur_rand = 0;
return r;
}
int peek_my_rand(int n = 0) {
return randarr[(cur_rand + n)%bufsize];
}
使用此实现,您始终可以查看 bufsize
个数字,并且查看永远不会干扰实际的生成器,这意味着它永远不会改变其内部状态。