【问题标题】:Random selection of weighted items随机选择加权项目
【发布时间】:2016-08-05 02:49:03
【问题描述】:

我的模型 TicketBuyer 列包括 ticket_buyer 名称和 number_of_tickets 购买。我想随机选择一张中奖彩票。我认为我的偏好是创建另一个模型(SelectTable),该模型将ticket_buyer 名称复制到等于购买的number_of_tickets 的行数上,从而为每条记录赋予相同的权重。然后我可以运行一个简单的排序并选择新表中的第一条记录。我无法为每个ticket_buyer 自动创建具有正确行数的表。当然,也可能有一种更雄辩/有效的方法来做到这一点。非常感谢您的建议。

【问题讨论】:

    标签: arrays sorting activerecord random


    【解决方案1】:

    如果速度不是问题,您可以在不创建任何额外数据结构的情况下做到这一点。

    • 查找任何人购买的最多 number_of_tickets
    • 随机选择购票者
    • 再抽一次,他们有 number_of_tickets / max_number_of_tickets 机会成为赢家
    • 如果第二次抽奖失败,则随机选择另一位购票者并重复该过程,直到有人中奖

    除非有一些疯狂的分布,比如一个人买一百万张票,其他人都买一张,否则这不会花太长时间。

    伪代码:

     max_tickets = max(table:number_of_tickets)
     while true do:
         // select a random buyer
         buyer = select random row from table
    
         // assume random(n) returns an integer number from 0 to n - 1 inclusive:
         if random(max_tickets) < buyer.number_of_tickets then
              return buyer   // we have a winner
     end
    

    【讨论】:

    • 我喜欢!让我们给一个名字:它类似于rejection sampling。此处列出了替代方案(更复杂):on wiki (part: finite discrete distributions),如果速度很重要,我推荐alias-method。不过,这需要额外的工作。
    • 谢谢。我以前没有见过这种方法,但看起来不错。任何示例代码将不胜感激。
    • 我没有提到我是在 Rails 中写这篇文章的。
    • 对不起,我不熟悉 Rails。当我回答这个问题时,我没有意识到这个问题是特定于 Rails 的。
    • @sasha 我认为这是离散分布的拒绝抽样。
    猜你喜欢
    • 2015-07-05
    • 2010-09-08
    • 2011-11-14
    • 2017-12-26
    • 2021-05-04
    • 2023-03-31
    • 2020-01-22
    相关资源
    最近更新 更多