[问题] 从机率不同的几个样本中随机抽出一个

楼主: shinjiyano (矢野真士)   2018-11-16 21:22:57
最近有个需求,有点像抽抽奖券
假设有5个人A B C D E
A手上有5张抽奖券
B手上有12张抽奖券
C手上有15张抽奖券
D手上有18张抽奖券
E手上有20张抽奖券
总共70张
当然抽奖券都是记自己名字的
他们将抽奖券都丢入同一个箱子
这时随机抽出一张
A被抽中的机率就是5/70
B被抽中的机率就是12/70
C被抽中的机率就是15/70
D被抽中的机率就是18/70
E被抽中的机率就是20/70
当然真正遇到的问题可能有上万人,每个人有几万张抽奖券之类的
我自己想过两种写法
第1种是最笨的做法
把ABCDE都丢入一个list,有几张就丢几个
[A,A,A,A,A,B,B,B,B,B,B,B,B,B,B,B,B,C......]
然后就用乱数随机抽出一个就行了
但遇到上万人这做法太没效率了而且很占内存甚至LIST可能会爆炸
第2种是用数值范围
先把总和加起来是70的话,就抽1~70的数字
若是抽中1~5就是A
6~17就是B
18~32就是C
33~50就是D
51~70就是E
但在抽之前就得先算好每个人的范围,感觉也蛮没效率的
想请教高手是否有比较有效率的做法呢? 感谢!
作者: jobsdone (完工了)   2018-11-16 22:05:00
Fenwick tree?
作者: idiont (supertroller)   2018-11-16 22:43:00
第二种建立前缀和 n个人只要做n次加法 要从random的结果推出是谁也可以使用二分搜加速 不会很慢吧
作者: bowin (尽其在我)   2018-11-17 03:35:00
写一个function随机产生uniform(0,1),然后用probability integral transform抽出你要的元素
作者: hare1039 (hare1039)   2018-11-17 05:06:00
用 std::discrete_distribution 就直接可以解了https://goo.gl/5qwWQ8 cppreference 上有范例
作者: Schottky (顺风相送)   2018-11-17 05:49:00
真士......是人狼君的作者?几万个加法并不慢啊,抽奖池几万笔资料也不会很大线性搜寻可以轻松处理的范围,不到一秒吧
作者: longlongint (华哥尔)   2018-11-17 10:48:00
看需求 求效率的话上面回复就够用了但是拿去抽转蛋会被骂死 不如用 list 照比例配票 XDD

Links booklink

Contact Us: admin [ a t ] ucptt.com