我正在开发一款游戏,在该游戏中,用户将获得随机奖励,并且每种奖励的分发机会均由“分享”系统加权。为了说明这个问题,让我们看一个例子:
比方说,我将给一个纯粹的随机奖励,但不合规定:[A,B,C]。就像获得随机索引并从数组中返回任何奖励一样简单。
但是,在我的用例中,奖励集是带有“份额”系统的权重。因此,我们遇到如下情况:
所以集合看起来像这样:[A,A,B,B,B,C,C,C,C,C]。
现在,我可以只是构建该数组并获得类似的随机结果,但是我担心性能的影响。这些奖励存储在数据库中(如果考虑到因素,则使用Django和PSQL作为后端),并且可能有100多个潜在奖励,每个奖励的权重为1-100(或更高)。
因此,我正在尝试找出一种有效的方法来根据这种权重获得随机奖励。
在撰写本文时,我想到了一件事(但我想听听其他想法):
我想我可能已经回答了我自己的问题,但希望能从第三方的角度来看。谢谢大家!
答案 0 :(得分:2)
您应该使用累积百分比。设置示例:
self.sql = '''SELECT EXISTS (SELECT 1 FROM Log WHERE Name=? AND
Password=?);'''
self.cur.execute(self.sql,self.log)
self.val = self.cur.fetchone()
if self.val[0]==1:
time.sleep(1)
print(f'\nLogged in as {self.user}\n')
所以表看起来像这样:
create table weights(label text, weight int, cumulative_percentage float);
insert into weights (label, weight) values
('A', 2),
('B', 3),
('C', 5);
update weights w
set cumulative_percentage = cumulative_sum::float/ total
from (
select
label,
sum(weight) over (order by label) as cumulative_sum,
sum(weight) over () as total
from weights
) s
where s.label = w.label;
使用公共表表达式在循环中获取单个随机数:
select *
from weights
label | weight | cumulative_percentage
-------+--------+-----------------------
A | 2 | 0.2
B | 3 | 0.5
C | 5 | 1
(3 rows)
或创建一个函数:
with seed(r) as (select random())
select min(label)
from weights, seed
where r <= cumulative_percentage
检查算法结果:
create or replace function get_percentageed_reward(r float)
returns text language sql as $$
select min(label)
from weights
where r <= cumulative_percentage
$$;