洗牌算法
通过先打乱目标list的方式然后依次获取目标值
假设目标范围为1~30,随机抽取15个:
-- 初始化随机数生成器
math.randomseed(os.time())
-- 游戏参数
local board_size = 30 -- 样本大小
local target_size = 15 -- 目标数量
local board = {} -- 样本列表
local target = {} -- 目标列表
local wash_limit = 2 -- 用于控制洗牌次数(> 1 & < board_size)
-- 初始化样本
for i = 1, board_size do
board[i] = i
end
-- 洗牌算法
for i = board_size, wash_limit, -1 do
local j = math.random(i)
board[i], board[j] = board[j], board[i]
end
-- 获取目标列表
for i = 1, target_size do
table.insert(target , board[i])
end
优点: 可以通过控制wash_limit来调节洗牌的均匀性,适用于抽取目标 >= board_size / 2的情况
缺点: 对于大规模的数据集合,可能需要较长的时间来完成洗牌操作。所以对于目标数量较少的情况建议采取随机样本算法
随机样本算法
随机样本算法的基本思想是从数据集合中随机选择一定数量的样本,以便更好地代表整个数据集合。
假设目标范围为1~30,随机抽取10个:
-- 初始化随机数生成器
math.randomseed(os.time())
-- 游戏参数
local board_size = 30 -- 样本大小
local target_size = 10 -- 目标数量
local board = {} -- 样本列表
local target = {} -- 目标列表
-- 初始化样本
for i = 1, board_size do
board[i] = i
end
-- 随机抽样
for i = 1, target_size do
local index = math.random(i, board_size)
target[i] = board[index]
board[index] = board[i]
end
优点: 更适用于抽取目标 <= board_size / 2的情况
缺点: 因为random的次数与目标值正相关,所以对于目标数量占比较多的情况会random较多次。对于目标数量较多的情况建议采取洗牌算法
总结: 实际应用中可以结合上述2种算法实现