2011-09-02 115 views
5

你知道一種將整數分成5個組的方法。 每組總數必須是隨機的,但其總數必須等於一個固定數字。如何使5總數爲100的隨機數

,比如我有「100」,我想這個數字分成

1- 20 
2- 3 
3- 34 
4- 15 
5- 18 

編輯:我忘了說,是一個平衡將是一個很好的事兒。想這可以通過製作,如果完成語句阻止30個以上實例的任何數字。

+1

這是可能的。你有沒有做過任何嘗試? –

+1

這是你有什麼麻煩?你知道如何產生隨機數嗎? –

+0

這似乎不是PHP的問題? – benck

回答

4

取決於你如何隨機需要它,以及如何資源豐富是您計劃運行腳本的環境中,你可以嘗試以下方法。

<?php 
set_time_limit(10); 

$number_of_groups = 5; 
$sum_to    = 100; 

$groups    = array(); 
$group    = 0; 

while(array_sum($groups) != $sum_to) 
{ 
    $groups[$group] = mt_rand(0, $sum_to/mt_rand(1,5)); 

    if(++$group == $number_of_groups) 
    { 
     $group = 0; 
    } 
} 

生成結果的示例將如下所示。很隨意。

[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(11) 
    [1]=> 
    int(2) 
    [2]=> 
    int(13) 
    [3]=> 
    int(9) 
    [4]=> 
    int(65) 
} 
[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(9) 
    [1]=> 
    int(29) 
    [2]=> 
    int(21) 
    [3]=> 
    int(27) 
    [4]=> 
    int(14) 
} 
[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(18) 
    [1]=> 
    int(26) 
    [2]=> 
    int(2) 
    [3]=> 
    int(5) 
    [4]=> 
    int(49) 
} 
[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(20) 
    [1]=> 
    int(25) 
    [2]=> 
    int(27) 
    [3]=> 
    int(26) 
    [4]=> 
    int(2) 
} 
[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(9) 
    [1]=> 
    int(18) 
    [2]=> 
    int(56) 
    [3]=> 
    int(12) 
    [4]=> 
    int(5) 
} 
[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(0) 
    [1]=> 
    int(50) 
    [2]=> 
    int(25) 
    [3]=> 
    int(17) 
    [4]=> 
    int(8) 
} 
[[email protected] ~]# php /var/www/dev/test.php 
array(5) { 
    [0]=> 
    int(17) 
    [1]=> 
    int(43) 
    [2]=> 
    int(20) 
    [3]=> 
    int(3) 
    [4]=> 
    int(17) 
} 
+0

嗨,你能解釋爲什麼在你放$ group = 0的情況下?我無法理解用法 –

+0

我想我明白了。這是爲了找到最後一個數字來達到總數,對吧?很聰明 :) –

0

我想招,這是保持設定上限爲您隨機#發電機100 - currentTotal

+0

這種方法不會給你一個特別平衡的分佈(第一個元素平均可能比後面的元素大得多)。但公平地說,OP沒有具體說明分配。 –

1

這應該做你需要的東西:

<?php 
$tot = 100; 
$groups = 5; 
$numbers = array(); 
for($i = 1; $i < $groups; $i++) { 
    $num = rand(1, $tot-($groups-$i)); 
    $tot -= $num; 
    $numbers[] = $num; 
} 
$numbers[] = $tot; 

它不會給你一個但真正平衡的分配,因爲第一個數字將平均更大。

+0

我得到了'Array([0] => 11 [1] => 48 [2] => 26 [3] => 7 [4] => 6)'。這加起來高達98. – webbiedave

+0

哎呦,固定。不過,最後一個數字並不是隨機的。 – EdoDodo

+1

如果您想「平衡分配」,您可以在最後添加一個步驟來隨機化數組索引。 – horatio

5

挑選4個隨機數,每個隨機數大約爲20(平均分佈爲20個左右的40%,即8個)。添加第五個數字,使得總數爲100.

作爲對其他答案的迴應,實際上最後一個數字不能是隨機的,因爲總數是固定的。作爲解釋,在下面的圖像中,只有4點(較小的蜱)可以隨機選擇,累計表示,每個點均加上一個隨機數(總數/ n,20),總和爲100。結果是5個間距,代表您正在查找的5個隨機數。

only 4 random point between 0 and 100

+0

@Sandro Antonucci:剛剛適應了我的解釋,看到你的例子20,3,34,15,18沒有加起來100.但這就是你的意思,對吧? (對我以前的回答有了一個贊成,並想知道爲什麼) – Remi

3
$number = 100; 
$numbers = array(); 
$iteration = 0; 
while($number > 0 && $iteration < 5) { 
    $sub_number = rand(1,$number); 
    if (in_array($sub_number, $numbers)) { 
     continue; 
    } 
    $iteration++; 
    $number -= $sub_number; 
    $numbers[] = $sub_number;  
} 

if ($number != 0) { 
    $numbers[] = $number; 
} 

print_r($numbers); 
+0

這看起來不錯,問題是,如果一個數字很高,它會在數學上減少總的「組」到達總數越早。例如,如何讓腳本「繼續嘗試」一個隨機數,直到它低於30爲止? –

+0

'if($ sub_number <= 30){ \t \t $ iteration ++; \t \t $ number - = $ sub_number; \t \t $ numbers [] = $ sub_number; \t}' 加入此作品,但最後一個數字可能會變得很大 –

+0

如果您的第一個數字是95或更高,它會炸燬。 95,1,2,?,?,?如果不允許重複,或99,1,?,?,?如果他們是。 –

0

,我發現這個問題的解決方法是稍有不同,但使得更有意義,我,所以在這個例子中,我生成,加起來就是960。希望這是有益的數字陣列。

// the range of the array 
$arry = range(1, 999, 1); 
// howmany numbers do you want 
$nrresult = 3; 
do { 
    //select three numbers from the array 
    $arry_rand = array_rand ($arry, $nrresult); 
    $arry_fin = array_sum($arry_rand); 
    // dont stop till they sum 960 
} while ($arry_fin != 960); 

//to see the results 
foreach ($arry_rand as $aryid) { 
    echo $arryid . '+ '; 
} 
0

的解決方案取決於如何隨機你想你的價值觀是,換句話說,什麼抽查情況看,你要去模仿。

要得到完全隨機分佈的,你必須做的100次調查,其中每個元素將被綁定到一組,在象徵性的語言

foreach i from 1 to n 
    group[ random(1,n) ] ++; 

對於更大的數字,你可以通過增加選擇的組random(1, n/100)或類似的東西,直到總和將匹配n。

但是,你想獲得平衡,所以我認爲最適合你的是正常分佈。畫出5個高斯值,將數字(它們的和)分成5部分。現在你需要對這些零件進行縮放,使它們的總和爲n並圍繞它們,所以你得到了5個組。

4

我對這裏的一些答案略有不同。我根據你想要計算的項目數量創建一個寬鬆的百分比,然後隨機增加或減去10%。

然後我做n-1次(n是迭代的總和),所以你有餘數。剩下的就是最後一個數字,它本身並不是隨機的,但它是基於其他隨機數字的。

工作得很好。

/** 
* Calculate n random numbers that sum y. 
* Function calculates a percentage based on the number 
* required, gives a random number around that number, then 
* deducts the rest from the total for the final number. 
* Final number cannot be truely random, as it's a fixed total, 
* but it will appear random, as it's based on other random 
* values. 
* 
* @author Mike Griffiths 
* @return Array 
*/ 
private function _random_numbers_sum($num_numbers=3, $total=500) 
{ 
    $numbers = []; 

    $loose_pcc = $total/$num_numbers; 

    for($i = 1; $i < $num_numbers; $i++) { 
     // Random number +/- 10% 
     $ten_pcc = $loose_pcc * 0.1; 
     $rand_num = mt_rand(($loose_pcc - $ten_pcc), ($loose_pcc + $ten_pcc)); 

     $numbers[] = $rand_num; 
    } 

    // $numbers now contains 1 less number than it should do, sum 
    // all the numbers and use the difference as final number. 
    $numbers_total = array_sum($numbers); 

    $numbers[] = $total - $numbers_total; 

    return $numbers; 
} 

此:

$random = $this->_random_numbers_sum(); 
echo 'Total: '. array_sum($random) ."\n"; 
print_r($random); 

輸出:

Total: 500 
Array 
(
    [0] => 167 
    [1] => 164 
    [2] => 169 
)