搜索
首页 电脑/网络 程序设计 VB

有关随机数的问题

VB中我现在用的rnd()这个函数都是假随机有哪位可以告诉我真随机应该怎么获取吗

全部回答

2005-11-10

0 0
    计算机中随机数的产生 大家可能很多次讨论过随机数在计算机中怎样产生的问题,在这篇文章中,我会对这个问题进行更深入的探讨,阐述我对这个问题的理解。 首先需要声明的是,计算机不会产生绝对随机的随机数,计算机只能产生“伪随机数”。
  其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会产生一串绝对随机的随机数。  计算机只能生成相对的随机数,即伪随机数。 伪随机数并不是假随机数,这里的“伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。
  怎样理解呢?产生的伪随机数有时遵守一定的规律,有时不遵守任何规律;伪随机数有一部分遵守一定的规律;另一部分不遵守任何规律。  比如“世上没有两片形状完全相同的树叶”,这正是点到了事物的特性,即随机性,但是每种树的叶子都有近似的形状,这正是事物的共性,即规律性。
  从这个角度讲,你大概就会接受这样的事实了:计算机只能产生伪随机数而不能产生绝对随机的随机数。 那么计算机中随机数是怎样产生的呢?有人可能会说,随机数是由“随机种子”产生的。  没错,随机种子是用来产生随机数的一个数,在计算机中,这样的一个“随机种子”是一个无符号整形数。
  那么随机种子是从哪里获得的呢? 下面看这样一个C程序: //rand01。c #include static unsigned int RAND_SEED; unsigned int random(void) { RAND_SEED=(RAND_SEED*123+59)%65536; return(RAND_SEED); } void random_start(void) { int temp[2]; movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4); RAND_SEED=temp[0]; } main() { unsigned int i,n; random_start(); for(i=0;i #include using namespace std; int main() { unsigned int seed=5; srand(seed); unsigned int r=rand(); cout #include using namespace std; int main() { srand((unsigned)time(NULL)); unsigned int r=rand(); cout #include using namespace std; int main() { int rNum,m=20; char *ch=new char[m]; for ( int i = 0; i<m; i++ ){ //大家看到了,随机种子会随着for循环在程序中设置多次 srand((unsigned)time(NULL)); rNum=1+(int)((rand()/(double)RAND_MAX)*36); //求随机值 switch (rNum){ case 1: ch[i]='a'; break ; case 2: ch[i]='b'; break ; case 3: ch[i]='c'; break ; case 4: ch[i]='d'; break ; case 5: ch[i]='e'; break ; case 6: ch[i]='f'; break ; case 7: ch[i]='g'; break ; case 8: ch[i]='h'; break ; case 9: ch[i]='i'; break ; case 10: ch[i]='j'; break ; case 11: ch[i]='k'; break ; case 12: ch[i]='l'; break ; case 13: ch[i]='m'; break ; case 14: ch[i]='n'; break ; case 15: ch[i]='o'; break ; case 16: ch[i]='p'; break ; case 17: ch[i]='q'; break ; case 18: ch[i]='r'; break ; case 19: ch[i]='s'; break ; case 20: ch[i]='t'; break ; case 21: ch[i]='u'; break ; case 22: ch[i]='v'; break ; case 23: ch[i]='w'; break ; case 24: ch[i]='x'; break ; case 25: ch[i]='y'; break ; case 26: ch[i]='z'; break ; case 27:ch[i]='0'; break; case 28:ch[i]='1'; break; case 29:ch[i]='2'; break; case 30:ch[i]='3'; break; case 31:ch[i]='4'; break; case 32:ch[i]='5'; break; case 33:ch[i]='6'; break; case 34:ch[i]='7'; break; case 35:ch[i]='8'; break; case 36:ch[i]='9'; break; }//end of switch cout<<ch[i]; }//end of for loop cout<<endl; return 0; } 而运行结果显示的随机字符串的每一个字符都是一样的,也就是说生成的字符序列不随机,所以我们需要把srand((unsigned)time(NULL)); 从for循环中移出放在for语句前面,这样可以生成随机的字符序列,而且每次运行生成的字符序列会不同(呵呵,也有可能相同,不过出现这种情况的几率太小了)。
     如果你把srand((unsigned)time(NULL));改成srand(2);这样虽然在一次运行中产生的字符序列是随机的,但是每次运行时产生的随机字符序列串是相同的。
  把srand这一句从程序中去掉也是这样。 此外,你可能会遇到这种情况,在使用timer控件编制程序的时候会发现用相同的时间间隔生成的一组随机数会显得有规律,而由用户按键command事件产生的一组随机数却显得比较随机,为什么?根据我们上面的分析,你可以很快想出答案。
    这是因为timer是由计算机时钟记数器精确控制时间间隔的控件,时间间隔相同,记数器前后的值之差相同,这样时钟取值就是呈线性规律的,所以随机种子是呈线性规律的,生成的随机数也是有规律的。
  而用户按键事件产生随机数确实更呈现随机性,因为事件是由人按键引起的,而人不能保证严格的按键时间间隔,即使严格地去做,也不可能完全精确做到,只要时间间隔相差一微秒,记数器前后的值之差就不相同了,随机种子的变化就失去了线性规律,那么生成的随机数就更没有规律了,所以这样生成的一组随机数更随机。
    这让我想到了各种晚会的抽奖程序,如果用人来按键产生幸运观众的话,那就会很好的实现随机性原则,结果就会更公正。 最后,我总结两个要点: 1。计算机的伪随机数是由随机种子根据一定的计算方法计算出来的数值。
  所以,只要计算方法一定,随机种子一定,那么产生的随机数就是固定的。   2。只要用户或第三方不设置随机种子,那么在默认情况下随机种子来自系统时钟。 。

2005-11-12

105 0
从 1 到 m 的整数中(伪)随机取 n 个整数(容许重复): Private Sub Command1_Click() Dim m As Long, n As Long, i As Long m = 10 n = 5 For i = 1 To n Randomize Print Int(Rnd * m + 1) Next i End Sub

2005-11-11

72 0
对,没有真正的随机,我投“问知识人”一票!!

2005-11-10

89 0
最简单的方法就是在程序开头加入 randomize timer 也就是从时钟取一个随机种子,然后再用rnd(0),可以得到(0,1)之间的随机单精度数字。

2005-11-10

103 0
    二楼正确,不存在真随机数,计算机里面的随机数都是通过某种算法计算出来的,无法实现自然界的真随机。 算法是:首先取一个固定的数作为种子,带入随机数生成器,生成第一个随机数,再用第一个随机数作为种子,生成第二个随机数………………。
  你可以试一下,每次用rand生成的随机数序列是完全一样的。     一楼说的先使用randomize是拿当时的系统时间做随机种子,这样可以保证每次生成的第一个数不一样,这样其实就是从前面说的那个随机数序列里面,从中间的某个由时间决定的随机位置开始作为第一个随机数,往后取得随机数列,可以达到比较随机。
   如果你是在一个循环里面取很多个随机数,每次都用randomize然后再用rnd的话,就可以认为生成的是一个真随机数列了。

2005-11-10

102 0
    Randomize 语句 初始化随机数生成器。 语法 Randomize [number] 可选的 number 参数是 Variant 或任何有效的数值表达式。
   说明 Randomize 用 number 将 Rnd 函数的随机数生成器初始化,该随机数生成器给 number 一个新的种子值。  如果省略 number,则用系统计时器返回的值作为新的种子值。
   如果没有使用 Randomize,则(无参数的)Rnd 函数使用第一次调用 Rnd 函数的种子值。 注意 若想得到重复的随机数序列,在使用具有数值参数的 Randomize 之前直接调用具有负参数值的 Rnd。
    使用具有同样 number 值的 Randomize 是不会得到重复的随机数序列的。 Randomize 语句示例 本示例用 Randomize 语句初始化随机数生成器。
  由于忽略了数值参数, 所以 Randomize 用 Timer 函数的返回值作为新的随机数种子值。   Dim MyValue Randomize ' 对随机数生成器做初始化的动作。
   MyValue = Int((6 * Rnd) + 1) ' 生成 1 到 6 之间的随机数值。 Rnd 函数 返回一个包含随机数值的 Single。   语法 Rnd[(number)] 可选的 number 参数是 Single 或任何有效的数值表达式。
   返回值 如果 number 的值是 Rnd 生成 小于 0 每次都使用 number 作为随机数种子得到的相同结果。 大于 0 序列中的下一个随机数。   等于 0 最近生成的数。
   省略 序列中的下一个随机数。 说明 Rnd 函数返回小于 1 但大于或等于 0 的值。 number 的值决定了 Rnd 生成随机数的方式。 对最初给定的种子都会生成相同的数列,因为每一次调用 Rnd 函数都用数列中的前一个数作为下一个数的种子。
     在调用 Rnd 之前,先使用无参数的 Randomize 语句初始化随机数生成器,该生成器具有根据系统计时器得到的种子。 为了生成某个范围内的随机整数,可使用以下公式: Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 这里,upperbound 是随机数范围的上限,而 lowerbound 则是随机数范围的下限。
     注意 若想得到重复的随机数序列,在使用具有数值参数的 Randomize 之前直接调用具有负参数值的 Rnd。使用具有同样 number 值的 Randomize 是不会得到重复的随机数序列的。
   种子 为初始值,用来生成伪随机数字。例如, Randomize 语句创建一种子值供 Rnd 函数使用,以接着创建唯一伪随机数列。   以上摘自MSDN关于RND函数和Randomize 语句的解释,其中只谈及伪随机数,你所说真随机数未找到出处,供参考。
  

类似问题换一批

热点推荐

热度TOP

相关推荐
加载中...

热点搜索 换一换

电脑/网络
VB
程序设计
电脑装机
操作系统/系统故障
硬件
笔记本电脑
百度
互联网
反病毒
软件
程序设计
VB
数据库
C/C++
JAVA相关
C#/.NET
VC++
汇编语言
其他编程语言
VB
VB
举报
举报原因(必选):
取消确定举报