Java中随机生成器的问题

时间:2010-12-03 21:58:01

标签: java random

我正在研究涉及模拟802.11 MAC协议的无线项目。 我在其中使用随机生成器。问题是我们变得蠕动而不是平滑的图形。我相信这个错误是因为随机生成器。为了测试我运行了以下代码,它生成0到19之间的100个随机数。如果仔细查看输出,有几个相同或非常接近的连续数字(例如17,15,16 ......或1,1) ,...)。它导致在我们的模拟中发生碰撞,并且相应的吞吐量在那时下降(即变得蠕动) 形状)。在这种情况下,增加模拟运行时间并没有多大帮助。

任何人都可以帮我弄清楚如何在Java循环中生成n个随机数,这些随机数是非常随机的(没有那种模式)?

这是要尝试的代码:

import java.util.Random;

public class RandomTest {

    public static void main(String[] args){

        int [] counter = new int [20];

        Random generator = new Random();
        int randomIndex = 0;

        for (int i=0; i<100; i++){

            randomIndex = generator.nextInt(20);
            counter[randomIndex]++;
            System.out.println(randomIndex);
        }
    }
}

8 个答案:

答案 0 :(得分:5)

随机并不是每次都不同。预计偶尔会出现重复或类似的值,尤其是当您从这么小的范围内选择数字时(20个值)。

如果您确实希望每个号码与前面的号码不同,那么您必须自己编程。最简单的方法之一(但不是最有效)是拒绝一个在前一个随机数的距离x内的随机数并选择另一个数字 - 重复直到得到一个你满意的数字。

答案 1 :(得分:4)

避免重复的最简单方法是使用Collections.shuffle()。

List<Integer> ints = new ArrayList<Integer>();
for(int i=0;i<20;i++) ints.add(i);
Collections.shuffle(ints);

同样,如果您希望值0到19恰好每次出现5次。

for(int i=0;i<100;i++) ints.add(i/5);

答案 2 :(得分:2)

你的算法对我来说有点奇怪。你创建20 int然后增加一个随机选择的,并重复100次?你为什么不这样做:

public static int[] randomNumbers(int n, int max) {
    Random r = new Random();
    int[] rndNums = new int[n];
    for (int i = 0; i < n; i++)
        rndNums[i] = r.nextInt(max);
    return rndNums;
}

这是一种避免重复的方法......(对于n很大且接近最大值的情况,有更有效的解决方案)

public static int[] randomNumbers(int n, int max) {
    Random r = new Random();
    Set<Integer> taken = new HashSet<Integer>();
    int[] arr = new int[n];
    for (int rnd, i = 0; i < n; i++) {
        while (!taken.add(rnd = r.nextInt(max)));
        arr[i] = rnd;
    }

    return arr;
}

另请注意,Random提供的数字是伪随机数。查看True random generation in Java的“真实”随机性。

答案 3 :(得分:2)

我不知道你的结果是否正常。但如果您对java.util.Random不满意,请查看java.security.SecureRandom

答案 4 :(得分:1)

无法保证一系列随机数不会重复;事实上,对于你正在使用的小范围,它很可能......真正的问题(和数学家有其他人):值是否均匀分布在一个长序列中?

答案 5 :(得分:1)

在0到19范围内的100个样本几乎肯定会获得一些连续的值重复或接近重复。如果你想要的数字都至少相差K,你可以试试这样的

randomIndex = (randomIndex + k + generator.nextInt(20 -2*k) % 20;

范围内的-2 * k是为了防止增加的随机量从“环绕”到当前值的k个单位内。

请注意,严格来说,这样获得的值并不像rng中的原始值那样随机,但听起来纯粹的随机性并不是您正在寻找的。

答案 6 :(得分:1)

“随机”并不意味着“均匀分布”。实际的随机序列实际上会偶尔出现类似数字的团块,或者重复相同的数字几次。如果你掷骰子三次,你不会连续三次连续滚动吗?

您真正希望分发看起来像什么?您可以使用进度序列并通过随机值修改序列返回的数字。通过这种方式,您可以获得具有一些随机干扰的整形结果。

答案 7 :(得分:0)