乱数

Python には何通りかの乱数が用意されています。ここではシミュレーション用の乱数を説明します。パスワード生成のためには安全な乱数をご覧ください。

標準ライブラリ random

random は標準ライブラリですのでインストールする必要はありません。Mersenne Twister が使われています。

import random

random.random()  # 引数をとらない。区間 [0,1) の1個の乱数を返す
random.randrange(1, 7)  # 1から6までの整数の乱数
random.randint(1, 6)    # 1から6までの整数の乱数

本格的なシミュレーションで大量の乱数を必要とする場合には次の NumPy による方法を使います。

ライブラリ NumPy

numpy.random を使います。

古い方法

Mersenne Twister が使われています。

import numpy as np

np.random.random(10)             # 0以上1未満の一様乱数10個
np.random.randint(1, 7, size=10) # 1以上7未満の整数の乱数10個

新しい方法

2013年にリリースされた NumPy 1.17.0 からは Generator を使った新しいインターフェースが推奨されています(NumPy のバージョンは np.__version__ でわかります)。デフォルトのアルゴリズムは PCG64 です。これは次のようにして使います:

import numpy as np

rng = np.random.default_rng(20200102) # seedの設定(空も可)

rng.random()             # 0以上1未満の一様乱数
rng.random(10)           # 0以上1未満の一様乱数10個の配列
rng.normal(5, 3)         # 平均5,標準偏差3の正規分布の乱数
rng.normal(5, 3, 10)     # 平均5,標準偏差3の正規分布の乱数10個の配列
rng.standard_normal()    # 標準正規分布(平均0,標準偏差1)の乱数
rng.standard_normal(10)  # 標準正規分布の乱数10個の配列
rng.integers(1, 7)       # 1以上7未満の整数の乱数
rng.integers(1, 7, 10)   # 1以上7未満の整数の乱数10個の配列
rng.exponential(3)       # 平均3の指数分布の乱数
rng.exponential(3, 10)   # 平均3の指数分布の乱数10個の配列

上の例のように「タネ(seed)」を与えるのがシミュレーションでの推奨です。同じタネからは同じ乱数列が生成されますので,あとで結果を再現できます。ゲームなどでは rng = np.random.default_rng() のように空にすると,再現性のない(毎回異なる)乱数列が得られます。

例えばモンテカルロ法で円周率を求めるには次のようにします:

import matplotlib.pyplot as plt

N = 10000
x = rng.random(N)
y = rng.random(N)
c = x*x + y*y < 1
plt.scatter(x, y, c=c)
plt.axis('scaled')
print('pi =', 4 * np.sum(c) / N)

ランダムウォークの例です:

N = 1000
x = np.cumsum(rng.random(N) - 0.5)
y = np.cumsum(rng.random(N) - 0.5)
plt.plot(x, y)
plt.axis('equal')

硬貨投げのシミュレーションは rng.integers(0, 2, size=100) のようにできます。表の枚数は np.sum(rng.integers(0, 2, size=100)) です。これを何回もやってヒストグラムを描いてみましょう。

a = [np.sum(rng.integers(0, 2, size=100)) for _ in range(10000)]

plt.hist(a, bins=range(min(a), max(a)+2), align="left", edgecolor="black")

plt.hist() のオプションがわずらわしいなら seaborn を使いましょう:

import seaborn as sns

sns.histplot(a, discrete=True)