【问题标题】:Random selection weighted against recent previous selections随机选择与最近的先前选择加权
【发布时间】:2010-12-15 15:03:33
【问题描述】:

我想选择列表中的一个元素,其中每个元素的权重是自上次选择以来的时长。

我可以制作一个 LRU(最近最少使用)列表,并根据队列中的位置对函数进行加权,这会很优雅,除了最初所有元素的权重应该相等。

在选择权重后仅将权重减去或除以一定数量在直觉上似乎并不正确。有没有更好的方法可能使用对数或倒数等数学概念? (不是我的强项)

【问题讨论】:

    标签: random selection lru weighting


    【解决方案1】:

    这样的事情怎么样:

    n = 元素数量list = 元素数组watermark := 0。

    r := random()
    i := floor(r * n)
    
    if i >= watermark :
        index := i
        watermark := watermark + 1  // weighted part grows
    else :
        index := floor(weight(r * n / watermark) * watermark)
    endif
    
    move list[index] to list[0]     // shifting elements list[0..index-1] up one place
    result := list[0]
    

    这里我们将列表分为两部分,加权和统一,边界由watermark 跟踪。最初加权部分是空的,但逐渐增长,最终消耗整个列表。

    random() 是一个返回 [0.0, 1.0) 中的随机数的函数。

    weight(x) 是一个从 [0.0, 1.0) 到 [0.0, 1.0) 的函数,它定义了所需的加权行为。

    weight() 的参数“r * n / watermark”用于规范化参数范围。对于某些加权函数的选择,可能不需要这种归一化。

    【讨论】:

    • atzz 我要试试你的算法,看看效果如何,谢谢!
    • @hippietrail - 不客气!请告诉我它是怎么做的,我也很感兴趣:)
    • 我担心的一件事是,如果列表变得庞大,我可能会在每次选择后使用大量 CPU 重新计算“断点”,而使用严格的 LRU 和权重作为这些断点在队列中的位置永远不会改变。
    • @hippietrail - 我认为这里最复杂的操作是列表修改,即 O(n)。但是也需要维护简单的 LRU,不是吗? “水印”只是一个简单的整数,它不应该影响任何东西。
    猜你喜欢
    • 1970-01-01
    • 2015-07-05
    • 2010-09-08
    • 1970-01-01
    • 2017-12-26
    • 2011-04-29
    • 1970-01-01
    相关资源
    最近更新 更多