我有一张如下表格:
Potion { id, name, freq }
我以'随机'的方式向用户赠送药水。但我希望能够控制随机性的频率,因为有些药剂比其他药剂更强大。最好的方法是什么?
我在考虑这样的事情:
id | name | freq
-------------------
1 | light | 5
2 | fire | 10
3 | water | 10
4 | earth | 10
5 | air | 5
光和空气比火,水和地球更强大,所以它们的频率更小。
sum = select sum(*) from potions;
x = random(1..sum)
table = select * from potions;
offset = 0
for each element in table
if offset + element[freq] > x
chosen = element[name]
end
offset += element[freq]
end
我认为上面的代码(ruby + sql)会起作用,但它不可扩展,我非常怀疑它是最有效的方法。有人可以帮我这么做吗?
提前谢谢你,
答案 0 :(得分:0)
我怀疑你需要更高效的东西。你想要扩展到什么?我会保持原样。干得好!
您可以使用存储子项总数的节点组织树结构中的元素。这将节省您迭代整个集合。但是这对此过度杀戮。
答案 1 :(得分:0)
首先需要在RAND()
之上创建一个视图,以便在执行期间为每次调用返回相同的值(否则会得到奇怪的结果):
create view constant_rand as select rand() as rand;
接下来选择一个由累积频率加权的随机行:
select id
from potion p1
join constant_rand
where rand * (select sum(freq) from potion) between
-- sum of freq below this row
ifnull((select sum(freq) from potion p2 where p2.id < p1.id), 0)
-- sum of freq below and including this row
and (select sum(freq) from potion p2 where p2.id <= p1.id);