实现随机数按概率显示 java版

来源:互联网 发布:行书笔顺演示软件 编辑:程序博客网 时间:2024/06/08 00:19

这个方法是网上找的最简洁的方法了。实现的也比较好。


一个常见的场景,在游戏中打一个怪物,10%几率出现miss,那么这次攻击是命中还是miss呢?我们可以用随机数来实现,miss的范围是[1,10],命中的范围是[11,100],然后我们取一个随机数,比如60就是命中了,如果不幸取到8就是miss了。只要测试的次数足够多,那么miss的比例将会趋向于10%。 


再举多个候选数的例子。比如a概率为20%,b概率为30%,c概率为40%,d概率为10%,那么他们的概率值范围分别是: 
a[1,20] 
b[21,50] 
c[51,90] 
d[91,100] 
然后取一个[1,100]的随机数,落到谁的范围谁就是选中了。 

算法描述如下: 
1.依次(顺序可随机)将各项按概率值从原点开始放在一维坐标上首尾相连,这样每一项对应一个取值区间 
2.在总区间范围内随机选取一个点,落在哪一项对应的区间就选中哪一项 

java实现: 
Java代码  收藏代码
  1. public class RandomEngine {  
  2.      /** 
  3.      * 概率选择 
  4.      * @param keyChanceMap key为唯一标识,value为该标识的概率,是去掉%的数字 
  5.      * @return 被选中的key。未选中返回null 
  6.      */  
  7.      public static String chanceSelect(Map<String, Integer> keyChanceMap) {  
  8.           if(keyChanceMap == null || keyChanceMap.size() == 0)  
  9.                return null;  
  10.             
  11.           Integer sum = 0;  
  12.           for (Integer value : keyChanceMap.values()) {  
  13.                sum += value;  
  14.           }  
  15.           // 从1开始  
  16.           Integer rand = new Random().nextInt(sum) + 1;  
  17.             
  18.           for (Map.Entry<String, Integer> entry : keyChanceMap.entrySet()) {  
  19.                rand -= entry.getValue();  
  20.                // 选中  
  21.                if(rand <= 0) {  
  22.                     return entry.getKey();  
  23.                }  
  24.           }  
  25.             
  26.           return null;  
  27.      }  
  28. }  

测试(次数足够多时,各值出现的比例跟概率是基本一致的): 
Java代码  收藏代码
  1. public class RandomEngineTest {  
  2.      public static void main(String[] args) {  
  3.           Map<String, Integer> keyChanceMap = new HashMap<String, Integer>();  
  4.           keyChanceMap.put("a"30);  
  5.           keyChanceMap.put("b"10);  
  6.           keyChanceMap.put("c"40);  
  7.           keyChanceMap.put("d"20);  
  8.             
  9.           Map<String, Integer> count = new HashMap<String, Integer>();  
  10.           for (int i = 0; i < 100000; i++) {  
  11.                String key = RandomEngine.chanceSelect(keyChanceMap);  
  12.                if(count.containsKey(key)) {  
  13.                     count.put(key, count.get(key) + 1);  
  14.                }  
  15.                else {  
  16.                     count.put(key, 1);  
  17.                }  
  18.           }  
  19.             
  20.           // print  
  21.           for (String key : count.keySet()) {  
  22.                System.out.println(key + ":" + count.get(key));  
  23.           }  
  24.      }  
  25. }  

参考:http://blogread.cn/it/article.php?id=4102