ここでの混乱は、疑似乱数ジェネレーターの動作に関するものです。
C のような疑似乱数ジェネレータrand
は、現在の「状態」を表す数値を持つことによって機能します。関数が呼び出されるたびrand
に、次の「状態」番号を生成するために「状態」番号に対していくつかの決定論的計算が行われます。したがって、ジェネレーターに同じ入力 (同じ「状態」) が与えられると、同じ出力が生成されます。
したがって、ジェネレーターに をシードするとsrand(74)
、毎回同じ数字の文字列が生成されます。ジェネレーターに をシードするとsrand(75)
、異なる数値の文字列などが生成されます。
毎回異なる出力を保証する一般的な方法は、常に異なるシードを提供することです。通常は、ジェネレーターに秒/ミリ秒単位の現在の時刻をシードすることによって行われsrand(time(NULL))
ます。
編集: これは、この動作を示す Python セッションです。それは完全に予想されます。
>>> import random
ジェネレーターに同じ番号をシードすると、常に同じシーケンスが出力されます。
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
異なるシードを与えると、わずかに異なるシードであっても、数値は古いシードとはまったく異なりますが、同じ (新しい) シードを使用しても同じです。
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
プログラムを毎回異なる動作にするにはどうすればよいでしょうか? 同じシードを指定すると、常に同じように動作します。time.time()
呼び出すたびに異なる数値を生成する関数を使用できます。
>>> import time
>>> time.time()
1347917648.783
>>> time.time()
1347917649.734
>>> time.time()
1347917650.835
したがって、 を呼び出して再シードし続けるとtime.time()
、シードが毎回異なるため、毎回異なる数のシーケンスを取得します。
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[60, 75, 60, 26, 19, 70, 12, 87, 58, 2, 79, 74, 1, 79, 4, 39, 62, 20, 28, 19]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[98, 45, 85, 1, 67, 25, 30, 88, 17, 93, 44, 17, 94, 23, 98, 32, 35, 90, 56, 35]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[44, 17, 10, 98, 18, 6, 17, 15, 60, 83, 73, 67, 18, 2, 40, 76, 71, 63, 92, 5]
もちろん、絶えず再シードするよりも、一度シードしてそこから継続する方が良いでしょう:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[94, 80, 63, 66, 31, 94, 74, 15, 20, 29, 76, 90, 50, 84, 43, 79, 50, 18, 58, 15]
>>> [random.randint(0, 100) for _ in xrange(20)]
[30, 53, 75, 19, 35, 11, 73, 88, 3, 67, 55, 43, 37, 91, 66, 0, 9, 4, 41, 49]
>>> [random.randint(0, 100) for _ in xrange(20)]
[69, 7, 25, 68, 39, 57, 72, 51, 33, 93, 81, 89, 44, 61, 78, 77, 43, 10, 33, 8]