java伪随机数概率_抽奖伪随机数生成器(Java)
update:
用概率算法解決的思路,沒有任何數(shù)量限制:
總數(shù)N,預(yù)計中獎數(shù)M,已中獎數(shù)K。0<=K<=M<=N
隨機一個數(shù)R,區(qū)間在[0,N-K)
如果R在[0,M-K)中,則中獎,K++.
完畢.
---- ----
最近在寫互動代碼,里面用到了概率發(fā)獎,在網(wǎng)上簡單搜索了一下沒看到Java版本,估計太簡單了。沒人稀罕寫,也或許又開源的方案,我沒找到。
順手把我寫的發(fā)出來記錄一下。這個是比較簡單的版本100%,1000%的方案。記得5年前寫過一個幾百萬人+的抽獎方案。用的是概率解法,記錄中獎人數(shù),然后用數(shù)學(xué)的方法,越往后中獎概率越高。
先發(fā)這個簡單版本吧:
/**
* 偽隨機數(shù),構(gòu)造從0~max的偽隨機數(shù)生成器.用完了可以自動填充.
* 一般在上層業(yè)務(wù)中放到static里面.
* 不同業(yè)務(wù)建議用一個static Map去管理.
* 此處放Set,不同場景可以使用ConcrrentHashMap將對應(yīng)的概率值里面放對應(yīng)的業(yè)務(wù)Object.
*/
public class PseudoRandom {
private CopyOnWriteArraySet copyOnWriteArraySet;
private int max;
private Random random;
public PseudoRandom(int max){
copyOnWriteArraySet = new CopyOnWriteArraySet();
this.max = max;
refill(this.max);
}
/**
* 重新生成所有隨機數(shù)
* @param max
*/
protected void refill(int max){
random = new Random(System.currentTimeMillis());
for(int i = 0; i < max; i++){
copyOnWriteArraySet.add(i);
}
}
/**
* 得到下一個隨機數(shù).
* 這個方法不用同步,因為如果在第一個線程里用完,另一個線程在初始化中,第一個線程拿到了數(shù)據(jù),也沒有關(guān)系,能保證全概率出現(xiàn)一遍,不會多不會少.
* 但如果是不同業(yè)務(wù),要在上層去保證不同業(yè)務(wù)拿到不同的實例instance,如果所有業(yè)務(wù)共用這一個,業(yè)務(wù)可能會有概率不全的情況.
* @return
*/
public int next(){
int nextInt = -1;
do {
int nextTryInt = random.nextInt(max);
if(copyOnWriteArraySet.remove(nextTryInt)) {
//如果移除成功,則返回
nextInt = nextTryInt;
}else {
//判斷是否已經(jīng)全部出現(xiàn)
if (copyOnWriteArraySet.isEmpty()) {
//如果一次全概率都出現(xiàn)了,重新填充
refill(max);
}
}
}while(nextInt == -1);
return nextInt;
}
public static void main(String[] args){
PseudoRandom p = new PseudoRandom(10);
for(int i = 0; i<20;i++){
System.out.println(p.next());
}
}
}
總結(jié)
以上是生活随笔為你收集整理的java伪随机数概率_抽奖伪随机数生成器(Java)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mybatis pagehelper自定
- 下一篇: Selenium+Java - 结合si