请教抽奖算法 奖品是 1-100 元整数

2020-02-12 13:46:39 +08:00
 Windowsxpplayer

抽奖算法

奖品是 1-100 元整数

要求金额越大抽中概率越小, 可以设置数学期望。

各位有什么思路?

4104 次点击
所在节点    程序员
25 条回复
oIMOo
2020-02-12 14:27:47 +08:00
笨办法:
把 1 - 100 按照你的意愿放入一个 list 里面
假设抽中 1 元的概率是抽中 100 元的 666 倍,那就在 list 里面放 1 个 100 和 666 个 1,其它金额同理。
然后随机选列表里面的一个数字。

没睡好,脑子不太转,等楼下……
shadeofgod
2020-02-12 15:39:21 +08:00
```js
function rand(max) {
const _rand = () => ~~(Math.random() * max);
const a = _rand();
return (Math.random() > a / 100) ? a : _rand();
}
```
shadeofgod
2020-02-12 15:40:21 +08:00
哦 上面这个只是 max = 100 的时候的,随便写了一下
hearfish
2020-02-12 15:43:40 +08:00
weighted random, 金额越大权重越小

有兴趣的话可以去看看 Alias Method
ferock
2020-02-12 15:44:16 +08:00
@oIMOo #1

这个方案并不是不可行
st2udio
2020-02-12 15:48:07 +08:00
要有个背景吧。抽奖人数是否可估,奖品总数是否固定。避免没被抽完或提前抽完。
daozhihun
2020-02-12 17:26:12 +08:00
有个简单的办法。
假如 1 的概率是 10 的 10 倍,是 100 的 100 倍
则可以考虑 1 ~ 100 为 1,101 ~ 199 为 2,……,5048 ~ 5049 为 99,5050 为 100。
则生成 1 ~ 5050 区间的随机数,按照上面的算法判断对应的区间表示哪个数,比如生成 145 对应的数字是 2。
这样的话 1 ~ 100 的概率递减,且 1 是 10 的 10 倍,是 100 的 100 倍
daozhihun
2020-02-12 17:28:26 +08:00
@daozhihun 概率算错了,但是思路大致这样。总的来说按照概率大小分成不同区间,再计算生成的随机数所在的区间对应的数字
xupefei
2020-02-12 17:47:59 +08:00
带权重的水塘抽样?
ylsc633
2020-02-12 17:50:50 +08:00
http://interview.wzcu.com/%E8%AE%BE%E8%AE%A1%E9%A2%98/%E5%B8%A6%E6%9C%89%E6%9D%83%E9%87%8D%E7%9A%84%E9%9A%8F%E6%9C%BA%E7%AE%97%E6%B3%95.html

实现很简单 不过看需求

这个概率 跟 奖品数量有没有关系!

比如 2 个奖品! 100 个人抽!每人一次机会!

跟库存有关的话 第一个人没中,第二个人概率就是 2/99
跟库存无关的话 第一个人没中,第二个人概率还是 2/100
ipwx
2020-02-12 18:02:55 +08:00
freakxx
2020-02-12 18:03:10 +08:00
看需求,
比如总金额固定,最简单的就是你事先生成 数组,你自己按比例配进去;

还有一种比较简单的,就是你划定好区间,随机生成一个数,然后用二分插入的算法做。
x = [1, 100, 300, 400 ... 9990, 10000]
y = [1, 2, 3 ... 100]

index = bisect_search(x)
y[index]
ccoming
2020-02-12 18:07:09 +08:00
会出现全部不中奖的情况么?
ETiV
2020-02-12 19:50:58 +08:00
https://zh.wikipedia.org/wiki/%E6%B3%8A%E6%9D%BE%E5%88%86%E4%BD%88

我首先想到的是泊松分布 lambda=1 的曲线

----
话说这种出真钱的概率不能是前后无关的吧
比如服务器记录一下今天 100 块已经被抽出去了,那今天就不应该再出现 100 块了…
dji38838c
2020-02-12 20:31:26 +08:00
要求金额越大抽中概率越小,并且可以设定期望值,可以用几何分布。
可以设定期待值 expected_value, 和抽奖的次数 n
np.random.geometric(p = 1.0/expected_value, size = n)
注意,如果期待值高的话,随机产生的值可能超出 100。
oIMOo
2020-02-12 21:45:20 +08:00
楼主不要被我 1 楼的回复迷惑,我现在清醒了。
#4 的关键词可以参考,下面这个也可以看看
https://medium.com/@peterkellyonline/weighted-random-selection-3ff222917eb6
kdashl
2020-02-12 21:51:22 +08:00
1 加到 100 是 5050...100 就是 1/5050,99 就是 2/5050.....以此类推到 1 就是 100/5050
CEBBCAT
2020-02-13 02:18:43 +08:00
这个我写过,网上也是稍微搜下就有。要是明天我还记得就过来贴代码
CEBBCAT
2020-02-13 02:23:05 +08:00
一个变量存权重之和,random 一个 r 然后对刚才那个 sum 求模。循环加权值,直到加和大于等于得到的模
VDimos
2020-02-13 02:30:53 +08:00
box muller 算法,不知道行不行

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/644011

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX