单遍历取等概率随机数问题

43 篇文章 0 订阅

转自 : http://happyprince.iteye.com/blog/1488318


问题描述:

假设我们有一堆数据(可能在一个链表里,也可能在文件里),数量未知。要求只遍历一次这些数据,随机选取其中的一个元素,任何一个元素被选到的概率相等。O(n)时间,O(1)辅助空间(n是数据总数,但事先不知道)。

 

引例:

5个人抽5个签,只有一个签意味着“中签”,轮流抽签,从很久很久以前我们就认为这个是非常公平的例子,这个应该不用去怀疑吧。如果怀疑了,好吧,看下面的分析:

分析:

设Ai为第i个人抽签抽中事件,P(Ai)表示第i个人中签的概念,依题意得:

第一个人中签概率:P(A1)=1/5;

第二个人中签概率:P(A2)=4/5*1/4=1/5;(因为第二个人是在第一个人选了之后才去抽的,所以,还有4/5是第一个没有选中的,剩下的四个再去抽一个所以是1/4)

同理, P(A3)=4/5*3/4*1/3=1/5; 

P(A4)=4/5*3/4*2/3*1/2=1/5; 

P(A3)=4/5*3/4*2/3*1/2*1=1/5;

就样,五个人抽到的是等概率的,相信了吧。

 

总结公式:

 

java产生随机数的几种方式

1.使用Math.random()方法来产生一个随机数,这个产生的随机数是0-1之间的一个double,可以乘以一定的数,比如说乘以100,他就是个100以内的随机。(j2me没有)

2.在java.util这个包里面提供了一个Random的类,我们可以新建一个Random的对象来产生随机数,他可以产生随机整数、随机float、随机double,随机long,这个也是我们在j2me的程序里经常用的一个取随机数的方法。 
3.在我们的System类中有一个currentTimeMillis()方法,这个方法返回一个从1970年1月1号0点0分0秒到目前的一个毫秒数,返回类型是long,我们可以拿他作为一个随机数,我们可以拿他对一些数取模,就可以把他限制在一个范围之内。

一般会用到java.util里面包中的,一个例子:

Java代码   收藏代码
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         java.util.Random r=new java.util.Random();   
  4.          for(int i=0;i<100;i++){   
  5.              System.out.println("i="+i+"  "+r.nextInt(100));   
  6.          }   
  7.     }  
  8. }  

结果打印了100个0到100(不包含100)的随机数。

看一下Random类:

还有nextFloat().nextLong()等方法,重点看看nextInt(int n)方法吧,看jdk说明文档。

 

参数:
n - 要返回的随机数的范围。必须为正数。 
返回:
下一个伪随机数,在此随机数生成器序列中  0(包括)和  n(不包括)之间均匀分布的  int 值。 
抛出:
IllegalArgumentException - 如果 n 不是正数

 

 

单遍历取等概率随机数问题求解JAVA实现:

 

Java代码   收藏代码
  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         java.util.Random r=new java.util.Random();   
  4.          int n= 0 ;  
  5.          int[] a = {12,34,56,78,9,91,87,4,5,62,12,3,41,8,89,541,11,54,36};  
  6.          int selectNum = 0 ;  
  7.         for(int k : a){  
  8.             n++ ;  
  9.             if(r.nextInt(n) == 0){  
  10.                 selectNum = k ;  
  11.             }  
  12.         }  
  13.         System.out.println("selectNum:"+selectNum);  
  14.     }  
  15. }  

 

参考:

http://www.gocalf.com/blog/random-selection.html

http://www.blogjava.net/cool2009/archive/2009/03/15/259882.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值