Fans实验室2:1亿次随机生成大乐透是否会中奖
1. 实验背景
最近好奇大乐透中奖概率,所以用C++写了一个程序模拟随机选号过程。程序会随机生成大乐透号码(前区5个1-35的数字,后区2个1-12的数字),并与目标号码(2023年7月14日开奖号码:前区02,14,32,34,35,后区05,11)进行对比,看看需要多少次才能"中奖"。
2. 关键技术点
2.1 CPU绑定
在多核系统中,为了获得稳定的性能,我们通常需要将程序绑定到特定的CPU核心上运行。这可以避免进程在不同核心之间切换带来的性能损耗。- void pin_thread_to_cpu(int cpu_id) {
- cpu_set_t cpuset;
- CPU_ZERO(&cpuset); // 清空CPU集合
- CPU_SET(cpu_id, &cpuset); // 设置要使用的CPU
- pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); // 绑定线程到指定CPU
- }
复制代码 函数说明:
- cpu_set_t:表示CPU集合的数据类型
- CPU_ZERO:初始化CPU集合,将所有位置零
- CPU_SET:将指定的CPU添加到集合中
- pthread_setaffinity_np:将当前线程绑定到指定的CPU集合
2.2 随机数生成
使用C++11引入的随机数生成器,比传统的rand()函数具有更好的随机性:- std::random_device rd; // 硬件随机数生成器
- std::mt19937 gen(rd()); // Mersenne Twister伪随机数生成器
- std::uniform_int_distribution<> dis_front(1, 35); // 前区分布
- std::uniform_int_distribution<> dis_back(1, 12); // 后区分布
复制代码 2.3 性能统计
使用chrono库进行时间统计,计算程序执行速度:- auto start_time = std::chrono::high_resolution_clock::now();
- // ...执行代码...
- auto current_time = std::chrono::high_resolution_clock::now();
- auto duration = std::chrono::duration_cast<std::chrono::seconds>(current_time - start_time).count();
复制代码 3. 实验结果
- ➜ build ./lottery_simulator 100000000
- 尝试次数: 100000 / 100000000, 已用时间: 0 秒, 速度: 100000 次/秒
- 尝试次数: 200000 / 100000000, 已用时间: 0 秒, 速度: 200000 次/秒
- 尝试次数: 300000 / 100000000, 已用时间: 0 秒, 速度: 300000 次/秒
- 尝试次数: 400000 / 100000000, 已用时间: 0 秒, 速度: 400000 次/秒
- 尝试次数: 500000 / 100000000, 已用时间: 0 秒, 速度: 500000 次/秒
- 尝试次数: 600000 / 100000000, 已用时间: 0 秒, 速度: 600000 次/秒
- 尝试次数: 700000 / 100000000, 已用时间: 0 秒, 速度: 700000 次/秒
- 尝试次数: 800000 / 100000000, 已用时间: 0 秒, 速度: 800000 次/秒
- 尝试次数: 900000 / 100000000, 已用时间: 0 秒, 速度: 900000 次/秒
- ......
- 尝试次数: 28900000 / 100000000, 已用时间: 28 秒, 速度: 1032142 次/秒
- 尝试次数: 29000000 / 100000000, 已用时间: 28 秒, 速度: 1035714 次/秒
- 尝试次数: 29100000 / 100000000, 已用时间: 28 秒, 速度: 1039285 次/秒
- 经过 29163768 次尝试后匹配成功!
- 生成的前区号码: 2 14 32 34 35
- 生成的后区号码: 5 11
复制代码 4. 结论
通过这个实验,我们可以直观地感受到大乐透一等奖的中奖难度 差不多和真实中奖差不多
5. 完整代码
[code]#include #include #include #include #include #include #include #include // 将线程绑定到指定CPU核心void pin_thread_to_cpu(int cpu_id) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(cpu_id, &cpuset); pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);}// 比较两个向量是否相等bool compare_vectors(const std::vector& v1, const std::vector& v2) { if (v1.size() != v2.size()) return false; return std::equal(v1.begin(), v1.end(), v2.begin());}void print_usage() { std::cout |