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

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

Страниц: [1] 2 3 ... 7   Вниз
  Печать  
Автор Тема: псевдослучайные числа типа float  (Прочитано 39778 раз)
Edynchik
Гость
« : Июнь 30, 2011, 08:02 »

Как получить псевдщслучайное число типа float?  с int все понятно - это qrand(), а вот float и double...
Записан
Blackwanderer
Гость
« Ответ #1 : Июнь 30, 2011, 08:50 »

Как получить псевдщслучайное число типа float?  с int все понятно - это qrand(), а вот float и double...
Код:
float(qrand())/max
Здесь max - максимальное число, выдаваемое qrand. В итоге получаем вещественное псевдослучайное число из диапазона [0;1].
Записан
Edynchik
Гость
« Ответ #2 : Июнь 30, 2011, 10:21 »

Здесь max - максимальное число, выдаваемое qrand. В итоге получаем вещественное псевдослучайное число из диапазона [0;1].
а как я могу узнать максимум qrand? или как получить псевдослучайное с заданным максимумом,или в определенном интервале?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #3 : Июнь 30, 2011, 10:37 »

Returns a value between 0 and RAND_MAX (defined in <cstdlib> and <stdlib.h>), the next number in the current sequence of pseudo-random integers.
Записан
Edynchik
Гость
« Ответ #4 : Июнь 30, 2011, 10:44 »

Returns a value between 0 and RAND_MAX (defined in <cstdlib> and <stdlib.h>), the next number in the current sequence of pseudo-random integers.
то есть надо менять эту константу,а если необходимо пять раз вывесть до разного максимума?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #5 : Июнь 30, 2011, 11:07 »

менять константу
You made my day. Смеющийся
Записан
ddrtn
Гость
« Ответ #6 : Июнь 30, 2011, 11:16 »

Числа в диапазоне [a;b]:

Код:
(b-a)*static_cast<float>(qrand())/RAND_MAX + a

Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #7 : Июнь 30, 2011, 16:18 »

http://www.johndcook.com/cpp_TR1_random.html
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июнь 30, 2011, 16:40 »

Нужно распределить точки на поверхности сферы "квази-случайно" - ну то есть случайно, но более-менее равномерно, так чтобы не было ни заметных "сгущений" ни заметных пустых мест. В то же время распределение должно быть именно случайным, равномерное не годится т.к. позволяет "ездить между рядами".

Ну быстро выясняется что просто random "не пляшет" - он "слишком случен", выгладить распределенные точки затем практически нереально. Пробовал так: разбросать в N раз больше точек и потом отфильтровать. Это так-сяк работает но требует  приличного N и весьма затратно

А что скажет научный работник? Улыбающийся  Если сфера - слишком сложно, то просто на плоском прямоугольнике размеры которого (width, height) известны
Записан
BRE
Гость
« Ответ #9 : Июнь 30, 2011, 16:54 »

В бусте есть Boost.Random: http://www.boost.org/doc/libs/1_46_1/doc/html/boost_random.html
Где можно поиграть с разными движками и распределителями.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Июнь 30, 2011, 17:05 »

В бусте есть Boost.Random: http://www.boost.org/doc/libs/1_46_1/doc/html/boost_random.html
Где можно поиграть с разными движками и распределителями.
Буст - сильный вещь, и, как я не брыкался, мне его поставить пришлось  Улыбающийся
Но в данном случае дело не в движках/распределителях. Обратите внимание что речь идет о "точках", а не о "числах" - это многое меняет.
Записан
BRE
Гость
« Ответ #11 : Июнь 30, 2011, 17:14 »

Первое что бы попробовал для плоского прямоугольника, это два отдельных генератора для каждой оси ([0..width-1], [0..height-1]).
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #12 : Июнь 30, 2011, 17:23 »

Нужно распределить точки на поверхности сферы "квази-случайно" - ну то есть случайно, но более-менее равномерно, так чтобы не было ни заметных "сгущений" ни заметных пустых мест. В то же время распределение должно быть именно случайным, равномерное не годится т.к. позволяет "ездить между рядами".

Ну быстро выясняется что просто random "не пляшет" - он "слишком случен", выгладить распределенные точки затем практически нереально. Пробовал так: разбросать в N раз больше точек и потом отфильтровать. Это так-сяк работает но требует  приличного N и весьма затратно

А что скажет научный работник? Улыбающийся  Если сфера - слишком сложно, то просто на плоском прямоугольнике размеры которого (width, height) известны

Вообще обычный rand() - это жесть. Он во-первых медленный, а во-вторых не обеспечивает ту статистическую случайность, какую хотелось бы)
Я, например использую класс MTRand, где реализован алгоритм Mersenne Twister. Считается одним из лучших по всем пунктам генератором случайных чисел.
Приаттачен ниже.

Что касается точек на сфере. Пусть радиус задан R.
Тогда любая точка на поверхности характеризуется двумя углами theta = [0, pi] и phi = [0, 2pi]
Пусть, для простоты, сфера нах. в начале координат, тогда
z = R*cos(theta);
x = R*sin(theta)*cos(phi);
y = R*sin(theta)*sin(phi).

А сам код примерно такой (с использованием MTRand):
Код
C++ (Qt)
#include "MersenneTwister.h"
 
struct Point3D
{
   Point3D(double x_ = 0.0, double y = 0.0, double z = 0.0) : x(x_), y(y_), z(z_) {}
   double x;
   double y;
   double z;
};
 
int main()
{
   vector<Point3D> vectorOfPoints(1000);
   MTRand mtRand;
   const double R = 1.0;
   for (size_t i = 0; i < vectorOfPoint.size(); ++i) {
       double theta = mtRand.rand(M_PI);
       double phi = mtRand.rand(M_PI+M_PI);
       double sin_theta = sin(theta);
       double z = R*cos(theta);
       double x = R*sin_theta * cos(phi);
       double y = R*sin_theta * sin(phi);
       vectorOfPoints[i] = Point3D(x, y, z);
   }
 
   return 0;
}
 

Примерно так  Улыбающийся  
Слабым местом здесь является то, что приходиться вычислять синусы с косинусами, что не быстро..
« Последнее редактирование: Июнь 30, 2011, 17:30 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
BRE
Гость
« Ответ #13 : Июнь 30, 2011, 17:32 »

Я, например использую класс MTRand, где реализован алгоритм Mersenne Twister. Считается одним из лучших по всем пунктам генератором случайных чисел.
Вот он в бусте - http://www.boost.org/doc/libs/1_46_1/doc/html/boost/mt19937.html
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Июнь 30, 2011, 17:40 »

Первое что бы попробовал для плоского прямоугольника, это два отдельных генератора для каждой оси ([0..width-1], [0..height-1]).
Так лезут все проблемы обычного random (сгустки, пустоты). Потом сколько ни гладь - все равно болт

Я, например использую класс MTRand, где реализован алгоритм Mersenne Twister. Считается одним из лучших по всем пунктам генератором случайных чисел.
Приаттачен ниже.
Ну переводить из полярных координат в декартовы Вы конечно умеете Улыбающийся Но пожалуйста предъявите визуализированные (любым путем) точки на сфере чтобы пипл заценил насколько они "равномерно-случайны". А исходники в данном случае не очень нужны (у нас, джентльменов, верят на слово). Разумеется, я отвечу своей картинкой.

К слову
Слабым местом здесь является то, что приходиться вычислять синусы с косинусами, что не быстро..
А не делается ли это сейчас (или уже давно) на уровне машинных команд? Возможно, то что мы учили - уже (давно) устарело
Записан
Страниц: [1] 2 3 ... 7   Вверх
  Печать  
 
Перейти в:  


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