Делать более свежие предметы более вероятными - PullRequest
1 голос
/ 02 июня 2010

В базе данных имеется несколько сотен записей книг, и у каждой записи есть время публикации. На главной странице сайта я должен написать несколько кодов, чтобы случайным образом выбрать 10 книг и поместить их туда. Требование состоит в том, что более новые книги должны иметь более высокие шансы на отображение.

Поскольку время является целым числом, я думаю вот так, чтобы рассчитать вероятность для каждой книги:

Probability of a book to be drawn = (current time - publish time of the book) / ((current time - publish time of the book1) +  (current time - publish time of the book1) + ... (current time - publish time of the bookn))

После того, как книга нарисована, следующий раунд цикла будет минус (текущее время - время публикации книги) от знаменателя и пересчитать вероятность для каждой из оставшихся книг, цикл продолжается, пока 10 книг нарисован.

Является ли этот алгоритм правильным?

Кстати, сайт написан на PHP.

Не стесняйтесь предлагать несколько кодов PHP, если у вас есть лучший алгоритм в уме.

Большое спасибо всем вам.

Ответы [ 2 ]

1 голос
/ 02 июня 2010

Вот очень похожий вопрос, который может помочь: Случайный взвешенный выбор Решение в C #, но код очень читабелен и близок к синтаксису PHP, поэтому его легко адаптировать.

Например, вот как можно сделать это в MySQL:

Сначала вычислите общий возраст всех книг и сохраните его в пользовательской переменной MySQL:

SELECT SUM(TO_DAYS(CURDATE())-TO_DAYS(publish_date)) FROM books INTO @total;

Затем выбирайте книги случайным образом, взвешивая их по возрасту:

SELECT book_id FROM (
  SELECT book_id, TO_DAYS(CURDATE())-TO_DAYS(publish_date) AS age FROM books
) b
WHERE book_id NOT IN (...list of book_ids chosen so far...)
  AND RAND()*@total < b.age AND (@total:=@total-b.age)
ORDER BY b.publish_date DESC
LIMIT 10;

Обратите внимание, что @total уменьшается только в том случае, если книга прошла тест случайного выбора из-за короткого замыкания AND выражений.

Это не гарантирует выбор 10 книг за один проход - даже не гарантируется, что вы выберете любые книги на данный проход. Таким образом, вы должны повторно выполнить второй шаг, пока не найдете 10 книг. Переменная @total сохраняет свое уменьшенное значение, поэтому вам не нужно пересчитывать его.

1 голос
/ 02 июня 2010

Прежде всего, я думаю, что ваша формула гарантирует, что более ранние книги будут выбраны. Попробуйте установить ваши начальные вероятности на основе:

Возраст - дни с момента публикации

Макс (возраст) - самая старая книга в выборке

Book Age (i) - возраст книги i

... Проб (i) = [Макс (возраст) + e - возраст книги (i)] / сумма по всем i [Макс (возраст) + e - возраст книги (i)]

Значение e обеспечивает вероятность выбора самой старой книги. Теперь, когда это сделано, вы всегда можете повторно вычислить пробу любого образца.

Теперь вам нужно найти ОБЪЯВЛЕННЫЙ способ выбора книг. Вероятно, наилучшим способом было бы рассчитать совокупное распределение, используя приведенное выше, а затем выбрать равномерную (0,1) об. Найти где то р.в. находится в накопительном распределении и выберите ближайшую к нему книгу.

Не могу помочь вам в кодировании. Есть смысл?

...