9.6. "random" --- 擬似乱数を生成する
************************************

**ソースコード:** Lib/random.py

======================================================================

このモジュールでは様々な分布をもつ擬似乱数生成器を実装しています。

整数用では、ある値域内の数の選択を一様にします。シーケンス用には、シー
ケンスからのランダムな要素の一様な選択、リストの要素の順列をランダムに
置き換える関数、順列を入れ替えずにランダムに取り出す関数があります。

実数用としては、一様分布、正規分布 (ガウス分布)、対数正規分布、負の指
数分布、ガンマおよびベータ分布を計算する関数があります。角度分布の生成
用には、フォンミーゼス分布が利用できます。

ほとんど全てのモジュール関数は、基礎となる関数 "random()" に依存します
。この関数はランダムな浮動小数点数を半開区間 [0.0, 1.0) 内に一様に生成
します。Python は中心となる乱数生成器としてメルセンヌツイスタを使いま
す。これは 53 ビット精度の浮動小数点を生成し、周期は 2**19937-1 です、
本体は C で実装されていて、高速でスレッドセーフです。メルセンヌツイス
タは、現存する中で、最も広範囲にテストされた乱数生成器のひとつです。し
かし、完全に決定論的であるため、この乱数生成器は全ての目的に合致してい
るわけではなく、暗号化の目的には全く向いていません。

このモジュールで提供されている関数は、実際には "random.Random" クラス
の隠蔽されたインスタンスのメソッドにバインドされています。内部状態を共
有しない生成器を取得するため、自分で "Random" のインスタンスを生成する
ことができます。異なる "Random" のインスタンスを各スレッド毎に生成し、
"jumpahead()" メソッドを使うことで各々のスレッドにおいて生成された乱数
列ができるだけ重複しないようにすれば、マルチスレッドプログラムを作成す
る上で特に便利になります。

自分で考案した基本乱数生成器を使いたい場合、クラス "Random" をサブクラ
ス化することもできます。 この場合、メソッド "random()" 、 "seed()" 、
"getstate()" 、 "setstate()" 、 "jumpahead()" をオーバライドしてくださ
い。 オプションとして、新しいジェネレータは "getrandbits()" メソッドを
提供することができます。 これにより "randrange()" メソッドが任意に大き
な範囲から選択を行えるようになります。

バージョン 2.4 で追加: "getrandbits()" メソッド.

サブクラス化の例として、 "random" モジュールは "WichmannHill" クラスを
提供します。このクラスは Python だけで書かれた代替生成器を実装していま
す。このクラスは、乱数生成器に Wichmann-Hill 法を使っていた古いバージ
ョンの Python から得られた結果を再現するための、後方互換の手段になりま
す。ただし、この Wichmann-Hill 生成器はもはや推奨することができないと
いうことに注意してください。現在の水準では生成される周期が短すぎ、また
厳密な乱数性試験に合格しないことが知られています。こうした欠点を修正し
た最近の改良についてはページの最後に挙げた参考文献を参照してください。

バージョン 2.3 で変更: メルセンヌツイスタが Wichmann-Hill の代わりにデ
フォルト生成器になりました。

"random" モジュールは "SystemRandom" クラスも提供していて、このクラス
は OS が提供している乱数発生源を利用して乱数を生成するシステム関数
"os.urandom()" を使うものです。

警告: このモジュールの擬似乱数生成器はセキュリティ上の手段に使うべき
  ではあ りません。暗号学的にセキュアな疑似乱数生成器が必要なら、
  "os.urandom()" や "SystemRandom" を使ってください。

保守(bookkeeping)関数:

random.seed(a=None)

   乱数生成器の内部状態を初期化します。

   引数が "None" または無い場合は、現在時刻もしくは利用可能ならオペレ
   ーティングシステム固有の乱数発生源をシードとします (利用可能かどう
   かについての詳細は "os.urandom()" 関数を参照してください)。

   *a* が "None" や "int" や "long" でない場合は "hash(a)" を代わりに
   使います。 "PYTHONHASHSEED" が有効なときは、ある型のハッシュ値は非
   決定的であることに注意してください。

   バージョン 2.4 で変更: 以前は、オペレーティングシステムのリソースは
   使われませんでした。

random.getstate()

   乱数生成器の現在の内部状態を記憶したオブジェクトを返します。このオ
   ブジェクトを "setstate()" に渡して内部状態を復帰することができます
   。

   バージョン 2.1 で追加.

   バージョン 2.6 で変更: Python 2.6 が作り出す状態オブジェクトは以前
   のバージョンには読み込めません。

random.setstate(state)

   *state* は予め "getstate()" を呼び出して得ておかなくてはなりません
   。 "setstate()" は "getstate()" が呼び出された時の乱数生成器の内部
   状態を復帰します。

   バージョン 2.1 で追加.

random.jumpahead(n)

   内部状態を、現在の状態から、非常に離れているであろう状態に変更しま
   す。 *n* は非負の整数です。これはマルチスレッドのプログラムが複数の
   "Random" クラスのインスタンスと結合されている場合に非常に便利です:
   "setstate()" や "seed()" は全てのインスタンスを同じ内部状態にするの
   に使うことができ、その後 "jumpahead()" を使って各インスタンスの内部
   状態を引き離すことができます。

   バージョン 2.1 で追加.

   バージョン 2.3 で変更: *n* ステップ先の特定の状態になるのではなく、
   "jumpahead(n)" は何ステップも離れているであろう別の状態にする。

random.getrandbits(k)

   *k* ビット分の乱数ビットを納めた Python の "long" 整数を返します。
   このメソッドは MersenneTwister 生成器で提供されており、その他の乱数
   生成器でもオプションのAPIとして提供されているかもしれません。このメ
   ソッドが使えるとき、 "randrange()" メソッドは大きな範囲を扱えるよう
   になります。

   バージョン 2.4 で追加.

整数用の関数:

random.randrange(stop)
random.randrange(start, stop[, step])

   "range(start, stop, step)" の要素からランダムに選ばれた要素を返しま
   す。この関数は "choice(range(start, stop, step))" と等価ですが、実
   際には range オブジェクトを生成しません。

   バージョン 1.5.2 で追加.

random.randint(a, b)

   "a <= N <= b" であるようなランダムな整数 *N* を返します。

シーケンス用の関数:

random.choice(seq)

   空でないシーケンス *seq* からランダムに要素を返します。 *seq* が空
   のときは、 "IndexError" が送出されます。

random.shuffle(x[, random])

   シーケンス *x* をインプレースにシャッフルします。オプションの引数
   *random* は、引数を持たず、 [0.0, 1.0) のランダムな浮動小数点数を返
   すような関数です。デフォルトでは、これは関数 "random()" です。

   やや小さい "len(x)" であっても、 *x* の順列の総数はほとんどの乱数生
   成器の周期よりも大きくなるので注意してください; このことは長いシー
   ケンスに対してはほとんどの順列は生成されないことを意味します。

random.sample(population, k)

   母集団のシーケンスから選ばれた長さ *k* の一意な要素からなるリストを
   返します。値の置換を行わないランダムサンプリングに用いられます。

   バージョン 2.3 で追加.

   母集団自体を変更せずに、母集団内の要素を含む新たなリストを返します
   。返されたリストは選択された順に並んでいるので、このリストの部分ス
   ライスもランダムなサンプルになります。これにより、くじの当選者 (サ
   ンプル) を1等賞と2等賞（の部分スライス）に分けることも可能です。

   母集団の要素はハッシュ可能 (*hashable*) でなくても、ユニークでなく
   ても、かまいません。母集団が繰り返しを含む場合、出現するそれぞれが
   サンプルに選択されえます。

   整数の並びからサンプルを選ぶには、引数に "xrange()" オブジェクトを
   使いましょう。特に、巨大な母集団からサンプルを取るとき、速度と空間
   効率が上がります。 "sample(xrange(10000000), 60)"

以下の関数は特定の実数値分布を生成します。関数の引数の名前は、一般的な
数学の慣例で使われている分布の公式の対応する変数から取られています; こ
れらの公式のほとんどはどんな統計学のテキストにも載っています。

random.random()

   値域 [0.0, 1.0) の次のランダムな浮動小数点数を返します。

random.uniform(a, b)

   "a <= b" であれば "a <= N <= b" 、"b < a" であれば "b <= N <= a" で
   あるようなランダムな浮動小数点数 *N* を返します。

   端点の値 "b" が範囲に含まれるかどうかは、等式 "a + (b-a) *
   random()" における浮動小数点の丸めに依存します。

random.triangular(low, high, mode)

   "low <= N <= high" でありこれら境界値の間に指定された最頻値 *mode*
   を持つようなランダムな浮動小数点数 *N* を返します。境界 *low* と
   *high* のデフォルトは 0 と 1 です。最頻値 *mode* 引数のデフォルトは
   両境界値の中点になり、対称な分布を与えます。

   バージョン 2.6 で追加.

random.betavariate(alpha, beta)

   ベータ分布です。引数の満たすべき条件は "alpha > 0" および "beta >
   0" です。範囲 0 から 1 の値を返します。

random.expovariate(lambd)

   指数分布です。*lambd* は平均にしたい値の逆数です。(この引数は
   "lambda" と呼ぶべきなのですが、Python の予約語なので使えません。)
   返される値の範囲は *lambd* が正なら 0 から正の無限大、*lambd* が負
   なら負の無限大から 0 です。

random.gammavariate(alpha, beta)

   ガンマ分布です。 (ガンマ関数 *ではありません* ！) 引数の満たすべき
   条件は "alpha > 0" および "beta > 0" です。

   確率分布関数は:

                x ** (alpha - 1) * math.exp(-x / beta)
      pdf(x) =  --------------------------------------
                  math.gamma(alpha) * beta ** alpha

random.gauss(mu, sigma)

   ガウス分布です。 *mu* は平均であり、 *sigma* は標準偏差です。この関
   数は後で定義する関数 "normalvariate()" より少しだけ高速です。

random.lognormvariate(mu, sigma)

   対数正規分布です。この分布を自然対数を用いた分布にした場合、平均
   *mu* で標準偏差 *sigma* の正規分布になります。 *mu* は任意の値を取
   ることができ、*sigma* はゼロより大きくなければなりません。

random.normalvariate(mu, sigma)

   正規分布です。 *mu* は平均で、 *sigma* は標準偏差です。

random.vonmisesvariate(mu, kappa)

   *mu* は平均の角度で、0 から 2**pi* までのラジアンで表されます。
   *kappa* は濃度パラメタで、ゼロ以上でなければなりません。*kappa* が
   ゼロに等しい場合、この分布は範囲 0 から 2**pi* の一様でランダムな角
   度の分布に退化します。

random.paretovariate(alpha)

   パレート分布です。 *alpha* は形状パラメタです。

random.weibullvariate(alpha, beta)

   ワイブル分布です。 *alpha* は尺度パラメタで、 *beta* は形状パラメタ
   です。

代替の乱数生成器:

class random.WichmannHill([seed])

   乱数生成器として Wichmann-Hill アルゴリズムを実装するクラスです。
   "Random" クラスと同じメソッド全てと、下で説明する "whseed()" メソッ
   ドを持ちます。このクラスは、Python だけで実装されているので、スレッ
   ドセーフではなく、呼び出しと呼び出しの間にロックが必要です。また、
   周期が 6,953,607,871,644 と短く、独立した2つの乱数列が重複しないよ
   うに注意が必要です。

random.whseed([x])

   これは obsolete で、バージョン 2.1 以前の Python と、ビット・レベル
   の互換性のために提供されてます。詳細は "seed()" を参照してください
   。 "whseed()" は、引数に与えた整数が異なっても、内部状態が異なるこ
   とを保障しません。取り得る内部状態の個数が 2**24 以下になる場合もあ
   ります。

class random.SystemRandom([seed])

   オペレーティングシステムの提供する発生源によって乱数を生成する
   "os.urandom()" 関数を使うクラスです。すべてのシステムで使えるメソッ
   ドではありません。ソフトウェアの状態に依存してはいけませんし、一連
   の操作は再現不能です。それに応じて、 "seed()" と "jumpahead()" メソ
   ッドは何の影響も及ぼさず、無視されます。 "getstate()" と
   "setstate()" メソッドが呼び出されると、例外 "NotImplementedError"
   が送出されます。

   バージョン 2.4 で追加.

基本使用例:

   >>> random.random()        # Random float x, 0.0 <= x < 1.0
   0.37444887175646646
   >>> random.uniform(1, 10)  # Random float x, 1.0 <= x < 10.0
   1.1800146073117523
   >>> random.randint(1, 10)  # Integer from 1 to 10, endpoints included
   7
   >>> random.randrange(0, 101, 2)  # Even integer from 0 to 100
   26
   >>> random.choice('abcdefghij')  # Choose a random element
   'c'

   >>> items = [1, 2, 3, 4, 5, 6, 7]
   >>> random.shuffle(items)
   >>> items
   [7, 3, 2, 5, 6, 4, 1]

   >>> random.sample([1, 2, 3, 4, 5],  3)  # Choose 3 elements
   [4, 1, 5]

参考: M. Matsumoto and T. Nishimura, "Mersenne Twister: A
  623-dimensionally equidistributed uniform pseudorandom number
  generator", ACM Transactions on Modeling and Computer Simulation
  Vol. 8, No. 1, January pp.3--30 1998.

  Wichmann, B. A. & Hill, I. D., "Algorithm AS 183: An efficient and
  portable pseudo-random number generator", Applied Statistics 31
  (1982) 188-190.

  Complementary-Multiply-with-Carry recipe  長い周期と比較的シンプルな
  更新操作を備えた互換性のある別の乱数生成器。
