netdog
net @
а куда он денетсяОоох! Дико извиняюсь!. Алгоритм не будет работать, по крайней мере в том виде как предложил его Кром. Имеем десять чисел, вероятность каждого 0.1 А дальше сами.

а куда он денетсяОоох! Дико извиняюсь!. Алгоритм не будет работать, по крайней мере в том виде как предложил его Кром. Имеем десять чисел, вероятность каждого 0.1 А дальше сами.
function random($ver,$rnd = false){
if ($rnd === false) $rnd = mt_rand(0,1e10)/1e10;
foreach ($ver as $k=>$v)
if ( ($rnd -= $v) <=0) return $k;
trigger_error('Сумма всех вероятностей недопустима', E_USER_WARNING);
return false;
}
echo random(array(1=>0.1,
2=>0.3,
3=>0.5,
));
Не разумеет. То что сумма вероятностей равна единице говорит только о том что вероятности заданы правильно. Но сравниывать надо не с ними а с границами интервалов на координатной прямой которые эти вероятности займут на единичном отрезке независимо в каком порядке ты их расположишь. Именно для этого нужно предварительное суммирование. Твой код работать не будет, для 0.5 он будет выдавать не каждый второй раз как ожидалось бы а два раза из десяти (5-3)/10Originally posted by SiMM
Развели тут дебаты из-за алгоритма в три строки...
Ни в коем разе. Ты не полностью понял алгоритм. Прокрути его в голове для генерации двух чисел, и ты поймешь что обнулять не надо.1) Довольно часто требуется выбирать несколько элементов без повторов, т.е. уже вероятность для уже выбранного искусственно обнуляется, а для остальных соответственно возрастает и перенормируется. В таком случае вариант с хранением массива интервалов впрок явно не проходит.
function random ($ver, $rnd=false) {
($rnd===false) && $rnd=mt_rand(0, 10) ;
$c=0;
$res=0;
foreach ($ver as $k => $v) ($c+=$v*10)>= $rnd && $c-$v*10<$rnd && $res = $k;
$c==10 || trigger_error('Сумма всех вероятностей недопустима', E_USER_WARNING);
return $c==10 ? $res : false ;
}
Наверное, в самом деле не понял. Даже стало интересно разобраться...Ты не полностью понял алгоритм. Прокрути его в голове для генерации двух чисел, и ты поймешь что обнулять не надо.
function random($ver,$rnd = false){
if ($rnd === false) $rnd = mt_rand(0,1e9)/1e9; // согласен, облажался ;)
foreach ($ver as $k=>$v)
if ( ($rnd -= $v) <=0) return $k;
trigger_error('Сумма всех вероятностей недопустима', E_USER_WARNING);
return false;
}
$c=array();
for ($i=10000;$i--;)
@$c[random(array(1 => 0.1, 2 => 0.3, 3 => 0.5))]++;
ksort($c);
print_r($c);
Это заблуждение.Автор оригинала: SelenIT
Допустим, первым выбран первый элемент массива, больше его выбирать нельзя.
Из определения вероятности и постановки задачи можно сделать вывод, что условие нормировки выполняется и недостающие до единицы 10% распределены между этими "и т.д." Если это не так, то это просто никакие не вероятности, а некие коэффициенты, пропорциональные им. Настоящие вероятности получатся, если поделить эти коэффициенты на их сумму. Ни о каких "промахах" имхо речь не идет - элемент должен быть выбран в любом случае.1 - 0,1
2 - 0,3
3 - 0,5
и т.д.
Хорошо, скажу иначе - мне было лень додумывать это и т.д. за автора вопроса (фантазия у меня небогатаяOriginally posted by SelenIT
Ни о каких "промахах" имхо речь не идет - элемент должен быть выбран в любом случае
Одна задача - один топик. Хочешь решать другую - открывай другой топик. А подобное твоему условие нужно разве что при размешивании карт колоды (если не ошибаюсь - это уже условные вероятности) - в теории событие с любой вероятностью может происходить хоть 10 раз подряд - другое дело, что вероятность такого повтора крайне низка, и возникновение подобной ситуации - проблема генератора псевдослучайных чисел или имеющихся условий.По поводу выбора случайных неповторяющися значений - это ограничивающее условие из другой задачи (притом нередко возникающей на практике - по крайней мере мне приходилось ее решать).