【问题标题】:Sliding probability scale for randomly picking a number between a range [closed]用于在范围之间随机选择数字的滑动概率标度[关闭]
【发布时间】:2013-10-03 02:47:36
【问题描述】:

假设我有很多现金,我想以 500 美元到 5,000 美元之间的随机增量发放。我希望范围的下限比更高的范围更有可能。我可以用 Ruby 编写以这种方式随机发放现金的最有效算法是什么?

【问题讨论】:

  • 你能添加一些你尝试过的东西吗?您的问题目前要求其他 SO 用户也能有效地解决您的问题,而您无需付出明显的努力。

标签: ruby algorithm probability


【解决方案1】:

我认为最简单的方法就是使用 case 语句:

def get_price
  case rand(100) + 1
    when  1..50  then 500 
    when 50..75  then 1000
    when 75..99  then 2500
    when 99..100 then 10000
  end
end

p get_price # => 500

调用 get_price 将以 50% 的概率返回 500,但只有 2% 的时间返回 10000。

【讨论】:

    【解决方案2】:

    一种方法是首先定义多个范围并为每个范围分配概率“权重”。这是一个例子:

    weights = {[500,  1000] => 17,
               [1001, 1500] => 15,
               [1501, 2000] => 13,
               [2001, 2500] => 12,
               [2501, 3000] => 11,
               [3001, 3500] => 10,
               [3501, 4000] => 10,
               [4001, 4500] => 10,
               [4501, 5000] => 10}
    

    在这里,权重为 15 的范围 [1001, 1500] 比权重为 10 的四个最高范围中的任何一个都高 50%。您可以有任意数量的范围和(如这里) 权重总和不必为 100。在这里,您可以将四个最高范围替换为单个范围 [3001, 5000] => 40

    我们的想法是使用您提供的权重随机选择一个范围,然后在该范围内选择一个随机值,其中该范围内的每个值都同样可能被选中。

    ranges = weights.keys       # => [[500,  1000], [1001, 1500],.., [4501, 5000]]
    cum_wights = weights.values # => [17, 15,.., 10] 
    (1..weights.size-1).each {|i| cum_weights[i] += cum_weights[i-1]}
       # cum_weights => [17, 32,.., 108]
    
    # Obtain range randomly
    rn = rand(cum_weights) # => random number between 0 and cum_weights.last (here 108)
    i = 0 # range index
    i += 1 while cum_weights[i] <= rn
    rr = ranges[i] # random range
    
    # Obtain uniform random value in range rr
    # Obtain uniform random value in range i
    # Since `rn` is equally-likely for any value in `rr`,
    cwt_min, cwt_max = (i > 0 ? cum_weights[i-1] + 1 : 0), cum_weights[i]
    random_amount = rr.first + ((rn - cwt_min).to_f/(cwt_max - cwt_min + 1)) * (rr.last-rr.first + 1)
    

    或者干脆生成另一个随机数:

    random_amount = rr.first + rand(rr.last-rr.first)
    

    顺便说一句,我在赠送随机金额方面非常有经验。如果我能提供帮助,请告诉我。

    【讨论】:

    • 如果你不想麻烦选择这么多的权重,你可以为 Beta-Binomial 分布选择几个参数;例如,这里的红色是右偏的,参数a=.7, b=2: en.wikipedia.org/wiki/Beta-binomial_distribution n+1 是箱子的数量,你可以通过计算pmf(显示在图表下方)。
    • @Frank,这可能是一个不错的选择。可以使用许多概率分布;我只是展示了如何使用离散分布来完成。
    【解决方案3】:

    听起来您想生成具有向左(或向右,我永远无法保持笔直;驼峰在左侧)分布的高斯(又名正态)分布的随机数。

    这里是采样偏态正态分布算法的 VBA 实现(警告:弹出窗口):http://www.ozgrid.com/forum/showthread.php?t=108175

    把它翻译成 ruby​​ 应该不难。

    【讨论】:

    • 高斯不是 OP 想要的。
    • 为什么不呢?他从未说过增量的粒度大于整数。但是,这个问题确实因为不够清晰而被搁置,所以可能是我误解了。
    猜你喜欢
    • 2011-08-26
    • 1970-01-01
    • 2011-10-20
    • 2020-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多