2011-04-30 74 views
23

我需要你的幫助,有點問題。我有四個標籤,我想顯示到100 0它們之間的隨機值,並把它們的總和必須是100如何生成總和爲預定值的N個隨機值?

這是我的代碼:

private void randomly_Click(object sender, EventArgs e) 
{ 
    double alpha = 0, beta = 0, gamma = 0, delta = 0; 
    double temp; 
    int tempDouble; 

    Random rnd = new Random(); 

    alpha = rnd.Next(0, 100); 

    temp = 100 - alpha; 
    tempDouble = (int)temp; 
    beta = rnd.Next(0, tempDouble); 

    temp = 100 - (alpha + beta); 
    tempDouble = (int)temp; 
    gamma = rnd.Next(0, tempDouble); 

    temp = 100 - (alpha + beta + gamma); 
    tempDouble = (int)temp; 
    delta = rnd.Next(0, tempDouble); 

    temp = alpha + beta + delta + gamma; 
    temp = 100 - temp; 
    temp = temp/4; 

    alpha = alpha + temp; 
    beta = beta + temp; 
    gamma = gamma + temp; 
    delta = delta + temp; 

    cInsertion.Text = alpha.ToString(); 
    cMoyens.Text = beta.ToString(); 
    cInternational.Text = gamma.ToString(); 
    cRecherche.Text = delta.ToString(); 
} 

的問題是,我賦予alpha值biggest的值,delta值爲lowest的值。

有什麼辦法讓他們有一個真正的random值?

+0

A **真**隨機數?總之,沒有。只有一個僞隨機數。 隨機數發生器運行時鐘週期,通常會看到重複的序列。使用的種子取決於當前DateTime.Now的.Tick屬性(*如果我沒有記錯*)。有許多像樣的隨機數字生成器和API。我會建議尋找那些,如果你覺得你沒有時間或想要推出自己的。 – IAbstract 2011-04-30 16:00:43

回答

45

你可以做這樣的事情:

double alpha = 0, beta = 0, gamma = 0, delta = 0, k = 0; 
Random rnd = new Random(); 

alpha = rnd.Next(0, 100); 
beta = rnd.Next(0, 100); 
gamma = rnd.Next(0, 100); 
delta = rnd.Next(0, 100); 

k = (alpha + beta + gamma + delta)/100; 

alpha /= k; 
beta /= k; 
gamma /= k; 
delta /= k; 

cInsertion.Text = alpha.ToString(); 
cMoyens.Text = beta.ToString(); 
cInternational.Text = gamma.ToString(); 
cRecherche.Text = delta.ToString(); 

這樣,你說讓我們來隨機值的所有4個變量,然後我們將通過一個因素k也許會讓他們擴展他們的總和爲100.

+5

+1非常聰明。 – Puddingfox 2011-04-30 15:47:02

+2

+1清晰且簡單... – 2011-04-30 16:33:19

-2

A real random number?總之,沒有。只有一個僞隨機數。

隨機數發生器運行時鐘週期,通常會看到重複序列。使用的種子取決於當前DateTime.Now的.Tick屬性(如果我沒記錯的話 。有許多像樣的隨機數字生成器和API。我會建議尋找那些,如果你覺得你沒有時間或想要推出自己的。

上傳到評論,因爲它似乎更合適。

+0

與我的代碼,你可以說這是一個隨機數字。 – 2011-04-30 15:19:14

+0

...標準P-RNG的問題在於,由於時鐘的循環特性,它將執行時幾乎沒有偏差。 – IAbstract 2011-04-30 15:22:32

+0

-1。你對PRNGs的評價是真實的,但是是不合理的 – finnw 2011-04-30 15:53:59

6

如果將所有四個值都粘貼在一個數組中,then shuffle them,然後根據它們的序數位置來分配它們會怎麼樣?這樣,每個變量(伽瑪,θ等)具有相等的可能性,從而獲得高與低的數字。

+2

+1你是唯一真正閱讀這個問題的人嗎? ;) – Guffa 2011-04-30 15:27:21

+1

這給了所有四個值相同的分佈,但它是一個非常奇怪的分佈。 – 2011-04-30 16:16:32

0

這是一個非常有趣的問題。我喜歡@Ivan_Ferić的解決方案,我認爲,它是完美的,但我有另一個想法:

int total = 100; 
Random rand = new Random(); 

int half = rand.next(0,total); // the line 

a = rand.Next(0,half); 
b = max - a; 
c = rand.Next(0,half); 
d = max - c; 

(未測試,也許+/- 1必須加入一些瓦爾的。)另外,你可以洗牌值。

有趣的部分現在來了。如果我們改變 「行」:

min = <some_value> 
max = <another_value>; 
int half = rand.next(min,max); 

...那麼我們就可以微調結果:

  • 分鐘= 0;最大= 100:原始;
  • min = 20;最大= 80:避免小數字;
  • min = 33;最大值= 100:強制兩個數字小於32。
+0

即使min = 0,max = 100,這與Ivan的解決方案並不相同,因爲如果半數<5,即發生5%的時間,那麼兩個數字將和小於5.爲了在Ivan的解決方案中發生這種情況,兩個數字必須小於5,而兩個數字大於50,這隻會發生在3/8%的時間。 – 2011-04-30 17:48:35

0

而是隨機產生的個體數量,產生的部分款項,然後計算出部分:

double alpha, beta, gama, delta = 0; 

var rnd = new System.Random(); 
var cuts = new List<double>(); 

cuts.Add(Math.Floor(rnd.Next(0, 101))); 
cuts.Add(Math.Floor(rnd.Next(0, 101))); 
cuts.Add(Math.Floor(rnd.Next(0, 101))); 

cuts.Sort(); 

alpha = cuts[0]; 
beta = cuts[1] - cuts[0]; 
gamma = cuts[2] - cuts[1]; 
delta = 100 - cuts[2]; 
+0

+1爲什麼這甚至是低調?事實上,這是一個很好的解決方案,不必依賴於分割/乘法。 – 2012-06-26 13:45:30

+1

謝謝@Philip。通常情況下,人們會希望在研究生階段的概率和統計類別中學到的技巧可以與現成的解決方案相媲美,但我認爲天真的選民更喜歡他們自己提出的天真解決方案。 – 2012-06-26 14:09:46

+0

我會非常懷疑阿爾法和三角洲有相同的分佈作爲測試版和伽馬,不像伊萬的。 – gnasher729 2014-03-30 17:05:47

0

如果你想代表互相排斥的結果概率的數字,你可以把它們想象爲多項分佈。既然你想要一個隨機的概率向量,你應該在多項分佈之前從共軛中抽樣:Dirichlet分佈。

在代碼中,你正是伊凡所建議的,除了alpha,beta,gamma和delta都應該從形狀參數alpha_shape,beta_shape,gamma_shape和delta_shape分別從Gamma分佈中繪製出來。 (讓Gamma分佈的其他參數爲1.)這些形狀參數控制預期的相對比例。