0

可能重复:
random.choice 的加权版本

为简单起见,假设一个函数接受 4 个输入:2 个名称及其各自的“偏差/权重”,我如何编写一个函数,使其返回ab随机返回,但仍将这些权重视为随机结果。

a = 'x'
b = 'y'
p_a = 10
p_b = 90

def myRand(a, p_a, b, p_b):
    return 'x' 10% of the time, 'y' 90% of time

到目前为止我所做的

import random

def myRand(a, p_a, b, p_b):
    probs = [a]*p_a + [b]*p_b
    return random.choice(probs)

有人可以指出为什么这是不正确或不是最佳答案吗?我的理由是我假设每个元素都有相同的被选中的概率,所以结果应该仍然有利于 10:90。或者也许我们可以在使用之前对数组进行洗牌random.choice()

有一个更好的方法吗?也许我在这里遗漏了一些明显的东西,或者这是正确的吗?

谢谢

4

3 回答 3

1

这将完成你想要做的事情:

#assumes p_a and p_b are both positive numbers that sum to 100
def myRand(a, p_a, b, p_b):
   return a if random.uniform(0,100) < p_a else b 

请注意,在只有 2 个权重的特殊情况下, p_b 变得不必要,因为p_b == 100-p_a.

于 2012-08-23T17:15:32.640 回答
1

我已经修改了函数以接受任意数量的输入和加权概率,所以如果稍后您决定要使用两个以上的输入,您可以。

import random

def myRand(i, w):
    r = random.uniform(0, sum(w))

    # loop through a list of inputs and max cutoff values, returning
    # the first value for which the random num r is less than the cutoff value
    for n,v in map(None, i,[sum(w[:x+1]) for x in range(len(w))]):
        if r < v:
            return n

示例用法:

inputs = ['e', 'f', 'g', 'h']
weights = [10, 30, 50, 10]

print myRand(inputs, weights)
于 2012-08-23T18:42:38.393 回答
0

a = 'x';b = 'y';p_a = 10;p_b = 90

比率 = p_a+pb = 100

生成一个介于 0 到 100 之间的随机数,如果数字小于 10,则使用 a=>x 否则使用 b=>y

于 2012-08-23T17:16:24.870 回答