Russian Qt Forum
Ноябрь 23, 2024, 05:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Random в Qt  (Прочитано 40257 раз)
splpwn
Гость
« : Май 08, 2012, 17:30 »

Добрый вечер, друзья.
Подскажите. Как реализовать случайную выборку из фиксированного набора чисел без повторений?
« Последнее редактирование: Май 10, 2012, 10:36 от Пантер » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Май 08, 2012, 17:50 »

qrand(), QSet или QHash. хотя не совсем понятно зачем тут использовать Qt - STL будет вполне достаточно.
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
splpwn
Гость
« Ответ #2 : Май 08, 2012, 18:09 »

Непонятно, приведите пример с тремя числами без повторений пожалуйста.
Записан
V1KT0P
Гость
« Ответ #3 : Май 08, 2012, 18:17 »

Непонятно, приведите пример с тремя числами без повторений пожалуйста.
Вот например банальный пример:
Код
C++ (Qt)
qsrand (QDateTime::currentMSecsSinceEpoch());
QList<int> numbers;
for (int i=0; i<4; ++i)
   numbers.append(i);
for (int i=0; i<3; ++i) {
   int num = qrand() % numbers.count();
   qDebug() << numbers.at(num);
   numbers.removeAt(num);
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Май 08, 2012, 18:35 »

Код
C++ (Qt)
int RandIndex( int limit,  // число элементов в исходном массиве
              int numSel,  // число выбираемых
              int n )      // выбираемое
{
int beg = n * limit / numSel;
int end = (n + 1) * limit / numSel;
return beg + (qrand() % (end - beg));
}
 

Вот например банальный пример:
Не много ли он жрет ресурсов?
« Последнее редактирование: Май 08, 2012, 20:38 от Igors » Записан
V1KT0P
Гость
« Ответ #5 : Май 08, 2012, 19:04 »

Вот например банальный пример:
Не много ли он жрет ресурсов?
Так написал-же банальный пример, а не высокопроизводительный идеальный =). Я даже мозг не включал, его жара плавит =(, хочу кондиционер...

Только я что-то не понял в твоем алгоритме:
Первым я выбрал количество чисел: 4, дальше указал число выбираемых чисел: 3, дальше указывал номер выбираемого числа, но что то в результате получил 0, 0, 1. С какого оно повторило 0, да в алгоритм не вникал, лениво =).
Код
C++ (Qt)
   qDebug() << RandIndex(4, 3, 0);
   qDebug() << RandIndex(4, 3, 1);
   qDebug() << RandIndex(4, 3, 2);
« Последнее редактирование: Май 08, 2012, 19:06 от V1KT0P » Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #6 : Май 08, 2012, 19:08 »

Непонятно, приведите пример с тремя числами без повторений пожалуйста.
Код
C++ (Qt)
qsrand (QDateTime::currentMSecsSinceEpoch());
QList<int> src; // исходный массив
QSet<int> dst; // наша выборка
int n; // количество элементов выборки
while (dst.size() < n)
   dst.insert(src.at(qrand() % src.size()));
пользуемся тем, что все элементы QSet уникальны. считаем, что src.size() > n, иначе в коде нет особого смысла. если использовать QHash вместо QSet, то можно ещё индекс сохранять.
Вот например банальный пример:
Не много ли он жрет ресурсов?
ну так попросили же пример на Qt Веселый
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
V1KT0P
Гость
« Ответ #7 : Май 08, 2012, 19:18 »

Код
C++ (Qt)
qsrand (QDateTime::currentMSecsSinceEpoch());
QList<int> src;
QSet<int> dst;
int n;
while (dst.size() < n)
   dst.insert(src.at(qrand() % src.size()));
пользуемся тем, что все элементы QSet уникальны. считаем, что src.size() > n, иначе в коде нет особого смысла. если использовать QHash вместо QSet, то можно ещё индекс сохранять.
Ахаха, только что замерил производительность на 100000 значений при 99990. Мой банальный тупой алгоритм отработал за 1-2 секунды. А твой пришлось прибить после 15 секунд, лень дальше ждать =).
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 08, 2012, 19:29 »

да в алгоритм не вникал, лениво =).
Там я сначала перепутал деление, должно быть * limit / numSel; (как сейчас)

пользуемся тем, что все элементы QSet уникальны. считаем, что src.size() > n,
И что будет для выборки 3 элементов из исходных (7,  7, 7, 1) ? Также никто не говорил что можно менять порядок следования

ну так попросили же пример на Qt Веселый
Стремление задействовать как можно больше "мощных тулзлов" и написать "как можно короче" выдает начинающего с головой  Улыбающийся

Ладно, вот более интересная задачка на ту же тему. Все то же самое + доп условия

- исходный массив отсортирован (выборка тоже должна быть сортирована)
- разница между любыми 2 соседними значениями выборки не должна быть меньше заданного N
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Май 08, 2012, 19:33 »

Мой банальный тупой алгоритм отработал за 1-2 секунды. А твой пришлось прибить после 15 секунд, лень дальше ждать =).
Вспомнился старый мультфильм в котором (кажется) мышонок на пне под гитару пел что-то типа
Цитировать
какой хороший Я
и песенка моя
Улыбающийся
Записан
V1KT0P
Гость
« Ответ #10 : Май 08, 2012, 19:42 »

Вспомнился старый мультфильм в котором (кажется) мышонок на пне под гитару пел что-то типа
Цитировать
какой хороший Я
и песенка моя
Улыбающийся
Да ладно, что лулзы нельзя уже половить =). Я как увидел цикл с неопределенным количеством итераций, так не удержался.
Ты свой алгоритм тестировал? У меня тоже самое 0 0 1.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Май 08, 2012, 20:00 »

Ты свой алгоритм тестировал? У меня тоже самое 0 0 1.
То у Вас с copy/paste проблемы, у меня все норм (0, 1, 3) или (0, 1, 2)
Записан
V1KT0P
Гость
« Ответ #12 : Май 08, 2012, 20:12 »

Ты свой алгоритм тестировал? У меня тоже самое 0 0 1.
То у Вас с copy/paste проблемы, у меня все норм (0, 1, 3) или (0, 1, 2)
Да действительно. Теперь другая проблема, нам нужны случайные числа, а в твоем алгоритме у меня постоянно первым 0 идет. Я что-то не догоняю смысла алгоритма.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Май 08, 2012, 20:46 »

Да действительно. Теперь другая проблема, нам нужны случайные числа, а в твоем алгоритме у меня постоянно первым 0 идет. Я что-то не догоняю смысла алгоритма.
Елы-палы, что ж тут "не догнать"? Делим на примерно равные интервалы, из каждого выбираем случайное число.

По поводу первого нуля. Во-первых взять число элементов побольше напр не 4 а 24. А во-вторых да, что-то у них с qrand - первое возвращаемое всегда маленькое если привести к [0..1]. Поэтому лучше использовать остаток от деления (исправил)
Записан
V1KT0P
Гость
« Ответ #14 : Май 08, 2012, 20:56 »

Да действительно. Теперь другая проблема, нам нужны случайные числа, а в твоем алгоритме у меня постоянно первым 0 идет. Я что-то не догоняю смысла алгоритма.
Елы-палы, что ж тут "не догнать"? Делим на примерно равные интервалы, из каждого выбираем случайное число.

По поводу первого нуля. Во-первых взять число элементов побольше напр не 4 а 24. А во-вторых да, что-то у них с qrand - первое возвращаемое всегда маленькое если привести к [0..1]. Поэтому лучше использовать остаток от деления (исправил)
Это получается не очень и случайные числа. При 3 из 4 первым числом будет либо 1(1 вариант из RAND_MAX) либо 0. Ну явно не годится. Работать должно на любых числах. Я думаю ему в идеале нужны все числа из диапазона но в случайном порядке.
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.147 секунд. Запросов: 23.