crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

eldar85
  опции профиля:
сообщение 15.7.2010, 15:36
Сообщение #1


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


пользуюсь рандомом такого вида
qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()));
   int rand = qrand()%9000+1000;

но если его запускать в цикле то получается слишком много повторов одного и того же числа, так как он генерит новое число со следующей секунды... нет ли способа усовершенствовать как то этот подход чтобы повторы были минимальны? кто нить пользовался такой штукой?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
2 страниц V   1 2 >  
Начать новую тему
Ответов (1 - 15)
igor_bogomolov
  опции профиля:
сообщение 15.7.2010, 15:41
Сообщение #2


Профессионал
*****

Группа: Сомодератор
Сообщений: 1215
Регистрация: 22.3.2009
Из: Саратов
Пользователь №: 630

Спасибо сказали: 235 раз(а)




Репутация:   29  


Так ты qsrand(QTime(0,0,0).msecsTo(QTime::currentTime())); вынеси за тело цикла
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 15.7.2010, 15:44
Сообщение #3


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


хмм, точно))) благодарю)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 15.7.2010, 18:54
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


eldar85, srand - инициализирует генератор (с чего начинать), а сам генератор - rand
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 15.7.2010, 20:51
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


зачем использовать какие-то непонятные Qt конструкции, всё гораздо проще:
#include <cstdlib>
#include <ctime>
std::srand(std::time(NULL));
int x = std::rand();

тем более в C++0x добавлена библиотека для генерации случайный величин которые имеют различные распределения: от нормального распределения до распределение студента, хи квадрат, гамма распределение и т.д.

Сообщение отредактировал DEADHUNT - 15.7.2010, 20:52
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 16.7.2010, 0:39
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DEADHUNT @ 16.7.2010, 0:51) *
зачем использовать какие-то непонятные Qt конструкции
те что в Qt можно использовать в разных потоках
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 16.7.2010, 1:27
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

Спасибо сказали: 26 раз(а)




Репутация:   2  


Цитата(Litkevich Yuriy @ 16.7.2010, 1:39) *
те что в Qt можно использовать в разных потоках

а из cstdlib нельзя? :blink: там для каждого потока отводится переменная(в VC++ например) с текущем значением(да и вообще реализация скрыта от пользователей).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 16.7.2010, 7:52
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(DEADHUNT @ 16.7.2010, 5:27) *
а из cstdlib нельзя?
тыц
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 2.8.2010, 12:59
Сообщение #9


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


все же в многопоточности рандом работает не так как хотелось бы, точнее вообще показывает очень часто одно и тоже число в каждом потоке. запускаю я к примеру 10 потоков. запуск каждого потока производится каждые 0,1 сек.
qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()));
объявлял в главной main функции и всюду, эфект почти один и тот же.
генератор числа в небольшом диапазоне, оьычно от 100 до 200.
 int rand = qrand()%100;

но потоки прям один за другим выдают одно и тоже число, затем несколько потоков могут что то иное выдать, но это как исключение. как быть?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 2.8.2010, 14:15
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Оно и понятно, потоки наверняка почти одновременно запускаются, не успевает даже время пройти. Ты вызови один раз qsrand(), потом вызови qrand() для каждого потока, затем в каждом потоке вызови снова qsrand(), но уже со значениями полученными от предыдущего qrand'a().
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.8.2010, 16:37
Сообщение #11


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


собственно троли сделали qsrand вместо srand, для того, чтобы эту функцию можно было в каждом потоке вызывать. И тогда у каждого потока будет своё начальное значение.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 2.8.2010, 16:48
Сообщение #12


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


получается что то типа такого, объявляем в мэйне
qsrand(QTime(0,0,0).msecsTo(QTime::currentTime()));


затем в каждом потоке
int rand = qrand()%100;
qsrand(rand);


как то так чтоли?


а потоки у меня запускаются каждые 0,1 сек

Сообщение отредактировал eldar85 - 2.8.2010, 16:54
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.8.2010, 17:20
Сообщение #13


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(eldar85 @ 2.8.2010, 20:48) *
как то так чтоли?
нет.
функция srand предназначена для задания начального значения Псевдослучайной Последовательности (ПСП). Т.е. её вызывают один раз и всё.
Но если тебе нужно использовать ПСП в нескольких потоках, то в каждом потоке, в самом начале, вызови qsrand, а затем, для получения очередного значения ПСП, только qrand


П.С.
Отличие трольтеховских функций от стандартных:
Если бы ты использовал стандартные srand/rand, вместо qsrand/qrand, то получилось бы так:
каждый вызов srand влиял бы на все потоки, т.е. для всех потоков устанавливалось бы одно и тоже начальное значение.
Справка:
Буква s в названии функции означает seed - сеятель, значение с которого начинается генерация ПСП
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 2.8.2010, 17:46
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Юр, мне кажется это не так.

Цитата
The sequence of random numbers generated is deterministic per thread. For example, if two threads call qsrand(1) and subsequently calls qrand(), the threads will get the same random number sequence.


Последовтельность сгенеренных номеров предопределены для каждого потока. Для примера 2 потока вызывают qsrand(1) и подпоследовательность вызывает qrand(), потоки получат ту же последовательность номеров.

Поэтому я предложил такой вариант:

qsrand(QTime(0,0,0).msecsTo(QTime::currentTime())); // вызов в main()
for (int i = 0; i < threads.size(); ++i) {
    int rand = qrand()%100;
    threads[i].setRandomSeed(rand);
}

void MyThread::run()
{
    qsrand(getRandomSeed());
    ...
    qrand()%100;
}


В итоге распределения "семечек" по потокам может быть таким:

Thread 1 - 1
Thread 2 - 50
Thread 3 - 23
Thread 4 - 78
...
А уж от этих "семечек" мы получаем разную последовательность случайных чисел при вызове qrand() в каждом из потоков.

В принципе можно еще как-нибудь так извернуться: qsrand((int)this)

Сообщение отредактировал SABROG - 2.8.2010, 17:48
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
eldar85
  опции профиля:
сообщение 2.8.2010, 18:40
Сообщение #15


программист
***

Группа: Участник
Сообщений: 283
Регистрация: 2.1.2010
Из: Москва
Пользователь №: 1348

Спасибо сказали: 0 раз(а)




Репутация:   0  


да, вот это уже очень даже рабочая схема будет я думаю))) спасибо за совет)) завтра буду внедрять)))
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.8.2010, 23:04
Сообщение #16


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(SABROG @ 2.8.2010, 21:46) *
Для примера 2 потока вызывают qsrand(1) и подпоследовательность вызывает qrand(), потоки получат ту же последовательность номеров.
ты не понял, о чём я написал.
Представь, что не оба потока инициализировали ПСП, а только один, он успел несколько раз дёрнуть генератор. Следующее значение ПСП допустим равно 100.
В этот момент второй поток инициализирует генератор тем же значением что и первый.

Вот в этой ситуации стандартные функции приведут к тому, что у первого потока ПСП собьётся. А при использовании Qt версии этих функций этого не произойдёт.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 27.5.2025, 20:21