java中随机数生成算法

   java语言中提供了三张随机数生成方法:

        ①:Math.random()方法,产生的随机数是0-1的一个double,可以把他乘以一个数,如乘以1000,他就是1000以内的随机数。

        ②:java.util包里面提供Random类,可以新建一个Random对象来产生随机数,它可以产生随机整数,float,double,long。

        ③:System类有一个currentTimeMillis()方法,该方法返回一个从1970年1月1日0点0分0秒到目前的一个毫秒数,返回类型是long,可以将它作为一个随机数,对一些数取模,就可以把它限制在一个范围内。

package com.unit6;
public class Demo6_3 {
public static void main(String[] args) {
for (int i=0;i<50;i++){
         double x=Math.random();
         System.out.println(x);
}
}
}


package com.unit6;
import java.util.Random;
public class Demo6_3 {
public static void main(String[] args) {
Random random=new Random();
for(int i=0;i<50;i++)
{
System.out.println(random.nextInt(10));
}

}


}

random.nextInt(10)生成[0,10)的伪随机数。

random.nextDouble()生成[0.0,1.0]的随机数。


虽然编程语言给我们提供了很方便的随机数生成方法,但有时我们也需要自己来编写随机数产生的算法。

   一:[0,1]之间均匀分布的随机数算法。

        首先,设定一个基数base=256.0,以及两个常数a=17.0和b=139.0。基数base一般取2的整数倍,常数a和b可以根据经验来随意取。然后按照如下递推算法来逐个得[0,1]之间的随机数。

             r(i)=mod(a*r(i-1)+b,base)         p(i)=r(i)/base           i=1,2,...    而p(i)便是递推得到的第i个随机数。

 注意:首先,此处取模运算是针对浮点数的,有些语言取模运算不支持浮点数,这样需要我们自己编写取模的程序。

            其次,r(i)是随着递推而每次更新的。因此,如果将该算法编写成方法则必须考虑参数是传值还是传地址的问题。

/*
 * 手动编写随机数生成算法。
 */
package com.unit6;
public class Demo6_3_1 {
public static void main(String[] args) {
double []arr={2.0};//初始化随机种子2.0

System.out.println("产生10个[0,1]之间的随机数:");
for(int i=0;i<10;i++)
{
System.out.println(rand(arr));
}     
}
static double  rand(double []arr){
double base,u,v,p,temp1,temp2,temp3;
base=256.0;
u=17.0;
v=139.0;

temp1=u*arr[0]+v;//计算总值
temp2=(int)(temp1/base);//计算商
temp3=temp1-temp2*base;//计算余数。

arr[0]=temp3;//更新随机数
p=arr[0]/base;//随机数。
return p;
}
}

根据随机生成[0,1]的算法,稍加改进,就可以得到随机任意范围的随机数

m+(n-m)rand(arr)   ->  [m,n]

m+(int)(n-m)rand(arr)  ->[m,n]之间均匀分布的随机整数算法,m,n都是整数。

二:正态分布的随机数生成算法。

                             RZT=μ+δ*(R(0)到R(n-1)的和-n/2)/n/12的平方根。   均值μ,方差δ^2   R(i)为[0,1]之间的均匀分布的随机数,当n趋近位无限大的时候,得到的随机分布为正态分布。   这里我们取n=12

package com.unit6;
public class Demo6_3_2 {
public static void main(String[] args) {
double []a={5.0};//随机种子
double u=2.0;
double t=3.5;
System.out.println("产生10个正态分布的随机数:");
for(int i=0;i<10;i++){
System.out.println(randZT(u,t,a));
}
}
static double randZT(double u,double t,double[]a){
double result;
double total=0.0;
for(int i=0;i<12;i++)
{
total+=rand(a);
}
result=u+t*(total-6.0);
return result;
}
static double  rand(double []arr){
double base,u,v,p,temp1,temp2,temp3;
base=256.0;
u=17.0;
v=139.0;

temp1=u*arr[0]+v;//计算总值
temp2=(int)(temp1/base);//计算商
temp3=temp1-temp2*base;//计算余数。
arr[0]=temp3;//更新随机数
p=arr[0]/base;//随机数。
return p;
}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值