2011-04-06 85 views
12

我需要生成3個隨機數,其數量等於1.如何生成三個隨機數,其總和爲1?

我的實現不支持均勻分佈。 :(

+2

你自己試過這個嗎?問題是什麼?你可以發佈一些代碼嗎? – 2011-04-06 09:01:06

+3

這三個數字不能從均勻分佈中得出,因爲它意味着樣本間的獨立性,而您對這些值有明確的約束('x + y + z = 1')。 – 2011-04-06 09:03:27

+0

爲什麼?這是功課嗎? – 2011-04-07 08:26:46

回答

21

剛拿到3個隨機數字,然後計算係數爲1/[您的數之和。最後用這個因子乘以每個隨機數。的總和將是1。

+1

這是迄今爲止公佈的3種方法中最明顯的一致;達人的*可能*是統一的,但我不得不考慮;這個*明顯*統一。但是,您可能會遇到四捨五入的問題 – 2011-04-06 09:03:16

+0

+1:很好的解決方案! – 2011-04-06 09:04:12

+0

+1:我喜歡你的解決方案! – 2011-04-06 09:06:36

3

由3. 第三生成0和1 鴻溝那些每個之間的兩個隨機數是1和差值兩個隨機三分之二:

void Main() 
{ 
    Random r = new Random(); 
    double d1 = r.NextDouble()/3.0; 
    double d2 = r.NextDouble()/3.0; 
    double d3 = 1.0 - d1 - d2; 
    System.Console.WriteLine(d1); 
    System.Console.WriteLine(d2); 
    System.Console.WriteLine(d3); 
    System.Console.WriteLine(d1 + d2 + d3); 
} 

這個輸出在LINQPad以下內容:

0.0514050276878934 
0.156857372489847 
0.79173759982226 
1 
+1

它不會被均勻分佈。第三個數字大於其他數字。 – turbanoff 2012-04-06 10:14:04

0

UPDATE

  1. 創建3張隨機數
  2. 的的Vector3規範化矢量
+0

@馬克:沒錯,我會更新到另一個答案。但總數必須是1,所以這是我的第一個想法。 – Marnix 2011-04-06 09:03:38

+1

和西門子的解決方案一樣,不是嗎? – 2011-07-20 18:47:12

+0

我不確定這是否正確。如果我正確地記住了我的數學,一個1級的向量不一定有它的分量總和。 – BradleyDotNET 2014-09-05 01:14:11

1

上馬尼克斯」答案輕微變化:

  1. 生成從[0,1]
  2. 的隨機數生成a兩個隨機數。 x從[0,A]和從y並[a,1]
  3. 集結果xy-x1-y
8

這實際上是一個棘手的問題。首先:
達人的解決方案是不統一的,因爲它不支持有兩個數字> 1/3。
西門子的解決方案是不均勻的假設「選擇一個隨機數」從均勻分佈中提取,但這有點微妙。它至少在變量之間是對稱的(即[a,b,c]的概率與任何變量的概率相同),但它非常支持更接近於(1/3,1/3,1/3)。通過查看極端情況,以這種方式考慮: (1/3,1/3,1/3)可能來自任何(a,a,a),其範圍從0到1. (1, 0,0),一個同樣有效的三元組,必須來自(1,0,0)。

一個解決方案:在三空間中加上1的正數形成一個等邊三角形,座標爲(1,0,0),(0,1,0),(0,0, 1)。將其延伸至平行四邊形 - 例如通過添加點(1,1,-1)作爲第四點。這個double區域 - 將第二個區域映射到第一個區域,以便在此平行四邊形中選取一個隨機點就足夠了。

平行四邊形可以通過(0,0,1)+ A(1,0,-1)+ B(0,1,-1)均勻採樣,其中A和B的範圍均勻從0到1。

-A

+0

關於西門子的解決方案,你說*「(1,0,0),一個同等有效的三元組必須來自(1,0,0)」 * ..我會說這是錯誤的:任何(a,0,0)'* a *(0,1)中的*(a,0,0)都會生成(1,0,0) – 2011-07-20 18:43:47

+0

好的結果,那是不正確的!一個更好的解釋: 想象一下立方體[0,1]^3;我們對這個立方體進行均勻採樣,然後歸一化爲1的有效歸一化點的三角形區域(x + y + z = 1; x, y,z> = 0)是[0,1]^3立方體中某些點集的歸一化後圖像 - 即立方體中的所有點也位於將原點連接到此點的直線上(1/3,1/3,1/3)是立方體對角線(len rt(3)),而通過(1,0,0)有len 1,所以前者的可能性是rt(3)倍 – 2011-12-09 23:24:55

1

有一個簡單的方法來做到這一點,但你需要能夠產生均勻的隨機數。

設X在(0,2/3)上是均勻的。如果X < 1/3,則設Y = X + 1/3。否則讓Y = X - 1/3。令Z = 1 - X - Y

在此設置下,X,Y和Z將總計爲1,它們將具有相同的均勻(0,2/3)邊緣分佈,並且所有三個成對相關將是 - (1/2)。

0

2/2方法:

  • 創建的隨機數爲0〜1的列表;縮放到總
  • 排序列表,從小到大
  • 通過測量每個元件之間的空間,在 第一列表
  • 回合在新列表中的每個元素創建一個新的列表
  • 更換到帳戶第一要素浮點

對不起,我不知道C#這是它看起來像蟒蛇:

import random 
import time 

PARTS  = 5 
TOTAL  = 10 
PLACES  = 3 

def random_sum_split(parts, total, places): 


    a = [0.0, total] 
    for i in range(parts-1): 
     a.append(random.random()*total) 
    a.sort() 
    b = [] 
    for i in range(1,(parts+1)): 
     b.append(a[i] - a[i-1]) 
    if places != None:  
     b = [round(x, places) for x in b] 
    c = b[-(parts-1):] 
    d = total - sum(c) 
    if places != None: 
     d = round(d, places) 
    c.insert(0, d) 

    log(a) 
    log(b) 
    log(c) 
    log(d) 

    return c 

def tick(): 

    if info.tick == 1: 

     start = time.time() 

     alpha = random_sum_split(PARTS, TOTAL, PLACES) 

     log('********************') 
     log('***** RESULTS ******') 
     log('alpha: %s' % alpha) 
     log('total: %.7f' % sum(alpha)) 
     log('parts: %s' % PARTS) 
     log('places: %s' % PLACES) 

     end = time.time() 

     log('elapsed: %.7f' % (end-start)) 

收率:

Waiting... 
Saved successfully. 
[2014-06-13 00:01:00] [0.0, 1.3005056784596913, 3.0412441135728474, 5.218388755020509, 7.156425483589107, 10] 
[2014-06-13 00:01:00] [1.301, 1.741, 2.177, 1.938, 2.844] 
[2014-06-13 00:01:00] [1.3, 1.741, 2.177, 1.938, 2.844] 
[2014-06-13 00:01:00] 1.3 
[2014-06-13 00:01:00] ******************** 
[2014-06-13 00:01:00] ***** RESULTS ****** 
[2014-06-13 00:01:00] alpha: [1.3, 1.741, 2.177, 1.938, 2.844] 
[2014-06-13 00:01:00] total: 10.0000000 
[2014-06-13 00:01:00] parts: 5 
[2014-06-13 00:01:00] places: 3 
[2014-06-13 00:01:00] elapsed: 0.0036860 
+0

在這個確切的問題上與其他評論相同。這個問題被標記爲C#,請用問題的語言回答。 – BradleyDotNET 2014-09-05 01:18:33

+0

抱歉,從python線程重定向。理論依然存在;顯示了兩種替代解決方案。我不知道C#,但我會編輯/發佈一個通用算法,以幫助移植。 – litepresence 2014-09-05 01:21:37

+0

它可以更好地格式化,我不認爲我可以親自執行這裏的信息轉換,但我很欣賞這種努力。我會刪除我的downvotes。 – BradleyDotNET 2014-09-05 01:29:55

0

1/2方法:

  • 創建的隨機數的列表,長度部分,每個部分爲0〜1。
  • 總和列表
  • 將每個元素的總和
  • 回合每個元素
  • 賬戶浮點運算,通過編輯的第一要素

對不起不知道C#,這裏的蟒蛇:

import random 
import time 

PARTS  = 5 
TOTAL  = 10 
PLACES  = 3 

def random_sum_split(parts, total, places): 

    a = [] 
    for n in range(parts): 
     a.append(random.random()) 
    b = sum(a) 
    c = [x/b for x in a]  
    d = sum(c) 
    e = c 
    if places != None: 
     e = [round(x*total, places) for x in c] 
    f = e[-(parts-1):] 
    g = total - sum(f) 
    if places != None: 
     g = round(g, places) 
    f.insert(0, g) 

    log(a) 
    log(b) 
    log(c) 
    log(d) 
    log(e) 
    log(f) 
    log(g) 

    return f 

def tick(): 

    if info.tick == 1: 

     start = time.time() 

     alpha = random_sum_split(PARTS, TOTAL, PLACES) 

     log('********************') 
     log('***** RESULTS ******') 
     log('alpha: %s' % alpha) 
     log('total: %.7f' % sum(alpha)) 
     log('parts: %s' % PARTS) 
     log('places: %s' % PLACES) 

     end = time.time() 

     log('elapsed: %.7f' % (end-start)) 

yeilds:

Waiting... 
Saved successfully. 
[2014-06-13 00:01:00] [0.33561018369775897, 0.4904215932650632, 0.20264927800402832, 0.118862130636748, 0.03107818050878819] 
[2014-06-13 00:01:00] 1.17862136611 
[2014-06-13 00:01:00] [0.28474809073311597, 0.41609766067850096, 0.17193755673414868, 0.10084844382959707, 0.02636824802463724] 
[2014-06-13 00:01:00] 1.0 
[2014-06-13 00:01:00] [2.847, 4.161, 1.719, 1.008, 0.264] 
[2014-06-13 00:01:00] [2.848, 4.161, 1.719, 1.008, 0.264] 
[2014-06-13 00:01:00] 2.848 
[2014-06-13 00:01:00] ******************** 
[2014-06-13 00:01:00] ***** RESULTS ****** 
[2014-06-13 00:01:00] alpha: [2.848, 4.161, 1.719, 1.008, 0.264] 
[2014-06-13 00:01:00] total: 10.0000000 
[2014-06-13 00:01:00] parts: 5 
[2014-06-13 00:01:00] places: 3 
[2014-06-13 00:01:00] elapsed: 0.0054131 
+0

這不是C#。請注意在問題上使用的標籤。 – BradleyDotNET 2014-09-05 01:17:12