有效:固定范围内的随机数,无需重复

时间:2011-03-27 16:31:00

标签: oop random performance

嘿伙计们,我知道随机数有一百万个问题,但正是因为我搜索了很多,但我找不到类似于我的东西 - 没有暗示它不在那里。在任何情况下,请原谅我,如果我重复一个问题,请指出我,如果是这样的话。

所以,我想以最有效的方式做一些简单的事情。

我想逐个N范围内随机生成所有[0, N]个整数,这样就不会重复。

我知道,我可以通过在list中插入所有内容,对其进行随机播放,获取头部然后从列表中删除头部来实现此目的。但是,我将把我的长度列表NN-1次洗牌。

有更好/更快的想法吗?

2 个答案:

答案 0 :(得分:6)

你可以只进行一次随机播放,然后单步执行列表。

我建议使用Fisher-Yates shuffle

答案 1 :(得分:0)

这个问题已被问过几次,并且在每种情况下给出的正确答案是改组数组(原始数组或索引数组),但是在这种情况下,这不是一个令人满意的答案。可能的指数数量过大(无论是巨大的,还是记忆力都很紧张,或者你只是因为某种原因而渴望最高效率)。

因此,为了完整起见,我想添加一个替代方案。现在,这不是真正的随机,所以如果你需要的话,那么不要使用这个,但是,如果你的目标只是"足够好"在内存需求最小的情况下,可能会对以下伪代码感兴趣:

function init:
    start = random [0, length)      // Pick a fully random starting index
    stride = random [1, length - 1) // Pick a random step size
    next_index = start

function advance_next_index:
    next_index = (next_index + stride) % length
    if next_index is equal to start then
        start = (start + 1) % length
        next_index = start

以下是如何实现抓取伪随机值的可重用函数的示例:

counter = length
function pseudo_random:
    counter = counter + 1
    if counter is equal to length then
        init()
        counter = 0
    advance_next_index()
    return next_index

很简单pseudo_randominit次迭代会调用length一次,从而重新随机播放"随机" advance_next_index生成的结果模式,并确保每个length值都没有一个重复。

重申;这不是一个特别随机的算法,因此必须才能用于需要真正随机性的情况。但是,对于一些基本的,非关键的任务,结果是随机的,并且它具有很小的内存占用。例如,如果你只是想在游戏中随机化某些行为以避免某些事情变得重复,或者数据集很大并且从未暴露给用户(在这种情况下它实际上是随机的)它需要很长时间拼凑订单并以某种方式利用它。

如果有人知道任何具有相似属性的更好算法,请分享!