目前,我使用随机数生成JPanel中的组件位置.我发现使用Random.nextInt(6000);返回太少的数字少于100,太多,我的意思是它们中的大多数都小于100.所以我调查了它,发现了一个更高质量的随机数发生器,Long所以我采用了自由地格式化它(参见下面的实现).之后我在1000-2000范围内获得了太多数字.
在使用计数器变量进行测试后,当我生成2000个数字时,其中大约1350个数字在该范围内.
我需要一个更随机的数字生成器,甚至是一个 真正随机的数字生成器(我不希望得到它,但如果我能得到它会很好).
随机类:
public class HighQualityRandom extends Random {
private static final long serialVersionUID = 1L;
private Lock l = new ReentrantLock();
private long u;
private long v = 4101842887655102017L;
private long w = 1;
public HighQualityRandom() {
this(System.nanoTime());
}
public HighQualityRandom(long seed) {
l.lock();
u = seed ^ v;
nextLong();
v = u;
nextLong();
w = v;
nextLong();
l.unlock();
}
public long nextLong() {
l.lock();
try {
u = u * 2862933555777941757L + 7046029254386353087L;
v ^= v >>> 17;
v ^= v << 31;
v ^= v >>> 8;
w = 4294957665L * (w & 0xffffffff) + (w >>> 32);
long x = u ^ (u << 21);
x ^= x >>> 35;
x ^= x << 4;
long ret = (x + v) ^ w;
return ret;
} finally {
l.unlock();
}
}
public int next(int bits) {
return (int) (nextLong() >>> (64-bits));
}
}
Run Code Online (Sandbox Code Playgroud)
执行:
public int getRandomX(){
HighQualityRandom ran = new HighQualityRandom();
int rand = (int) ran.nextLong();
String p = rand + "";
if(rand < 0){
rand = rand * -1;
}
p = rand + "";
p = p.substring(0, 4);
rand = Integer.parseInt(p);
while(rand > 6144){
rand = (int) ran.nextLong();
p = rand + "";
if(rand < 0){
rand = rand * -1;
}
p = rand + "";
p = p.substring(0,4);
rand = Integer.parseInt(p);
}
System.out.print("X is: " + rand + " Y is: ");
return rand;
}
public int getRandomY(){
HighQualityRandom ran = new HighQualityRandom();
int rand = (int) ran.nextLong();
String p = rand + "";
if(rand < 0){
rand = rand * -1;
}
p = rand + "";
p = p.substring(0, 4);
rand = Integer.parseInt(p);
while(rand > 4608){
rand = (int) ran.nextLong();
p = rand + "";
if(rand < 0){
rand = rand * -1;
}
p = rand + "";
p = p.substring(0,4);
rand = Integer.parseInt(p);
}
System.out.println(rand);
return rand;
}
Run Code Online (Sandbox Code Playgroud)
作为解释我正在做什么long来得到我的4位数字:
作为旁注,课堂上的seed参数是什么Random?我试过谷歌搜索,人们在谈论加密的东西......
编辑:
使用java.util.random()实现:
public int getRandomX(){
Random ran = new Random();
int rand = ran.nextInt(6144);
if(rand <= 100){
Game.between++;
}
return rand;
}
public int getRandomY(){
Random ran = new Random();
int rand = ran.nextInt(4608);
if(rand <= 100){
Game.between++;
}
System.out.println(Game.between);
return rand;
}
Run Code Online (Sandbox Code Playgroud)
平均而言,其中约37-40人不到100人(满分为1000人).所以我错了,绝对不是50%的人在盒子外面或外面.但是:出于28311552可能的解决方案(地图是6144x4608)可供选择,似乎太多而不能被卡在<100.
我不知道你在做什么,但这是一个小例子程序:
Random r = new Random();
int count = 0;
for (int i = 0; i < 1000_000; i++)
if (r.nextInt(6000) < 100)
count++;
System.out.println(count);
Run Code Online (Sandbox Code Playgroud)
召唤Random.nextInt(6000)一百万次.结果是:
16655
Run Code Online (Sandbox Code Playgroud)
在理想的情况下,它将是:100/5999 * 1000000 = 16669.我认为这非常接近.
你做错了什么.请发给您原始代码,证明Random.nextInt(6000)在超过50%的情况下,不到100.
为了在游戏中生成随机数,java.util.Random完全没问题.还有,java.security.SecureRandom但你不需要这个游戏,而且速度要慢得多.
编辑:
编辑:你总是在创建一个新Random实例!不要那样做.如果始终创建新Random实例但未指定种子值,则将根据计算机的当前时间对其进行播种.这本身会降低发电机的"随机性".
在我的示例中执行:创建一个Random实例,可选择将其播种到您想要的任何位置,并始终使用它!
编辑#2:
种子:它类似于随机数生成器的"状态".引用Random类javadoc:
如果使用相同的种子创建两个Random实例,并且对每个实例都进行相同的方法调用序列,则它们将生成并返回相同的数字序列.
实际上,如果要重现相同的序列,则只需设置种子.例如,您保存游戏/重播,并且您希望重新设置游戏.在这种情况下,您将保存起始种子以及游戏/重放,并且当再次玩游戏时,您将设置保存的种子,因此您将获得相同的随机序列.