当前位置: 首页 > news >正文

C++生成随机数

一、传统方式:std::rand 和 std::srand

rand 

srand

在 C++ 标准库中,std::rand() 和 std::srand() 是较早的随机数生成方法,适用于简单的需求。需要注意的是,它们的随机数质量不高,且每次运行程序时,如果没有设置种子,生成的随机数序列是固定的。

使用方法:

/* rand example: guess the number */
#include <stdio.h>      /* printf, scanf, puts, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */int main ()
{int iSecret, iGuess;/* initialize random seed: */srand (time(NULL));/* generate secret number between 1 and 10: */iSecret = rand() % 10 + 1;do {printf ("Guess the number (1 to 10): ");scanf ("%d",&iGuess);if (iSecret<iGuess) puts ("The secret number is lower");else if (iSecret>iGuess) puts ("The secret number is higher");} while (iSecret!=iGuess);puts ("Congratulations!");return 0;
}
#include <iostream>
#include <cstdlib>
#include <ctime>int main() {// 设置随机数种子(使用当前时间作为种子)std::srand(static_cast<unsigned int>(std::time(0)));// 生成 0 到 99 之间的随机数int random_number = std::rand() % 100;std::cout << "Random number: " << random_number << std::endl;return 0;
}

优缺点:

  • 优点:简单,适合快速生成随机数。
  • 缺点:随机数的质量较低,容易受到周期限制,难以控制随机数的分布。

二、现代方式:<random> 库(推荐)

random文档

C++11 引入了 <random> 库,提供了比 rand() 更好的随机数生成机制,包括多种分布(均匀分布、正态分布、伯努利分布等)和更复杂的生成器。它的优点是可以生成高质量的随机数,并且能够控制随机数的分布。

所有类型

随机整数
随机浮点数
布尔值
字符
正态分布(高斯分布)
离散分布的随机数
随机字符串
UUID(通用唯一标识符)

1. 随机整数

生成随机数

int main()
{std::random_device rd;//打印结果是随机数std::cout << "Random value: " << rd() << std::endl;return 0;
}

std::random_device      

文档

std::uniform_int_distribution

std::uniform_int_distribution文档

使用 std::uniform_int_distribution 可以生成指定范围内的均匀分布的整数。

std::mt19937的文档 

 mt19937 - C++ Reference (cplusplus.com)

#include <iostream>
#include <random>int main() {std::random_device rd;   // 获取随机数种子std::mt19937 gen(rd());  // 梅森旋转算法生成随机数std::uniform_int_distribution<> dis(1, 100);  // [1, 100] 范围的整数int random_int = dis(gen);std::cout << "Random integer: " << random_int << std::endl;return 0;
}

random_int是1到100的随机数         

2. 随机浮点数

使用 std::uniform_real_distribution 可以生成指定范围内的均匀分布浮点数。

uniform_real_distribution 文档

#include <iostream>
#include <random>int main() {std::random_device rd;std::mt19937 gen(rd());std::uniform_real_distribution<> dis(0.0, 1.0);  // [0.0, 1.0] 范围的浮点数double random_float = dis(gen);std::cout << "Random floating-point number: " << random_float << std::endl;return 0;
}

3. 布尔值

布尔值可以通过生成随机的整数(0 或 1)来实现。

#include <iostream>
#include <random>int main() {std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> dis(0, 1);  // 生成 0 或 1bool random_bool = dis(gen);std::cout << "Random boolean value: " << (random_bool ? "true" : "false") << std::endl;return 0;
}

4. 字符

通过生成字符的 ASCII 码,再将其转换为字符类型。

#include <iostream>
#include <random>int main() {std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> dis('A', 'Z');  // [A, Z] 范围的字符char random_char = dis(gen);std::cout << "Random character: " << random_char << std::endl;return 0;
}

5. 正态分布(高斯分布)

std::normal_distribution 可以生成符合正态分布的随机数,适用于模拟许多自然现象。

#include <iostream>
#include <random>int main() {std::random_device rd;std::mt19937 gen(rd());std::normal_distribution<> dis(0.0, 1.0);  // 均值 0,标准差 1 的正态分布double random_normal = dis(gen);std::cout << "Random normal distributed number: " << random_normal << std::endl;return 0;
}

6. 离散分布的随机数

std::uniform_int_distribution 可以用于生成离散值的随机数。例如,模拟掷骰子时生成 1 到 6 之间的随机数。

#include <iostream>
#include <random>int main() {std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> dis(1, 6);  // [1, 6] 范围的整数int dice_roll = dis(gen);std::cout << "Dice roll: " << dice_roll << std::endl;return 0;
}

7. 随机字符串

通过生成一系列随机字符,可以构造一个随机字符串。

#include <iostream>
#include <random>
#include <string>int main() {std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> dis('A', 'Z');  // [A, Z] 范围的字符std::string random_string;for (int i = 0; i < 10; ++i) {random_string += dis(gen);}std::cout << "Random string: " << random_string << std::endl;return 0;
}

8. UUID(通用唯一标识符)

虽然 C++ 标准库没有直接支持生成 UUID,但可以使用一些第三方库(如 Boost 或 libuuid)来生成 UUID。

三、std::shuffle:用于打乱序列

std::shuffle 可以用来打乱容器中的元素,通常用于生成随机排列。

#include <iostream>
#include <vector>
#include <algorithm>
#include <random>int main() {std::vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};std::random_device rd;std::mt19937 gen(rd());std::shuffle(vec.begin(), vec.end(), gen);std::cout << "Shuffled vector: ";for (int num : vec) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

四、总结:选择合适的随机数生成方法

  • **std::rand()**:简单、快速,但质量较低。适用于简单的需求。
  • <random> 库:推荐使用现代的 <random> 库,它提供了更高质量的随机数,并支持多种分布。
  • 分布选择:根据需求选择合适的分布类型(均匀分布、正态分布等)。
  • 随机字符与字符串:通过生成字符的 ASCII 值来生成随机字符或字符串。
  • **std::shuffle**:用于打乱容器元素顺序,常用于生成随机排列。

通过 std::random,C++ 允许开发者根据需求灵活选择随机数生成方式,不仅提供了更高质量的随机数生成,还能更精细地控制生成数值的范围和分布。

在 C++ 中生成随机数是很多应用程序和算法中的重要组成部分。随机数的生成不仅是数学模型、模拟实验、加密技术等领域的核心需求,而且在游戏开发、数据分析、机器学习等多种场景中也有广泛的应用。生成随机数的质量直接影响到程序的准确性、可靠性以及安全性,因此理解其重要性和用途至关重要。

一、C++ 中随机数生成的重要性

1. 模拟与建模

在科学计算和工程中,随机数是很多模拟方法的基础,尤其是在 蒙特卡罗模拟(Monte Carlo Simulation)中,随机数用于通过随机抽样估算复杂问题的解。例如,模拟粒子运动、气候变化、金融市场等都依赖于高质量的随机数生成。

例子:
  • 天气预报:通过模拟不同天气条件下的气象模型,随机数帮助生成可能的天气情景。
  • 金融建模:用随机数生成可能的市场波动情况,从而预测风险。

2. 游戏开发

在游戏开发中,随机数用于生成不可预测的事件和行为,从而增强游戏的娱乐性和重玩性。例如,随机生成关卡、物品掉落、敌人行为等都是基于随机数的。

例子:
  • 随机敌人生成:在角色扮演游戏(RPG)中,敌人的生成是随机的,增加了游戏的挑战性。
  • 随机事件:在策略游戏中,随机事件(如自然灾害、市场波动等)常常改变游戏局势。

3. 密码学和安全性

在 密码学 中,随机数用于生成密钥、初始化向量(IV)、盐值等,以确保加密算法的安全性。加密系统的强度依赖于随机数的质量和不可预测性,因此,使用高质量的随机数是防止安全漏洞的关键。

例子:
  • 生成加密密钥:生成随机的密钥对,以确保加密的安全性。
  • 随机盐值:生成盐值(salt),防止密码破解时的预计算攻击(如字典攻击、暴力破解等)。

4. 机器学习与优化算法

在机器学习中,随机数用于初始化神经网络的权重、选择训练样本、进行随机梯度下降(SGD)等优化算法。随机化可以帮助跳出局部最优解,找到全局最优解。

例子:
  • 随机初始化神经网络权重:避免神经网络收敛到相同的局部最优解。
  • 数据增强:在图像处理任务中,随机旋转、平移、裁剪等操作增加数据多样性,提升模型的泛化能力。

5. 统计分析和实验设计

在统计学中,随机数广泛应用于 随机抽样、 实验设计 和 假设检验 等领域。随机数帮助生成代表性样本,从而推导出准确的统计结果。

例子:
  • 随机抽样:从一个大的数据集中随机选择子集进行分析,以推测总体的特征。
  • 假设检验:通过随机模拟实验来检验统计假设的有效性。

二、C++ 中随机数的用途

1. 生成随机整数

随机整数广泛用于游戏、模拟、加密、统计等多个领域。通过生成均匀分布的整数,可以模拟许多现实世界中的随机现象。

用途:
  • 骰子模拟:生成随机整数,模拟骰子的掷点。
  • 随机生成任务:在任务分配、队列管理等系统中,使用随机数生成任务顺序或队列顺序。

2. 生成随机浮点数

随机浮点数通常用于模拟概率、物理模型、优化问题等。例如,模拟粒子在空间中的分布或生成符合某种分布(如正态分布)的随机数。

用途:
  • 模拟真实世界问题:通过随机浮点数模拟粒子物理、分子动力学、金融市场的波动等。
  • 随机化算法:某些优化算法,如模拟退火(Simulated Annealing)或遗传算法(Genetic Algorithm),会使用随机浮点数来探索解空间。

3. 生成布尔值

布尔值的随机生成广泛应用于决策系统、算法优化等领域。通过生成随机布尔值,可以模拟随机决策或选择。

用途:
  • 概率决策:在机器学习中的某些启发式方法或模拟算法中,通过随机选择布尔值来决定是否执行某些操作。
  • 随机试验:在统计学实验或蒙特卡罗模拟中,使用布尔值模拟成功或失败的事件。

4. 生成随机字符和字符串

生成随机字符或字符串常用于密码生成、验证码生成、测试用例生成等场景。随机字符生成可以用于生成用户的初始密码、随机的用户名等。

用途:
  • 生成验证码:生成随机字符的字符串作为验证码,防止自动化程序攻击。
  • 生成随机密码:用于生成难以猜测的强密码。

5. 生成正态分布随机数

正态分布的随机数用于模拟自然现象、金融数据建模等场景。在金融建模、风险管理、科学模拟等领域,正态分布的随机数是非常常见的。

用途:
  • 金融建模:模拟股票市场的价格变化。
  • 误差建模:许多自然现象的误差都遵循正态分布,如测量误差、噪声等。

6. 生成离散分布随机数

离散分布的随机数通常用于模拟有限的选择范围。例如,模拟掷骰子、抽奖、选择样本等场景。

用途:
  • 抽奖系统:从多个奖项中随机选择获奖者。
  • 选择随机样本:从大量数据中随机抽取若干个样本进行实验分析。

7. 随机排列(std::shuffle

std::shuffle 可以用来打乱容器中的元素,常用于游戏、数据排序等场景。

用途:
  • 洗牌算法:在卡牌游戏中,洗牌时使用 std::shuffle 随机打乱牌组。
  • 数据集重排:在机器学习中,随机重排数据集以提高模型的泛化能力。

三、总结

随机数的生成在 C++ 中具有以下重要性:

  1. 模拟与建模:帮助模拟复杂系统或自然现象,如气候变化、金融市场等。
  2. 游戏开发:增强游戏的随机性和可玩性,如随机生成地图、敌人行为等。
  3. 密码学与安全性:保障数据的安全性,生成密钥、IV 等加密所需的随机值。
  4. 优化与机器学习:用于随机化算法、优化模型和数据增强等。
  5. 统计分析:用于随机抽样、假设检验和实验设计等。

随机数在 C++ 中的用途广泛,涵盖了从简单的数值模拟到复杂的密码学应用等各个领域。了解和使用高质量的随机数生成方法对于提高程序的准确性、安全性和效率至关重要。


http://www.mrgr.cn/news/70563.html

相关文章:

  • 【前端面试系列】JavaScript闭包
  • 【在Linux世界中追寻伟大的One Piece】多路转接epoll
  • arm 汇编技巧
  • TensorFlow|猫狗识别
  • 最好用的免费多线程下载软件 Free Download Manager
  • 植物明星大乱斗1
  • 数据结构与算法:二分搜索/二分查找的python实现与相关力扣题35.搜索插入位置、74.搜索二维矩阵
  • 衍射光学理解
  • 组件间通信(组件间传递数据)
  • 双十一”买买买!法官告诉你注意这些法律问题
  • 别再为视频转文字烦恼啦!这10个转换工具帮你一键搞定。
  • STM32系统的GPIO原理与结构
  • 如何提升测试的覆盖率?
  • VisionPro —— CogSobelEdgeTool边缘提取工具
  • jupyter+pycharm内部直接运行
  • 面试击穿mysql
  • go语言 分布式一致
  • Linux指令的基本使用
  • MySQL-初识数据库
  • 调整TCP参数, 优化网络性能
  • KafKa为什么这么快?
  • 使用服务器时进行深度学习训练时,本地必须一直保持连接状态吗?
  • 如何保证Redis与MySQL双写一致性
  • 数据集划分
  • 模块与包的应用
  • 调试、发布自己的 npm 包