更新:
用概率算法解决的想法没有数量限制:
总数n、预计当选数m、当选数k。 0=K=M=N
随机数r,区间为[0,N-K
如果r中了[0,M-K,则当选,k。
结束了。
------------
我最近在写互动代码,其中一些一直使用到有概率发奖为止。 我试着在网上简单地搜索了一下,但是没有看到Java版本。 我觉得太简单了。 没有人稀罕写,也许有开源的方案,但我找不到。
请随手记录下我写的东西。 这是比较简单的100%、1000%版本的方案。 我记得五年前写了几百万人的抽签方案。 使用概率解法,记录中奖人数,然后使用数学方法,越晚中奖概率越高。
我先把这个简单的版本发给你吧:
//*
*构建伪随机数、0~max的伪随机数发生器。 用完可以自动填充
*通常在上层业务进入静态。
*建议使用一个静态地图管理不同的业务。
*在这里输入Set,根据场景可以使用ConcrrentHashMap在对应的概率值中输入对应的业务Object。
*/
公共类仿真随机{
私有副本写入器副本写入器;
隐私int max;
私有随机随机;
公共仿真随机(intmax ) {
版权所有者=newcopyonwritearrayset (;
this.max=max;
refill(this.max;
}
//*
*重新生成所有随机数
* @param max
*/
保护性语音文件(intmax ) {
random=new random (system.current time millis ();
for(intI=0; i max; I ) {
copyonwritearrayset.add(I;
}
}
//*
*得到下一个随机数。
*此方法不需要同步。 因为如果第一个线程用完了,则在另一个线程初始化时第一个线程得到数据也没关系。 保证全概率出现一次,不少也不少。
*但是,对于不同的业务,必须保证上层有不同的业务得到不同的实例实例instance,如果所有业务共享,业务就有可能概率不完整。
* @return
*/
公共int next () {
int nextInt=-1;
do {
intnexttryint=random.nextint (max;
if (复印写入程序arrayset.remove (nexttryint ) ) }
//删除成功后返回
nextInt=nextTryInt;
}else {
//判断是否全部出现
if(copyonwritearrayset.isempty () () ) )
//一旦出现全概率,再填充
再填充(max;
}
}
}while(nextint==-1 );
返回下一步;
}
publicstaticvoidmain (字符串[ ] args ) {
仿真随机p=新仿真随机(10;
for(intI=0; i20; I ) {
系统. out.println (p.next ) );
}
}
}