1

我有一个概率算法的问题

目标是获得一个包含三个项目的列表。作为最终名单

有四个源列表。

ALIST、BLIST、CLIST、DLIST

都有未知长度。它们包含独特的元素

(其实程序一开始都是空的,从redis排序列表中获取。运行时,有增长)

从此源列表中选择项目。拾取随机项目以生成 FinalList

确保以下要求

在决赛名单中,

  • ALIST 的项目出现的概率是 43%
  • BLIST的物品出现的概率是37%
  • CLIST的物品出现的概率是19%
  • DLIST 的项目出现的概率是 1%

我写了一些代码,但这只是为了四个列表有很多元素。

from random import choice

final_list = []
slot = []

a_picked_times = 0

while a_picked_times < 43:
    item = choice(ALIST)
    ALIST.remove(item)

    if item in already_picked_list:
        continue

    slot.append(item)
    a_picked_times += 1


b_picked_times = 0

while b_picked_times < 37:
    ...

SOME CODE SIMILAR

# now slot is a list which contains 100 elements, 
# in slot, there are 43 elements of ALIST'items, 37 of B, 19 of C, 1 of D

for i in range(3):
    final_list.append( choice(slot) )

所以,这样可以保证概率要求。 但仅在条件下:这四个列表有很多元素。

list.remove(item) 不会删除列表中的所有元素,因此我们将根据需要的时间更正拾取项目。

当 A、B、C、D 为空或元素不足时,如何保证概率要求?

A、B、C、D 列表都是从 redis 排序列表中获取的。或者redis的一些解决方案?

4

3 回答 3

2

(对于每个元素)选择一个介于 1 和 100 之间的数字,然后根据该数字选择一个源列表可能更有意义。

于 2012-08-25T16:24:27.473 回答
1

据我了解,您正在生成随机大小的列表,然后您想以给定的概率选择 3。如果我的理解是正确的,那么你需要简单地在 [0,1] 上生成一个统一的变量random.uniform(0., 1.)

然后简单地将 0..1 区间划分为适当的长度:

import random

for i in range(3):
    r = random.uniform(0., 1.)
    if r < .43:
        final_list.append(random.choice(ALIST))
    elif r < .43 + .37:
        final_list.append(random.choice(BLIST))
    elif r < .43 + .37 + .19:
        final_list.append(random.choice(CLIST))
    else:
        final_list.append(random.choice(DLIST))

从列表中选择应该很容易,因为您只需选择一个索引。

请注意,这相当于 Ofir 的回答,但可能会或可能不会更吸引您。

于 2012-08-25T16:36:04.350 回答
0

因此,据我所知,您的代码正在删除 43 个 ALIST 元素、37 个 BLIST 元素等。

更好的解决方案是使用给定的概率来构造你的 final_list 。当您的其他列表为空时,这也会考虑在内。

ALIST_PROB = 0.43
BLIST_PROB = ALIST_PROB + 0.37
CLIST_PROB = BLIST_PROB + 0.19
DLIST_PROB = CLIST_PROV + 0.01

while len(final_list) < 3:

    #generate a random number
    rand = random.random()        

    if rand <= ALIST_PROB:
        element = getEl(ALIST)
    elif rand <= BLIST_PROB:
        element = getEl(BLIST)
    elif rand <= CLIST_PROB:
        element = getEl(CLIST)
    elif rand <= DLIST_PROB:
        element = getEl(DLIST)

    if not element == None:
        final_list.append(element)

def getEl(list):
    try:
        element = random.choice(list)
    except IndexError:
        element = None
    return element
于 2012-08-25T16:41:16.350 回答