Java 双色球随机模拟实现

双色球规则:从 133 中选 6 个不重复的红球,再从 116 中选 1 个蓝球。下面的代码模拟大量随机"开奖",统计每个红球位置和蓝球出现次数最多的号码:

 1import java.util.ArrayList;
 2import java.util.Arrays;
 3import java.util.List;
 4import java.util.Random;
 5
 6public class Ball {
 7
 8    public static void main(String[] args) {
 9        System.out.println(ball(5000000));
10    }
11
12    public static List<String> ball(int length) {
13        int[][] red = new int[6][34];   // red[位置][号码],位置按红球升序
14        int[] blue = new int[17];
15        Random r = new Random();
16        int[] pool = new int[33];       // 1~33,部分洗牌取前 6 个,只需初始化一次
17        for (int i = 0; i < 33; i++) pool[i] = i + 1;
18
19        for (int n = 0; n < length; n++) {
20            for (int p = 0; p < 6; p++) {
21                int j = p + r.nextInt(33 - p);          // 部分 Fisher-Yates:抽出 6 个不重复红球
22                int t = pool[p]; pool[p] = pool[j]; pool[j] = t;
23            }
24            Arrays.sort(pool, 0, 6);                    // 按升序对齐真实开奖的呈现方式
25            for (int p = 0; p < 6; p++) red[p][pool[p]]++;
26            blue[r.nextInt(16) + 1]++;
27        }
28
29        List<String> result = new ArrayList<>();
30        for (int[] pos : red) result.add(String.valueOf(maxIndex(pos)));
31        result.add(String.valueOf(maxIndex(blue)));
32        return result;
33    }
34
35    private static int maxIndex(int[] counts) {
36        int idx = 1;
37        for (int i = 2; i < counts.length; i++) {
38            if (counts[i] > counts[idx]) idx = i;
39        }
40        return idx;
41    }
42}

实现要点:

  • 红球不重复抽取用部分 Fisher-Yates 洗牌:每轮只洗前 6 个位置,开销远小于整池 Collections.shuffle
  • pool 只初始化一次,循环内复用。
  • maxIndex 统计每个位置出现次数最多的号码,作为模拟结果返回。

注意:每注号码概率相同,模拟结果只是数学上的频率统计,不构成任何"选号依据"。