计算 Ruby 中的指数衰减值

Calculate Exponential Decay Value In Ruby

今天我突然想到我几乎忘记了所有的高中数学,所以我需要一些帮助来解决 Ruby 中的一些基础数学问题。

基本上,我有一组从 1 到 10 的值。现在,我只需将它们乘以 10 就可以得到我用作百分比的数字。例如 2 = 20%、4 = 40% 等

这有点太线性了,所以我真正需要做的是计算一个指数衰减样式值,其中越接近 1 的值给出的百分比越大,而接近 9 和 10 的数字给出的百分比变平。

未来也有可能会有10个以上的数字,比如1到20。我想这就足够改变了?

这是一个快速图表,描述了我正在尝试做的事情。

谁能帮我解决这个问题?最好在 Ruby 中,否则任何伪代码都会有所帮助。

首先,你需要有概率分布函数,比如F(x)。它不需要标准化。在你的情况下(指数衰减),这个函数可以是

F(x) = e^(-kx)

您可以调整 k 来调整衰减的速度。 然后计算 F(x) 在你的域上的范围。

然后求出它的反函数G(x),即

G(x) = -(1/k)ln(x)

然后你可以通过G(rand(range of F))

进行抽样

这是我的 ruby 代码:

k = 1

f = -> x {Math.exp(-k * x)}
l, h = f.call(10), f.call(1)

g = -> x {-Math.log(x) / k}
r = -> {rand(h - l) + l}

samples = 10_000.times.map{g.call(r.call)}

samples.count{|x| x < 1}  #=> 6327
samples.count{|x| x < 2}  #=> 8620
samples.count{|x| x < 3}  #=> 9477
samples.count{|x| x < 4}  #=> 9809
samples.count{|x| x < 5}  #=> 9929
samples.count{|x| x < 6}  #=> 9970
samples.count{|x| x < 7}  #=> 9986
samples.count{|x| x < 8}  #=> 9994
samples.count{|x| x < 9}  #=> 9997
samples.count{|x| x < 10}  #=> 10000

另一条可能适合你的曲线是square/squareroot/parabola

> 11.times{|x| puts "#{x}, #{100-(10-x)**2}"}
0, 0
1, 19
2, 36
3, 51
4, 64
5, 75
6, 84
7, 91
8, 96
9, 99
10, 100

要将比例更改为 20,请使用

> 21.times{|x| puts "#{x}, #{100-(10-x/2.0)**2}"}