首页 > 解决方案 > 从整数列表中随机选择与其大小成正比的数字

问题描述

从给定的 n 个元素数组中随机选择一个数字,其概率与其大小成正比。考虑一个实验,从列表 A 中随机选择一个元素,其概率与其大小成正比。假设我们在替换的情况下进行 100 次相同的实验,在每个实验中,您将打印一个从 A 中随机选择的数字。

例 1:A = [0 5 27 6 13 28 100 45 10 79] 令 f(x) 表示 x 在 100 次实验中被选中的次数。f(100) > f(79) > f(45) > f(28) > f(27) > f(13) > f(10) > f(6) > f(5) > f(0)

def pick_a_number_from_list(A):
    sum=0
    cum_sum=[]
    for i in range(len(A)):
        sum = sum + A[i]
        cum_sum.append(sum)
    #print(cum_sum)           
    r = random.uniform(0,sum)
    number=0
    for index,i in enumerate(cum_sum):
        if(r>=cum_sum[index] and r<cum_sum[index+1]):
            return A[index]
    return number

def sampling_based_on_magnitued():
    A = [0,5,27,6,13,28,100,45,10,79]
    for i in range(1,100):
        number = pick_a_number_from_list(A)
        print(number)

sampling_based_on_magnitued()

我已经编写了上面的代码,但没有得到正确的输出。

标签: pythonrandom

解决方案


这是你犯的逻辑错误。当您检查范围 r>=cum_sum[index] and r<cum_sum[index+1]时,您实际上是在使用数字A[index+1]而不是A[index]

import random

def pick_a_number_from_list(A):
    sum=0
    cum_sum=[]
    for i in range(len(A)):
        sum = sum + A[i]
        cum_sum.append(sum)
    #print(cum_sum) 
    r = int(random.uniform(0,sum))
    print(r)
    number=0
    for index in range(len(cum_sum)):
        if(r>=cum_sum[index] and r<cum_sum[index+1]):
            return A[index+1]
    return number

def sampling_based_on_magnitued():
    A = [0,5,27,6,13,28,100,45,10,79]
    a = dict()
    #A.sort()
    print(A,sum(A))
    for i in range(1,100):
        number = pick_a_number_from_list(A)
        #print(number)
        if number not in a:
            a[number] = 1
        else:
            a[number]+=1
    print(a)

sampling_based_on_magnitued()

这是我在机器上得到的最终选择频率

{100: 35, 5: 1, 45: 15, 79: 20, 28: 8, 13: 8, 6: 2, 27: 9, 10: 1}

推荐阅读