NS中一种新的随机数提取

时间:2022-04-24 01:55:42

摘要:随机数在软件开发和程序设计中应用较为广泛,该文从分析随机数的一般原理入手,指出它们的缺陷,然后从NS(network simulator)中提取一种新的产生随机数的方法,并验证它的可行性。

关键词:伪随机数;随机数;种子

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2009)05-1138-03

A New Approach to Generate Random Numbers Extracted from the NS(Network Simulator)

DUAN Min1,QIAN Guang-ming2,XIAO Min3

(College of Mathematics and Computer Science of Hunan Normal University, Changsha 410081, China)

Abstract: Random number is widely used in the software development andprogramming. This article analyses the general principles of the random numbers ,points out their shortcomings and puts forward a new approach to generate random numbers extracted from the NS(network simulator).Then we verifyits feasibility.

Key words: Pseudo-random number; Random Numbers; Seed

1 引言

在用计算机编制程序时,经常需要用到随机数,我们也知道随机数在实际运用中非常之多,如游戏设计,信号处理,网络仿真领域。特别在网络仿真等领域,对随机数的产生提出了较高的要求,仅使用C++语言类库中的随机函数可能会很难完成相应的工作。本文简单的介绍我们从NS中所提取的这种随机数的原理,并对其进行了测试,希望以后可以应用到我们需要的领域中去。

2 随机数

2.1 伪随机数

随机数是计算机随机产生的一个任意数字,但是计算机不会产生一个绝对随机的随机数,我们希望计算机产生一个绝对的随机数,这是一种理想的随机数,然而计算机产生的只能是相对的随机数,即伪随机数。

伪随机数并不是假随机数,这里的“伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。怎样理解呢?产生的伪随机数有时遵守一定的规律,有时不遵守任何规律;伪随机数有一部分遵守一定的规律;另一部分不遵守任何规律。比如“世上没有两片形状完全相同的树叶”,这正是点到了事物的特性,即随机性,但是每种树的叶子都有近似的形状,这正是事物的共性,即规律性。从这个角度讲,计算机只能产生伪随机数而不能产生绝对随机的随机数。

2.2 种子(seed)

种子(seed)是用来产生随机数的一个初始值,可以是我们自己给定的,也可以通过一定的运算而得到的,也可能是通过获取当前系统的时间而得到的。获取种子的值不同,那么其后面产生的一系列化的随机数也不同,如果每次给定的种子是一样的,那很有可能其后产生的一系列化的随机数是相同的。所以我们要产生随机数时,要避免给一个固定的初始值,种子通常是一个无符号的整形数。

3 VC++中随机数的实现

在VC的环境下,我们可以用库函数random()来产生一个随机数,它返回的是C32768 到32767中的任意一个数。在VC6.0环境下是这样定义的:random(数字)。数字是我们自己给予赋值的,注意的是random(1)产生的是数字0,而不是1,因为random()产生的是由0到数字减一的效果。例如random(10)产生的实际上是0~9的数字。

在VC中还可能用另外一个随机函数rand()来产生随机数,包含在头文件中,它没有参数,返回是0到最大数之间的一个整数,也就是说该随机数是在0~RAND_MAX之间平均分布的, RAND_MAX是一个常量,在VC6.0环境下是这样定义的:

#define RAND_MAX 0x7fff(32767)

它是一个short 型数据的最大值,如果要产生一个浮点型的随机数,可以将rand()/1000.0这样就得到一个0~32.767之间平均分布的随机浮点数,我们也可以自己去定义这个最大数。

我们写一个小程序,来产生一个随机数。

#include

#include

int main()

{int k;

k = rand();

printf("%d\n", k);

return 0;

}

这个程序是产生了随机数,但是我们同时也发现它产生的随机数是不变的。我们就需要讲到VC中另一个函数srand()函数进行随机化, srand()函数也包含在头文件中, 这个函数能给随机数产生一个随机种子,种子不同,产生的随机数也就不同。我们先包含“time.h”头文件,然后使用srand(time())来使用当前时间使随机数随机化,这样就可以保证每两次运行时可以得到不同的随机序列。函数原型是srand((unsigned)time(NULL)),time的值每时每刻都不同。种子不同,所以产生的随机数也不同。所以说,要想产生不同的随机数,在使用rand之前需要先调用srand()。

#include #include

#include

void main(void)

{ int i;

srand( (unsigned)time( NULL ) );

for( i = 0; i

printf("%6d\n", rand());

}

这样所产生的数便是随机数,因为它所得到的种子(seed) 是根据系统时间所获取的,因为系统的时间是在不断变化的,所以种子(seed)也变化,那么rand()所产生的这样产生的随机数也就不一样了。

4 NS中随机数程序抽取

在网络仿真中,对随机数的要求特别的高,要产生一系列的随机数,仅仅利用VC中为我们提供的库函数还是不行的,这样得到的随机数的范围小,精度不够高,达不到我们的目的。现在我们就来介绍NS 中抽取的一种经典的随机数算法。

在程序中我们定义了三种类型的种子,一种是RAW_SEED_SOURCE的种子,当我们接受到这种类型的种子时,不做任何操作,第二种是PREDEF_SEED_SOURCE的种子,我们通过先前定义的数组predef_seeds[N_SEEDS_]对种子(seed)进行一个初始的赋值,这个值根据seed传来的参数不同,所得的初始种子的值也会不同,但是这样以后产生的种子是可以预见的,也就是说这样产生的一系列化的数不带有随机性。当我们接受的种子类型是HEURISTIC_SEED_SOURCE(启发式种子类型)时,我们调用了函数gettimeofday(struct timeval *p, struct timezone *z)获取系统的目前时间,它返回数组的元素包括秒(sec)和百万分之一秒/微秒(usec),然后通过一个运算操作,获得种子(seed)的初值。然后由这个初始化的种子(seed)值去产生一系列化的随机数。由于时间都在不断的变化,所以种子(seed)也就在相应产生着变化,以至于以后每次产生的数都不同的。其中gettimeofday(struct timeval *p, struct timezone *z)的函数定义为:

Inline int gettimeofday(struct timeval *p,struct timezone *z) //获取时间的函数

{ struct timeb tb; //定义一个时间结构体,用来传递时间

ftime(&tb); //时间函数

p->tv_sec = tb.time; //把当前所得到的时间传给结构体p,单位是秒

p->tv_usec = tb.millitm;//

return 0;

}

gettimeofday()会把目前的时间用p所指的结构返回,当地时区的信息则放到z所指的结构中。

timeval结构定义为:

struct timeval{

long tv_sec; /*秒*/

long tv_usec; /*微秒*/

};

timezone 结构定义为:

struct timezone{

int tz_minuteswest;

int tz_dsttime; };

我们就是利用这个函数来获是时间,并用它来对种子赋初值,并且在后面调用了next()函数来产生下一组随机数。每次产生的随机数都是和第一次的种子相关的,我们把它产生的随机数与由PREDEF_SEED_SOURCE类型所产生的随机数相比。每运行一次,PREDEF_SEED_SOURCE类型所产生的随机数是相同的,而由HEURISTIC_SEED_SOURCE(启发式种子类型)类型的种子产生的随机数却在不断变化。

5 随机数的测试

虽然我们已经提取了随机数,但是还需要进一步的验证和测试,函数RngTest()就是为了验证所产生的数是否是真正的随机数。首先它实例化了一个对象RNG rng(RNG::RAW_SEED_SOURCE, 1L),对seed(种子)进行了一次初始化,然后通过一系列的调用来确定以后产生的种子符合哪一种类型的种子。因为如果是HEURISTIC_SEED_SOURCE(启发式种子类型),其后的调用过程和测试时调用的过程是一致的,并且通过后面数值的比较,我们发现所得到的随机数的是属于哪一种类型的。其调用过程如图1所示。

通过这种测试和验证,我们从NS中提取的这种随机数方法具有可行性,它产生的随机数是真正的随机数,并且精度高。

6 结束语

随机数应用十分广泛,随机现象也随处可见,伪随机数作为系统仿真中首要问题之一,对它的研究来提高系统工程仿真有着重要的意义。本文提供的这种随机数,具有一定的实用价值,其具体应用可以根据实际的情况要求进行选择。

参考文献:

[1] 徐雷鸣,庞博,赵耀. NS与网络模拟[M]. 北京:人民邮电出版社,2003.

[2] 西蒙. Visual C++ 6编程宝典[M]. 北京: 电子工业出版社,2005.

[3] 梁田贵,张鹏. 算法分析与设计[M]. 冶金工业出版社,2004.

[4] /nsnam/ns-2.

上一篇:基于SOA的数据集成研究 下一篇:基于相似度综合计算的本体映射方法的研究