带权随机数问题--根据权重随机选择一条路径

   最近工作中遇到了一个根据权重随机选择一条路径的问题,一时没有啥好方案,参考借鉴了网上的经验,得出了如下解决方案:       思路:1.求权重的和,对(0,权重之歌和]区间进行划分,每个权重占用长度为权重的区间;            2.产生一个在(0,权重之和]区间的等概率随机数;            3.该随机数落在哪个区间,则该区间对应的权重的映射为本次产生的带权随机数。

 1 import java.util.ArrayList;
 2 import java.util.HashMap;
 3 import java.util.List;
 4 import java.util.Map;
 5 import java.util.Random;
 6
 7 public class WeightRandomTest {
 8     public static void main(String[] args) {
 9         //数据初始化key:value=权重:值
10         Map<Integer, String> operMap=new HashMap<Integer, String>();
11         operMap.put(5, "001001");
12         operMap.put(10, "005001");
13         operMap.put(40, "004001");
14         operMap.put(30, "006004");
15         operMap.put(15, "007003");
16
17         //实验次数
18         int testCount=100000;
19
20         //求权重的和
21         int sumWeight=0;
22         for(Map.Entry<Integer,String> kv:operMap.entrySet())
23             sumWeight+=kv.getKey();
24
25         //随机抽样100000次
26         List<String> res=new ArrayList<String>();
27         for(int k=0;k<testCount;k++){
28             //产生0到sumWeight的随机数
29             Random r=new Random();
30             double randNum=r.nextInt(sumWeight);
31             int stepWeightSum=0;
32             //一次遍历
33             for(Map.Entry<Integer,String> kValue:operMap.entrySet()){
34                 stepWeightSum+=kValue.getKey();//区间(stepWeightSum,stepWeightSum+weights[i]]
35                 if(randNum<=stepWeightSum){//选择随机数落在该区间的那个值为随机产生的带权重随机数
36                     res.add(kValue.getValue());
37                     break;
38                 }
39             }
40         }
41
42         //统计并输出实验结果
43         Map<String, Integer> map=new HashMap<String, Integer>();
44         Map<String, String> mapP=new HashMap<String, String>();
45         int value=0;
46         for(String key:res){
47             if(map.get(key)!=null){
48                 value=map.get(key)+1;
49                 map.put(key, value);
50                 mapP.put(key,value*100.0/testCount+"%");
51             }
52             else {
53                 map.put(key, 1);
54                 mapP.put(key,1*100.0/testCount+"%");
55             }
56         }
57         System.out.println("次数统计:"+map);
58         System.out.println("概率统计:"+mapP);
59     }
60 }
61
62 实验结果:
63     次数统计:{005001=9977, 006004=29179, 001001=6026, 007003=14986, 004001=39832}
64     概率统计:{005001=9.977%, 006004=29.179%, 001001=6.026%, 007003=14.986%, 004001=39.832%}   实验结论:从实验数据来看,100000次实验,每个值随机出现的概率基本与相应的权重值相符合,除去实验次数循环和实验统计等辅助空间外,算法的时间复杂度为O(n),空间复杂度为O(1)
时间: 2024-08-06 07:56:32

带权随机数问题--根据权重随机选择一条路径的相关文章

根据权重随机选取指定条数记录的简单算法实现(C#)

一.应用场景: 有时我们需要从一些列数据中根据权重随机选取指定条数记录出来,这里需要权重.随机,我们根据权重越大的,出现概率越大.例如广告系统:可根据客户支付金额大小来调控客户们的广告出现概率,客户支付金额越大,其广告出现频率越频繁,例如:加入有10条广告,然后每条广告都有一个权重,我们每次要根据权重选取5条广告出来进行显示.有了需求,我们就进行解决,本文章就是利用一种简单的算法来实现根据权重来随机选取. 二.简单算法的实现: 根据我们需求,上网找了不少资料,都没有找到一种比较适合的方案,就自己

Oracle随机选择一条记录SQL

Oracle随机选择一条记录SQL: SELECT * FROM (SELECT * FROM t_enterprise_info order by dbms_random.value) WHERE rownum =1

我的游戏服务器类库 -- 按权重随机选择1个或n个对象

按权重选择 在编写游戏服务器的时候,经常会遇到类似的需求:从列表中随机选出1个或多个条目,且条目是有权重的(权重越大,选中它的可能性就越大).比如说,砍死一个怪物可以从一个装备列表里掉一个装备.这种需求,和现实生活中的幸运大转盘很类似: 算法实现 因为这种需求很常见,所以我想把它写的通用一点.首先,接口Weighted表示有权重值的对象,getWeight()方法返回权重值: public interface Weighted { public int getWeight(); } Weight

加权重随机算法

场景:有N个合作方,每一个合作方都有一定的权重,按权重随机选择一个合作方 typedef struct { string k;//partner_id string v;//value string m;//0:number 1:ratio }Bookpartner_count_listInfo; string GetRandNumRatio( vector<Bookpartner_count_listInfo> arpartner_count_list) { int weight = 0;

【HDOJ3047】Zjnu Stadium(带权并查集)

题意:浙江省第十二届大学生运动会在浙江师范大学举行,为此在浙师大建造了一座能容纳近万人的新体育场. 观众席每一行构成一个圆形,每个圆形由300个座位组成,对300个座位按照顺时针编号1到300,且可以认为有无数多行.现在比赛的组织者希望观众进入场地的顺序可以更加的有趣,在门票上并没有规定每个人的座位,而是与这个圈中某个人的相对位置,可以坐在任意一行. 门票上标示的形式如下:A B x 表示第B个人必须在A的顺时针方向x个位置(比如A坐在4号位子,x=2,则B必须坐在6号位子). 现在你就座位志愿

HDU3635 Dragon Balls (带权并查集)

Dragon Balls Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10628    Accepted Submission(s): 3802 Problem Description Five hundred years later, the number of dragon balls will increase unexpect

随机选择带权重的item

http://blog.csdn.net/pipisorry/article/details/44491727 Question:(随机数相关) 假设张三的mp3里有1000首歌,现在希望设计一种随机算法来随机播放.与普通随机模式不同的是,张三希望每首歌被随机到的改了吧是与一首歌的豆瓣评分(0~10分)成正比的,如item0评分为8.9分,item1评分为9.5分,则希望听item0的概率与item1的概率比为89:95,.现在我们已知这1000首歌的豆瓣评分. 解决方案: 一. def ran

飘逸的python - 带权随机算法及在抽奖中的应用

带权随机在游戏开发中重度使用,各种抽奖和爆装备等. 运营根据需要来配置各个物品出现的概率. 今天要说的这个带权随机算法思想很简单,就是"把所有物品根据其权重构成一个个区间,权重大的区间大.可以想象成一个饼图.  然后,扔骰子,看落在哪个区间," 举个栗子,有个年终抽奖,物品是iphone/ipad/itouch. 主办方配置的权重是[('iphone', 10), ('ipad', 40), ('itouch', 50)]. 用一行代码即可说明其思想,即random.choice(['

权重随机算法的java实现

一.概述 平时,经常会遇到权重随机算法,从不同权重的N个元素中随机选择一个,并使得总体选择结果是按照权重分布的.如广告投放.负载均衡等. 如有4个元素A.B.C.D,权重分别为1.2.3.4,随机结果中A:B:C:D的比例要为1:2:3:4. 总体思路:累加每个元素的权重A(1)-B(3)-C(6)-D(10),则4个元素的的权重管辖区间分别为[0,1).[1,3).[3,6).[6,10).然后随机出一个[0,10)之间的随机数.落在哪个区间,则该区间之后的元素即为按权重命中的元素. 实现方法