如何制作一个唯一的随机数生成器



这段代码显然是一个随机数生成器,但是我如何以最简单的方式让它是唯一的呢?

import java.util.Random;

public class Scramble {
public static void main(String[] args) {
            for (int i=0; i < 10; i++)
            {
            Random randomGenerator = new Random();
            int n = randomGenerator.nextInt(10);
            System.out.println("Random number is " +n);
            }
      }
}

对于这少量可能的值:

  1. 生成所有可能值的列表
  2. 随机播放
  3. 返回每个步骤中的下一项

最大长度 LFSR(例如 PRBS 序列)是否合适?

例如,PRBS31 序列 (x31+x28+1) 保证在一个周期(2 31-1 位长)中仅生成一次每个31 位整数(0 除外)。

它也相当容易实现:

public int prbs31(int state) {
    int feedback = ((state >> 30) ^ (state >> 27)) & 1;
    return ((state << 1) | feedback) & 0xffffffff;
}

你从某个(非零!)整数开始,然后依次调用prbs31 - 将上一个结果传递回去。(这是一个反馈寄存器!

PRBS31 生成非常好的统计随机位模式(不要与真正的随机位模式混淆)

但是,请记住,相邻值将非常相似 - 上面建议的方法在PRBS序列上执行一位滑动窗口,这意味着每个相邻值都有30位共同点(尽管在不同的地方)

但是我们可以每次将寄存器提前 31 步,如下所示:

// initial seed, doesn't really matter which value you use
// as long as it's not zero (remember that the sequence goes over
// all the possible 31-bits values anyway)
private static final int SEED = 0x55555555;
private int state = SEED;
public int nextInt() throws SequenceCycleException {
    for (int i = 0; i < 31; ++i) {
        state = prbs31(state);
        if (state == SEED) {
            throw new SequenceCycleException();
        }
    }
    return state;
}

这将生成一个看似随机的整数序列,长度为 (2 31-1)/31

免责声明:单个LFSR的天真使用是高度可预测的。在这种情况下,知道一个值可以了解所有未来的值 - 这使得这种方法适用于模拟(例如游戏),但对于具有加密或秘密意义的任何东西也非常糟糕!

就个人而言,我使用此方法为在哈希表中用作键的对象生成唯一 ID。

最简单的方法是使用时钟算术。如果您添加一个不是 10 因数的数字,例如素数(并且差值也不是因数),您将在随机游走中获得每个可能的值。它不是很随机,但非常简单。

例如,假设您为 10 个值选择 3。

3, 6, 9, 2, 5, 8, 1, 4, 7, 0

您可以生成一个随机数,将其存储在 Array/HashMap/Whatever 中并返回。然后,您只需每次检查新号码是否已经在您保存的旧号码中。效率不是很高,但很容易。

这是随机数(整数)生成的代码示例。我们知道Math.random()总是返回双精度类型值。所以,我把它转换成int。

class RNumber{
    public static void main(String str[]){
        int countNum=100;   
        for(int i=0;i<countNum;i++){
            System.out.println("Random Unique values="+(int)(Math.random()*100));
        }
    }
}

希望它能帮助你。

相关内容

最新更新