2011-04-11 12 views
5

在某些代碼中,我想選擇n[0,1)中的隨機數,其總和爲1用固定金額選擇n個號碼

我通過獨立於[0,1)選擇號碼,通過將每一個由總和歸他們這樣做的:

numbers = [random() for i in range(n)] 
numbers = [n/sum(numbers) for n in numbers] 

我的「問題」是,我走出分佈是相當扭曲。選擇一百萬個數字不是一個單一的數字會超過1/2。通過一些努力,我已經計算出pdf,並且它不好。

這裏是怪異的PDF我得到了5個變量:

enter image description here

你有一個很好的算法來選擇號碼的想法,那結果更均勻或簡單的分佈?

+5

我不確定我是否理解,如果你將數字1分成一百萬個隨機片段,那麼_不應該超過0.5。如果有的話,那意味着其他999,999將不得不適合另一半。 – DShook 2011-04-11 14:23:01

+0

可能的重複[生成多個隨機數等於蟒蛇中的值](http://stackoverflow.com/questions/3589214/generate-multiple-random-numbers-to-equal-a-value-in-python) – 2011-04-11 16:39:58

回答

15

您正在尋找從0的距離劃分爲1

選擇N - 1倍的數字從0到1,對它們進行排序並確定它們各自之間的距離。

這會將空格0分隔爲1,這應該會產生偶爾會遇到的大問題,而您並沒有收到這樣的結果。即使如此,對於大數值的n,您通常可以預期您的最大值也會減少,但不會像您的方法那麼快。

+1

一個可愛的算法。你知道這可能導致什麼分配嗎? – 2011-04-11 20:50:41

+0

除了將其稱爲「隨機分區」之外,我不知道指向它的方法。我一直從事物的分區來看,而不是從分段長度的分佈來看。 – LanceH 2011-04-12 15:24:15

+0

我推導出了cdf'1-(1-x)^ n'和pmf'n(1-x)^(n-1)'。分佈接縫具有較小的概率(它沒有接近1/n的峯值)的概率比我的高,所以它可能也有更多的數字。我還沒有將它與Dirichlet發行版進行比較。 – 2011-04-12 21:56:23

4

看看Random Vectors with Fixed Sum。下載鏈接導致帶有MATLAB代碼的文件和解釋該算法的文檔。

+0

這是一個普遍的情況,每個'xi'都被限制爲'a <= xi <= b'。 – 2011-04-11 22:00:38

4

如果您正在尋找概率,您可能對Dirichlet distribution感興趣,用於生成數量總和爲1的數量。還有一節介紹如何使用伽瑪分佈here來生成它們。

+0

你通常需要一些分佈,而不是統一的從哪裏繪製你的數字。如工作答案所示,您可以使用alpha <1的Gamma分佈來獲得「尖峯」結果。這樣做會讓你從Dirichlet分佈中抽取出來,這很方便,因爲它是你尋求的多項式之前的共軛。 – 2011-04-11 15:34:14

+0

該文章有一個很好的「繪圖」部分,我已經添加了一些代碼示例。我不確定參數是否重要,只要它們相同即可? – 2011-04-12 21:58:24

0

另一種方式來獲得n隨機數的總和,其高達1:

import random 


def create_norm_arr(n, remaining=1.0): 
    random_numbers = [] 
    for _ in range(n - 1): 
     r = random.random() # get a random number in [0, 1) 
     r = r * remaining 
     remaining -= r 
     random_numbers.append(r) 
    random_numbers.append(remaining) 
    return random_numbers 

random_numbers = create_norm_arr(5) 
print(random_numbers) 
print(sum(random_numbers)) 

這使得較高的數字更容易。