要求就是 扩大一倍或者缩小一倍,两边的概率相同。
这个可以用 Math.radom(),仅以数学的方式,一行就完成吗?
我好像只能先随机出是扩大还是缩小,然后在分别写扩大 /缩小的倍率。
大大们可以给个其他的思路么?
1
huijiewei 2020-11-13 14:56:36 +08:00
不就是 50~200 之间 /100 就好了
|
3
yukiww233 2020-11-13 15:00:42 +08:00
没懂啥意思
ran(1.5)+0.5? |
5
adajoy 2020-11-13 15:02:57 +08:00
(Math.random() * 3 + 1) / 2
|
6
rioshikelong121 2020-11-13 15:04:39 +08:00
Math.random() * 1.5 + 0.5 不行么。
|
7
rioshikelong121 2020-11-13 15:05:35 +08:00
@ukipoi 写几个测测简单跑跑几万次就知道了。验证成本又不高。
|
8
nvkou 2020-11-13 15:06:34 +08:00 via Android
random 0.0 - 1 期望 0.5
0.5—2 期望 1.25 所以平移过去 random()+1.25 为啥不行? |
9
wysnylc 2020-11-13 15:06:39 +08:00
随机数一律建议使用 ThreadLocalRandom
|
10
kop1989 2020-11-13 15:08:41 +08:00
不太懂所谓“0.5-1 和 1-2 的概率不一样”是什么意思(概率论估计已经还给老师了😂)
0.5~1 的跨度是 0.5,1~2 的跨度是 1,我的理解,如果是真随机,落在这两个域的概率必然不同…… |
11
rioshikelong121 2020-11-13 15:10:46 +08:00
真正有这种概率不均等的情况一般是用现成的 random API 求随机整数的时候。
|
12
ukipoi OP |
13
ipwx 2020-11-13 15:13:11 +08:00
是说:
1. 先投掷一枚硬币,决定是扩大或是缩小; 2. 然后决定 1~2 之间的倍率? 我的思路: u = random(-1, 1) if u < 0: ..x = x / (1 - u) else: ..x = x * (1 + u) |
14
xcstream 2020-11-13 15:14:13 +08:00
不知道题目表达的意思
大概我想是 e 的 x 次方 在 0.5-2 之间 ,x 是平均分布 |
15
ukipoi OP |
16
dobest 2020-11-13 15:15:17 +08:00
如果要求 [0.5, 1] 和 [1, 2.0] 等概率的话,可以试试 v = math.random(); v + 0.5 if v <=0.5 else v*2; 但一行可能搞不定。其他 ax+b 的形式是线性变换可能无法做到直接变换成 [0.5, 1] 和 [1, 2.0] 是等概率的。
|
17
misdake 2020-11-13 15:15:43 +08:00
lz 的意思我觉得是先抛一个硬币决定乘和除,然后随机一个 1~2 之间的数字,用当前值乘或除(根据硬币)这个数。
|
21
Xs0ul 2020-11-13 15:34:04 +08:00 via Android
因为概率密度不一样,是个分段函数,感觉上肯定是要用到 if else 。宁可多写几行,不然以后很容易被自己坑
|
22
H15018327040 2020-11-13 15:35:43 +08:00
Math.floor((Math.random()*1.5)+0.5),先随机一个 0 到 1.5 的数,然后再加上 0.5
|
23
anzu 2020-11-13 15:35:58 +08:00 2
Math.random 范围是 [0, 1),对其乘除改变区间长度,加减相当于数轴平移
0.5~2 的区间长度 1.5,是原区间的 1.5 倍,所以 乘以 1.5 新区间距数轴原点 0.5,所以 + 0.5 因此结果是 Math.random() * 1.5 + 0.5 任何区间都可以以此求解 |
24
ukipoi OP @anzu
但是原先 0-0.5 和 0.5-1 这两个区间的数是一样多的 乘以 1.5 后 应当是 0-0.75 和 0.75-1.5 这两个区间的数是一样多的 加上 0.5 后 应当是 0.5-1.25 和 1.25-2 这两个区间的数是一样多的 我的要求是 0.5-1 和 1-2 这两个区间 数一样多 |
25
nightwitch 2020-11-13 15:50:08 +08:00
|
26
nightwitch 2020-11-13 15:52:22 +08:00
@ukipoi 你#24 写的需求和题干的需求完全不一样啊。
|
27
nightwitch 2020-11-13 15:55:09 +08:00
你#24 的需求应该写成分段的形势,两个生成器,1 个生成[0.5,1) 一个[1,2), 然后用抛硬币的方式决定选用哪个生成器。
|
28
ukipoi OP @nightwitch
我应该是写了的 [要求就是 扩大一倍或者缩小一倍,两边的概率相同。] 可能表达的不太清楚 |
29
vgbhne 2020-11-13 16:00:05 +08:00 via Android
可以想成有两个面积相同的靶,用两次 ran 取其坐标看落在哪个靶上。
|
30
Jooooooooo 2020-11-13 16:03:36 +08:00
随机两次
|
31
hitmanx 2020-11-13 16:07:50 +08:00
r = rand() # 假设 rand()返回[0, 1]
return (r + 0.5) if (r < 0.5) else r * 2 #相当于 50%的概率位于[0, 0.5),要把它 scale 到[0.5, 1); 50%的概率位于[0.5, 1],要把它 scale 到[1, 2] |
32
wlsnx 2020-11-13 16:08:39 +08:00
你是不是想实现“使一个数乘以[0,2)中的一个随机数”? n*(random()*2),(random()*2) < 1 就是缩小,>1 就是放大,倍率也是随机的。( python 里 random()返回[0,1)中的一个随机浮点数,其他语言自行修改。)
|
34
hitmanx 2020-11-13 16:15:19 +08:00 1
发完贴想起来,我这样写和你原帖是一样的,需要分情况讨论,原因是你这种表示方法(0.5 表示缩小一倍,2 表示放大一倍)不是对称也不是均匀分布的;另一个表示方法是负数表示缩小,正数表示放大,那么实际上就从[0.5,2]变成了[-2, 2],就对称了。
因此换个思路的话,你这个其实是指数对称,也就是 2^-1 表示缩小一倍,2^1 表示放大一倍,这样指数项就变成了对称且均与分布的了: # 假设返回[-1, 1] return exp(2, rand()) |
35
ifzzzh 2020-11-13 16:17:35 +08:00
生成-0.5~0.5,如果>0 就 x2,最后+1
|
36
lsylsy2 2020-11-13 16:20:16 +08:00 1
x=(-1,1)之间随机数
y=2^x ( 2 的 x 次方) 这个 y 的分布不是线性平均的,但是可能是 LZ 需要的 |
37
lsylsy2 2020-11-13 16:21:32 +08:00
|
38
Wincer 2020-11-13 16:21:50 +08:00
0-0.5,0.5-1,1-2,这几个区间的数的数量没办法比较大小,因为都是无穷多个数
|
39
ifzzzh 2020-11-13 16:24:33 +08:00
建议先画出想要的概率密度函数
|
40
ukipoi OP @x4400177
问题是,我要扩大或者缩小 N 倍 ,其中 1<N<=2 那在数学中的表述就是乘以一个 [0.5-2]的数值把。 我认为扩大和缩小,应该是有一个概率是一样的。 所以[0.5-1 )和( 1-2]也应该是一样的 |
42
wlsnx 2020-11-13 16:54:52 +08:00
rand = random()
if rand >= 0.5: return n * (rand * 2) else : return n * (rand + 0.5) 是不是想要这个效果? |
43
ukipoi OP |
44
reus 2020-11-13 17:00:16 +08:00 via Android
I =random()
If i < 0.5 return i + 0.5 Else return i * 2 就是个分段函数啊,当然不可能一行公式表达出来 |
45
ukipoi OP @ukipoi
主要是思路明显就不一样 我要的结果不一定是他们的结果 我就想要一种新的思路 “要扩大或者缩小 N 倍 ,其中 1<N<=2,那在数学中的表述就是乘以一个 [0.5-2]的数值把” 我是这么理解的,既然[0.5-1)表示缩小,(1-2]表示扩大。他们在逻辑中没有问题,但是比较反常理。 我就认为数学中一定有一个合理的解释,但是仅仅以无穷的数来解释我感觉很单调。 那一定有一个让人一眼看到就很合理的解释 |
46
ukipoi OP |
47
lllllliu 2020-11-13 17:14:10 +08:00
..大数随机然后归一化哦。归一化之后哪个范围都是符合分布规律的呀。
比如用高斯分布出的归一化随机数在转换扩大到哪个范围都是符合高斯分布到呀。 |
48
lllllliu 2020-11-13 17:15:54 +08:00
假设高斯分布得到到随机数是 0.5,那就是 min + 0.5 x (max-min) 比如 1-2 那就是 1.5 哦
|
49
ukipoi OP |
50
lllllliu 2020-11-13 17:18:10 +08:00
最简单的归一化 x = (x - min) / (max - min), 前端随机算法可以看你选择哦。输出的都是 0 ~ 1 直接的数,按照这个 min + 0.5 x (max-min) 怎么扩大都行。
|
54
oldw4ng 2020-11-13 17:20:21 +08:00
随机一个 1-2 的数然后再随机一个决定乘或除?
|
55
lllllliu 2020-11-13 17:21:25 +08:00
@ukipoi 相同的 bit 相同的算法出来的概率是相同的。不同的动态范围 那就存在压缩和扩展呢,就会出现你说的,永远不可能出现一些数。
|
56
ukipoi OP |
57
lllllliu 2020-11-13 17:23:07 +08:00 1
@ukipoi 啦啦啦,所以有不同的归一化和标准化算法,题主可以研究下,俺们在研究很多东西的时候都会转换到 0 ~ 1 之间来解决的。
|
58
xuanbg 2020-11-13 17:25:14 +08:00
小数先定义精度吧,不定义精度的话,说啥都没意义。
|
59
lllllliu 2020-11-13 17:32:33 +08:00
总的来说感觉有点牛角尖了。
假设精确到 1 位,也就是 0 ~ 1 之间有 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 这几个数。(动态范围) 然后假设一个随机数算法输出 0.5 的几率是 50%。。 那么扩大到 1-2 之间的话按照这个随机数算法出来 1.5 的几率也是 50%; 所以。。。简单归一化(虽然多余) x = (x - min) / (max - min) = ( 0.5-0 ) / ( 1-0 ) = 0.5 (动态位置); 然后。。1 + 0.5 x (2-1) = 0.5 (扩大后的位置); 所以重心点应该在 随机数生成规则以及你需要的动态范围(精度,采样)这个在计算机里是有上限的。 但是再怎么上限也不会影响随机算法的结果。。 当您觉得精度不够可以升采样,当你觉得精度(动态过了)可以降采样。。 啊啊啊随便扯的。。下班。 |
60
0o0o0o0 2020-11-13 17:38:21 +08:00
|random(0,2)-0.5|+0.5
|
61
idlerlestat 2020-11-13 17:43:53 +08:00
这……不就是 2^randint([-1,1])吗,randint 表示从一个数组里随机取一个数
|
62
wty 2020-11-13 17:46:38 +08:00 via Android
扩大和缩小比例本来就不均匀,感觉应该在对数上随机然后转换过来
|
63
cigarzh 2020-11-13 17:49:47 +08:00
先考虑精度+1
这个不理清楚后面没法做 |
64
xiaopang132 2020-11-13 17:54:25 +08:00
math.ramdom()*1.5 + 0.5
|
65
0o0o0o0 2020-11-13 17:54:54 +08:00
有个问题,“1/N 倍”概率如果要均匀分布,那肯定不是 if else 就能解决的
|
66
reus 2020-11-13 17:56:57 +08:00 via Android
@ukipoi 你才明白啊?我给你的答案就是两条直线推出来的公式啊。0-0.5 是缩小,0.5 到 1 是放大,概率一样,再映射到 0.5-1 和 1-2,答案不就出来了
设随机出来的是 x,要用的乘数是 y 那就是 Y =x + 0.5 和 Y= 2x |
67
laqow 2020-11-13 17:57:54 +08:00 via Android
没看懂,感觉应该从概率分布和概率分布的计算方面找答案。random 没记错就是 uniform 分布,根据自己需要把这个分布转换成其它分布就完了。
|
68
CRVV 2020-11-13 17:59:33 +08:00
如果只考虑数学问题(不考虑什么浮点数运算的事情),也不考虑边界([] 和 () 的差别),这个问题是这样的
已有一个 0-1 之间均匀分布的随机数 x,在上面加一个变换 f,变成 0.5-2 之间分布的随机数 y,要求 0.5-1 的概率和 1-2 的概率相等。问这个变换是什么。 先假定 f 在 0.5-2 之间是单调连续函数(不单调的 f 当然也可以有,先不考虑了) 那么,f(0.5) = 1 且 0.5 <= f(x) <= 2 的 f 都符合要求,比如 f(x) = x + 0.5 如果再增加一个条件,y 在 0.5 - 2 的整个区间内的概率密度都不为 0 那么只要 f(0) = 0.5, f(0.5) = 1, f(1) = 2,f 就满足要求,你随便假设比如 f(x) = ax^2 + bx + c 然后解 a b c 就好了。 如果假设 f(x) = 2^(ax+b) ,就得到 lsylsy2 给出的指数函数。 类似的还有很多符合条件的函数。 如果再增加一个条件,0.5-1 和 1-2 之间的概率密度分别都是常数,那么两边都是直线。 给定 f(0) = 0.5, f(0.5) = 1, f(1) = 2,结果是唯一的,就是那个分段函数。 |
69
zhyl 2020-11-13 18:03:32 +08:00
分成两步:
1. 一颗石子落在数轴(整个数轴 0.5 ~ 2 )上,落在 0.5 ~ 1 范围的概率 = 1 ~ 2 范围的概率 2. 在落入的范围内取任意随机数,其概率都是相同的 计算步骤: 0. p = Math.random() 1. p <= 2/3 则 (重置随机数种子后) Math.random()*0.5 + 0.5 2. p > 2/3 则 (重置随机数种子后) Math.random()+1 |
70
cmdOptionKana 2020-11-13 18:27:44 +08:00
随机数有两种:一种是 0-1 之间取随机数,有无限个;另一种是在有限的数量中(比如 5 号小球至 20 号小球,共 16 个小球中)随机选一个。
区分这两种不同的方式来取随机数,就比较清晰了。 |
71
cmdOptionKana 2020-11-13 18:38:15 +08:00
因此,如果楼主说的是 0.5 - 2 之间的 *无限个* 数字中取随机数,那么,这个问题本身就是错的。
不存在这样的随机数,或者说这样设定范围必然会影响随机性。 从无限个数字中取随机数,只能是在 0-1 之间取,或者 1-2 这样可以无损转换成 0-1 的范围中取。比如 1-3 就不行,2-4 就可以。 |
72
cmdOptionKana 2020-11-13 18:39:21 +08:00
说错了,2-4 不行,2-3 可以,3-4 可以。
|
73
xymn 2020-11-13 18:42:23 +08:00 via Android
var rand = Math.random()
if(rand<0.25){ return r*8 }else{ return r*2 } |
74
lancelock 2020-11-13 19:19:42 +08:00 via iPhone
随机范围 0-2,结果大于 1 直接乘,小于 1 的话先加 1 在反转作为分母,分子为 1,这个分数作为乘数
|
75
wchyqqgmail 2020-11-13 19:20:34 +08:00 via Android
random(1,4)/2
|
76
vgbhne 2020-11-13 20:30:25 +08:00 via Android
计算机浮点数虽然可能精度上有差距,但是落在(-1,1 )以零为原点的个数是一样的。具体生成的数经过计算或许是错的,但是不影响两边的概率。具体和底层设计也相关。
|
77
lance6716 2020-11-13 20:47:47 +08:00 via Android
充分证明程序员的数学基础有多差🤣
|
78
yanqiyu 2020-11-13 21:47:25 +08:00
扩大和缩小概率一样?你可能希望无论是扩大还是缩小概率分布都均匀(生成一个线性变换),抑或是一边均匀另一边按照幂函数映射(你原先的做法就是 best practice ),或者两边都不一定均匀但是要满足幂函数变换下的不变( exp(2, rand()))。
更一般的情况更为复杂(比如你需要指定某一侧具有复杂的概率密度函数形式)那就需要先计算出 pdf/cdf 做专门的生成器了( Inverse Transform Method ) |
79
cnt2ex 2020-11-13 23:57:04 +08:00 1
(2 * Math.random()) % 1.5 + 0.5
|
80
cnt2ex 2020-11-14 00:04:51 +08:00
```
import random run = 1000000 first = 0 second = 0 for i in range(run): rnd = (2 * random.random()) % 1.5 + 0.5 if rnd >= 0.5 and rnd < 1.: first += 1 if rnd >= 1. and rnd < 2.: second += 1 print(first / run, second / run, first + second == run) ``` 试着跑了一下,0.5 到 1 和 1 到 2 之间的概率差不多都是 0.5 |
81
Lemeng 2020-11-14 00:14:45 +08:00
都*10,就是 5-20 之间
|
82
luwies 2020-11-14 00:22:45 +08:00
1.5 * Math.radom() + 0.5
|
83
Takuron 2020-11-14 08:36:36 +08:00 via Android
先不说怎么写,让你“缩小一倍”的老师一定语文有问题,记得清清楚楚这是高考病句类型的一种。
|
84
chenyu8674 2020-11-14 09:35:01 +08:00
没有“缩小 N 倍”这种说法,应为为“变为 N 倍或变为 N 分之一”
|
85
Anarchy 2020-11-14 10:31:48 +08:00 via Android
所以楼主是希望生成一个 0.5-1 和 1-2 概率相同的么 79 楼的可以
|
86
crackhopper 2020-11-14 10:46:31 +08:00
一行代码? Math.pow(Math.random()+1, Math.pow(-1, (Math.random()>0.5)))
|
87
crackhopper 2020-11-14 10:48:21 +08:00
或者 (Math.random()>0.5) and Math.random()+1 or 1/(Math.random()+1)
|
88
crackhopper 2020-11-14 10:48:37 +08:00
或者 (Math.random()>0.5) and (Math.random()+1) or 1/(Math.random()+1)
|
89
Delbert 2020-11-14 12:57:38 +08:00
@ukipoi 0.5-1 和 1-2 这两个区间 数都是无穷多,哪怕 0.5-0.5000001 数也是无穷多,不存在数字谁多谁少的问题。
你的问题在与区间长度而不是数字数量。 |
90
qaqLjj 2020-11-14 13:27:54 +08:00
```javascript
Math.pow(2,Math.random()*2 - 1) ``` |
91
exiledkingcc 2020-11-14 15:43:07 +08:00
你想要的是一个在 0.5-1 上是均匀分布,在 1-2 上也是均匀分布,但是落到 0.5-1 与 1-2 上的概率相等?
这样的话,很多答案写的 2^(random() * 2 - 1)是不满足的。因为在这两个区间不是均匀分布的。 其实很简单:abs(random() * 2 - 0.5) + 0.5 |
92
PopRain 2020-11-14 17:26:41 +08:00
楼主数学水平不知道怎么样,语文水平我觉得有点堪忧。。。。看标题很简单,看说明、补充说明越看越看不懂到底要干什么
|
93
dejavuwind 2020-11-16 10:13:38 +08:00
同 90L,缩小一倍为 2^-1,放大 1 倍为 2^1,其实就是放大的倍数均匀分布(-1,1 )
|
94
ukipoi OP @exiledkingcc
请教下,为什么是不满足的? 2^(random() * 2 - 1) 这个函数图像时连续的,那应该是所有的 X 都有唯一对应的 Y,并且 所有确定的 X 都是 1/K 的概率(假设 K 是-1 到 1 的所有数的总量)。那所有的 Y 也是 1/K 的概率,[0.5,1)和(1,2]的概率也是一样,那范围内的所有数都在了 abs(random() * 2 - 0.5) + 0.5 的话,有些 Y 对应了两个 X,这个意思是一样的么? |
95
ukipoi OP @CRVV
请教下 2^(random() * 2 - 1) 得到 0.5-0.75 的概率是比 0.75 到 1 的概率大。 但是每一个 X 都只对应一个 Y,并且这个函数是连续的。 那这个对应关系到底对不对呢? 因为每一个 Y 出现的概率都是 1/K,这个是肯定的 |
96
exiledkingcc 2020-11-16 11:18:55 +08:00
@ukipoi
2^(random() * 2 - 1)是指数分布啊,怎么可能和均匀分布是一样的??? 它取值在 0.5-1 与 1-2 上是等概率的。但是显然在 1-1.5 与 1.5-2 上不是的。其它等区间的概率也不是一样的。 关键在于你想要的是一个什么样的概率分布。 |
97
ukipoi OP @exiledkingcc
但是每一个确定的 Y 出现的概率是一样的吧? |
98
CRVV 2020-11-16 11:41:14 +08:00
@ukipoi
首先你需要说清楚你在讨论实数还是在讨论 64 位浮点数 如果是实数,那么 “K 是-1 到 1 的所有数的总量” 这句话不成立,后面就不用讨论了。 不能设 K 是无限,然后把 K 当一个有限的数来做后续的讨论。 如果是 64 位浮点数,那么 “每一个 Y 出现的概率都是 1/K” 是错的。 比如 2 ^ 0.1000000000000002 和 2 ^ 0.10000000000000014 的结果都是 1.0717734625362934 |
99
no1xsyzy 2020-11-16 11:53:17 +08:00
|
100
CRVV 2020-11-16 12:04:45 +08:00
这里的关键是楼主没想清楚自己要的是什么
给定的要求只有一个,>1 和 <1 的概率相等。 这样不能确定唯一的答案,所以下面给出了很多不同的解答。 给的解释又超出了楼主能解理的数学,所以估计现在更不懂了。 除了上面那个给定的要求,显然还存在一个要求是概率在某种程度上是均匀的,但均匀又存在不同的均匀。 比如把所有结果 round 到一个最接近的数,然后 0.5 0.6 0.7 0.8 0.9 1.0 1.2 1.4 1.6 1.8 2.0 的概率相同 1/2.0 1/1.8 1/1.6 1/1.4 1/1.2 1/1.0 1.2/1 1.4/1 1.6/1 1.8/1 2.0/1 的概率相同 这两个也不一样,都可以被认为是均匀的 上面说的,其实不仅 “每一个 Y 出现的概率都是 1/K” 对浮点数是错的,“所有确定的 X 都是 1/K 的概率” 也是错的。 因为浮点数本身是不均匀的,但那个随机数是均匀的。 建议楼主放弃这个问题吧,需要补的课挺多的。 |