Есть MySQL таблица такой структуры: id | factor 1 | 1 2 | 6 3 | 4 4 | 1 5 | 3 где: id - идентификатор(думаю это очевидно) factop - множитель шанса его выбора Нужно случайным образом выбрать один из id, но не совсем случайно, а с учетом множителя шанса его выбора, т.е. в данном примере у id 2 вероятность быть выбранным должна быть в 6 раз больше чем у id 1, в 2 раза больше чем у id 5 итд Моих знаний хватает только чтобы выбрать из этих 5 id случайный без влияющих факторов - rand(1, 5); подскажите как реализовать это с учетом шанса. Заранее спасибо за помощь.
Первый элемент будет иметь шанс 1/15, второй 6/15, третий 4/15... Можно продублировать второй элемент 5 раз (чтобы было 6), третий 3 раза (чтобы было 4), поставить их в ряд, потом перемешать. Потом рандомно выбираешь из 15-ти.
YSandro ты это как придумал? тут шансы вобще отсутствуют. тут только некие гипотетические множители этих самых шансов.
когда-то я такое уже делал... дай бог памяти вспомнить, как это работало... PHP: <? mt_srand((int)(10000000*microtime(true))); $arr_Res = array('1'=>1,'2'=>6,'3'=>4,'4'=>1,'5'=>3); $int_adder = 0; foreach($arr_Res as $key=>$value){ $arr_Res[$key] += $int_adder; $int_adder += $value; } $max = end($arr_Res); $arr_RevRes = array_reverse($arr_Res); $int_Grad = mt_rand(0,$max); $int_Pos = ''; foreach($arr_RevRes as $key=>$value){ if($int_Grad>=$value){ $int_Pos = $key; break; } } echo "id = $int_Pos"; за правильность не ручаюсь - только что написал ps: вероятность выпадения не должна равняться 0. иначе будет косяк. теоретически можно сразу удалить все элементы, где вероятность = 0 еще на этапе выборки из базы
Огромное спасибо, вроде как работает, только вот сколько не обновлял страницу со скриптом 5 никогда не выбрасывает не сморя на хороший шанс, а иногда еще и выбрасывает 0. Слушай если я не слишком многого прошу пожалуйста распиши каждую строчку кода в комменте(что она делает) просто мне бы надо понимать с чем я работаю, а в данном слуучае что-то не могу понять как это работает. =) Заранее спасибо.
Детальней изучив данный код сделал вывод что влияние шансов неправильное... Вот что получается в итоге array_reverse: $key=>$value 0=>15 1=>12 2=>11 3=>7 4=>1 дальше $int_Grad становится любым числом от 0 до 15 без всяких шансов Ищем $key $value которого больше или равен $int_Grad, он и будет выбран. Из этого следует что у четверки тут шанс быть выбранной 6 из 15(хотя должен быть 1 из 15), у тройки шанс 4 из 15(должен быть 4 из 15, тоесть в данном случае попали xD), у двойки шанс 2 из 15(должен быть 6 из 15, самый большой), у единицы шанс 3 из 15(должен быть 1 из 15, самый маленький), и соответственно нет пятерки и появился ноль.
а... ну ессно. я писал это на сон грядущий. передайте в array_reverse еще один параметр, чтобы сохранить ключи. array_reverse($arr_Res,true); остальное в порядке вроде как
Это я уже понял и сделал) тока это все проблемы не решило: $int_Pos = $key+1; break; Я до сих пор не совсем разобрался как именно работает этот код(главный смысл не пойму как происходит расчет процентов) т.к. когда я пытаюсь запарится и понять это я сразу запутываюсь xD...вобщем: если ставить $int_Pos = $key; break; то расчет идет неправильно, я думал уж все, не заработает, потом присмотревшись обнаружил что разница между value совпадает с необходимыми множителями шанса если смотреть значение для нужного key "на строчку выше". Вобщем теперь почти все работает как надо, но в том то и проблема что почти все - из за +1 может быть выведен key на 1 больше чем максимальный, и key №1 не может быть вызван(в принципе это не столь серьезно, я могу просто зарезервировать key 1 для пустого значения чтобы его не занял пользователь и если будет выбран кей max+1 запускать скрипт по второму кругу чтобы получить другое значение...но все же хотелось бы без этого, можно ли как-то исправить? И еще такая проблема: $arr_Res = array('1'=>1,'2'=>6,'3'=>4,'4'=>1,'5'=>3); Как мне заполнить такой массив данными из MySQL БД? mysql_fetch_array выводит какую-то хрень...
Вот почему человеу нужно давать идею, а реализует он ее пусть сам. А то разверни, в рот положи - а он спросит как сосать. Представьте ваши значения серией отрезков на одной линии. Длина отрезка - это ваш "фактор". Т.е. общая длина будет равна сумме всех факторов, т.е. 15. Берем случайное число от 1 до 15 и смотрим, в какой отрезок оно попадет - это и будет искомое id. Вперед, пишите код.
В данный момент все итак работает по этому принципу) правда ваши слова меня все равно натолкнули на мысль =) Переворачивание массива было излишним действием... Теперь в общем все работает отлично, но последний вопрос все равно остался(яндекс адекватного ответа не дал, ну либо я хреново искал, иначе бы не писал): $arr_Res = array('1'=>1,'2'=>6,'3'=>4,'4'=>1,'5'=>3); Как мне заполнить такой массив данными из MySQL БД? Тут уже нужен конкретный код а не идея)
И тут все просто. Идете на страничку описания функции в документации, смотрите, что она делает, смотрите примеры... и потихоньку понимаете, что же нужно делать.
Ок, на страничку какой функции? И вообще этот форум создан для того чтобы люди задавали вопросы а другие ЖЕЛАЮЩИЕ люди на них отвечали а не посылали читать макулатуру, разве я не прав? Я задал конкретный вопрос, если у вас нет желания на него отвечать пройдите мимо.
igordata, в долях. вот есть у тебя 3 яблока и 7 бананов в мешке. вероятность вытянуть наугад банан - 7/10. кидаем туда еще 10 помидоров и вероятность вытянуть банан уже 7/20. помидор соответственно 1/2, а яблоко - 3/20. эластичность такого подхода в том, что если ты добавляешь еще новые элементы, то автоматически изменяется вероятность выпадения всех остальных элементов.