游戏服务器算法-关于权重的随机抽取算法,抽一个次或抽多次的实现

本文深入探讨了基于权重的随机抽取算法,包括线性扫描、有序线性扫描、跳跃扫描、有序二分查找及别名采样等方法。针对单次与多次抽取场景,对比了不同算法的时间复杂度与优化策略,为游戏服务器开发中的奖励分配提供了实用指南。

    游戏服务器开发还真会常遇到,策划需求根据权重作概率发奖励,比如奖励和权重分别是:A10、B20、C70,这时候出现A的概率就要是10%,B就是20%,C是70%,就是出现的概率是当前权重 / 总权重。该怎么设计算法呢?抽多个奖励ID并且每个奖励ID只能出现一次时候改怎样实现呢?

单次抽取

方法一:普通的线性扫描

    通过总权重随机值,再线性扫描,通过权重随机值去查找所在的权重区间。

时间复杂度:O(N)

过程:

1、先计算出所有道具的权重总和S

2、然后调用随机函数得到一个区间在[1, S]的随机值N

3、扫描列表,如果N小于当前的权重,则返回当前道具

4、若N大于当前权重,则把N减去当前权重

# 测试数据 
# [(奖励ID: 权重)]
pool_data = [
    (1, 50),
    (2, 20),
    (3, 40),
    (4, 10),
]

def linear_random(pool_data):
    sum_weight = sum(a[1] for a in pool_data)
    n = random.randint(1, sum_weight)
    for key, weight in pool_data:
        if n <= weight:
            return key
        else:
            n -= weight

方法二:有序的线性扫描

    在方法一的基础上做优化,即权重大的(概率大的)排序在前面,即线性查找时先从概率大的开始查找,命中率会更高。

时间复杂度:O(N)

过程:

1、将奖池根据权重从大到小排序

2、方法同上


                
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值