提交 b4a53b50 编写于 作者: W wizardforcel

4.1

上级 75fea232
# Generating Uniform Random Numbers
# 生成均匀的随机数
> **Q**: *How to generate pure random string?*<br>
**A**: *Put a fresh student in front of vi editor and ask him[/her] to quit.*<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-- Emiliano Lourbet (@taitooz)
> **Q**:如何生成随机字符串?
>
> **A**:把一个新学生放在 vi 编辑器前面,让他/她退出。
>
> -- Emiliano Lourbet (@taitooz)
To perform computer-based simulation we need to be able to generate random numbers. Generating random numbers following a uniform distribution are the easiest to generate and are what comes out of the standard programming language "give me a random number" function. Here's a sample Python session:
要执行基于计算机的模拟,我们需要能够生成随机数。 生成均匀分布的随机数是最容易的,并且是标准编程语言的“给我一个随机数”函数。 这是一个 Python 会话示例:
```python
import random
......@@ -22,36 +23,37 @@ print(random.random())
'''
```
均匀随机变量非常重要,因为它们是我们生成其他随机变量的基础,如二项,正态,指数等。
Uniform random variables are super important because they are the basis from which we generate other random variables, such as binomial, normal, exponential etc.
## Discussion
We could generate real random numbers by accessing, for example, noise on the ethernet network device but that noise might not be uniformly distributed. We typically generate pseudorandom numbers that aren't really random but look like they are. From Ross' *Simulation* book, we see a very easy recursive mechanism (recurrence relation) that generates values in $[0,1)$ using the [modulo](https://en.wikipedia.org/wiki/Modulo_operation) (remainder) operation:
## 讨论
$x_{i+1} = a x_i$ modulo $m$
我们可以通过访问以太网网络设备上的噪声来生成实际随机数,但噪声可能不是均匀分布的。 我们通常会生成伪随机数,这些伪随机数不是随机的,而是看起来像。 从 Ross' Simulation 一书中,我们看到一个非常简单的递归机制(递归关系),使用 [模/余数](https://en.wikipedia.org/wiki/Modulo_operation)操作生成`[0,1)`中的值:
That is recursive (or iterative and not *closed form*) because $x_i$ is a function of a prior value:
$x_1 = ax_0$ modulo $m$<br>
$x_2 = ax_1$ modulo $m$<br>
$x_3 = ax_2$ modulo $m$<br>
$x_4 = ax_3$ modulo $m$<br>
$...$
```
x{i+1} = a xi modulo m
```
Ross indicates that the $x_i$ values are in [0,m-1] but setting any $x_i=0$ renders all subsequent $x_i=0$, so we should avoid that. Practically speaking, then, this method returns values in (0,1).
这是递归的(或迭代的而不是*闭式*),因为`xi`是先前值的函数:
To get random numbers in [0,1) from $x_i$, we use $x_i / m$.
```
x1 = a x0 modulo m
x2 = a x1 modulo m
x3 = a x2 modulo m
x4 = a x3 modulo m
...
```
We must pick a value for $a$ and $m$ that make $x_i$ seem random. Ross suggests choosing a large prime number for $m$ that fits in our integer word size, e.g., $m = 2^{31} - 1$, and $a = 7^5 = 16807$.
Ross 表示`xi``[0, m-1]`中,但设置任何`xi = 0`会使所有后续`xi = 0`,所以我们应该避免这种情况。 实际上,然后,此方法返回`(0,1)`中的值。
Initially we set a value for $x_0$, called the *random seed* (it is not the first random number). Every seed leads to a different sequence of pseudorandom numbers. (In Python, you can set the seed of the standard library by using `random.seed([x])`.)
要从`xi`获得`[0,1)`中的随机数,我们计算`xi / m`
我们必须为`a``m`选择一个使`xi`看似随机的值。 Ross 建议为`m`选择一个大的素数,它符合我们的整数的字大小,例如`m = 2 ^ 31 - 1``a = 7 ^ 5 = 16807`
## Python implementation
最初我们为`x0`设置了一个值,称为*随机种子*(它不是第一个随机数)。 每个种子都会产生不同的伪随机数序列。 (在 Python 中,您可以使用`random.seed(x)`来设置标准库的种子。)
Our goal is to take that simple recursive formula and use it to generate uniform random numbers. Function `runif01()` returns a new random value *for every call*. Use $m = 2^{31} - 1$, $a = 7^5 = 16807$, and an initial seed of $x_0 = 666$.
## Python 实现
我们的目标是采用这个简单的递归公式并使用它来生成统一的随机数。 函数`runif01()`为每个调用*返回一个新的随机值*。 使用`m = 2 ^ 31 - 1``a = 7 ^ 5 = 16807`,初始种子`x0 = 666`
```python
a = 16807
......@@ -67,8 +69,7 @@ def runif01():
return x_i / float(m)
```
Notice that x_i is in the global space not the runif() space.
请注意,`xi`位于全局空间而不是`runif()`空间。
```python
from lolviz import callsviz
......@@ -77,11 +78,9 @@ runif01()
# 0.005212361926777457
```
![svg](img/4.1_random-uniform_7_0.svg)
Let's try it out:
让我们试试它:
```python
[runif01() for i in range(4)]
......@@ -94,15 +93,9 @@ Let's try it out:
'''
```
### 练习
### Exercise
Define a new function, `runif(a,b)` that generates a random number in [a,b) instead of [0,1). Hint: We need to scale and shift a random uniform value in [0,1). Note: *You can't use random.random() or any other built-in random number generators for this lab.*
定义一个新函数`runif(a, b)`,它生成`[a,b)`中的随机数而不是`[0,1]`。 提示:我们需要缩放和移动`[0,1)`中的均匀随机值。 注意:*您不能在本实验中使用`random.random()`或任何其他内置随机数生成器。*
```python
def runif(a,b):
......@@ -130,10 +123,9 @@ print([runif(5,6) for i in range(3)])
'''
```
### 练习
### Exercise
Define a new function, `setseed(x)`, that updates the `seed` global variable.
定义一个新函数`setseed(x)`,它更新`seed`全局变量。
```python
def setseed(s):
......@@ -141,7 +133,7 @@ def setseed(s):
...
```
This test sequence:
测试序列:
```python
setseed(501)
......@@ -150,7 +142,7 @@ print runif01()
print runif01()
```
should generate:
应该生成:
```
0.00392101099897
......@@ -179,10 +171,9 @@ print([runif(5,6) for i in range(3)])
```
### Random variable density function estimate
Jumping ahead a bit, we can use the histogram plotting example from [Manipulating and Visualizing Data](data.ipynb) as a crude form of density estimation to verify that the distribution of random values is approximately uniform:
### 随机数密度函数估计
稍微向前走一步,我们可以将[数据操纵和可视化](data.ipynb)中的直方图绘制示例,用作密度估计的粗略形式,来验证随机值的分布是近似均匀的:
```python
import matplotlib.pyplot as plt
......@@ -197,8 +188,6 @@ plt.ylabel('Probability')
plt.show()
```
![png](img/4.1_random-uniform_15_0.png)
In the case of generating pseudorandom numbers, we are interested in the sequence of values generated by the recurrence relation. Now we'll turn our attention to iterative methods that loop until the recurrence relation value converges.
在生成伪随机数的情况下,我们感兴趣的是由递归关系生成的值序列。 现在我们将注意力转向迭代方法,它循环到递归关系的值收敛为止。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册