1
impanghu 2019-01-20 21:53:20 +08:00
mark 我也想知道
|
2
alvin666 2019-01-20 21:55:01 +08:00 via Android 1
这就不叫随机数吧...
而且最简单的方法就是随机生成,然后总和 /100 = k,每个数再 /k |
3
celeron533 2019-01-20 22:00:32 +08:00 139
在一根 1 到 100 的数轴上,随机取 9 个点,拿到 10 个线段。计算每个线段的长度,即是取值。
|
4
weijidong 2019-01-20 22:01:31 +08:00 via iPhone
关注
|
5
weijidong 2019-01-20 22:02:47 +08:00 via iPhone
@celeron533 牛逼
|
6
JCZ2MkKb5S8ZX9pq 2019-01-20 22:05:14 +08:00
需要补全一下问题,比如你现在包含 0,是否确定?另外 10 个随机数可以重复吗?
如果不可以重复,那第一步取值范围就剩 1-55 或者 0-64 了。 |
7
Kagari 2019-01-20 22:05:30 +08:00
@celeron533 #3 稳了,反正没要求是整数
|
8
JCZ2MkKb5S8ZX9pq 2019-01-20 22:07:00 +08:00 1
有个思路是先在一个范围里随机取 10 个数,然后 sum,然后缩放到 100,然后做点去重的偏移。
|
9
commoccoom OP @JCZ2MkKb5S8ZX9pq 包含 0 和 100,可以重复,需要是整数 @Kagari
|
10
chinvo 2019-01-20 22:08:15 +08:00 via iPhone 1
在马桶上随便写写,没怎么仔细想,各位见笑
伪代码 func(nums: array = [0]) if i=nums.length < 11 nums[i] = rand(nums[i-1], 100) return func(nums) nums.removeAt(0) return nums func() 但是严格意义上讲,虽然数列中的每个元素都是随机函数生成的,但是这个数列并不是随机数列 |
11
chinvo 2019-01-20 22:09:55 +08:00 via iPhone
@JCZ2MkKb5S8ZX9pq #6 不含 0 是 (0, 100]
|
12
F1024 2019-01-20 22:15:10 +08:00
递减呗
|
13
emric 2019-01-20 22:18:04 +08:00 1
fisher yates 洗牌算法,生成 1~100 数组打乱即可。
|
14
alvin666 2019-01-20 22:18:38 +08:00 via Android
@celeron533 这根本不是随机数
|
15
JCZ2MkKb5S8ZX9pq 2019-01-20 22:25:09 +08:00 3
照着 @celeron533 思路
points = [random.randint(0, 100) for i in range(9)] # 生成 9 个随机点 points = [0] + sorted(points) + [100] # 排个队 points = [points[i + 1] - points[i] for i in range(10)] # 算每段距离 print(points, sum(points)) |
16
emric 2019-01-20 22:26:17 +08:00
忽略我上面的答案,没认真审题...
|
17
smdbh 2019-01-20 22:36:45 +08:00
那就生成 9 个随机数,范围看你需求
最后一个 100 - 9 个和 不就好了。 |
19
zys864 2019-01-20 22:56:06 +08:00 via Android
生成 9 个随机数,然后用 100 减去 9 个数的和作为第十个数
|
20
niuoh 2019-01-20 23:16:03 +08:00 via Android
第一次取 0 到 100 第二次取 0 到 100 减第一个数
|
21
lance6716 2019-01-20 23:19:59 +08:00 via Android 2
凡是描述概率问题的时候不给分布瞎答就可以了
|
22
ps1aniuge 2019-01-20 23:20:13 +08:00
$数组 = 1..100
while ($true) { $a,$b,$c,$d,$e,$f,$g,$h,$i,$j = Get-Random -InputObject $数组 -Count 10 $和 = $a + $b + $c + $d + $e + $f + $g + $h + $i + $j if ($和 -lt 120) { Write-Host "$a $b $c $d $e $f $g $h $i $j $k" } } 上面的 powershell 代码,设定值小于 120 时 ,5 分钟没出结果。 我估计 -eq 100 得一年才能出结果。而设定 -lt 200 很好出结果,大家可以试试。 |
23
evgm 2019-01-20 23:25:52 +08:00
生成一个[0, 100] 的随机数,第二个数范围是 [0, 100-num1],第三个是[0, 100-num1-num2],以此类推?
|
24
epicnoob 2019-01-20 23:27:08 +08:00
你这个不能叫随机数,近似使用可以 10+randint(-10,10)
|
25
Vegetable 2019-01-20 23:29:01 +08:00 via iPhone
很有意思的问题,有很多实现方式,随着限制条件(去重,整数,负数)的增加,变数更多,很适合作为面试口答题哦。
|
26
stevenbipt 2019-01-20 23:29:21 +08:00 via Android
生成 9 个,最后一个用 100 减去🌚🌚🌚
|
27
18219304774 2019-01-20 23:39:24 +08:00
Python 没学过,用 js 实现一个
var arr=new Array(10); for(let i=0; i<10; i++){ arr[i]=0; } for(let i=0; i<100; i++){ var index=Math.floor(Math.random()*10); arr[index]++ } |
28
flowfire 2019-01-20 23:41:04 +08:00 via Android
3 楼正解,取 9 个点然后拿到十个线段长度即可,如果需要整数,可以规定随机到的九个点都是整数即可
|
29
ticotico 2019-01-20 23:45:08 +08:00
random 取整数,加和,映射到 100 内( 100/加和总数*十个数总值)
结果:前九个数+0.5 取整 最后一个数 100-前九个数的合 这个问题就是微信红包是怎么随机分配的吧 |
30
gransh 2019-01-21 00:15:37 +08:00 1
10 个数和为 100,均值也就是 10,也就是说最好在 0-20 里面取值。
而且绝对不能取到大于 91 的数,92-100 已经被排除在外了 这种条件,还能叫随机吗 |
31
jinyang656 2019-01-21 00:27:59 +08:00
|
32
luozic 2019-01-21 00:41:51 +08:00 via iPhone
直接 100 落概率桶,总和为 10,难道还有负数?
|
33
dapang1221 2019-01-21 00:44:21 +08:00 2
关键在于随机数不一定要同时生成吧
第一个数 n[0] = rand(0, 100); 第二个数 n[1] = rand(0, 100 - n[0]); 第三个数 n[2] = rand(0, 100 - n[0] - n[1]); 而且应该也是均匀分布的吧 |
35
AX5N 2019-01-21 00:50:07 +08:00
还是 3 楼的答案最好
|
36
xujunfu 2019-01-21 00:53:43 +08:00 via Android
感觉三楼解法,稍微有 bug,就是有可能 9 个数全部落在 1 点(9 个点中有重复数出现);个人觉得这是个线性代数问题,先求解线性方程 组 x1+x2+…… x10=100 的所以解,然后从解的集合随机取出。
|
37
CEBBCAT 2019-01-21 00:56:19 +08:00 via Android
这不就是微信红包算法吗?
|
38
Linxing 2019-01-21 01:03:45 +08:00 1
随机十次 每次范围都是 100 减去余下的数
|
39
Linxing 2019-01-21 01:04:34 +08:00
额 说错了 随机九次
|
40
ywcjxf1515 2019-01-21 01:20:36 +08:00 via iPad
就没人想到深度优先搜索嘛,深度优先能用其他图算法就可能能用。
|
41
abysmalIQ 2019-01-21 01:29:11 +08:00
你要先定义你这里的“随机”是什么意思
|
42
umbrellakkk 2019-01-21 04:18:10 +08:00 2
0-100 随机生成 10 个数,然后加起来,如果等于 100,直接输出,不等于就返回继续生成 10 个随机数,直到等于 100 为止,反正现在计算机快,不在乎没效率。
|
43
imzhong 2019-01-21 04:30:38 +08:00
你这是线性方程组求解
|
44
yuikns 2019-01-21 04:33:17 +08:00 via iPad
先随机十个数字,再求和,得到的结果除以 100 得到 f,对每个数字除以这个值即可。
若需要,还可以高斯分布再 curve 一下 |
45
imzhong 2019-01-21 05:19:27 +08:00 via iPad
@yuikns 也可以随机出来 10 个,最后再加一个数使 11 个数总和为 100,然后随机出来的每一个数加上 1/10 最后一个数
|
47
jssyxzy 2019-01-21 06:10:15 +08:00
很简单的问题,你生成 9 个随机数不就是了,最后一个 100- 下。
别杠说你这不是 10 个随机数,你题目本来就做不到 10 个数全部完全随机。 |
48
jssyxzy 2019-01-21 06:10:47 +08:00
@celeron533 感谢仁兄的思路。
|
49
Mutoo 2019-01-21 06:20:14 +08:00
另一个红包算法(精度到 0.01 元)
https://2013.mutoo.im/2015/09/how-wechat-do-the-luckey-money-division.html |
50
ayyll 2019-01-21 07:19:08 +08:00 via Android
@umbrellakkk 计算机是快。。。但这不是写垃圾代码的理由
|
51
Cbdy 2019-01-21 07:21:38 +08:00 via Android
概率论了解一下,47 楼正解
|
52
bugcoder 2019-01-21 07:35:07 +08:00
整数:
穷举所有相加等于 100 的 10 个[0, 100)整数的组合,然后每次随机抽取一组。 非整数: 每次随机完从剩下的份额里面随机就行了。 |
53
opengps 2019-01-21 08:10:27 +08:00
这个做法,完全就是微信或支付宝的**随机红包**逻辑。参考 3 楼的方案使用几何角度解决很完美!!
不过实现起来未必容易,要求普通程序员写数学模型算法不见得容易。那么可以先围绕单个平均值随机时候检查大小,每 2 个红包随机结果求和等于 2 个红包总平均值。 |
54
xujinkai 2019-01-21 08:23:05 +08:00 via Android
楼主啊 看你拿来干嘛了 是要做红包还是只要求随机 红包的话还会多几个约束条件 比如取到小数点后两位 而且虽然随机但差距又不要太大
|
55
airfling 2019-01-21 08:26:39 +08:00
你这是个伪命题,即使前面九个数据都满足,最后一个数据就不可能是随机数,你这个最终结果是越来越不随机
|
56
lrh3321 2019-01-21 08:29:19 +08:00
先生成 10 个随机数 wi,作为权重。然后每个数是 100 * wi / sum(wi)
|
57
Forbidden 2019-01-21 08:40:00 +08:00
@imzhong 这个思路也是可以的,10 个数之和大于 100 的,第 11 个数取负数即可,但要保证前 10 个数中最小一个要大于第 11 个数绝对值的 1/10
或者最小的不参与减值,其他的减 1/9,然后又回到刚才的要避免的情况里面了…… 又或者是第 11 个数随机分 10 份,哈哈又变成原题了…… |
58
NotFamous 2019-01-21 08:40:08 +08:00
感觉顶多只能随机前 9 个,第 10 个妥妥的 100 减去前边的和。。。(其实每次抽,下一个数都是 100 减去前边数的总和吧)
|
59
MrUser 2019-01-21 08:50:11 +08:00
坐等比 3# 更牛 B 的方法
|
60
auciou2 2019-01-21 09:18:16 +08:00 1
先获得所有的情形:0 ~ 100,共有 101 个数。
假设要求这 10 个数不重复,这 10 个随机数共有:1+2+3+4+5+6+7+8+9+10+11=66 种。(其实不需要统计有多少种) 编写一个循环程序,从 0-100,列举出所有的 10 个不重复的数的组合、与和,循环次数为 101*101。 从这些组合中,让程序自动筛选出所有的和为 100 的(10 个数的)组合。 之后,从这 10 个组合,随机拿出一个组合。 再将这个拿到的组合,再进行随机排列大小。 如果要生成 10 个随机数的和为 200、300,或者 N 个随机数的和为 M,同理。 |
61
werty 2019-01-21 09:21:57 +08:00
网上有微信红包算法, 抄一遍就行了,
|
62
alex1504 2019-01-21 09:22:08 +08:00
@celeron533 思路不错
|
63
bigbigfly 2019-01-21 09:30:24 +08:00
组合数学里的整数拆分了解下,思路:先有一个 1 行 100 列的数组,每个值为 1 ;再随机生成 100 内的 9 个数(升序排列),这样,每个间隔(如 0-随机生成的 9 个数中最小的那个,依次类推会一般有十个间隔)累加起来当做一个值,个人感觉这样很合理,很随机。
|
64
jrient 2019-01-21 09:31:24 +08:00
其实题主的问题有两个分支:
1. 直接获得 10 个数字 2. 每次生成一个,一共生成 10 个数字 |
65
hanwujibaby 2019-01-21 09:35:08 +08:00
@celeron533 学习了。这是数学思维啊。
|
66
SeaRecluse 2019-01-21 09:35:11 +08:00
import random
num_list = [] tmp_num = 0 tmp_sum = 0 get_num = 0 for i in range(1,10): tmp_sum = i * 10 - get_num tmp_num = random.randint(1,tmp_sum) get_num += tmp_num num_list.append(tmp_num) num_list.append(100 - get_num) print(num_list) |
67
PALELESS 2019-01-21 09:39:31 +08:00
先定义一个生成两个数的过程, 并给出总和
第一个数为随机 第二个数为和减去第一个数 返回这两个数 那么 10 个数即为: |
68
PALELESS 2019-01-21 09:42:36 +08:00
先定义一个生成两个数的过程, 参数为其和
第一个数为随机 第二个数为和减去第一个数 返回这两个数 那么 10 个数即为: 求出第一个随机数, 第二个数为第一个数减去第一个数, 用第二个数作为和接着递归 不给代码了(空格按错多回了一次) |
69
lithiumii 2019-01-21 09:42:49 +08:00
比较看脸的算法,供参考(滑稽
from random import randint sum_ints = 0 while sum_ints != 100: ints = [randint(0,100) for ii in range(0,10)] sum_ints = sum(ints) print(ints) |
70
fromxt 2019-01-21 09:44:32 +08:00
如果是要均匀分布随机数的话,可以采用 numpy 库里面的狄利克雷分布函数 numpy.random.dirichlet,这个函数能保证随机数是正的,和为 1.
参考 https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.random.dirichlet.html import numpy as np np.random.dirichlet(np.ones(10))*100 |
72
xxlong 2019-01-21 09:58:11 +08:00
@JCZ2MkKb5S8ZX9pq 算法有问题 出现了 0 的时候
我觉得算法还是生成随机数后,用可控总和去减比较稳妥,因为不可能做到完全随机,如果第一个或者有一个随机数是 99 怎么办?我觉得这样比较稳妥:先生成 0~( 100-10 )的随机数 a,然后再生成 0~( a-10 )的随机数,最后一个用综合减去,这样能保证稳妥的随机性 |
74
SeaRecluse 2019-01-21 10:00:10 +08:00
@SeaRecluse 写错了,是 i*11
|
75
xinClever 2019-01-21 10:14:37 +08:00
num1 = [0, 100],num2 = [0, 100 - num1],num3 = [0, 100 - num1 - num2],以此类推,可以吧?
|
76
celeron533 2019-01-21 10:16:15 +08:00
@commoccoom 但实际上最可操作的还是取一堆介于 0-1 之间的浮点 /单精 /双精,然后把它们相加,最后总和与 100 等比放大。这个之前#2 @alvin666 操作过了
|
77
beforeuwait 2019-01-21 10:18:34 +08:00
3 楼正解
|
78
huahuajun9527 2019-01-21 10:24:26 +08:00
照 3 楼说的
import random a = [random.randint(0, 100) for i in range(10)] a.append(0) a.append(100) a.sort() b = [a[i + 1] - a[i] for i in range(10 + 1)] print(b) print(sum(b)) |
79
huahuajun9527 2019-01-21 10:28:00 +08:00
@huahuajun9527 数字取多了,写成取 11 个数了==
|
80
dlrdegk 2019-01-21 10:32:59 +08:00
@celeron533 #3 看到这个第一反应:《几何原本》
|
81
commoccoom OP @xinClever 我能想到的也是这样。
|
82
commoccoom OP @celeron533 感谢帮助!
|
83
shintendo 2019-01-21 10:37:43 +08:00
我这个思路不知道对不对:
想象你有 100 个小球排成一行,标号 1-100,现在要随机插入 9 块隔板,把它分成 10 段,每段的个数就是你要的结果。 再把隔板视为特殊的小球,问题转化为从 109 个小球中随机选 9 个。 |
84
SeaRecluse 2019-01-21 10:38:35 +08:00
@huahuajun9527 这样的写法其实对于第一位和最后一位是不公平的
|
85
shintendo 2019-01-21 10:39:20 +08:00
看错了,是 0-100。
那就是从 0-109 中随机取 9 个整数即可。 |
86
SeaRecluse 2019-01-21 10:41:18 +08:00 1
@shintendo 你的想法是对的,但是是插入 10 个隔板,因为围成圈后没有开头结尾。
|
87
SeaRecluse 2019-01-21 10:41:57 +08:00
@SeaRecluse get_sum = -10 初始化的时候,写错了
|
88
biossun 2019-01-21 10:42:52 +08:00
把 100 进行 10 等分,两两之间随机偏移一下。
|
90
xpresslink 2019-01-21 10:47:28 +08:00
@jssyxzy 你说的办法理论上是可行的,但是实践中是不可用的。
生成的 9 个随机数之和大于 100 的概率太大了,要远远大于正好小于 100 的概率,所以就要反复生成直要碰上符合条件的,极端情况下上秒出不了结果的可能都有,算法时间复杂度不可控制。 还是 3 楼方法科学一些。 |
91
shintendo 2019-01-21 10:54:40 +08:00
@SeaRecluse
还是老哥考虑仔细 |
92
xpresslink 2019-01-21 11:05:28 +08:00
@seven777 那个方法是很垃圾的方法
我试验了一下,连续生成的 9 个 1-100 的随机数之和小于 100 的概率是上百万分之一。 |
93
wqzjk393 2019-01-21 11:14:28 +08:00
随机取 10 个点,按从小到大排序。取最大的一个放大到 100,其余的根据这个放大比例放大。最后的返回的 10 个随机数就是这 10 个点的间隔,就是 x[10]-x[9],x[9]-x[8]....x[0]
|
94
shuson 2019-01-21 11:27:06 +08:00
total = 10
count = 10 nTotal = total * 10 from random import randint for i in range(10): if nTotal < 1: break n = randint(1, nTotal) while n + (10 - i) > nTotal: n = randint(1, nTotal) nTotal -= n print("person " + str(i) + " got " + str(n/10) + " dollar") |
95
imaple 2019-01-21 11:28:48 +08:00
拿个秒表然后 100 秒内点 9 下暂停 https://www.v2ex.com/static/img/doge.gif
|
96
jssyxzy 2019-01-21 11:29:21 +08:00
|
97
wjfz 2019-01-21 11:31:14 +08:00
你这不是“像”,感觉就“是”啊。
|
98
wjfz 2019-01-21 11:33:39 +08:00
哎哟没发完提交了。
前两天帮朋友解决了这么一个需求,最后也是靠红包算法解决的。 要求给一个数字,如 15.14 再给一个浮动范围,± 0.03 求 5 个数字在浮动范围内,并且平均值==15.14 |
99
LifStge 2019-01-21 11:35:59 +08:00 via iPhone
大小为 10 的数组 选个分布合适的随机函数 循环 100 次 范围 0_99 然后指定下标+1 吧 哈哈哈哈
|
100
kart891209 2019-01-21 11:38:53 +08:00
随机 9 个数,每次 random 的 bound 是(剩余可取的数值+剩余坑数)最后一个减法即可
|