MATLAB随机数为什么会重复?

首先,各位不妨在新启动的MATLAB中使用randperm生成随机整数,看看结果是否和笔者一致?

randperm 是一个返回随机整数的函数,例如 randperm(10) 以随机顺序返回从 1 到 10 的所有整数。

>> randperm(10)

ans =

     6     3     7     8     5     1     2     4     9    10

尝试过的朋友们可能会发现在新启动的MATLAB中,上述命令生成的随机数是相同的,而且与MATLAB版本、操作系统等因素无关。

同样的,使用randrandirandn等函数同样会在新启动的MATLAB会话中每次生成相同的随机数。

>> rand

ans =

    0.8147

或是

>> randn

ans =

    0.5377

随机数相同的原因

事实上,MATLAB中的随机数并非纯粹意义上的随机数,而是完全确定的。

不止MATLAB,其实现代编程语言和模拟平台中使用的所有“随机数”生成器(pseudorandom number generator)都是完全确定性的,是通过一定的算法使用程序生成的伪随机数, 而通过物理现象产生的随机数才是真随机数。

真伪随机数之间的最大差别在于是否可以预测。

在MATLAB中,所有随机数函数(randrandnrandirandperm)均可从共享随机数生成器中取值,每次启动 MATLAB 时,生成器都会使用默认算法和种子将自身重置为相同的状态

因此,在MATLAB 会话中启动后立即执行一个命令(例如randperm(10))时,会返回相同的结果。

此外,无论何时重新启动,任何调用随机数函数的脚本或函数均返回相同的结果。

所以说造成随机函数的结果取决于两点:

  • 随机数生成器的算法
  • 随机数生成器的种子(seed)

算法我们在下文进行详细介绍,那么种子又是什么呢?

随机数生成器的种子(seed)是初始化随机数生成器状态的一个数值。设置种子确保每次生成相同的随机数序列,这对于结果复现、调试和测试非常重要。

种子相当于随机数生成器的起点,从这个起点开始,生成器会按照确定的算法产生一系列的随机数。

种子的作用:

  1. 可复现性:设置相同的种子,每次运行代码时生成的随机数序列相同。这在调试和结果验证时尤为重要。
  2. 控制实验条件:在模拟和仿真中,使用相同的种子可以确保条件一致,便于比较不同条件的结果。
  3. 分布式计算:在分布式计算环境中,可以为每个子任务设置不同的种子,确保任务之间的独立性和随机性。

MATLAB的随机数算法

目前MATLAB支持的随机数生成器算法有:

1.Mersenne Twister

梅森旋转算法是 MATLAB 的默认随机数生成算法,名字源于选择梅森素数作为其周期长度。

其特点是具有非常长的周期219937-1,质量高且生成速度快,适用于大多数应用。

不仅Matlab使用其作为默认随机数算法,R、Python、Ruby、IDL、Free Pascal、PHP、Maple、GNU多重精度运算库和GSL均使用其作为默认的伪随机数算法。从C++11开始,C++也可以使用这种算法。

2. SIMD-Oriented Fast Mersenne Twister

SFMT(SIMD-oriented Fast Mersenne Twister)是梅森旋转算法的新变体,其周期同样为219937-1,支持 32 位和 64 位整数,以及双精度浮点作为输出。

在大多数平台中,SFMT 比传统的梅森旋转算法快得多,而且 v 位精度的等分布维数也得到了提高。此外,从 0 超出初始状态恢复要快得多。

3. Combined Multiple Recursive

结合了多个递归生成器来生成随机数,周期为 2191,生成速度快且质量高,适用于并行计算。

4. Multiplicative Lagged Fibonacci

乘法时滞斐波那契生成器(MLFG),来源于时滞斐波那生成器, 使用了两个时滞斐波那契序列乘法的组合。

特点是周期较长(约 26331),随机性质量高,适合高精度需求的应用。

5. ThreefryPhilox

Threefry与Philox都是基于对称密钥加密技术的随机数生成器,特点是适合并行计算和 GPU 计算,提供均匀分布的高质量随机数。

Threefry 在 CPU 上速度更快,而 philox 最适合在 GPU 上使用。

Philox的周期为2193,Threefry的周期为2514

6. 兼容旧版的生成器

还有三种支持早期版本MATLAB(4.0,5.0)的随机数生成器,分别是v4v5uniformv5normal。

特点是与旧版本兼容,但周期和随机性质量不如现代生成器。

比较和选择

  • 性能和速度:大多数现代生成器如 Mersenne Twister、Threefry 和 Philox 在性能和生成速度方面表现出色。
  • 周期长度:对于需要超长周期的应用,Mersenne Twister 和 MLFG 是优选。
  • 并行计算:Threefry 和 Philox 特别适合并行和 GPU 计算,因为它们设计为能够在并行环境中提供高质量的随机数。
  • 兼容性:如果需要与旧版本 MATLAB 的结果兼容,可以选择兼容旧版的生成器。

随机数生成器的设置

在 MATLAB 中,使用 rng 函数设置随机数生成器的算法和种子。

rng(seed,generator) 

seed指随机数种子,指定为小于 2^32 的非负整数或"shuffle"

seed 指定为 "shuffle" 时,rng 函数根据当前时间初始化生成器种子,在每次调用 rng 后会产生一个不同的随机数序列。

默认使用种子0初始化生成器,即rng("default")等效于rng(0)

generator指随机数生成器算法,可以用传值关键字的方法进行设置,两种方法是等效的。

默认使用Mersenne Twister算法,即rng(0)等效于rng(0,"twister")

%% Mersenne Twister 算法
rng(0, "twister"); %传值
rng mt19937ar	   %关键字

%% SIMD-Oriented Fast Mersenne Twister 算法
rng(0, "simdTwister"); %传值
rng dsfmt19937	   %关键字

%% 	Combined Multiple Recursive 算法
rng(0, "combRecursive"); %传值
rng mrg32k3a	   %关键字

%% 	Multiplicative Lagged Fibonacci 算法
rng(0, "multFibonacci"); %传值
rng dsfmt19937	   %关键字

%% Philox 算法
rng(0, "philox"); %传值
rng mt19937ar	   %关键字

%% Threefry 算法
rng(0, "threefry"); %传值
rng dsfmt19937	   %关键字

%% 	MATLAB 4.0 版旧生成器算法
rng(0, "v4"); %传值
rng mt19937ar	   %关键字

%% SMATLAB 5.0 版旧式均匀随机数生成器
rng(0, "v5uniform"); %传值
rng dsfmt19937	   %关键字

%% 	MATLAB 5.0 版旧式正态分布随机数生成器
rng(0, "v5normal"); %传值
rng mt19937ar	   %关键字

总结

MATLAB生成的随机数是确定且可控的,通过使用rng函数设置随机数生成器(算法)与随机数种子来控制。

  • 如果想在重启 MATLAB 时避免重复相同的随机数数组,在调用 randrandnrandirandperm 之前使用 rng("shuffle")或自定义不同的随机数种子。
  • 如果想在不重启 MATLAB 会话的情况下重复该会话开始时获得的结果,可使用 rng("default") 将生成器重置为启动状态。
### MATLAB 中的随机数生成函数及使用方法 MATLAB 提供了多种随机数生成函数,这些函数可以用于生成不同分布的随机数。以下详细介绍几种常用的随机数生成函数及其使用方法。 #### 1. `rand` 函数 `rand` 函数用于生成均匀分布在区间 `[0, 1]` 的伪随机数。可以通过指定矩阵的大小来生成随机数矩阵。 ```matlab % 生成一个 3x3 的随机数矩阵 A = rand(3); ``` 如果需要生成其他范围内的随机数,可以通过简单的线性变换实现。例如,生成在 `[a, b]` 范围内的随机数: ```matlab a = 5; b = 10; randomNumbers = a + (b-a) * rand(1, 10); % 生成 10 个 [5, 10] 范围内的随机数 ``` [^1] #### 2. `randn` 函数 `randn` 函数用于生成标准正态分布(均值为 0,标准差为 1)的伪随机数。 ```matlab % 生成一个 3x3 的标准正态分布随机数矩阵 B = randn(3); ``` 如果需要生成具有特定均值和标准差的正态分布随机数,可以通过以下公式实现: ```matlab mu = 5; % 均值 sigma = 2; % 标准差 normalRandomNumbers = mu + sigma * randn(1, 10); % 生成 10 个均值为 5,标准差为 2 的随机数 ``` [^1] #### 3. `randi` 函数 `randi` 函数用于生成指定范围内的整数随机数。 ```matlab % 生成一个 1x10 的向量,其中每个元素是 [1, 100] 范围内的随机整数 C = randi([1, 100], 1, 10); ``` [^2] #### 4. `rng` 函数 `rng` 函数用于控制随机数生成器的状态和算法。这在需要重复实验或确保结果可重现时非常有用。 ```matlab % 设置随机数生成器的种子为 1,使用梅森旋转算法 rng(1, 'twister'); D = rand(1, 5); % 生成 5 个随机数 ``` [^1] #### 5. `randperm` 函数 `randperm` 函数用于生成整数的随机排列。 ```matlab % 生成 1 到 10 的随机排列 E = randperm(10); ``` [^3] #### 示例代码汇总 以下是一个完整的示例,展示如何使用上述函数生成不同类型的随机数: ```matlab % 设置随机数生成器 rng(0, 'twister'); % 生成均匀分布随机数 uniformRandom = rand(1, 5); % 生成正态分布随机数 normalRandom = randn(1, 5); % 生成整数随机数 integerRandom = randi([1, 100], 1, 5); % 生成整数的随机排列 randomPermutation = randperm(10); % 显示结果 disp('Uniform Random Numbers:'); disp(uniformRandom); disp('Normal Random Numbers:'); disp(normalRandom); disp('Integer Random Numbers:'); disp(integerRandom); disp('Random Permutation:'); disp(randomPermutation); ``` [^1] ### 注意事项 - 随机数生成器的默认算法是梅森旋转算法(Mersenne Twister),但可以通过 `rng` 函数更改。 - 如果需要生成单精度数据类型的随机数,可以结合 `single` 类型使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值