Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Random

Аноним
Как присвоить переменной (int) значение random, те. случайное число, между 0 и 1000
452
02 октября 2002 года
quasar1983
38 / / 20.04.2000
int x=rand()%1000;
540
02 октября 2002 года
AL C++ Programmer
36 / / 20.01.2000
Не совсем так... При rand()%1000 случайные числа не будут распределены равномерно.
Попробуй так:
int((float(rand())/float(RAND_MAX))*1000.0f)
409
02 октября 2002 года
Ramzes
163 / / 20.09.2000
>>числа не будут распределены равномерно.

А почему случайные числа должны быть расположены равномерно? Они ведь случайные.
И к чему вся эта туфта с флоатом. Первый вариант нормально работает...
409
02 октября 2002 года
Ramzes
163 / / 20.09.2000
Цитата:

On 2002-10-02 0225, AL C++ Programmer wrote
Не совсем так... При rand()%1000 случайные числа не будут распределены равномерно.
Попробуй так
int((float(rand())/float(RAND_MAX))*1000.0f)



Еще раз посмотрел твое сообщение ))
Ну ты даешь!!! такое написать!!!

1.0K
02 октября 2002 года
Shooter
7 / / 20.05.2000
Цитата:

On 2002-10-01 2243, quasar1983 wrote
int x=rand()%1000;


На самом деле здесь будут случайные числа от 0 до 999 так как %1000 - означает взятие по модулю от 1000. Т.е. 1000%1000= 0.
правильней было бы использовать
int x = rand() % 1001;
И еще...
для того чтобы при каждом запуске числа не повторялись нужно привязать начальное значение к дате-времени функцией
srand((unsigned) time(NULL));

540
02 октября 2002 года
AL C++ Programmer
36 / / 20.01.2000
>> А почему случайные числа должны быть расположены равномерно?

Мда... Я разве сказал "расположены"?

Равномерное распределение, термин из теории вероятностей
означающий, что любой элемент из множества {0, 1, ... n-1}
может быть выбран с вероятностью 1/n

>> И к чему вся эта туфта с флоатом. Первый вариант нормально работает...

Ты проверял?

Рассмотрим пример:
int x=rand()%10000

rand() возвращает псевдослучайное число от 0 до 32677.
В x окажется число 2768-9999 если rand() вернет:
2768-9999; 12768-19999; 22768-29999 итого 21696 из 32768;
21696/32768 = 0.662109375 а доля чисел 2678-9999 составляет 0.7322 от 10000
В x окажется число 0-2677 если rand() вернет
0-2767; 10000-12767; 20000-22767; 30000-32767 итого 11072 из 32768;
11072/32768 = 0.337890625, а доля чисел 0-2677 составляет 0.2678 от 10000

Вот так-то.

Впрочем, "нормально" понятие относительное, и кого-то такой расклад вполне устраивает...
Так же прошу заметить что я прежде всего Programmer а уже потом C++ Programmer

С уважением, AL C++ Programmer.
380
02 октября 2002 года
Arestov
285 / / 20.09.2000
Цитата:

А почему случайные числа должны быть расположены равномерно? Они ведь случайные.
И к чему вся эта туфта с флоатом. Первый вариант нормально работает...



если распределение "случайных" чисел не равномерное, то это уже не совсем "случайные" в понятии обычного человека (хотя в теорвере исследованы множество распределений имеющих практическую ценность нормальное, пуассона, стьюдента, равномерное, и пр).
Дык вот когда события не совсем случайные, это иногда может сильно мешать. Хотя есть системы где события не равномерны, скажем в СМО (системах массового обслуживания) поток заявок обычно имеет Пуассоновское распределение.

Скажем ты делаешь какую-нить игру, у тебя события которые должны были быть равнозначными станут предопределёнными.

а с float иногда тоже имеет смысл заморочится, простой пример, делаем подобие салюта, задача из точки A(x,y) должны вылететь N пикселей в разные стороны, и потом под действием гравитации упасть на "землю".

На ум приходит

struct particle{
. int x,y;
. int dx,dy;
};

particle g_particles[N];
const max_speed = 13;
const gravity = 1;


void InitBoom(int x, int y)
{
. particle *p = g_particles;
. for (int i=0; i<N; i++, p++)
. {
. p->x = x;
. p->y = y;
. // dx от -6 до 6
. p->dx = max_speed/2 - rand() % max_speed;
. // dy от -6 до 6
. p->dy = max_speed/2 - rand() % max_speed;
. }
}

void MoveParticles()
{
. particle *p = g_particles;
. for (int i=0; i<N; i++, p++)
. {
. p->x += p->dx;
. p->y += p->dy;
. // тут мы проверям на столкновение с краями экрана
.
. if (p->x < 0)
. {
. p->x-=p->dx;
. p->dx=-p->dx;
. }
. // ну и так далее со всеми краями, опускаю, тк это не интересно
. //. ..........
....................
. увеличиваем скорость вниз, как бы под действием гравитации
. p->dy+=gravity;
. }
}

void DrawParticles()
{
. particle *p = g_particles;
. for (int i=0; i<N; i++, p++)
. {
. PutPixel(p->x, p->y);
. }
}

void main()
{
. InitBoom(rand() % 320, rand() % 200);
. SetMode(0x13);
. do{
. DrawParticles();
. MoveParticles();
. if (kbhit())
. {
. if (getch()==' ') InitBoom(rand() % 320, rand() % 200);
. else break;
. }
. }while(1);
. SetMode(0x03);
}

вот я опустин несущественные детали допустил какие-то ошибки, но я думаю идея понятна.

Дык очём это я, ах вот так если мы посмотрим на то как двигаются эти пиксели, то увидим что на салют они мало похожи, т.к. разлетаются, они квадратом, а не кругом.
Чтобы стало всё ок надо изменить структуру particle и InitBoom()

struct particle{
. float x,y,dx,dy; // дробные числа на обеспечат плавное движение
};

void InitBoom(int x, int y)
{
. particle *p = g_particles;
. for (int i=0; i<N; i++, p++)
. {
. p->x = x;
. p->y = y;
. берём &quot;псевдослучайный&quot; угол в радианах
. float angle = 3.1415 * 2 * (float)rand()/RAND_MAX;
. а это вектор направления
. // dx от ~-6.0 до ~6.0
. p->dx = (float)sin(angle) * max_speed/2;
. // dy от ~-6.0 до ~6.0
. p->dy = (float)cos(angle) * max_speed/2;
. }
}

а при рисовании округляем координаты

PutPixel((int)floor(p->x+.5), (int)floor(p->y+.5));

409
03 октября 2002 года
Ramzes
163 / / 20.09.2000
Цитата:
Originally posted by AL C++ Programmer
>> А почему случайные числа должны быть расположены равномерно?

Мда... Я разве сказал &quot;расположены&quot;?

Равномерное распределение, термин из теории вероятностей
означающий, что любой элемент из множества {0, 1, ... n-1}
может быть выбран с вероятностью 1/n

>> И к чему вся эта туфта с флоатом. Первый вариант нормально работает...

Ты проверял?

Рассмотрим пример:
int x=rand()%10000

rand() возвращает псевдослучайное число от 0 до 32677.
В x окажется число 2768-9999 если rand() вернет:
2768-9999; 12768-19999; 22768-29999 итого 21696 из 32768;
21696/32768 = 0.662109375 а доля чисел 2678-9999 составляет 0.7322 от 10000
В x окажется число 0-2677 если rand() вернет
0-2767; 10000-12767; 20000-22767; 30000-32767 итого 11072 из 32768;
11072/32768 = 0.337890625, а доля чисел 0-2677 составляет 0.2678 от 10000

Вот так-то.

Впрочем, &quot;нормально&quot; понятие относительное, и кого-то такой расклад вполне устраивает...
Так же прошу заметить что я прежде всего Programmer а уже потом C++ Programmer

С уважением, AL C++ Programmer.



Что-то ты перемудрил. Функция rand() возвращает псевдослучайное число от 0 до RAND_MAX при любом раскладе. А потом ты делишь это по модулю на 1000. И получаешь теже числа но в сжатом диапазоне. И все таки ты туфту нагнал. Проверь у себя ошибки, почитай Кнута.
P.S. RAND_MAX не всегда равно 2^16

540
03 октября 2002 года
AL C++ Programmer
36 / / 20.01.2000
Цитата:
Originally posted by Ramzes


Что-то ты перемудрил. Функция rand() возвращает псевдослучайное число от 0 до RAND_MAX при любом раскладе. А потом ты делишь это по модулю на 1000. И получаешь теже числа но в сжатом диапазоне. И все таки ты туфту нагнал. Проверь у себя ошибки, почитай Кнута.
P.S. RAND_MAX не всегда равно 2^16



Укажи мне пожалуйста хоть на одну мою ошибку.
Я знаю, что RAND_MAX не всегда равно 2^16-1, но это не важно...
Важно то, что (rand() % x) будет равномерно распределенной последовательностью случайных чисел только при RAND_MAX кратном x. Т.е. например если x==1000, то RAND_MAX должно быть равно 30000 или 40000, не важно. В противном случае (например, с теми же 32678) вот эти самые 2678 и дают дополнительнуй вероятность выпадения чисел 1-2678...
Т.е. числа 1-2678 будут встерчаться чаще, чем 2679-9999 и 0.
Вариант с флоатом от таких недочетов избавлен.

Простейший вариант проверки - сгенерить 100000 чисел твоим и моим способом и вычислить среднее. С флоатом среднее будет ближе к 5000, а с % ближе к 2678.

P.S. После твоего ответа я специально посмотрел Кнута, на всякий случай, а вдруг я правда ошибся. Хммм... Нет, все правильно.

409
03 октября 2002 года
Ramzes
163 / / 20.09.2000
Цитата:
Originally posted by AL C++ Programmer


Укажи мне пожалуйста хоть на одну мою ошибку.
Я знаю, что RAND_MAX не всегда равно 2^16-1, но это не важно...
Важно то, что (rand() % x) будет равномерно распределенной последовательностью случайных чисел только при RAND_MAX кратном x. Т.е. например если x==1000, то RAND_MAX должно быть равно 30000 или 40000, не важно. В противном случае (например, с теми же 32678) вот эти самые 2678 и дают дополнительнуй вероятность выпадения чисел 1-2678...
Т.е. числа 1-2678 будут встерчаться чаще, чем 2679-9999 и 0.
Вариант с флоатом от таких недочетов избавлен.

Простейший вариант проверки - сгенерить 100000 чисел твоим и моим способом и вычислить среднее. С флоатом среднее будет ближе к 5000, а с % ближе к 2678.

P.S. После твоего ответа я специально посмотрел Кнута, на всякий случай, а вдруг я правда ошибся. Хммм... Нет, все правильно.



Да результаты действительно такие. Но не так сильно отклонение:
(С флоатом среднее будет ближе к 5000, а с % ближе к 2678)

4948.32 - с флоатом
4641.69 - с %

Но для большинства задач наверно подойдет и целочисленный вариант.
А лучше самому написать ГСЧ.

2.4K
03 октября 2002 года
svp
2 / / 03.10.2002
Цитата:
Originally posted by Guest
Как присвоить переменной (int) значение random, те. случайное число, между 0 и 1000


В целых числах можно сделать так:
int RandomValue = rand()*1000/RAND_MAX

Но это справедливо только, если RAND_MAX*1000 не вызывает переполнения int.

Можно еще так:
int RandomValue = (int)(((long)rand())*1000/RAND_MAX)

409
04 октября 2002 года
Ramzes
163 / / 20.09.2000
Цитата:
Originally posted by svp

В целых числах можно сделать так:
int RandomValue = rand()*1000/RAND_MAX

Но это справедливо только, если RAND_MAX*1000 не вызывает переполнения int.

Можно еще так:
int RandomValue = (int)(((long)rand())*1000/RAND_MAX)



Ты читал то что выше?

2.4K
04 октября 2002 года
svp
2 / / 03.10.2002
Цитата:
Originally posted by Ramzes
Ты читал то что выше?


Конечно. Но способ rand()%1000 мне однозначно не нравится по приведенным выше причинам. Или я что-то пропустил ?

298
05 октября 2002 года
zatch
622 / / 20.01.2000
Ребята, это я изначально вопрос задал, и по количиству ответов я понял что это не такая уж легкая тема, впрочем, я уверен что для нормальных кодеров (как вы) нет проблем написать простинькую прогу с использованием рандома...

СПАСИБО ВСЕМ!!!!

зы если нечего не получится я напишу.

-=ZATCH=-
[zatch@mail.ru]
475
08 октября 2002 года
Winnie
90 / / 20.03.2000
понятно что программистом чего-бы не объяснять лишь бы не работать :D

тогда и я приму участие:
- никто не гарантирует что rand() сам по себе генерирует случайное число с равномерным распределением..... он тока гарантирует что оно будет псевдослучайным :) и все....
- при выборке 1000000 мат ожидание:
rand()%1000 - ~497
(float) ля-ля ля - ~499
- если надо "просто случайное число" то rand()%1000 вполне подходит...
- если нужна математически точное нормальное распределение то можно побаловаться и с float.. есть еще более точные алгоритмы использующие несколько значений полученных при помощи rand()... а можно свой алгоритм написать (так например сделано в пакетах a-la MathCad)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог