我发现我的程序发生了一些奇怪的事情.
该程序主要用于组件点击,因为它是测试随机性的概念.

正如你所看到的,它正确打印,因为它应该倾向于向中间点击,这是完美的.
问题是,它似乎有偏见.
import java.applet.Applet;
import java.awt.Point;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.awt.*;
public class Testing extends Applet {
/**
*
*/
private static final long serialVersionUID = -2441995094105327849L;
public void init() {
setSize(WIDTH, HEIGHT);
img = createImage(WIDTH, HEIGHT);
g = img.getGraphics();
paint(g);
setVisible(true);
g.setColor(new Color(0, 0, 0));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(new Color(55, 55, 55, 55));
main();
}
public final static int WIDTH = 400, HEIGHT = 400;
public static int[] widths = new int[WIDTH], heights = new int[HEIGHT];
public static ArrayList<String> set = new ArrayList<String>();
public Image img;
public Graphics g;
public void paint(Graphics g) {
g.drawImage(img, 0, 0, null);
}
public void update(Graphics g) {
paint(g);
}
public void main() {
int count101 = 0;
int count100 = 0;
int count99 = 0;
try {
PrintWriter pw = new PrintWriter(new FileWriter(
new File("Data.dat")));
Point center = new Point(WIDTH / 2, HEIGHT / 2);
int runs = 10000000;
for (int i = 0; i < runs; i++) {
int x = center.x
- (int) ((Math.random() - Math.random())
* Math.random() * center.x);
int y = center.y
- (int) ((Math.random() - Math.random())
* Math.random() * center.y);
widths[x]++;
heights[y]++;
repaint();
g.fillRect(x, y, 1, 1);
if((x & y) == 101){
count101++;
}
if((x & y) == 100){
count100++;
}
if((x & y) == 99){
count99++;
}
}
System.out.println(count101);
System.out.println(count100);
System.out.println(count99);
repaint();
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
这会不断打印出有偏见的结果.
它打印以下内容:
3640
10918
3741
Run Code Online (Sandbox Code Playgroud)
这是相当偏颇,因为它遵循的大部分趋势,在与所有其他值线性增加,但是一旦达到100标记,则决定了它要投下炸弹,并挑选其6%以上,然后每隔.
有人知道任何理由吗?
哦,顺便说一句,我确实有一个txt文件,其中包含重复10,000,000次百分比等打印出来的所有结果,它很长,所以我不会发布,但我确实有信息.
Tom*_*icz 16
它既不是Java Math.rand()也不是伪随机生成问题.这导致了奇怪的(但预期的)行为:
Math.random() - Math.random()
Run Code Online (Sandbox Code Playgroud)
两个均匀分布的随机变量的和(和减法)不会导致均匀分布的变量.据我记得,他们导致三角分布:

请参阅:两个标准均匀变量的均值分布.
这就是你所看到的 - 二维随机变量与三角分布的完美例证.此外,如果您继续添加均匀分布的随机变量,您最终将获得正态分布.
要实现统一分配,您所要做的就是替换尴尬:
int x = center.x
- (int) ((Math.random() - Math.random())
* Math.random() * center.x);
Run Code Online (Sandbox Code Playgroud)
简单:
int x = (int) (Math.random() * center.x * 2);
Run Code Online (Sandbox Code Playgroud)
代码(不用乘法)产生与从可能值的随机变量0,以center.x * 2与预期值在center.x.到现在为止还挺好.但是分布是trangular,这意味着概率密度在该范围内不相等.
两个随机变量(其中一个不再均匀分布)的乘法具有更复杂的分布,但肯定不均匀.
后一个代码片段生成一个简单,均匀分布的变量,其概率密度函数在整个空间中相等.
在你的程序中,这是一个明显的数学错误,但伪随机生成器实际上可以在空间中生成"非随机"模式.看一下Strange Attractors和TCP/IP序列号分析,该文章中的图片:
3d空间http://lcamtuf.coredump.cx/oldtcp/tcpseq/data.jpg