Ruby 有什么分区段产生随机数的好办法嘛?

macknight · 2015年02月09日 · 最后由 lhy20062008 回复于 2015年03月06日 · 2866 次阅读

如题... 效果是 1-10 之间的占比 80% 10-20 之间的占比 20%

不过有个问题,a.map!{|x,i| x*2}如何用到前一个元素?这个只能用当前元素和当前 index。

Random.rand(x..y)

#1 楼 @michael0015 我是要那种, 1-10 之间的占比 80% 10-20 之间的占比 20%

1-10 的随机 80 次,10-20 随机 20 次不成?

#2 楼 @macknight 比例你自己调控啊

#4 楼 @michael0015 恩,这个我自己写了。不过有个问题,a.map!{|x,i| x*2}如何用到前一个元素?这个只能用当前元素和当前 index。

#3 楼 @rudy 不过有个问题,a.map!{|x,i| x*2}如何用到前一个元素?这个只能用当前元素和当前 index。

思路

x = Random.rand(1..100)

if (1..80).include? x
  return Random.rand(1..10)
elsif (81..100).include? x
  return Random.rand(10..20)
end

遗传算法。

其实换种思路,可以很简单…1 到 50 随机,40 以下的每个数除以 4 取整,大于 40 的减去 30,得到的就是你要的

#7 楼 @libuchao 简单方便,我后来也是这么干得

#8 楼 @rasefon 哥,别整复杂了

#9 楼 @cassiuschen 7 楼方案比较简洁

这样有人喜欢不:

a = (1..10).to_a * 4 + (11..20).to_a
a.sort!
a.sample(1)[0]

#9 楼 @cassiuschen 这种解决办法的话 整数 10 只有在随机到 40 的时候才能实现,那么显然整数 10 的出现概率明显比 1-10 中其它的数低很多啊,或者修改为 1-43 直接除以 4,而 44-54 直接减去 33。

#15 楼 @lhy20062008

((1..10).to_a * 4 + (11..20).to_a).shuffle.pop

#16 楼 @imconfused 用 shuffle 效率太低了:

require 'benchmark'
class A
    def shuffle_or_sample(a =0)
        Benchmark.bm do |x|
            arr = (1..a).to_a
            x.report("shuffle") do
                a.times do |i|
                    arr.shuffle.pop
                end
            end

            x.report("sample") do 
                a.times do |i|
                    arr.sample(1).first
                end
            end
        end
    end
end

A.new.stuffle_or_sample(10000) 的结果:

shuffle  3.600000   0.030000   3.630000 (  3.651668)
sample  0.000000   0.000000   0.000000 (  0.003996)

A.new.stuffle_or_sample(50000) 的结果:

shuffle  256.740000   3.160000 259.900000 (262.763773)
sample  0.020000   0.000000   0.020000 (  0.018795)
需要 登录 后方可回复, 如果你还没有账号请 注册新账号