SAS产生随机数的方法随机数函数
和CALL 子程序
原文地址:SAS产生随机数的方法:随机数函数和CALL子程序作者:supersasmacro运用SAS进行MonteCarlo蒙特卡罗模拟(第四弹):
SAS产生随机数的方法:随机数函数和CALL子程序
本文未经作者同意严禁转载
1随机数函数产生随机数序列
随机数函数产生随机数序列的语法:var=name(seed,arg),我们在前面的文章里使用的都是此类方法,变量var记录了由随机数种子为seed的随机函数name产生的一个随机数。我们举两个例子来深入说明随机数函数产生随机数序列的原理。
程序1:
DATATEMP1(DROP=I);
DOI=1TO10;
RUNI=RANUNI(123);
SEED=RUNI*(2*31-1);
OUTPUT;
END;
RUN;
PROCPRINTDATA=TEMP1;
RUN;
程序2:
DATATEMP2(DROP=I);
DOI=1TO5;
RUNI1=RANUNI(123);
RUNI2=RANUNI(456);*这里我们虽然指定了另一个随机数种子的值,但其实并不起作用;
OUTPUT;
END;
RUN;
PROCPRINTDATA=TEMP2;
RUN;
程序1的结果:
程序2的结果:
将程序1的结果和程序2的结果进行比较,程序2中的RUNI1是程序1中的RUNI的第1,3,5,7,9条数据,而程序2中的RUNI2是程序1中的RUNI的第2,4,6,8,10条数据。我们可以看到,虽然RUNI2=RANUNI(456);,但是这条语句中的随机数种子456并没有起作用。
RANUNI等随机函数的值产生后,SAS系统会隐含地将其转化为(0,1)的区间内,如果要看到这些随机数序列原始的值,可以通过程序1中的
SEED=RUNI*(2*31-1);语句,结果如程序1输出结果中的seed所示。
2CALL子程序产生随机数序列
CALL子程序产生随机数序列的语法如下:callname(seed,arg,var),与随机数函数产生随机数序列的语法类似。由上面的例子我们知道,随机数函数产生随机数序列时,其序列的值只由第一个随机数种子的值决定,而用CALL子程序时,每一次调用随机函数,都会重新产生新的随机数种子,下面举例进行讲解:
DATATEMP3(DROP=I);
RETAINSEED1123SEED2123SEED3123SEED4456;
DOI=1TO10;
RUNI1=RANUNI(SEED1);
CALLRANUNI(SEED2,RUNI2);
CALLRANUNI(SEED3,RUNI3);
CALLRANUNI(SEED4,RUNI4);
IFI=5THENDO;SEED1=456;*第五列开始,改变随机数种子的值;
SEED3=456;
END;
OUTPUT;
END;
RUN;
PROCPRINTDATA=TEMP3;
RUN;
结果如下:
从上面的结果,我们可以看出:
前五行中,由于seed1=seed2=seed3,所以RUNI1,RUNI2和RUNI3的值相等,而SEED4=456,RUNI4与其它三个seed产生的值不一致,这就说明当使用CALL子程序进行随机数序列生成时,该随机数种子seed4起作用了,这是与使
用函数生成随机数序列的一个重要的区别。
第六行开始,由于seed1和seed3的值有了变化,对随机数序列的变化情
况如下:RUNI1和RUNI2的值并没有变化(可与前面两个程序的结果进行比对),RUNI3的值发行了变化。原因是在RUNI1=RANUNI(SEED1);这条语句中,SEED1
的变化并不起作用,原因上一节已经讲了,因些RUNI1不发生变化,为什么RUNI3会变化呢,原因是CALL子程序调用函数生成随机数序列时,其随机数种
子会更新,因此其随机数结果数据会发生变化。我们可以看到,RUNI3的第6
到第10个随机数与RUNI4的第1到第5个随机数是一致的。
3Seed为零时的随机数序列
前一篇文章已经讲过,随机数据集由随机数种子(seed)R0决定,它的值可
以是(-(2^31-2),2^31-2)中的任何一个数。其中,当随机数种子(seed)的值大
调用子程序的例子于0时,每次产生的R0的值都是一样的,但当随机数种子(seed)的值小于或等
于零时,每次产生的R0的值是不同的,它会以系统的时间为种子产生随机数值。
当Seed为零时,每一次执行CALL子程序所产生的随机数序列结果都会不
一致,下面举例进行讲解:
%MACROSEED0;
DATATEMP4(DROP=I);
SEED=0;
DOI=1TO3;
CALLRANUNI(SEED,RUNI);
OUTPUT;
END;
RUN;
PROCPRINTDATA=TEMP4;
RUN;
%MEND;
TITLE'FirstMacroCall';
%SEED0TITLE'SecondMacroCall';
%SEED0RUN;
结果如下:
FirstMacroCallOBSSEEDRANUI1212875390.00991219727378070.9186337900 227200.36788Secon
dMacroCallOBSSEEDRANUNI11569353220.0730829727557480. 45297320600252180.95927
我们可以看到,两个结果不一致。因此,我们可以将SEED=0看作是随机种子。
4生成大量不重复的seed序列
在实际的应用中,我们经常会遇到需要大量随机数序列的情况,这时候我们就不能靠手工输入随要数种子。在第3节中,当SEED=0时,我们可以用这个随机种子产生大量的随机数序列,但是这里产生的随机数序列并不一定能保证这些随机数序列不重复。因此,本节介绍一个产生不重复的随机数种子的宏:
%MACROSEEDGEN(FSEED=,LSTREAM=,NSEEDS=);
DATATEMP(KEEP=SEED);
RETAINSEED&FSEED;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。