如何获得线性下降随机分布?

时间:2011-04-03 13:24:10

标签: python random

在django中我随机实现在主页上显示人物。 但现在我需要向人们展示他们的重要性(这是数字)。 例如: 名称| SORTKEY 约翰|五 汤姆| 8

John必须更频繁地线性展示。

person_number = random.randrange(Person.objects.count())
context = { 'person': Person.objects.all()[person_number], }

我尝试了random.expovariate但是第一个人太经常了。 那么我需要使用随机库中的哪个函数?

UPD: 基本上randrange(10)给出了[6,2,8,6,4,1,9,5,3,0,] 我需要算法给出一些东西[1,7,3,1,2,2,3,4,1,5,0] 1 - 最常见(3次),2次(2次)..等等。

1 个答案:

答案 0 :(得分:5)

我猜你的意思是加权随机选择。基本上你需要:

  1. 使用累计权重总和创建列表。
  2. 选择随机值[0,sum_of_weights-1]
  3. 找到随机值下降的索引。
  4. 在Python术语中,使用功能方法( ireduce = scanl = partial_sum = ...),它可能看起来:

    import operator
    import bisect
    import random
    
    def ireduce(f, state, it):
        """Accumulative reduce. ireduce(operator.sum, 0, [1, 2, 3, 4]) -> 1, 3, 6, 10."""
        for x in it:
            state = f(state, x)
            yield state
    
    people = [
      {"name": "Iain David", "weight": 1}, 
      {"name": "John Martyn", "weight": 2},
    ]
    weights = (person["weight"] for person in people)  
    accumulated_weights = list(ireduce(operator.add, 0, weights))
    random_value = random.randrange(accumulated_weights[-1])
    index = bisect.bisect_right(accumulated_weights, random_value)
    random_person = people[index]["name"] 
    # "Iain David" (p=1/3), "John Martyn" (p=2/3)