数学#random是不是随机的?

5 java random math

我发现我的程序发生了一些奇怪的事情.

该程序主要用于组件点击,因为它是测试随机性的概念.

在此输入图像描述

正如你所看到的,它正确打印,因为它应该倾向于向中间点击,这是完美的.

问题是,它似乎有偏见.

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://lcamt​​uf.coredump.cx/oldtcp/tcpseq/data.jpg