2016-06-23 14 views
1

この小さなスクリプトは、0と1 beweenランダムな浮動小数点数を生成した場合、その「0.000111111111111」それはメッセージを出力します未満「は、それが見つかりました」しかし実際には "見つけられる"というわけではありませんが、if文の前にprint文をコメントアウトすると、rand値が値より小さくなくても "found it"でコマンド行が埋められます。なんてこったい?奇妙なPythonの行動ランダム

答えて

2

あなたのプログラムは、それはそれらのすべてをプリントアウトするかどうか、両方小さいと「値」より大きい数字を見つけるん。それは出力、両方の方法は、あなたを混乱させるだけです。これは、(a)コンピュータがの方が速い場合は、何も印刷する必要がない限り、恐らく想像するよりも、です。 (b)しかし、の場合は何かを印刷する必要がありますが、印刷物が実際に見える場所にまで減速します。 (c)成功した​​「発見」の間の反復の回数は、予想していたよりも大きい。

は、上記のすべてを実証するために、私はにこのスクリプトを書いた:それはあなたの「値」より1少ない見つかるまでこれが乱数を生成し、それがループの繰り返し回数を書き出す

#! /usr/bin/python 

import time 
import random 
import csv 
import sys 

def how_long_until(v): 
    n = 0 
    start = time.clock() 
    rng = random.random 
    while True: 
     n += 1 
     if rng() < v: break 
    stop = time.clock() 
    return n, stop - start 

wr = csv.writer(sys.stdout, quoting=csv.QUOTE_MINIMAL) 
wr.writerow(("loops", "cpu.time")) 

value = 0.4/3600 
for _ in range(10000): 
    wr.writerow(how_long_until(value)) 

それを見つけるためにCPU時間が経過しました。これは、十七の時代です。私のコンピュータでは古いですが、ではなく、古い、このプログラムは6時間を実行しました。

そして、私は両方のヒストグラムをプロットしました。まずは、ループの数を見てみましょう:

Histogram of number of loops needed to find a small random number, with inset zoom-in on the range 0...20000

あなたはそれは多くの場合、0.4/3600未満の乱数を見つけるために、わずか数千回の反復がかかりますが、それはとして取ることができ、ことがわかります多くの場合、80,000回繰り返します!これが、あなたが「見つけた」ことは決して印刷されていないように見えたのかもしれません。

今度は、経過時間を見てみましょう:

Histogram of CPU time in milliseconds needed to find a small random number

それはループの数のヒストグラムと非常によく似ていますが、X軸スケールに気づきます。時間はミリ秒です。 0.4/3600より小さい次の数字を見つけるのに80,000回の反復がかかるときでさえ、コンピュータを4ミリ秒かかるだけでその偉業を達成する!このため、反復プリントアウトをコメントアウトしたときに、「見つかった」ことがであり、連続してと表示されたようです。

+0

うわー。分析のように、作家の一部を盗む可能性があります。上記のようにコードにブレークを追加したのは、欠けている部分でした。 – Hashman

+0

@ハッシュマンOPが十分に小さい値を見つけたときにスクリプトが停止することを望んでいたかどうかは私には明らかではありませんでした。 'csv' stdlibモジュールは評価されていません。 – zwol

3

whileループは、常にTrueTrueであるため、永遠に実行されるように設計されています。その無限ループから抜け出すことは決してありません。たとえ値が見つかったとしても、whileループに与えた条件はTrueのままであるため、単に値を出力します。あなたが条件を変更することはできませんので、あなたはbreak文を追加する必要があります。

while True: 
    rand = random.random() 
    print "RAND IS: " + str(rand) + "----- VAL IS " + str(value) 
    if rand < value: 
     print "found it" 
     break 
+0

ありがとうございます、私は狂っていると思います – Cherona