我有一份约。 10000件物品。目前的情况是每个项目都有相关的权重(优先级或重要性)。现在最小的权重是-100
(可以删除负值和零值),最高权重是1500
。体重由人们的直觉决定(人们如何认为该项目对社区很重要)。因为要确定最重要的项目并不容易,所以我想使用一些随机因素,这样重量较轻的物品选择的机会就会减少,而且将来会调整它们的重量(常识和随机性)。
您知道如何编写函数getItem
吗?
def getItem(dict):
# this function should return random item from
# the dictionary of item-weight pairs (or list of tuples)
# Normally I would return only random item from the dictionary,
# but now I'd like to have this: The item with weight 1500 should
# have much more chance to be returned than the item with weight 10.
# What's my idea is to sum up the weights of all items and then compute
# some ratios. But maybe you have better idea.
return randomItem
谢谢
答案 0 :(得分:13)
看看这个,我认为你需要的是不同方法之间的一些比较Weighted random generation in Python
建议的最简单的方法是:
import random
def weighted_choice(weights):
totals = []
running_total = 0
for w in weights:
running_total += w
totals.append(running_total)
rnd = random.random() * running_total
for i, total in enumerate(totals):
if rnd < total:
return i
您可以在上面的链接中找到更多详细信息和可能的改进以及一些不同的方法。
答案 1 :(得分:6)
Python 3.6引入了random.choices()
def get_item(items, items_weights):
return random.choices(items, weights=items_weights)[0]
答案 2 :(得分:3)
您应该在0和权重之和(按定义为正)之间提取一个随机数。然后使用bisect:http://docs.python.org/library/bisect.html(bisect标准模块)从列表中获取项目。
import random
import bisect
weight = {'a':0.3,'b':3.2,'c':2.4}
items = weight.keys()
mysum = 0
breakpoints = []
for i in items:
mysum += weight[i]
breakpoints.append(mysum)
def getitem(breakpoints,items):
score = random.random() * breakpoints[-1]
i = bisect.bisect(breakpoints, score)
return items[i]
print getitem(breakpoints,items)
答案 3 :(得分:2)
如果权重不是负数,则更容易。如果你必须有负重,你必须用尽可能低的重量来抵消重量。在您的情况下,offsetted_weight = itemweight + 100
在伪代码中,它是这样的:
Calculate the sum of all the weights.
Do a random from 0 to the sum of the weights
Set i to 0
While the random number > 0
Subtract the weight of the item at index i from random
If the random number is < 0 return item[i]
Add 1 to i
答案 4 :(得分:-2)
如果要将数据存储在数据库中,可以使用SQL:
SELECT * FROM table ORDER BY weight*random() DESC LIMIT 1