2011-09-02 47 views
5

bạn có biết cách tách một số nguyên thành nói ... 5 nhóm. Tổng số nhóm phải là ngẫu nhiên nhưng tổng số nhóm phải bằng một số cố định.Cách tạo 5 số ngẫu nhiên với tổng số 100

ví dụ tôi có "100" Tôi muốn chia con số này vào

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

EDIT: i quên nói rằng có một sự cân bằng sẽ là một thing.I tốt cho rằng điều này có thể được thực hiện bằng cách làm một nếu tuyên bố chặn bất kỳ số nào trên 30 trường hợp.

+1

này là có thể. Bạn đã thực hiện bất kỳ nỗ lực nào chưa? –

+1

Bạn đang gặp sự cố nào trong số này? Bạn có biết cách tạo số ngẫu nhiên không? –

+0

Điều này có vẻ không phải là vấn đề về PHP? – benck

Trả lời

4

Tùy thuộc vào cách ngẫu nhiên bạn cần nó để được và làm thế nào nguồn tài nguyên giàu có là môi trường bạn có kế hoạch để chạy các kịch bản, bạn có thể thử các phương pháp sau đây.

<?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; 
    } 
} 

Ví dụ về kết quả được tạo ra, sẽ trông giống như thế này. Khá ngẫu nhiên.

[[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

hi, bạn có thể giải thích lý do tại sao trong điều kiện nếu bạn đặt $ group = 0? Tôi không thể hiểu cách sử dụng –

+0

Tôi nghĩ rằng tôi đã nhận nó. Nó được thực hiện để tìm một con số cuối cùng để đạt được tổng số, phải không? Rất thông minh :) –

0

Tôi nghĩ rằng thủ thuật này như là để giữ cho thiết trần cho # phát ngẫu nhiên của bạn đến 100 - currentTotal

+0

Cách tiếp cận này sẽ không cung cấp cho bạn sự phân bố đặc biệt cân bằng (các yếu tố đầu tiên có khả năng lớn hơn nhiều so với các phần tử sau này). Nhưng để công bằng, OP không chỉ định phân phối. –

1

này nên làm những gì bạn cần:

<?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; 

Nó sẽ không cung cấp cho bạn một thực sự phân phối cân bằng, mặc dù, vì những con số đầu tiên trung bình sẽ lớn hơn.

+0

Tôi nhận 'Mảng ([0] => 11 [1] => 48 [2] => 26 [3] => 7 [4] => 6)'. Điều đó thêm đến 98. – webbiedave

+0

Rất tiếc, đã được sửa. Tuy nhiên, số cuối không phải là ngẫu nhiên. – EdoDodo

+1

Nếu bạn muốn "cân bằng phân phối", bạn có thể thêm một bước ở cuối để ngẫu nhiên chỉ mục mảng. – horatio

5

Chọn 4 số ngẫu nhiên, mỗi con số trung bình là 20 (với phân phối ví dụ: khoảng 40% 20, tức là 8). Thêm số thứ năm sao cho tổng số là 100.

Để trả lời một số câu trả lời khác ở đây, trên thực tế số cuối không thể ngẫu nhiên, vì tổng được cố định. Như một lời giải thích, trong hình dưới đây, chỉ có 4 điểm (bọ ve nhỏ hơn) có thể được chọn ngẫu nhiên, biểu diễn tích lũy với mỗi số ngẫu nhiên xung quanh giá trị trung bình của tất cả (tổng cộng/n, 20) để có tổng 100. Kết quả là 5 spacings, đại diện cho 5 số ngẫu nhiên bạn đang tìm kiếm.

only 4 random point between 0 and 100

+0

@Sandro Antonucci: chỉ thích nghi với lời giải thích của tôi và thấy rằng ví dụ của bạn 20,3,34,15,18 không thêm tối đa 100. Nhưng đây là ý của bạn, đúng không? (có một downvote trên câu trả lời trước đây của tôi và tự hỏi tại sao) – 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

điều này có vẻ ok, vấn đề là nếu một số là cao, nó sẽ làm giảm toán học tổng số "nhóm" đạt tổng số sớm hơn. Làm thế nào có thể nói kịch bản để "tiếp tục cố gắng" một số ngẫu nhiên cho đến khi nó thấp hơn 30, ví dụ? –

+0

'if ($ sub_number <= 30) { \t \t $ iteration ++; \t \t $ number - = $ sub_number; \t \t $ number [] = $ sub_number; \t} ' thêm công trình này nhưng số cuối cùng có thể trở thành lớn –

+0

Nó sẽ phát sinh nếu số đầu tiên của bạn là 95 hoặc cao hơn. 95,1,2,?,?,? nếu không được phép lặp lại, hoặc 99,1,?,?,? nếu họ là. –

0

Các giải pháp tôi đã tìm thấy cho vấn đề này là một chút khác nhau nhưng làm cho ý nghĩa hơn đối với tôi, vì vậy trong ví dụ này tôi tạo ra một mảng các số mà thêm lên đến 960. Hy vọng điều này là hữu ích.

// 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

Các giải pháp phụ thuộc vào cách ngẫu nhiên bạn muốn giá trị của bạn được, nói cách khác, những gì tình huống ngẫu nhiên bạn đang đi để mô phỏng.

Để có được phân phối hoàn toàn ngẫu nhiên, bạn sẽ phải làm các cuộc thăm dò 100, trong đó mỗi phần tử sẽ được binded vào một nhóm, trong ngôn ngữ biểu tượng

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

Đối với các số lớn hơn, bạn có thể tăng nhóm đã chọn bởi random(1, n/100) hoặc tương tự như vậy cho đến khi tổng số tiền khớp với n.

Tuy nhiên, bạn muốn nhận số dư, vì vậy tôi nghĩ điều tốt nhất cho bạn sẽ là phân phối bình thường. Vẽ 5 giá trị gaussian, sẽ chia số (tổng của chúng) thành 5 phần. Bây giờ bạn cần phải mở rộng các phần này để tổng của chúng sẽ là n và làm tròn chúng, vì vậy bạn có 5 nhóm của bạn.

4

Tôi có cách tiếp cận hơi khác so với một số câu trả lời ở đây. Tôi tạo ra một tỷ lệ phần trăm lỏng lẻo dựa trên số lượng các mục bạn muốn tổng hợp, và sau đó cộng hoặc trừ 10% trên cơ sở ngẫu nhiên.

Sau đó tôi làm điều này n-1 lần (n là tổng số lần lặp), vì vậy bạn có phần còn lại. Số còn lại là số cuối cùng, không phải ngẫu nhiên, nhưng nó dựa trên các số ngẫu nhiên khác.

Hoạt động khá tốt.

/** 
* 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; 
} 

này:

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

Đầu ra:

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