如何把 100 块钱随机地分成 30 份呢?

2017-04-26 10:47:32 +08:00
 crist
如何把 100 块钱随机地分成 30 份,也就是每一份的钱是不固定的,但是总数加起来必须等于 100 。
9940 次点击
所在节点    问与答
68 条回复
Vizogood
2017-04-26 15:28:58 +08:00
@crist https://www.zhihu.com/question/22625187
我没有什么好的算法 原来在知乎上看过一个类似问题
crist
2017-04-26 15:37:10 +08:00
29 楼我那个方法有点缺陷哈:就是结果起伏变化不是很大, 100 块钱 30 份的每一份都很少有低于 2.0 或者高于 4.0 的
blankme
2017-04-26 15:52:00 +08:00
@ifishman 确定,区间多大,总数就多大,这不是显而易见的吗。。
wbt
2017-04-26 16:21:44 +08:00
随机生成 30 个( 0-1 之间的)数字,然后求和计算每个数字的百分比,最后乘以 100 。
rogerchen
2017-04-26 16:29:24 +08:00
#1 隔板法
#14 正则化
两个都是好方法,正则化可以完全控制分布
slixurd
2017-04-26 16:37:52 +08:00
"首先,我来讨论一下为什么要采用截尾正态分布。首先介绍一种更加直接的方法(我有一些朋友也这样猜测):如果我有 50 元,要发给 25 人。那么我用连续均匀分布随机产生 24 个位于 0 到 50 之间的数字。这 24 个数字将整个 0-50 的区间划分为 25 份,分别分给这 25 个人。但事实并不是这样的。学过序列统计的人应该知道,由于这 24 个点是连续均匀分布产生的,因此他们的序列统计量也是连续均匀分布产生的,因此他们之间的间隔的分布是指数分布的。具体证明从略,可参照 John Rice 2007 。

作者: Mr.L
链接: https://www.zhihu.com/question/22625187/answer/85431684
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。"
nszm
2017-04-26 16:47:00 +08:00
@crist #42 有可能分不到吗....
qxd123
2017-04-26 16:53:30 +08:00
关于这个问题,如果单纯为了每个人获得的金额都相差不大的话,用一楼的确实就够用了,但如果要想跟微信红包差不多的结果,用正态分布的算法来更为合理,楼上也都给出了些方法,在保证大部分人的金额处于平均数附近,但是又有极少人的金额是相对大一点或者小一点,另外之前在网上看到过类似这种的,可以参考看看 https://segmentfault.com/q/1010000006002081
geelaw
2017-04-26 16:57:27 +08:00
你这个问题根本不是 well-asked ,都不知道你想要什么分布,怎么随机?
di94sh
2017-04-26 17:28:19 +08:00
就一楼的方法, 10000 里面生成 29 个不想等的随机数,大小排序,从零开始判断区间。/100 可以精确到分。
fl2d
2017-04-26 17:44:57 +08:00
你要的是啥分布的随机,这很重要
wangleineo
2017-04-26 17:53:57 +08:00
实践出真知,楼主建个群发红包,看看微信红包到底什么分布。
zjp
2017-04-26 19:01:09 +08:00
是我想的太简单吗😂 #15 的方法不就可以了吗
yellowV2ex
2017-04-26 20:14:57 +08:00
随机 100 个数记下来,再计算他们的和,然后每一份的钱就是

每一个随机数
------------------- x 100.00
所有随机数总和
qqjt
2017-04-26 20:35:45 +08:00
钱应该最小是 0.01 , 0-100 间有 999 个取值,问题变成了 [1-999]里面随机取 30 个整数。
qqjt
2017-04-26 20:36:20 +08:00
@qqjt 不对是取 29 个。
Actrace
2017-04-26 21:14:39 +08:00
既然入坑了,我就贴一下代码把。。
```````````
<?php
$total = 10000;//总额,按分
$max = 500;//最大可分额度
$min = 100;//最小可分额度
$times = 30;//分几个人
for($i=1;$i<=$times;$i++){
$exp = ($total-($times-$i))>$max?$max:($total-($times-$i));
$now = rand($min, $exp);
$total = $total - $now;
$f1 = $now/100;
$f2 = $total/100;
echo "//第{$i}个人:{$f1}元,剩余{$f2}元。\n";
}
echo "//第 30 个人:{$f2}元。\n";
?>
````````````
//第 1 个人:3.69 元,剩余 96.31 元。
//第 2 个人:2.82 元,剩余 93.49 元。
//第 3 个人:4.79 元,剩余 88.7 元。
//第 4 个人:3.57 元,剩余 85.13 元。
//第 5 个人:4.39 元,剩余 80.74 元。
//第 6 个人:2.45 元,剩余 78.29 元。
//第 7 个人:2.1 元,剩余 76.19 元。
//第 8 个人:4.89 元,剩余 71.3 元。
//第 9 个人:4.93 元,剩余 66.37 元。
//第 10 个人:4.19 元,剩余 62.18 元。
//第 11 个人:2.2 元,剩余 59.98 元。
//第 12 个人:4.52 元,剩余 55.46 元。
//第 13 个人:4.67 元,剩余 50.79 元。
//第 14 个人:3.92 元,剩余 46.87 元。
//第 15 个人:3.44 元,剩余 43.43 元。
//第 16 个人:1.32 元,剩余 42.11 元。
//第 17 个人:1 元,剩余 41.11 元。
//第 18 个人:3.52 元,剩余 37.59 元。
//第 19 个人:2.21 元,剩余 35.38 元。
//第 20 个人:4.19 元,剩余 31.19 元。
//第 21 个人:1.29 元,剩余 29.9 元。
//第 22 个人:2.87 元,剩余 27.03 元。
//第 23 个人:4.88 元,剩余 22.15 元。
//第 24 个人:3.98 元,剩余 18.17 元。
//第 25 个人:2.93 元,剩余 15.24 元。
//第 26 个人:3.83 元,剩余 11.41 元。
//第 27 个人:3.82 元,剩余 7.59 元。
//第 28 个人:1.57 元,剩余 6.02 元。
//第 29 个人:1.26 元,剩余 4.76 元。
//第 30 个人:2.2 元,剩余 2.56 元。
//第 30 个人:2.56 元。
Actrace
2017-04-26 21:18:17 +08:00
过大的粒度可能会让结果偏离更大,比如一个人拿了 99 块钱。。
过小的粒度同样如此,最后一个人拿了 99 块钱。。。
mingyun
2017-04-26 23:03:43 +08:00
可以参考微信红包算法
zhihaofans
2017-04-26 23:38:12 +08:00
用 html+js 做了个粗暴的方法,为什么大部分都在前面呢, js 随机算法的原因?

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

https://tanronggui.xyz/t/357405

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

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

© 2021 V2EX