2017-07-11 21 views
0

Python 2.7.12Anaconda 4.2.0 (64-bit)を使用しています。 ランダムパッケージで乱数を生成しようとしています。 intervalnの数字を生成する必要があり、その平均はspecified valueである必要があります。たとえば:Pythonで与えられた間隔と平均を持つ乱数ジェネレータがC#

私は42,00091,00014ランダムに生成された数字をしたいと私はこれらの数字は60,000の平均を持っていると思います。

私は整数を生成するためにランダムに使用する方法を知っている:

random.randint(42000, 91000)

と私は60,000としてその平均値を調整することができますどのように、forループでこれを置くことができますが?

+4

どのように配布するのですか?ガウス? – Alfe

+0

固定平均の乱数の可能な複製(https://stackoverflow.com/questions/25761998/random-number-with-fixed-average) –

+0

完全にランダムに生成し、平均を計算し、最後にそれらをシフトする方法はありますか希望の結果を得るには? –

答えて

1
while True: # until a good sample was found 
    s = [ random.randint(42000, 91000) for _ in range(13) ] 
    v = 60000 + (60000 - (sum(s)/len(s))) * 13 
    if 42000 <= v <= 91000: 
    s.append(v) 
    break 
print sum(s)/len(s) # will print 60000 

これは、標準発生器から13のランダムな値を作成し、平均が14値が与えられた範囲内ではないかもしれないので、正確に60000になるように、14値を計算し、それが有効になるまで何度も何度もこれをしようとします14番目の値が可能です。

これは優雅でもいいです。しかし、それは疑問でした。

EDIT:

このアプローチは、与えられた数字のために動作しますが、それは再試行何かがあるので、それは異なる数を無制限に実行する可能性がある(例えば範囲= [42K、91K]、= 60Kを意味し、= 100Kをカウント) 。

99999個の要素をランダムに作成すると、その平均は(42k + 91k)/ 2になり、これを60kに均衡させるために使用される1つの要素では十分ではありません(したがって常に範囲外です)。もう少し複雑な乱数ジェネレータを使って、42kと91kの間の乱数を平均60kで生成することができます(方法がわからない場合は別の質問をしてください)。この他の乱数生成器を使用すると、終了の可能性が向上します。

終了の可能性を高め、結果を見つけるもう1つの方法は、それぞれが望む意味を持つ小さなチャンクから結果を作り出すことです。私が提示した方法で5000個のチャンクを20個の要素で作成する。

もちろん両方の方法を組み合わせることができます。

+0

これは逆説的な質問に対する最良の答えです。 @ user8028576では、 'a = 42000'と' b = 91000'の離散的な一様分布を作るように求めています。問題は、数学的には、この分布の平均は、(a + b)/ 2_ = 66,500、またはaとbの平均で、60,000ではないことです。だからあなたは、分布が_random_ではないと記述しています。それは、あなたが望むより低い平均に従う歪みを示します。 –

+0

私の質問に答える。ありがとう@Alfe。 – user8028576

+0

平均は2つ(最小および最大)の数字だけでなく、66,500であってはなりません。 14の数字があります。 – user8028576

1

2つの値と特定の平均の間に乱数を生成する方法はたくさんあります。 Pythonには、これらの方法のいくつかのためのメソッドが組み込まれていますが、多くの方法があると言えば、私はそれを意味します。

最も簡単な方法は、三角分布を使用することです。 random.triangular(low, high, mode)は、指定されたモードで、低と高の間の分布から数値を生成します。これは十分に良いかもしれませんが、あなたが本当に平均をしたい場合は、次の機能を使用することができます:あなたがより複雑な取得したい場合は、あなたがrandom.beta(alpha,beta)を呼び出すことにより、ベータ分布を使用することができ

def triangular_mean(low, high, mean): 
    mode = 3 * mean - low - high 
    return random.triangular(low, high, mode) 

。これらは本当に柔軟で非常に奇妙です。 Wikipediaのこの画像は、どれほど奇妙であるかを強調しています。 Beta distribution examples

ベータ分布の平均はalpha/(alpha+beta)あり、結果はそうのは、この機能でそれをラップさせ、あなたのユースケースにそれをスケールアップするために、0と1の間で常に:

def beta_mean(low, high, mean, alpha): 
    offset = low 
    scale = high - low 
    true_mean = (mean - offset)/scale 
    beta = (alpha/true_mean) - alpha 
    return offset + scale * random.beta(alpha, beta) 

で上記の関数では、alphaは平均値を変更することなく分布の形状を変更します。分布の中央値、モード、分散、および他の特性を変更します。

あなたのユースケースに合わせて関数をラップすることができる他のディストリビューションもありますが、私は上記の2つがあなたの好きなユースケースに合うと推測しています。

これらも浮動小数点数を生成するので、整数を必要とする場合は、関数を編集するか、呼び出した後に明示的にキャストするかのいずれかで整数にキャストする必要があります。

+1

私は、OPが_population_ meanではなく_sample_ meanを固定することに興味があると思います。 –

+0

おそらく、私はその機能を得ることができませんでした。しかし、私はそれを1回実行すると、60,000であると予想されるので、60,000を返すと仮定します。しかし、50585.37639745854が得られます。乱数は実際には60,000に近くありません。 – user8028576

関連する問題