LINUX.ORG.RU

Как выбрать из таблицы несколько элементов случайно с удельными весами?


0

0

order by weight() * rand() - не то, так как элементы с меньшими весами при большом количестве элементов выпадают с очень маленькой вероятностью.

Если нужно выбрать один элемент, можно выгрузить все-все веса из таблицы, посчитать их сумму, выбрать случайное число из промежутка от 1 до суммы, идти по массиву и суммировать элементы, нужный элемент будет тогда, когда сумма достигнет случайного число.

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

Есть у кого-нибудь ещё варианты?

anonymous

> order by weight() * rand() - не то, так как элементы с меньшими весами при большом количестве элементов выпадают с очень маленькой вероятностью.

Попробуй более слабую функцию от weight(), например ln(w) или w^a, a < 1;

т.е. order by ln(weight()) * rand() ...

YesSSS ★★★
()

Кроме того, описанный мной алгоритм неправильный при количестве элементов больше 1. Есть какой-нибудь правильный алгоритм?

anonymous
()
Ответ на: комментарий от YesSSS

Опечатка: weight - поле, а не функция.

anonymous
()
Ответ на: комментарий от anonymous

Даже если придётся это считать средствами ЯП, а не СУБД.

anonymous
()

Можно держать в таблице подсчитанные заранее весовые суммы для фиксированного порядка строк. То есть, нужно добавить столбец, в котором сохранять сумму весов всех предыдущих строк. Случайное число нужно выбирать из диапазона 0 - <суммарный вес>, а затем запрашивать у базы по условию

rand >= <sum_w>

и брать первую выбранную строку (учитывая, что в запросе идет сортировка согласно фиксированному порядку строк).

Sorcerer ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.