伪随机数生成的一个问题

GoonYangXiaofang 2010-11-17 12:00:51
程序如下:

#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

unsigned long int next = 1;

void mysrand(unsigned int seed)
{
next = seed;
}

int myrand()
{
cout << "next: " << next << endl;
next = next * 1103515245 + 12345;
unsigned int ret = (unsigned int)(next / 65536) % 32768;
return ret;
}

int main()
{
mysrand((unsigned int)time(0));
for (int i = 0; i < 10; ++i)
{
//mysrand((unsigned int)time(0));
cout << myrand() << endl;
}

return 0;
}

为什么如果将 mysand((unsigned int)time(0)) 放在循环里,每次都到的伪随机数都是一样的
把 mysand((unsigned int)time(0)) 放在循环外,这样只调用 mysrand 一次,循环里每次的 种子 都不一样了
谁能解释一下?
...全文
197 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
GoonYangXiaofang 2010-11-17
  • 打赏
  • 举报
回复
谁能解释一下,为什么 mysand((unsigned int)time(0)) 放在循环外,这样只调用 mysrand 一次,也就是之修改了一次 next

为什么在循环里,next 的值就改变了,怎么改变的?
gules 2010-11-17
  • 打赏
  • 举报
回复
一般随机种子只需要初始化一次。

你的随机种子放在循环中,由于每次循环执行mysrand(unsigned int seed)时得到是同一个数(time调用时间间隔太短,如果是用其它机制生成种子并保证每次不一样,就不会有这样的问题了),相当于把next又拉回到第一次调用时的值,所以后面得到的伪随机数就一样了。
wokonglinglude 2010-11-17
  • 打赏
  • 举报
回复
这个没怎么深究过,理解的不对的话 ,后面的大侠们也指点下我。。。。。。
wokonglinglude 2010-11-17
  • 打赏
  • 举报
回复

rand 需要你给一个种子
for(int i=0;i!=N;++i)
rand();// 输出的是i个伪随机数 具体是个什么数学函数没研究
比方是 1 2 3 2 1 是一个周期的数 伪随机的

for(int i =0;i!=N;++i)
{
seed =1;
rand();// 输出1个 总是那一个 周期里面的第一个
}
無_1024 2010-11-17
  • 打赏
  • 举报
回复
这是因为timer是由计算机时钟记数器精确控制时间间隔的控件,时间间隔相同,记数器前后的值之差相同,这样时钟取值就是呈线性规律的,所以随机种子是呈线性规律的,生成的随机数也是有规律的。而用户按键事件产生随机数确实更呈现随机性,因为事件是由人按键引起的,而人不能保证严格的按键时间间隔,即使严格地去做,也不可能完全精确做到,只要时间间隔相差一微秒,记数器前后的值之差就不相同了,随机种子的变化就失去了线性规律,那么生成的随机数就更没有规律了,所以这样生成的一组随机数更随机。这让我想到了各种晚会的抽奖程序,如果用人来按键产生幸运观众的话,那就会很好的实现随机性原则,结果就会更公正。


http://baike.baidu.com/view/1127.htm


在后面有详细的说明LZ自己看着理解一下啊
無_1024 2010-11-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wokonglinglude 的回复:]
time(null) 是要保证每两次运行时间不同间隔1秒

在循环里面 你的种子就是当前时间,每次相当于初始化一次 seed 间隔没操过1秒,就相当于调用一次rand当然是一样的了。

在外面的时候 种子定了 运行的rand 就不一样了,rand是个线性的分布的 掉了i次rand
[/Quote]
就这样解释了
就是一个生命周期的问题
wokonglinglude 2010-11-17
  • 打赏
  • 举报
回复
time(null) 是要保证每两次运行时间不同间隔1秒

在循环里面 你的种子就是当前时间,每次相当于初始化一次 seed 间隔没操过1秒,就相当于调用一次rand当然是一样的了。

在外面的时候 种子定了 运行的rand 就不一样了,rand是个线性的分布的 掉了i次rand
wokonglinglude 2010-11-17
  • 打赏
  • 举报
回复

//rand产生的原理:y=ax+b(mod n) 线性同余
//具体原理 网上查查
//打个比方吧 从0-RAND_MAX 中间的数 返回 周期长(可以理解成返回队列的数很多)
//但是返回顺序是一定的 相当于几率是一样的
//就是为什么说是伪随机的原因
//当变了seed 返回的数的顺序就变一次
//取了 不同的seed rand()出来的顺序就变了


wokonglinglude 2010-11-17
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 goonyangxiaofang 的回复:]
谁能解释一下,为什么 mysand((unsigned int)time(0)) 放在循环外,这样只调用 mysrand 一次,也就是之修改了一次 next

为什么在循环里,next 的值就改变了,怎么改变的?
[/Quote]

它是一个数学函数问题,有个很长的周期,输出的时候 好像每次都不同似的,但是顺序是一定的。
只是周期特别长,不设置变的seed,每次运行输出都是一样的。
放在里面 每次都从第一个输出,放在外面则不同。
赵4老师 2010-11-17
  • 打赏
  • 举报
回复
纠正:线性同余
赵4老师 2010-11-17
  • 打赏
  • 举报
回复
用线型同余法获取伪随机数的常识之一就是:
设置种子只需在初始化时调用一次而非在每次产生伪随机数时多次调用。
GoonYangXiaofang 2010-11-17
  • 打赏
  • 举报
回复
*************************************************


谁能解释一下,为什么 mysand((unsigned int)time(0)) 放在循环外,这样只调用 mysrand 一次,也就是之修改了一次 next

为什么在循环里,每次 next 的值都不同,怎么改变的?


*************************************************
libinfei8848 2010-11-17
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wokonglinglude 的回复:]
time(null) 是要保证每两次运行时间不同间隔1秒

在循环里面 你的种子就是当前时间,每次相当于初始化一次 seed 间隔没操过1秒,就相当于调用一次rand当然是一样的了。

在外面的时候 种子定了 运行的rand 就不一样了,rand是个线性的分布的 掉了i次rand
[/Quote]

zhengjie

64,662

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧