Случайный выбор из набора записей

Алгоритмы: от сортировки пузырьком до численных методов

Модераторы: C_O_D_E, DeeJayC

Ответить
Albor
Сообщения: 482
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

04 янв 2005, 18:44

Задача такая: имеется набор записей ( массив, Recordset...) необходимо выбирать определённое число записей случайным образом. Например: есть Recordset из 500 записей (повторяющихся данных нет), а мне нужно, скажем 200, но они должны бать выбраны не по порядку и в выборе не должно быть повторов. Вроде бы можно генерировать случайное число в пределах размерности источника и затем копировать данные (предварительно проверяя нет ли уже такой записи) в целевой массив или список. Но это работает пока нужно выбрать данных значительно меньше, чем размер источника, если же необходимо вернуть все данные, но хаотически перемешанные, то данный метод может работать чрезвычайно долго. Подскажите пожалуйста что-либо по данному вопросу.
chur
Сообщения: 195
Зарегистрирован: 17 фев 2004, 10:44
Откуда: Riga, Latvia

05 янв 2005, 12:30

Попробуй такой вариант. Описываешь функцию, которая просто возвращает случайное число. При выборке сортируешь по результату этой функции. Примерно так (для Access'а)

Код: Выделить всё

SELECT TOP 5 field1, field2, field3
FROM table1
ORDER BY random_function(field1);
Сама функция.

Код: Выделить всё

Function random_function(ind As Integer) As Integer
random_function = Int((1000 * Rnd(1)) + 1)
End Function
ЗЫ. В Access'е пришлось передавать какой-либо параметр в функцию, чтобы ее значение изменялось.
Albor
Сообщения: 482
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

05 янв 2005, 17:48

буду пробовать
Albor
Сообщения: 482
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

06 янв 2005, 11:55

Уважаемый chur, действительно, такой запрос решает мою проблему. Одна просьба, если Вам не трудно, в двух-трёх словах - каким образом происходит сортировка (как влияет входной параметр ф-ции на результат, ведь этот параметр не используется ф-цией,а без него результат получается всегда один и тот-же, хотя SELECT function_random(1) возвращает всегда разное число) , везде в литературе про ORDER BY пишется что он используется либо с именем, либо с номером столбца, я провёл много экспериментов с этим запросом, но так до конца и не разобрался, например, если пишу ORDER BY 1, то работает как должно, а если ORDER BY Int(1), то сортировка идёт не понятно как, причём совершенно не зависит от параметра 1 или 600, или чего другое. И второе, не получается выполнить такой запрос через ODBC драйвер, то есть выполнение заканчивается ошибкой "нет такой ф-ции", если знаете, подскажите как правильно указать путь к ф-ции. ( ф-цию определял в Модуле (MS Access))
chur
Сообщения: 195
Зарегистрирован: 17 фев 2004, 10:44
Откуда: Riga, Latvia

06 янв 2005, 13:00

Я думаю, что параметр, передаваемый в функцию, на ее результат никак не влияет. Просто его нужно передавать, что бы Access вызывал фунцию для каждой записи, а не использовал значение, полученное при первом вызове фунции.
Про ORDER BY Int(1). В данном случае происходит вычисление значения нового поля (для сортировки), и т.к. это значение для всех записей будет одно и тоже, то порядок сортировки неопределен. Хотя, надо думать, что для каждого recordset'а он будет постоянным, т.к. внутренний алгоритм не меняется.
Как достучаться до функции через ODBC я так сразу и не скажу. Наверно, проще описать эту функцию в том проекте, который использует ODBC.
Rager
Сообщения: 2
Зарегистрирован: 29 фев 2004, 23:17

22 фев 2005, 02:35

To Albor.
Предлагаю такой алгоритм выборки чисел из набора:
Есть массив A размерностью N (A[N]). Из него нужно составить массив B из M элементов (B[M], M <= N )

В цикле по i от 0 до M делаешь:
1. Берешь рандомное число j из диапазона от 0 до N (какой-нибудь функцией random).
2. Полученное число j используешь в качестве индекса элемента массива A (A[j]).
3. Ставишь этот элемент на i-е место массива B (B = A[j]).
4. Берешь последний элемент массива A (A[N]) и меняешь его с A[j].
5. Уменьшаешь N на единицу и увеличиваешь на единицу i.

Вот и все. Данный алгоритм можно использовать для рассортировки массива. Итог: один цикл и никаких проверок.
Albor
Сообщения: 482
Зарегистрирован: 06 сен 2004, 13:34
Откуда: Днепропетровск

28 фев 2005, 16:01

В стандартной библиотеке есть ф-ция random_shufle, принимающая в качестве параметров итераторы начала и конца диапазона. Она перемешивает довольно быстро. Я перемешиваю весь диапазон, а потом считываю сначала массива столько, сколько нужно. Большое спасибо за помощь!
Ответить