случайные числа
Здравствуйте! Подскажите пожалуйста, как записать в файл 1000 случайных чисел? Или о как вообще получить эти случайные числа? В паскале это random, а в Си что?
#include <stdlib.h>
int main()
{
randomize();
int x=rand();
return 0;
}
Числа которые выдает rand, как и в паскале random, на самом деле псевдослучайные, но это так, к слову:)
#include <stdlib.h>
int main()
{
randomize();
int x=rand();
return 0;
}
Числа которые выдает rand, как и в паскале random, на самом деле псевдослучайные, но это так, к слову:)
Спасибо, дружище! =)у меня правда это работает в таком виде:
#include<stdlib.h>
int x;
void main()
{
randomize();
x=rand();
}
Спасибо! Теперь буду тестировать на случайном массиве! =)
Спасибо, дружище! =)у меня правда это работает в таком виде:
#include<stdlib.h>
int x;
void main()
{
randomize();
x=rand();
}
Спасибо! Теперь буду тестировать на случайном массиве! =)
А можно как у Мелкомягких:
#include <stdio.h>
#include <time.h>
void main( void )
{
int i;
/* Seed the random-number generator with current time so that
* the numbers will be different every time we run.
*/
srand( (unsigned)time( NULL ) );
/* Display 10 numbers. */
for( i = 0; i < 10;i++ )
printf( " %6d\n", rand() );
}
Хотя не удивлюсь, если обнаружу в сырцах стандартных библиотек запись вроде
{
srand( (unsigned)time( NULL ))
}
А можно как у Мелкомягких:
#include <stdio.h>
#include <time.h>
void main( void )
{
int i;
/* Seed the random-number generator with current time so that
* the numbers will be different every time we run.
*/
srand( (unsigned)time( NULL ) );
/* Display 10 numbers. */
for( i = 0; i < 10;i++ )
printf( " %6d\n", rand() );
}
Хотя не удивлюсь, если обнаружу в сырцах стандартных библиотек запись вроде
{
srand( (unsigned)time( NULL ))
}
НЕсколько слов по поводу случайности, Вы не задумывались на каком зоконе распределения она основана..Я долго мучился чтобы получить нормальное распредление и скажу сразу вероятность повторяемых чисел при использовании rand почти 0,91 что согласитесь круто...
НЕсколько слов по поводу случайности, Вы не задумывались на каком зоконе распределения она основана..Я долго мучился чтобы получить нормальное распредление и скажу сразу вероятность повторяемых чисел при использовании rand почти 0,91 что согласитесь круто...
Как-то не проверял закон распределения выборки rand. Но подозреваю, что равномерное. А что-бы получить нормальное распределение из любого другого существует специальная процедура нормализации выборки. Правда я ее давно забыл:) и, может быть, неправильно выразился :) А что такое вероятность повторяемых чисел ?
Как-то не проверял закон распределения выборки rand. Но подозреваю, что равномерное. А что-бы получить нормальное распределение из любого другого существует специальная процедура нормализации выборки. Правда я ее давно забыл:) и, может быть, неправильно выразился :) А что такое вероятность повторяемых чисел ?
ОН сначала действительно генерит по равномерному а все фунции которые есть для нормализации полный отстой, я сам в учебнике нашел очень хороший способ вылечить эту бяку, а вероятность повторяющихся чисел , это то что к примеру если ты сгенеришь 100 чисел , то возможно что 20 чисел будет одинаковыми...Блин ошибся вероятность не 0,91 а 0,21...:}
ОН сначала действительно генерит по равномерному а все фунции которые есть для нормализации полный отстой, я сам в учебнике нашел очень хороший способ вылечить эту бяку, а вероятность повторяющихся чисел , это то что к примеру если ты сгенеришь 100 чисел , то возможно что 20 чисел будет одинаковыми...Блин ошибся вероятность не 0,91 а 0,21...:}
Мне вообще сдается, что лучше всего побольше замутить, взяв от каждого метода что-то свое, я-бы попробовал после генерилки еще бы их обработать разными там >> сдвигами или поделить % на такое же число, чтобы к примеру 5-значное число собрать из трех. Тогда может получиться уйти от запланированности
Мне вообще сдается, что лучше всего побольше замутить, взяв от каждого метода что-то свое, я-бы попробовал после генерилки еще бы их обработать разными там >> сдвигами или поделить % на такое же число, чтобы к примеру 5-значное число собрать из трех. Тогда может получиться уйти от запланированности
хех... уйти можно и так: (использую Вашу идею)
генерим 3 (три!) массива чисел
массив1 из иксового к-ва элементов от .. до ...
массив2 из иксового к-ва элементов от .. до ...
массив3 из иксового к-ва элементов от 0 до игрек
икс - к-во нужных элементов
.. и ... - диапазон
игрек - к-во операций (сложение, вычитание, умножение и т.д.) (напр. 0 - сложение, 1 - деление нацело, 2 - остаток от деления, ..., игрек - сдвиг по фазе... ;) )
далее в цикле от 0 до икс (индекс - ка) : с катым элементом первого массива производим катую операцию третьего массива над катым элементом второго массива...
вот и всё... кому непонятно, могу объяснить... P(
хех... уйти можно и так: (использую Вашу идею)
генерим 3 (три!) массива чисел
массив1 из иксового к-ва элементов от .. до ...
массив2 из иксового к-ва элементов от .. до ...
массив3 из иксового к-ва элементов от 0 до игрек
икс - к-во нужных элементов
.. и ... - диапазон
игрек - к-во операций (сложение, вычитание, умножение и т.д.) (напр. 0 - сложение, 1 - деление нацело, 2 - остаток от деления, ..., игрек - сдвиг по фазе... ;) )
далее в цикле от 0 до икс (индекс - ка) : с катым элементом первого массива производим катую операцию третьего массива над катым элементом второго массива...
вот и всё... кому непонятно, могу объяснить... P(
Да-да, именно так, а теперь, если не сложно, то же самое кодом, для тех, кому не вполне ясно (кстати про массивы я не догадался)
хех... уйти можно и так: (использую Вашу идею)
генерим 3 (три!) массива чисел
массив1 из иксового к-ва элементов от .. до ...
массив2 из иксового к-ва элементов от .. до ...
массив3 из иксового к-ва элементов от 0 до игрек
икс - к-во нужных элементов
.. и ... - диапазон
игрек - к-во операций (сложение, вычитание, умножение и т.д.) (напр. 0 - сложение, 1 - деление нацело, 2 - остаток от деления, ..., игрек - сдвиг по фазе... ;) )
далее в цикле от 0 до икс (индекс - ка) : с катым элементом первого массива производим катую операцию третьего массива над катым элементом второго массива...
вот и всё... кому непонятно, могу объяснить... P(
Попробуйте сгнерировать две выборки с помощью вашего алгоритма таким образом:
запустите прогу первый раз запишите\запомните выборку чисел, запустите второй раз и сравните с первой. Я думаю обе выборки будут одинаковы.
ОН сначала действительно генерит по равномерному а все фунции которые есть для нормализации полный отстой, я сам в учебнике нашел очень хороший способ вылечить эту бяку, а вероятность повторяющихся чисел , это то что к примеру если ты сгенеришь 100 чисел , то возможно что 20 чисел будет одинаковыми...Блин ошибся вероятность не 0,91 а 0,21...:}
А зачем вам это надо?
Попробуйте сгнерировать две выборки с помощью вашего алгоритма таким образом:
запустите прогу первый раз запишите\запомните выборку чисел, запустите второй раз и сравните с первой. Я думаю обе выборки будут одинаковы.
- при условии отсутствия randomize(); да, а так вероятность очень мала
кстати классная штука в линуксе - как мне говорили он генерит случайные числа собирая аппаратные шумы компа, потому они действительно случайные
- при условии отсутствия randomize(); да, а так вероятность очень мала
кстати классная штука в линуксе - как мне говорили он генерит случайные числа собирая аппаратные шумы компа, потому они действительно случайные
Ну всё зависит от целей, для которых нужно получить последовательность.
Если просто внести элемент случайности - то хватит и стандартных rand-ов. Если для расчётов - монте-карло и всё такое - то лучше поискать что-нить посерьёзней. Генератор ПСП для криптографии -это вообще отдельная наука.
А при помощи генератора ПСП с равномерным распределением можно получить последовательности с любым необходимым распределением, хоть с нормальным, хоть с каким ещё.
А что касается всяких аппаратных шумов - это опять же непонятно, по какому закону они распределены, да и анализ последовательностей показывает, что в таких областях, как криптография, такие физические датчики не применимы
Ну всё зависит от целей, для которых нужно получить последовательность.
Если просто внести элемент случайности - то хватит и стандартных rand-ов. Если для расчётов - монте-карло и всё такое - то лучше поискать что-нить посерьёзней. Генератор ПСП для криптографии -это вообще отдельная наука.
А при помощи генератора ПСП с равномерным распределением можно получить последовательности с любым необходимым распределением, хоть с нормальным, хоть с каким ещё.
А что касается всяких аппаратных шумов - это опять же непонятно, по какому закону они распределены, да и анализ последовательностей показывает, что в таких областях, как криптография, такие физические датчики не применимы
Относительно генерации для монте карло не так просто как кажется на самом деле, так как там нуно учитывать кучу параметров которые влияют на систему...
Относительно генерации для монте карло не так просто как кажется на самом деле, так как там нуно учитывать кучу параметров которые влияют на систему...
Это понятно, что системы сложные. Но всё равно, какая б ни была система, нужен генератор ПСП с равномерным распределением, причём достаточно качественный. А уж дальше - всё зависит от решаемой задачи.
Это понятно, что системы сложные. Но всё равно, какая б ни была система, нужен генератор ПСП с равномерным распределением, причём достаточно качественный. А уж дальше - всё зависит от решаемой задачи.
Во-первых, как я понял, линуск генерит именно не по алгоритму, в отличии от виндов, а во-вторых, распределение вещь хорошая, но когда мне традиционный rand(); выдает примерно так 105668-105446-105224-105003 и т. д., как-то не хочется называть его даже псевдослучайным
Во-первых, как я понял, линуск генерит именно не по алгоритму, в отличии от виндов, а во-вторых, распределение вещь хорошая, но когда мне традиционный rand(); выдает примерно так 105668-105446-105224-105003 и т. д., как-то не хочется называть его даже псевдослучайным
rand() плох уже тем, что он, насколько я помню, выдаёт числа от 0 до (2^16)/2
Этого далеко не всегда достаточно.
А насчёт распределения - построй гистограмму, только выборку сделай побольше. Я думаю, оно будет вполне равномерным. Опять же, смотря для каких целей нужна последовательность. Как я уже говорил, для расчётов МК и криптографии это ну никак не годится :)
хех... уйти можно и так: (использую Вашу идею)
генерим 3 (три!) массива чисел
массив1 из иксового к-ва элементов от .. до ...
массив2 из иксового к-ва элементов от .. до ...
массив3 из иксового к-ва элементов от 0 до игрек
икс - к-во нужных элементов
.. и ... - диапазон
игрек - к-во операций (сложение, вычитание, умножение и т.д.) (напр. 0 - сложение, 1 - деление нацело, 2 - остаток от деления, ..., игрек - сдвиг по фазе... ;) )
далее в цикле от 0 до икс (индекс - ка) : с катым элементом первого массива производим катую операцию третьего массива над катым элементом второго массива...
вот и всё... кому непонятно, могу объяснить... P(
Раз пошла такая пьянка...
Прямиком из книги J. Tennat-Smith, BSc Tech, ATI, FSS, "BASIC statistics":
20 B=M*M-D
30 PRINT:PRINT "Генерирование высококачественных случайных чисел"
40 PRINT:INPUT "Введите длину серии";N
50 PRINT:PRINT "Введите начальное целое число (от 1 до ";D-1;")";:INPUT S
60 R=S
70 FOR I=1 TO N
80 C=INT(R/M)
90 R=B*C+M*(R-M*C)
100 IF R>D THEN R=R-D
110 PRINT R, R/D
120 NEXT I
130 PRINT: PRINT "Начально целое число = ";S:Print "Конечное целое число = ";R
140 GOTO 30
150 END
Перевести на C++ или Pascal, думаю, несложно.
Если кто захочет, могу процитировать из этой книги некоторое описание концепции этого генератора ПСЧ, но оно там довольно лаконичное.
Кстати, автор настоятельно не рекомендует упрощать данный алгоритм, т.к. упрощённый алгоритм даёт быстро вырождающуюся последовательность псевдослучайных чисел.
Дело в том, что для получения "более равновероятностных" величин, я в цикле несколько раз вызывал randomize(). И каждый раз, видимо, датчик инициализировался одним и тем же "семенем".
А если всё-таки попробовать как у Мелкомягких:
Ы?
А если всё-таки попробовать как у Мелкомягких:
Ы?
Спасибо, попробую, кстати, и цитатку можно приписать тоже, пригодится (в смысле из книжки)
P. S. А чего там была за лингва, вроде не ассемблер, fortran какой-ньть?
Спасибо, попробую, кстати, и цитатку можно приписать тоже, пригодится (в смысле из книжки)
P. S. А чего там была за лингва, вроде не ассемблер, fortran какой-ньть?
Язык, конечно, Basic (Бэйсик). Не Visual и даже не Quick, а просто.
А вот и обещанная цитата из книги.
4.6 Получение высококачественных случайных чисел.
Для серьёзных задач моделирования весьма существенно умение генерировать качественную последовательность псевдослучайных чисел и, кроме этого, желательно иметь возможность при необходимости повторить эту последовательность. Этим требованиям удовлетворяют метеды, основанные на формуле
R[n+1] = M * R[n] - D * INT(M * R[n] / D)
которая при соответствующем подборе целых величин M и D вырабатывает случайные целые числа между 1 и D - 1. Возьмём для примера целые значения 10 и 97 (которые слишком малы для практического использования) и, положив R[0] = 1, получим такую последовательность:
R[1] = 10 * 1 - 97 * INT(10 * 1 / 97) = 10
R[2] = 10 * 10 - 97 * INT(10 * 10 / 97) = 3
R[3] = 10 * 3 - 97 * INT(10 * 3 / 97) = 30
Далее последовательность продолжается числами 9, 90, 27, 76, 81, 34, 49 и т.д. Указанные значения M и D удобны для составления и отладки программы генерирования псевдослучайных чисел, но затем их необходимо заменить на лучшую пару. Известно, например, что превосходную пару составляют числа M = 8192 и D = 37101323.
Трудности тем не менее остаются. Последовательность окажется неудовлетворительной, если действия над целыми числами выполняются неточно, а ведь в нашем случае требуется умножение 8192 на 6711323, что, как показано в разд. 3.1, превосходит возможности большинства компьютеров, использующих Бейсик. Выход состоит в том, что большие целые числа разбиваются на два или более отдельных целых числа с тем, чтобы одно из них было кратно 10000, а другое представляло собой остаток от деления на 10000. Арифметические действия выполняются аналогично программе 3.8, но, кроме того, требуется программа деления. Чтобы разработать такой алгоритм, необходима некоторая изобретательность. Предлагаемая здесь программа 4.4 использует в качестве множителей не 10000, а M. Применяемый в ней быстрый метод деления на D основан на том, что число D больше M * (M - 1) и меньше M ^ 2, что справедливо для обеих рассмотренных пар значений. При этом необходимо, чтобы в Бейсике точно выполнялись действия над целыми числами до величины M ^ 2, что бывает не во всех версиях языка (на нашем микрокомпьютере такая возможность имелась). Читателю также будет небезынтересно проследить за работой этой программы с помощью карандаша и бумаги, "прокрутив" её с указанными значениями M и D вручную. Следует отметить, что получающаяся последовательность состоит из целых чисел, однако при практическом использовании может протебоваться деление случайных целых чисел на D с целью получения случайных значений, лежащих в диапазоне между 0 и 1.
Программа 4.4
20 B=M*M
30 PRINT:PRINT:PRINT "Генерирование высококачественных случайных чисел"
40 PRINT:INPUT "Введите длину серии "; N
50 PRINT:PRINT "Введите начальное целое число (от 1 до ";D-1;")";:INPUT S
60 R=S
70 FOR I=1 TO N
80 C=INT(R/M)
90 R=B*C*M+M*(R-M*C)
100 IF R>D THEN R=R-D
110 PRINT R,R/D
120 NEXT I
130 PRINT:PRINT "Начальное целое число = ";S:PRINT "Конечное целое число =";R
140 GOTO 30
150 END
На практике, разумеется, строку 110 следует заменить некоторой последовательностью операций моделирования, использующих случайное число R/D или какой-нибудь его множитель. В строке 130 для напоминания выдаются на печать начальное и конечное целые числа. Если, например, S = 1 и N = 10000, то получающаяся последовательность случайных чисел будет всегда одной и той же, что может быть удобно при сравнении качества работы различных систем обслуживания, сталкивающихся с одной той же последовательностью заявок. В этом случае конечное число равно 42995302, и экспериментатор будет знать, что, используя его значение в качестве начального, он получит новую последовательность от 10000 случайных чисел. Более того, объединение результатов двух серий даст в точности такой же результат, как и использование одной серии из 20000 чисел.
Повторив утверждение о том, что огромные потенциальные возможности статического моделирования трудно переоценить, мы должны ещё раз подчеркнуть важность тщательной постановки статического эксперимента и использования высококачественных случайных чисел, предпочтительно в виде воспроизводимой последовательности. Малое знание опасно, и в статистике, пожалуй, более опасно, чем в других предметах.
Нам однажды встретился студент, который полагал, что можно работать с дробями и тем самым обойтись без больших целых чисел типа 8192 и 67101323, и наверняка он был не одинок в своём сомнении. В сущности его метод выглядел так, как в программе 4.5
Программа 4.5
20 PRINT:PRINT:PRINT "Оптимистичные случайные числа"
30 PRINT:INPUT "Введите длину серии "; N
40 PRINT:PRINT "Введите начальное целое число (от 1 до ";D-1;")";:INPUT S
50 X=S/D
60 FOR I=1 TO N
70 X=M*X:X=X-INT(X)
80 PRINT X
90 NEXT I
100 END
Если бы компьютер точно делил числа, по программа 4.5 давала бы те же самые результаты, что и программа 4.4. Но, так как вычисления в компьютере производятся неточно, оказалось. что этот метод в конце концов приводит к вырождению вырабатываемой последовательности в последовательность нулей. Но насколько быстро последовательность выродится? Вы, наверное, удивитесь не меньше, чем мы, когда станете проверять работу программы 4.5.
Программа 3.8
20 T=1000:Z$="000"
30 PRINT:PRINT "Точное произведение целых чисел"
40 PRINT:INPUT "Введите первое число";A$
50 LA=LEN(A$):NA=INT((LA-1)/3)
60 FOR I=0 TO NA-1
70 A(I)=VAL(MID$(A$,LA-2-3*I,3))
80 NEXT I
90 A(NA)=VAL(LEFT$(A$,LA-3*NA))
100 PRINT:INPUT "Введите второе число";B$
110 LB=LEN(B$):NB=INT((LB-1)/3)
120 FOR I=0 TO NB-1
130 B(I)=VAL(MID$(B$,LB-2-3*I,3))
140 NEXT I
150 B(NB)=VAL(LEFT$(B$,LB-3*NB))
160 NC=NA+NB+1
170 FOR I=1 TO NC: C(I)=0:NEXT I
180 FOR I=1 TO NA
190 FOR J=0 TO NB
200 K=I+J:X=A(I)*B(J)+C(K)
210 Y=INT(X/T):C(K)=X-T*Y
220 IF Y>0 THEN K=K+1:X=Y+C(K):GOTO 210
230 NEXT J
240 NEXT I
250 PRINT:PRINT "Произведение = ";
260 IF C(NC)=0 THEN NC=NC-1
270 PRINT C(NC)
280 FOR I=NC-1 TO 0 STEP -1
290 PRINT ",";RIGHT$(Z$+STR$(C(I)),3);
300 NEXT I
310 GOTO 30
320 END
Да, материалец многообещающий, однако есть ли статистика по нему, скажем сгенерить 1000000 чисел и сравнить, или десяток файлов по млн-у каждый, потом вывести процент и посмотреть чаво надо поменять или не надо...
Кстати, может под винды еще хороший источник для генерилки - аппаратная температура из биоса- кадый раз немного разная
///
Вот этот самый srand( (unsigned)time( NULL ));
у меня вообще выдавал одно и тоже число - это чего была хохма?
[/CODE]
Вот этот самый srand( (unsigned)time( NULL ));
у меня вообще выдавал одно и тоже число - это чего была хохма?
Небось, 0?
Это не хохма. Функция srand() инициализирует генератор случайных чисел, а для собственно генерации надо пользоваться функцией rand().
Столько не делал, но с 10 и 97 он, афаир, выдавал 97 неповторяющихся чисел... Проверял очень давно.
Раз пошла такая пьянка...
Мне всё эти случай ные числа покая не дают...
Вспомнил ещё один простой алгоритм, который я применял:
static double myRandField;
double mySetRand(double NewRand) // инициализация
{
return myRandField = NewRand;
}
double myRand(void)// генерируем новое СЧ.
{
double p;
p = myRandField + myPI;
p = p * p * p * p;
return myRandField = fabs(p - (double)((int)p));
}
Мне всё эти случай ные числа покая не дают...
Вспомнил ещё один простой алгоритм, который я применял:
static double myRandField;
double mySetRand(double NewRand) // инициализация
{
return myRandField = NewRand;
}
double myRand(void)// генерируем новое СЧ.
{
double p;
p = myRandField + myPI;
p = p * p * p * p;
return myRandField = fabs(p - (double)((int)p));
}
Лучше всего генерировать случайные числа по тактам процессора...
Небось, 0?
Это не хохма. Функция srand() инициализирует генератор случайных чисел, а для собственно генерации надо пользоваться функцией rand().
Ну я так и думал, все опять на rand(), а мелкомягкий мне писал одно и тоже число, восьмизначное, типа 36475869, кстати вот этот rand() по-моему самый левый из них всех
Столько не делал, но с 10 и 97 он, афаир, выдавал 97 неповторяющихся чисел... Проверял очень давно.
Нисколько не умаляя авторитет книги, хотел бы заметить, что мой, который почти у же долепил, выдает спокойно 4500 разных чисел(от 4 - до 10- значных), без повторов, другое дело что Rich упорно не хочет вмещать больше, а чаво делать, пока не придумал, (память под лишни естроки чтоли выделять?)Если кто с таким сталкивался, чтоньть посоветуйте
Нисколько не умаляя авторитет книги, хотел бы заметить, что мой, который почти у же долепил, выдает спокойно 4500 разных чисел(от 4 - до 10- значных), без повторов, другое дело что Rich упорно не хочет вмещать больше, а чаво делать, пока не придумал, (память под лишни естроки чтоли выделять?)Если кто с таким сталкивался, чтоньть посоветуйте
Дык, 97 -- это на паре 10 и 97. На паре M=8192 и D=37101323 алгоритм де юре должен выдавать 37101322 неповторяющихся числа.
Я, кстати, делал не со строками, а элементарно с БД (Paradox или Access). Кстати, когда я проверял алгоритм с первой парой чисел (это было очень давно, СУБД для персоналок тогда были слабо распространены ввиду отсутствия на большинстве персоналок жёстких дисков), обходился массивом.
Кстати, если надо получить большее количество неповторяющихся чисел, никто не мешает поэкспериментировать с другими парами, требования к ним изложены в вышеотквоченной статье.
В качестве "Рича" рекомендую попробовать RichView.
Дык, 97 -- это на паре 10 и 97. На паре M=8192 и D=37101323 алгоритм де юре должен выдавать 37101322 неповторяющихся числа.
Я, кстати, делал не со строками, а элементарно с БД (Paradox или Access). Кстати, когда я проверял алгоритм с первой парой чисел (это было очень давно, СУБД для персоналок тогда были слабо распространены ввиду отсутствия на большинстве персоналок жёстких дисков), обходился массивом.
Кстати, если надо получить большее количество неповторяющихся чисел, никто не мешает поэкспериментировать с другими парами, требования к ним изложены в вышеотквоченной статье.
В качестве "Рича" рекомендую попробовать RichView.
Столько внимания сл. числам?
Столько внимания сл. числам?
Да. Одно время я занимался генераторами случайных чисел, а тут вдруг о них заговорили. Вот я и решил поделиться.
_
Да. Одно время я занимался генераторами случайных чисел, а тут вдруг о них заговорили. Вот я и решил поделиться.
_
Согласен.