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