在Google上找不到这个,所以如果有人可以提供帮助。我有这样的字典:
{8: 0, 5: 0, 6: 1, 4: 2, 7: 3, 9: 2, 11: 1, 10: 3}
现在我需要随机地从这个dict中取出3个键,这也是一个棘手的部分,在这样做时要考虑它们的价值。具体地说,我希望分配给它们的值较低的键具有较大的随机优先级,所以简而言之,如果有3个值为0/1的键,则不要给我一个值为2/3的键。现在我知道我可以按值排序并取3个最低值,但这是可以预测的,所以我需要任何类型的随机函数,同时采用最低的随机函数。 我希望我有一些道理......任何想法? 提前谢谢!
答案 0 :(得分:1)
将Select k random elements from a list whose elements have weights与How can I make a random selection from an inversely-weighted list?结合并应用于您的词典:
import random
from operator import mul
class Node:
__slots__ = ['w', 'v', 'tw']
def __init__(self, w, v, tw):
self.w, self.v, self.tw = w, v, tw
def rws_heap(items):
h = [None]
for w, v in items:
h.append(Node(w, v, w))
for i in range(len(h) - 1, 1, -1):
h[i>>1].tw += h[i].tw
return h
def rws_heap_pop(h):
gas, i = h[1].tw * random.random(), 1
while gas > h[i].w:
gas -= h[i].w
i <<= 1
if gas > h[i].tw:
gas -= h[i].tw
i += 1
w, v = h[i].w, h[i].v
h[i].w = 0
while i:
h[i].tw -= w
i >>= 1
return v
def random_weighted_sample_no_replacement(items, n):
heap = rws_heap(items)
for i in range(n):
yield rws_heap_pop(heap)
def random_weighted_sample_no_replacements_inverse_weights(mapping, n):
keys, values = zip(*mapping.items())
total = reduce(mul, (v + 1 for v in values))
weights = (total / (v + 1) for v in values)
heap = rws_heap(zip(weights, keys))
for i in xrange(n):
yield rws_heap_pop(heap)
我稍微压缩Jason's Python implementation,并通过使用乘法将所有权重反转(将所有权重向上移动1以允许除法技巧)。
将此应用到您的词典:
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[9, 11, 8]
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[8, 6, 9]
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[4, 8, 5]
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[4, 10, 11]
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[4, 9, 10]
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[5, 10, 8]
>>> list(random_weighted_sample_no_replacements_inverse_weights(d, 3))
[6, 4, 5]
其中8
和5
的显示频率高于7
和11
。