自学内容网 自学内容网

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 或 1

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


原文地址:https://blog.csdn.net/2401_83427936/article/details/143693151

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!