I have a problem of probability algorithm

The goal is obtain a list which contains three items. as the FinalList

There has Four source lists.

ALIST, BLIST, CLIST, DLIST

There are all Unknown length. They contains unique elements

( In fact, there are all empty at the program beginning, get from redis sorted list. when running, there growing )

Choose items form this source lists. pick up random items to generate the FinalList

Ensure The Following Requirements

In the FinalList,

• probability of ALIST's item appeared is 43%
• probability of BLIST's item appeared is 37%
• probability of CLIST's item appeared is 19%
• probability of DLIST's item appeared is 1%

I have written some code, but this just for the four lists are have a lots of elements.

``````from random import choice

final_list = []
slot = []

a_picked_times = 0

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

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) )
``````

So, this can ensure the probability requirements. BUT only under the condition: this Four lists have a lots of elements.

list.remove( item ) that will not remove all elements in list, so we will correct pick up items with the needs times.

when A, B, C, D empty OR not enough elements, How could ensure the probability requirements?

A, B, C, D list are all get from redis sorted list. Or some solution with redis ?

preguntado el 25 de agosto de 12 a las 17:08

## 3 Respuestas

It might make more sense to (for each element) pick a number between 1 and 100 and then select a source list based on that.

Respondido 25 ago 12, 17:08

As I understand it, you're generating lists of random sizes, then you want to choose 3 with the given probability. If my understanding is correct, then you need to simply generate a uniform variate on [0,1] with `random.uniform(0., 1.)`.

Then simply partition the 0..1 interval into the appropriate lengths:

``````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))
``````

Choosing from the lists should be easy, since you just pick an index.

Note that this is equivalent to Ofir's answer, but may or may not appeal to you more.

Respondido 25 ago 12, 17:08

Creo que quieres decir `random.choose`. Incidentally, if there were more than four lists, this could be done a bit more compactly using `numpy.cumsum` y `bisect` (though this solution is great as it is). - David Robinson

@DavidRobinson Right you are (actually random.choice), corrected. - Código de CodieMono

So from what I can gather, your code is removing exactly 43 ALIST elements, 37 BLIST elements, etc.

A better solution would be to construct your final_list by using the given probabilities. This will also take into account when your other lists are empty.

``````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
``````

Respondido 25 ago 12, 17:08

Thanks, this is almost meets my needs - Yueyoum

I wanna ensure the probability requirements even the source list are not enough elements. But, It seems that difficult, Or impossible - Yueyoum

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.