Python 随机性的多种用途

发布于 2025-03-12 17:27:10 字数 4904 浏览 6 评论 0

计算机随机数生成器(RNGs)有很多用途. 最近在教授一次程序课时,我演示了随机数的一种用法,本来我觉得这是很普遍的一种用法,结果居然有一位参与者对这种用法表示很惊奇. 这件事情使得我意识到,对于许多初学者,甚至有些富有经验的程序员来说,恐怕对于随机数的很多用法都不是很熟悉。

因此我想到了写这篇博客,这里我会演示随机数的一些用法. 这里的例子使用的是 python 语言,但是其原理和概念也可以被借用于其他编程语言--只要它也能产生随机数。

注意:所有关于随机数的使用方法,都无需用到什么高深的数学知识。

让我们开始吧。

首先,从 Python 标准库中导入并查看一下随机模块包含了哪些内容

  import random
  dir(random)
['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random', 'SG_MAGICCONST', 'SystemRandom', 'TWOPI', 'WichmannHill', '_BuiltinMethodType', '_MethodType', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_acos', '_ceil', '_cos', '_e', '_exp', '_hashlib', '_hexlify', '_inst', '_log', '_pi', '_random', '_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn', 'betavariate', 'choice', 'division', 'expovariate', 'gammavariate', 'gauss', 'getrandbits', 'getstate', 'jumpahead', 'lognormvariate', 'normalvariate', 'paretovariate', 'randint', 'random', 'randrange', 'sample', 'seed', 'setstate', 'shuffle', 'triangular', 'uniform', 'vonmisesvariate', 'weibullvariate']

我们可以看到,该模块中包含了许多函数以及包括重要数学常量(例如_e 为数学常量 e,_pi 为数学常量 pi. 这两个常量也可以在 math 模块中找到,分别为 math.e 和 math.pi) 在内的其他属性。

在本篇博文中,我需要展示的是 random() 函数的一些使用方法. 该函数是 random 模块中最基础的几个函数之一. 也许在以后的博文中,我还会接着演示其他函数及其在其他领域的使用方式。

让我们来输出一下 random 函数的文档说明字符串:

print random.random.__doc__
random() -> x in the interval [0, 1).

可以看到,该函数返回一个处于半闭区间[0,1) 的随机浮点数,即随机的一个 x,满足 0.0<=x<1.0

下面是一个名为 fn_random.py 的程序,演示了 random() 函数的一些用法:

  from __future__ import print_function

  # fn_random.py
  # A program showing various uses of the "random" function 
  # from the "random" module of Python's standard library.
  # Author: Vasudev Ram - https://vasudevram.github.io 
  # Copyright 2016 Vasudev Ram

  from random import random
  from random import getstate, setstate

  print("Ex. 1. Plain calls to random():")
  print("Gives 10 random float values in the interval [0, 1).")
  for i in range(10):
      print(random())

  print()

  print("Ex. 2. Calls to random() scaled by 10:")
  print("Gives 10 random float values in the interval [0, 10).")
  for i in range(10):
      print(10.0 * random())

  print()

  print("Ex. 3. Calls to random() scaled by 10 and offset by -5:")
  print("Gives 10 random float values in the interval [-5, 5).")
  for i in range(10):
      print(10.0 * random() - 5.0)

  print()

  print("Ex. 4. Calls to random() scaled by 20 and offset by 40:")
  print("Gives 10 random float values in the interval [40, 60).")
  for i in range(10):
      print(20.0 * random() + 40.0)

下面是该程序的运行输出:

  python fn_random.py

  Ex. 1. Plain calls to random():
  Gives 10 random float values in the interval [0, 1).
  0.978618769308
  0.429672807728
  0.807873374428
  0.00775248310523
  0.367435959496
  0.452718276649
  0.15952248582
  0.183989787263
  0.240112681717
  0.873556193781

  Ex. 2. Calls to random() scaled by 10:
  Gives 10 random float values in the interval [0, 10).
  8.66851830984
  8.06203422551
  6.68791916223
  6.83023335837
  2.28298961244
  5.06491614858
  9.27404238781
  2.30473573581
  7.62983863372
  7.18179372151

  Ex. 3. Calls to random() scaled by 10 and offset by -5:
  Gives 10 random float values in the interval [-5, 5).
  4.28960887925
  -1.48913007202
  -0.534170376124
  3.36741617894
  -3.50802287142
  1.46218930484
  -3.37237288568
  -2.49675571636
  -3.56593768859
  -1.49924682779

  Ex. 4. Calls to random() scaled by 20 and offset by 40:
  Gives 10 random float values in the interval [40, 60).
  56.4292882009
  40.888150119
  56.867782498
  58.3162130934
  41.642982556
  40.8419833357
  52.3684662857
  45.3000297458
  43.1515262997
  52.1129658036

上面的程序演示了如何通过乘法和加法将 random() 返回的原本处于 0 到 1 之间的值,转换为其他区间的值。

注意上面程序中 4 个部分输出的值都是完全不一样的,即使将乘法和加法的运算因素算在内也是完全不同的. 例如,第二个部分输出的值并不都是第一个部分输出值的 10 倍--虽然从代码上看,第二部分与第一部分唯一不同点就在于乘以了一个 10. 产生这个结果的原因是因为,随机数是通过遍历一个很长的序列来产生的,即序列前 10 个值作为第一部分代码的输出,而后 10 个值作为第二部分代码的输出。

若我们希望四个部分所产生的随机数一样怎么办呢(不算上乘法与加法造成的差异)?例如在有些科学与统计实验中,需要不断重复同一样的数据. 一个很直观的办法就是将第一次产生的随机数保持下来,然后在之后的代码中使用保存下来的这些随机数。

但是通过模块中的 getstate() 和 setstate() 函数,我们也能实现这一点。

首先将这一行放在 Ex.1 的代码前。

state = random.getstate()

然后将下行放在 Ex.2 到 Ex.4 的代码前. Then put this line:

random.setstate(state)

然后你会很神奇的发现,四个部分的代码所生成的随机数是一样的(不算上乘法与加法造成的差异)。在以后的博文中,我还会展示随机数的其他用法,例如可以用来对字符串做一些事情,敬请期待吧。

脚注

严格来说,这些都是尾随机数(PRNGs),但是为了简便,让我们就认为是真正的随机数吧。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
30 人气
更多

推荐作者

颉】

文章 0 评论 0

hiasdf

文章 0 评论 0

过期以后

文章 0 评论 0

悲歌长辞

文章 0 评论 0

梦归所梦

文章 0 评论 0

梦境

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文