Задавайте вопросы, мы ответим
Вы не зашли.
Страниц: 1
Здравствуйте!
Имеется баннерокрутилка. Хочу сделать зависимость частоты показа каждого баннера от стоимости перехода по нему ( стоимость перехода для каждого баннера разная ). То есть мне необходимо тем чаще показывать баннер, чем большая стоимость перехода по нему назначена.
Стоимость перехода для всех баннеров сложил и принял за 100% и рассчитал исходя из стоимости перехода вероятность показа каждого из баннеров в диапазоне от 0 до 100 соответственно. А дальше зашел в тупик. Как выбрать из таблицы один баннер случайным образом, но с учетом вероятности?
Буду благодарен за любые советы!
Неактивен
Я бы сделал следующим образом:
-- Рассчитал вероятность каждого баннера таким образом, чтобы в сумме все вероятности давали 1 (или 100%), т.е. распределил бы эти вероятности по некоторой области. Например в итоге может получиться массив:
[ .1, .3, .34, .456, .56, .78, 1 ] -- разность между соседними элементами будет составлять вероятность, а индекс элемента будет соответствовать определенному баннеру. Т.е. вероятность появления первого будет 10%, второго 20%, третьего 14% и т.д.
-- Далее генерировать случайное число от [0 до 1) (к примеру получилось .567), и проверять в какую из областей оно попадает. Т.е. идти по массиву до тех пор, пока сгегерированное число меньше значения элемента массива. В данном случае получиться до .78, а номер баннера 6 (или 7, если номера баннеров с 1 начинаются).
-- Выбрать баннер из таблицы в зависимости от номера.
Неактивен
udaaff, спасибо!
сделал по предложенному Вами методу ... все отлично работает!
Отредактированно savit (25.11.2009 16:25:15)
Неактивен
Есть еще один способ. Пусть колонка w - приоритет показа баннера (причем сумма их не обязательно 1).
Неактивен
насколько я слышал ORDER BY RAND() это крайне тормозная штука в мускуле ... а скрипт который производит выборку и транслирует баннеры должен все делать с максимально возможной скоростью т.к иначе сайты на которых транслируются баннеры просто напросто подвиснут ( iframe сейчас не использую для отображения, хотя отчасти проблемы скорости загрузки он решает )
Неактивен
тут еще дело в том, что все завязано на гео-таргетинге т.е для разных стран соответственно отображаются разные баннеры ... для равномерности я делаю расчет интервалов для каждой страны отдельно
Неактивен
ORDER BY RAND() это конечно неоптимальное по скорости решение. Стоит применять, только если баннеров порядка десяти или ста.
Неактивен
Чего-то я на этой единице зациклился... Можно ведь проще сделать.
Если каждому баннеру соответствует некое число, которое пропорционально количеству его показов, достаточно будет отталкиваться от этих чисел, т.е. к примеру:
есть четыре баннера с вероятностями 345, 24, 4, 100 соответственно. Далее составляем массив: [ 345, 369, 374, 474 ]. Ну и далее принцип тот же, только случайное число должно быть в диапазоне [ 0; 474 )
Неактивен
Решил не плодить темы, а задать вопрос тут т.к он касается все той же баннерокрутилки.
Раньше было необходимо выбрать один случайный баннер и способ предложенный udaaff подходил, но теперь условия немного изменились и необходимо выбирать не один а например 15-20 баннеров ( случайно, но с учтом вероятности )
генерить в PHP 20 случайных чисел и делать 20 запросов мне кажется не лучший варинт т.к 150-300 обращений за баннерами в секунду x 20 запросов на обращение = no good.
Пока стоит сделан такой варинт: WHERE RAND()<0.1 ORDER BY RAND()*weight DESC LIMIT 20 но он неибежно приводит к using temporary, using filesort.
Вариант прегенарции случайных чисел при генерации таблицы ( раз в 15 мин ) не подходит т.к в это время по сути баннеры не ротируются.
У кого-нибудь имется мысли как еще можно сделать? using temporary, using filesort напрягают
Неактивен
Это для одной записи. А надо несколько...
Я вот склоняюсь к мысли, что никак не обойтись без N последовательных запросов, если нужно N записей, и деваться тут некуда.
Но как-то связывать случайные числа для разных записей нельзя, поскольку каждое выпадение RAND() - независимое событие.
(или можно?)
Неактивен
А в чем различие одной записи или нескольких? Генерируешь M >= N случайных индексов,
вытаскиваешь LIMIT N, если вылезло меньше — повторяешь.
Неактивен
Страниц: 1