关于随机数产生的问题

linkquant 2004-08-09 03:45:54
我现在有一个随机数分布均匀的函数
用时间做随机种子 每次运行 多比较有规律
即然是用时间做种子 怎么会出现2次运行相同的数据
而且srand()我每次多只调用了一次阿
可能是原理不明白 那位大虾指点一下 怎么能产生分布均匀的随机数阿
...全文
340 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
MikeChen2003 2004-08-18
  • 打赏
  • 举报
回复
mark
zjz800800 2004-08-10
  • 打赏
  • 举报
回复
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

void main( void )
{
int i;

/* Seed the random-number generator with current time so that
* the numbers will be different every time we run.
*/
srand( (unsigned)time( NULL ) );

/* Display 10 numbers. */
for( i = 0; i < 10;i++ )
printf( " %6d\n", rand() );
}


Output

6929
8026
21987
30734
20587
6699
22034
25051
7988
10104

linkquant 2004-08-10
  • 打赏
  • 举报
回复
重声一下 我srand()在每次运行的时候调用一遍 循环里根本没调用
我现在是想分布均匀 特别是在小的范围内比如取1--10之间的值得时候
我每过一段时间调用rand结果总是不尽人

楼上 kvw3000(回家念经) 说的挺好 能不能参考你的程序
或者把大素数数组 发给我一下
谢谢 我qq是 44077023
msn : turboyu@hotmail.com 或留下你的邮件
lwglucky 2004-08-10
  • 打赏
  • 举报
回复
class RndGen
{
int n;
float *oldrand;
void advance_random();

public:
RndGen() { oldrand = 0; }
~RndGen();
float randm();
void init_random(const float randomseed = 0.1f);
};

RndGen::~RndGen()
{
if (oldrand)
free(oldrand);
}

void RndGen::init_random(const float randomseed)
{
float new_random = 1.0e-9f;
float prev_random = randomseed;

oldrand = (float*)calloc(55, sizeof(float));
oldrand[54] = randomseed;

for (int i = 0; i < 53; i ++)
{
int j = (21 * (i + 1)) % 55;
oldrand[j] = new_random;
new_random = prev_random - new_random;
if (new_random < 0) new_random ++;
prev_random = oldrand[j];
}

advance_random();
advance_random();
advance_random();
n = 0;
}

void RndGen::advance_random()
{
float new_random;
for (int i = 0; i <= 23; i ++)
{
new_random = oldrand[i] - oldrand[i+31];
if (new_random < 0)
new_random ++;
oldrand[i] = new_random;
}

for (i = 24; i <= 54; i ++)
{
new_random = oldrand[i] - oldrand[i-24];
if (new_random < 0)
new_random ++;
oldrand[i] = new_random;
}
}

float RndGen::randm()
{
n ++;
if (n > 54)
{
n = 1;
advance_random();
}

return oldrand[n];
}
Mutalisk 2004-08-09
  • 打赏
  • 举报
回复
srand()
在你的进程里应该只运行一次,如果每次rand前都srand,出来的数肯定都是一样的
turnmissile 2004-08-09
  • 打赏
  • 举报
回复
既然是随机数,自然有重复的时候,只是这种可能会根据数的定义方式而不同。

你如果希望保证不同,可以用一个64为数,前面32为随机数,后面32位为时间,这样就一定能够保证不相同了。
zhangyilan 2004-08-09
  • 打赏
  • 举报
回复
可以看看统计计算这类的书,上面有专门的算法讲解满足各种分布的随机数。
ringphone 2004-08-09
  • 打赏
  • 举报
回复
我觉得取时间的毫秒数,应该是比较随机的了。
kvw3000 2004-08-09
  • 打赏
  • 举报
回复

我觉得是 整数随机数=(种子值(时间随机种子)*大素数数组某项*随机数发生器值)mod随机数取值范围)
一般这个随机数作为下次的种子值,

种子值(时间随机种子)其实是一个全局系统变量,没有设置时是一个固定的值,这样是为了保证可以产生相同的随机数序列来方便一些测试(C语言就是这样实现的),在正式情况下才通过专门的函数来启动(设置为时间关系随机值,一般取当时的计算机时钟值),大素数数组就是一个含有比较大的素数的数组,一般含有几十个,这样的目的是第一个随机数取数组的第一个值进行计算,后面的值就和前面结果或者种子值有关系了,比如是种子值取数组长度的模来确定某项(也可以第一个就这样),随机数发生器可以是一个步进(步长为素数而且可以设定)循环计数器,这样仅仅是增加随机性。
上面仅仅是我个人的实现,我这样实现过一个简单的伪随机数发生器,不过我不敢说这是好的方法,用计算机产生随机数还有许多方法,其实比较好的方法就是真正的找到一个随机源,现在有的系统上就实现了这样的源,比如检测电源的波动来实现一个随机源(电源是模拟量,就是计算机里的稳压电源的电压其实在一定范围内也是不停波动的,在足够好的数模转换中就可以转换为一个随机数发生器了(种子发生器)
vericky 2004-08-09
  • 打赏
  • 举报
回复
对,我一般以秒为单位,对随机数产生速度要求不高的情况下可用!
lixiaosan 2004-08-09
  • 打赏
  • 举报
回复
http://www.china-askpro.com/msg22/qa36.shtml
快乐鹦鹉 2004-08-09
  • 打赏
  • 举报
回复
用时间做种子数,那也要看你要到时间的哪一个精度啊。如果只有分钟的话,那么在一分钟内执行两次srand的话,结果还是一样的。必须保证srand每次的参数都是不同的才能达到随机的目的。
DentistryDoctor 2004-08-09
  • 打赏
  • 举报
回复
楼上说得有理。
bohut 2004-08-09
  • 打赏
  • 举报
回复
Q 李刚:
问题: 怎样获得一个真正的随机数?要知道,rand()是不能产生真正的随机数的!即使不能产生真正的随机数,也要大概接近呀!而rand()好象每次的随机都一样。

A回答:

之所以rand()每次的随机数都一样是因为rand()函数使用不正确。各种编程语言返回的随机数(确切地说是伪随机数)实际上都是根据递推公式计算的一组数值,当序列足够长,这组数值近似满足均匀分布。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。这个特性被有的软件利用于加密和解密。加密时,可以用某个种子数生成一个伪随机序列并对数据进行处理;解密时,再利用种子数生成一个伪随机序列并对加密数据进行还原。这样,对于不知道种子数的人要想解密就需要多费些事了。当然,这种完全相同的序列对于你来说是非常糟糕的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。你可以在调用rand()函数之前调用srand( (unsigned)time( NULL ) ),这样以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。你也可以使用srand函数来人为指定种子数。Windows 9x/NT的游戏FreeCell就允许用户指定种子数,这样用户如果一次游戏没有成功,下次还可以以同样的发牌结果再玩一次。


陈翔宇: 我按照上述方法并不能产生随机数,仅产生公差为3或4的等差数列:
#include <stdlib.h>
#include <iostream.h>
#include <conio.h>
#include <time.h>
void main()
{
for(int i=0;i<100000;i++)
{
srand( (unsigned)time( NULL ) );
cout<<rand()<<endl;
}
}
答:你的程序是有问题的,你每产生一个随机数之前,都调用一次srand,而由于计算机运行很快,所以你每次用time得到的时间都是一样的(time的时间精度较低,只有55ms)。这样相当于使用同一个种子产生随机序列,所以产生的随机数总是相同的。你应该把srand放在循环外:
srand( (unsigned)time( NULL ) );
for(int i=0;i<100000;i++)
{
cout<<rand()<<endl;
}

bohut 2004-08-09
  • 打赏
  • 举报
回复
http://www3.ccw.com.cn/club/essence/200108/4039.htm

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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