Java 实现大整数排列组合,解决抽卡欧气计算问题

白送的10连,抽爆,抽完攀比思想冒头,循环乘嘛,实现一个!(其实是不想在 WolframAlpha(一个付费在线数学计算应用)里输长长一串)

#

#背景

最近玩的某游戏开了新卡池,抽了8个10连共计80次,
出了4个稀有度最高的角色,
我突发奇想想算算我这个爆率算什么水平,
程序模拟一下,顺便复习排列组合。

#程序设计

Java 标准类库中,没有排列组合甚至阶乘的现成方法, 搜了一下
但为了这个引入一个第三方库又未免太麻烦,于是自己来实现。

实现第一想到的是 int 和 long 两个基本类型,但想了想发现有坑 :int 最多12!,long 最多到20!
这可不行,我这都80抽了。
于是换 Java 的 BigDecimal 类(大整数)。

问题换算成伪代码是这样:
res=0
res += c(n, i) * 爆率^i * (1 - a)^(n-i) (i=a~b,i为整数)

#代码


import java.math.BigDecimal;

public class factorial {

	public static void main(String[] args) {

		// 出货率2.5%
		double a = 0.025d;
		int n = 80;
		// result
		double res = 0;
		double res2 = 0;

		for (int i = 0; i < 5; i++) {
			res2 += c(n, i).longValue() * Math.pow(a, i) * Math.pow(1 - a, n - i);
		}
		System.out.println("0~4: " + res2);

		for (int i = 4; i < n + 1; i++) {
			res += c(n, i).longValue() * Math.pow(a, i) * Math.pow(1 - a, n - i);
		}
		System.out.println("4~80: " + res);
	}

	// n!
	public static BigDecimal n(int n) {
		if (n == 0)
			return new BigDecimal(0);

		BigDecimal result = new BigDecimal(1);
		BigDecimal a;
		for (int i = 2; i < n + 1; i++) {
			a = new BigDecimal(i);
			result = result.multiply(a);
		}
		return result;
	}

	// n!/m!
	public static BigDecimal n2m(int n, int m) {

		BigDecimal result = new BigDecimal(n);
		BigDecimal a;
		for (int i = n - 1; i > m; i--) {
			a = new BigDecimal(i);
			result = result.multiply(a);
		}
		return result;
	}

	// n!/(n-m)! === a(n,m)
	public static BigDecimal a(int n, int m) {
		if (m == 0)
			return new BigDecimal(1);

		BigDecimal result = new BigDecimal(n);
		BigDecimal a;
		for (int i = n - 1; i > n - m; i--) {
			a = new BigDecimal(i);
			result = result.multiply(a);
		}
		return result;
	}

	// c(n,m) === a(n,m)/(m)!
	public static BigDecimal c(int n, int m) {
		if (m == 0)
			return new BigDecimal(1);
		if (m == n)
			return new BigDecimal(1);

		// 优化计算,避免大除大
		if (m > n / 2)
			return n2m(n, m).divide(n(n - m));
		else
			return a(n, m).divide(n(m));
	}

}

#结果&结论

  • 0~4: 0.8176930694561881
  • 4~80: 0.14056818112756556

抽80次,出0~4次货的概率 高达94.9%、
出4次及以上的概率为 14%,其中出4次占9%
这样一看我还行,乐上加乐,没钱人的开心就是这么简单。

updatedupdated2023-08-082023-08-08