знаете ли вы способ разделить целое число на … 5 групп. Каждая общая группа должна быть случайной, но общая сумма должна равняться фиксированному числу.
например, у меня есть «100». Я хочу разбить это число на
1- 20 2- 3 3- 34 4- 15 5- 18
EDIT: я забыл сказать, что да, баланс был бы хорошим. Предположим, это можно сделать, сделав оператор if, блокирующий любое число выше 30 экземпляров.
В зависимости от того, насколько это необходимо и насколько ресурсоемкой является среда, в которой вы планируете запускать скрипт, вы можете попробовать следующий подход.
<?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; } }
Пример сгенерированного результата будет выглядеть примерно так. Довольно случайный.
[root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(11) [1]=> int(2) [2]=> int(13) [3]=> int(9) [4]=> int(65) } [root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(9) [1]=> int(29) [2]=> int(21) [3]=> int(27) [4]=> int(14) } [root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(18) [1]=> int(26) [2]=> int(2) [3]=> int(5) [4]=> int(49) } [root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(20) [1]=> int(25) [2]=> int(27) [3]=> int(26) [4]=> int(2) } [root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(9) [1]=> int(18) [2]=> int(56) [3]=> int(12) [4]=> int(5) } [root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(0) [1]=> int(50) [2]=> int(25) [3]=> int(17) [4]=> int(8) } [root@server ~]# php /var/www/dev/test.php array(5) { [0]=> int(17) [1]=> int(43) [2]=> int(20) [3]=> int(3) [4]=> int(17) }
Выберите 4 случайных числа, каждый из которых составляет в среднем 20 (с распределением, например, около 40% от 20, т. Е. 8). Добавьте пятое число, чтобы общее число составляло 100.
В ответ на несколько других ответов здесь фактически последнее число не может быть случайным, поскольку сумма фиксирована. В качестве объяснения, в нижнем изображении, есть только 4 очка (меньшие тики), которые можно случайным образом выбрать, которые представляются в совокупности с каждым добавлением случайного числа вокруг среднего значения (total / n, 20), чтобы иметь сумму 100. Результат – 5 интервалов, представляющих 5 случайных чисел, которые вы ищете.
$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);
Это должно делать то, что вам нужно:
<?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;
Это не даст вам по-настоящему сбалансированного распределения, хотя, поскольку первые числа в среднем будут больше.
Я думаю, что трюк заключается в том, чтобы сохранить настройку потолка для вашего случайного генератора # до 100 – currentTotal
Решение зависит от того, насколько случайны вы хотите, чтобы ваши ценности были, другими словами, какую случайную ситуацию вы собираетесь моделировать.
Чтобы получить полностью случайное распределение, вам нужно будет выполнить 100 опросов, в которых каждый элемент будет привязан к группе, на символическом языке
foreach i from 1 to n group[ random(1,n) ] ++;
Для больших чисел вы можете увеличить выбранную группу random(1, n/100)
или что-то вроде этого, пока общая сумма не будет соответствовать n.
Однако вы хотите получить баланс, поэтому я считаю, что лучшим для вас будет нормальное распределение. Нарисуйте 5 гауссовских значений, которые будут делить число (их сумма) на 5 частей. Теперь вам нужно масштабировать эти части, чтобы их сумма была n и вокруг них, поэтому вы получили 5 групп.
Решение, которое я нашел для этой проблемы, немного отличается, но для меня имеет смысл, поэтому в этом примере я генерирую массив чисел, который составляет до 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 . '+ '; }