记录一下最近的数学作业:
超几何分布定义:
代码实现:
因为是离散型随机变量,所以顺次计算出每种情况的概率,再随机生成10000个0-1之间的随机数(用于模拟概率),然后用这些生成的概率去比对他们应该落入的区间,最后逐个累加,统计频率,然后用频率/10000去计算概率,最后绘制2条曲线,1条是理论,1条是模拟。
package test;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import java.awt.*;
import java.text.DecimalFormat;
import java.util.Scanner;
public class Cjhfb {
private static double[] rn;//随机数
private int n;//摸球总数
private int m;//黑色球总数
private int z;//球的总数
public Cjhfb() {
this.rn = randomNum();
}
//求概率 返回数组
public double[] Probability() {
double[] prob = new double[10000];
for (int i = 0; i <= n; i++) {
double temp = (double) (combination(i, m)) * (double) (combination(n - i, z - m)) /
(double) (combination(n, z));
String result = String.format("%.6f", temp);
prob[i] = Double.parseDouble(result);
}
return prob;
}
//计算累计概率
public double[] cumulativeProbability() {
double[] probability = Probability();
double[] cumulativeprobability = new double[10000];
int k = 0;
for (int i = 0; i <= n; i++) {
double temp = 0;
for (int j = 0; j <= i; j++) {
temp += probability[j];
}
cumulativeprobability[k++] = temp;
}
return cumulativeprobability;
}
//计算频率
public int[] frequency() {
int[] freq = new int[n + 1];
for (int i = 0; i < n + 1; i++) {
freq[i] = 0; //初始化数组为0
}
double[] rnum = randomNum();
double[] cpro = cumulativeProbability();
for (int i = 0; i < 10000; i++) {
for (int j = 0; j < n + 1; j++) {
if (rnum[i] < cpro[j]) {
freq[j]++;
break;
}
}
}
return freq;
}
//计算生成的频率对应的概率
public double[] frequencyProbability() {
double frequencyprobability[] = new double[n + 1];
int[] freq = frequency();
for (int i = 0; i < n + 1; i++) {
frequencyprobability[i] = (double) freq[i] / 10000;
}
return frequencyprobability;
}
//求期望
public double expectation() {
return (double) n * (double) m / (double) z;
}
//求方差
public double variance() {
double n1 = (double) n;
double m1 = (double) m;
double z1 = (double) z;
return (n1 * m1 * (z1 - m1) * (z1 - n1)) / (z1 * z1 * (z1 - 1));
}
//生成随机数
public static double[] randomNum() {
double[] rn = new double[10000];
for (int i = 0; i < 10000; i++) {
double a = Math.random();
DecimalFormat two = new DecimalFormat("#.000000");//"0.00"
String str = two.format(a);
rn[i] = Double.parseDouble(str);
}
return rn;
}
//求阶乘
public static long factorial(int x) {
long sum = 1;
while (x > 0) {
sum = sum * x--;
}
return sum;
}
//求组合
public static long combination(int m, int n) {
if (m > n)
return 0;
if (m == n || m == 0) return 1;
if (m > n / 2) {
m = n - m;
}
return factorial(n) / (factorial(m) * factorial(n - m));
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入样本总数N");
Cjhfb cjhfb = new Cjhfb();
cjhfb.z = input.nextInt();
System.out.println("请输入指定样本数量M");
int x0 = input.nextInt();
cjhfb.m = x0;
System.out.println("请输入抽样个数n");
int x = input.nextInt();
cjhfb.n = x;
if (x0 < x) x = x0;
System.out.println("---------------------期望-------------------------");
System.out.println(cjhfb.expectation());
System.out.println("---------------------方差-------------------------");
System.out.println(cjhfb.variance());
System.out.println("---------------------概率-------------------------");
double[] probs = cjhfb.Probability();
for (int i = 0; i <= x; i++) {
System.out.println("X="+i+": "+probs[i]);
}
System.out.println("--------------------累计概率----------------------");
double[] cumulativeProbability = cjhfb.cumulativeProbability();
for (int i = 0; i <= x; i++) {
System.out.println(cumulativeProbability[i]);
}
System.out.println("----------------------频率------------------------");
int[] freq = cjhfb.frequency();
for (int i = 0; i <= x; i++) {
System.out.println("X="+i+":的频率:"+freq[i]+" 对应的概率:"+cjhfb.frequencyProbability()[i]);
}
DefaultCategoryDataset dataset = new DefaultCategoryDataset();//创建数据集对象
for (int i = 0; i <= x; i++) {
dataset.addValue(probs[i],""+i,""+i);//数据值,X轴,Y轴
}
JFreeChart mchart = ChartFactory.createBarChart(
"bar chart",
"X",//横坐标1
"probability", //纵坐标
dataset,//数据集
PlotOrientation.VERTICAL,
true,//显示图例
true,//采用标准生成器
false//是否生成超链接
);
CategoryPlot mplot = (CategoryPlot) mchart.getPlot();
mplot.setBackgroundPaint(Color.lightGray);
mplot.setRangeGridlinePaint(Color.orange);//背景底部横虚线
mplot.setOutlinePaint(Color.green);//边界线
ChartFrame mchartframe = new ChartFrame("超几何分布", mchart);
mchartframe.pack();
mchartframe.setVisible(true);
}
}