我正在研究涉及模拟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);
}
}
}
答案 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中的原始值那样随机,但听起来纯粹的随机性并不是您正在寻找的。 p>
答案 6 :(得分:1)
“随机”并不意味着“均匀分布”。实际的随机序列实际上会偶尔出现类似数字的团块,或者重复相同的数字几次。如果你掷骰子三次,你不会连续三次连续滚动吗?
您真正希望分发看起来像什么?您可以使用进度序列并通过随机值修改序列返回的数字。通过这种方式,您可以获得具有一些随机干扰的整形结果。
答案 7 :(得分:0)