Algoritmo de probabilidad
Frecuentes
Visto 443 veces
1
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)
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) )
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 ?
3 Respuestas
2
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
1
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
0
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
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python algorithm redis or haz tu propia pregunta.
Creo que quieres decir
random.choose
. Incidentally, if there were more than four lists, this could be done a bit more compactly usingnumpy.cumsum
ybisect
(though this solution is great as it is). - David Robinson@DavidRobinson Right you are (actually random.choice), corrected. - Código de CodieMono