forum.kai.ru

Форум КНИТУ-КАИ
Текущее время: 26 сен 2017, 19:44

Часовой пояс: UTC




Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Си. Генератор случайных чисел
СообщениеДобавлено: 22 сен 2005, 11:43 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 19 май 2005, 05:19
Сообщений: 328
Откуда: Инженер-системотехник, с 09.06.2007
Кто нибудь разрабатывал генератор случайных чисел?
К примеру чтобы к i(int) присвоилось случаное число в диапазоне от 0 до заданного числа?
Поделитесь кодом или идеями :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Си. Генератор случайных чисел
СообщениеДобавлено: 22 сен 2005, 12:30 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 15 апр 2003, 12:09
Сообщений: 1439
Откуда: Кaзань
Anton_K писал(а):
Поделитесь кодом или идеями :)

Помнится в эпоху трёхгерцового МК-56 генератор случайных чисел в диапазоне (0,1) реализовывался так:
K(i+1)=дробная_часть_от(11*K(i)+pi)

Ну чем не код? :)


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Си. Генератор случайных чисел
СообщениеДобавлено: 23 сен 2005, 03:13 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 19 май 2005, 05:19
Сообщений: 328
Откуда: Инженер-системотехник, с 09.06.2007
Alex писал(а):
Помнится в эпоху трёхгерцового МК-56 генератор случайных чисел в диапазоне (0,1) реализовывался так:
K(i+1)=дробная_часть_от(11*K(i)+pi)

Ну чем не код? :)


Прочитал в man rand о случайных числах
там пример есть на генерацию от 0 до 10 на основе этого создал вот такую программку
Код:
#include <stdlib.h>
#include <stdio.h>
main()
{
long int j;
int i;
for(i=0;i<5;i++)
   {
   j=1+(int) (10.0*rand()/(RAND_MAX+1.0));
   printf("%d\n",j);
   }
}

Генерирует последовательность случайных чисел
Код:
[root@FCLinux c]# ./a.out
9
4
8
8
10
[root@FCLinux c]# ./a.out
9
4
8
8
10

и как видно - при каждом запуске программы оодну и туже :( а не случайную. Есть идеи?[/code]


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: Си. Генератор случайных чисел
СообщениеДобавлено: 23 сен 2005, 05:12 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 15 апр 2003, 12:09
Сообщений: 1439
Откуда: Кaзань
Я уж было подумал что генерировать случайные числа вручную надо, а оказывается можно пользоваться rand. :)

Anton_K писал(а):
и как видно - при каждом запуске программы оодну и туже :( а не случайную. Есть идеи?

Там рядом с функцией rand в описании где-то должна быть функция инициализирующая генератор случайных чисел. Randseed или что-то подобное. Как она инициализируется -- зависит от системы (си я не знаю). В других системах она инициализируется либо средствами самой операционной системы (тогда в качестве "опорной точки" берётся например количество миллисекунд от момента загрузки, т.е. типа uptime) либо сохраняется в файле последнее сгенерированное случайное значение чтобы при последующем пуске его считать и использовать его для следующего случайного числа.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 23 сен 2005, 05:51 
Не в сети
Ideology Admin
Аватар пользователя

Зарегистрирован: 13 ноя 2004, 12:14
Сообщений: 2256
Откуда: 4фак. славного КГТУ-КАИ!!!
С Сайта Интуит.ру:

Функция получения случайных чисел
Сейчас мы покажем генератор псевдослучайных чисел. Это означает, что фактическая последовательность чисел предсказуема, но они разбросаны довольно равномерно в пределах возможного диапазона значений.

Схема начинает с числа, называемого "зерно". Она использует его для создания нового числа, которое становится новым зерном. Затем новое зерно можно использовать для создания более нового зерна и т.д. Чтобы эта схема работала, функция случайных чисел должна помнить зерно, которое она использовала при последнем вызове. Отметим, здесь нужно использовать статическую переменную!

/* Первая версия функции rand( )*/
rand( )
{
static int randx = 1;
randx = (randx * 25173 + 13849)%65536;
/* магическая формула */
return(randx);
}
Статическая переменная randx начинает со значения 1 и изменяется при помощи магической формулы каждый раз при вызове функции. Результатом в нашей системе является число, находящееся в диапазоне -32768 до 32767. Системы с разной длиной переменной типа int будут давать различные результаты.

Проверим работу функции при помощи этого простого драйвера:

/*драйвер 1 функции rand( ) */
main( )
{
int count;
for(count = 1; count <= 5; count++)
printf(" %d\n",rand( ));
}
Получим результат:

-26514
-4449
20196
-20531
3882
Эта последовательность чисел выглядит довольно случайной. Запустим драйвер еще раз. Теперь имеем

-26514
-4449
20196
-20531
3882
Получилось абсолютно то же самое. Это и есть псевдоэффект. Каждый раз, когда работает основная программа, мы начинаем с одного и того же значения зерна, равного 1. Можно обойти эту проблему, введя вторую функцию srand( ), которая позволяет вновь устанавливать зерно в начальное значение. Хитрость заключается в том, чтобы сделать randx внешней статической переменной, известной только функциям rand( ) и srand( ). Эти две функции нужно хранить в своем собственном файле и компилировать этот файл отдельно. Вот модификатор программы:

/* Файл для rand( ) и srand( ) */
static int randx = 1;
rand( )
{
randx = (randx * 25173 + 13849) % 65536;
return(randx);
}
srand(x)
unsigned x;
{
randx = x;
}
Используем другой драйвер:

/* драйвер 2 функции rand( ) */
main( )
{
int count;
int seed;
printf(" Введите свое значение зерна.\n");
scanf("%d", & seed);
srand(seed);
/* установите зерно в начальное значение */
for(count = 1; count <= 5; count++)
printf("%\n",rand( ));
}
Программа проработала один раз:

Введите свое значение зерна.

1
-26514
-4449
20196
-20531
3882
Используя значение 1 для переменной seed, получаем те же значения, что и прежде. Введем значение 2 и посмотрим, что получится:

2
23832
20241
-1858
-30417
-16204
Мы получили другую последовательность чисел.

_________________
Только летом может быть счастливым, кто зимой по парусу тоскует


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 23 сен 2005, 08:52 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 19 май 2005, 05:19
Сообщений: 328
Откуда: Инженер-системотехник, с 09.06.2007
Айратский писал(а):

Используя значение 1 для переменной seed, получаем те же значения, что и прежде. Введем значение 2 и посмотрим, что получится:
2
23832
20241
-1858
-30417
-16204
Мы получили другую последовательность чисел.

Ну это же надо опять частично быть самому генератором чисел ) вводя зерно
пока вот на чем остановился - определить диапазон генерации [a;b]
Код:
a + rand() % ((b-a) + 1);

копаю в сторону привязки к железу
посоветанное Алексом uptime нашёл в /proc/uptime
2 разряда после точки меняются там хаотично при каждом просмотре
вобщем истина гдето рядом


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 23 сен 2005, 11:26 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 19 май 2005, 05:19
Сообщений: 328
Откуда: Инженер-системотехник, с 09.06.2007
Объединив всё вышесказанное пришёл вот к чему
Код:
#include <stdlib.h>
#include <stdio.h>
main(int argc, char **argv[])
{
static int randx=1;
FILE *uptime;
float time;
long int t;
int i;  /* Dlina ryada sluchainyh chisel */
int a,b; /*Granicy diapazona, mojno budet zadavat' iz shella v args*/
a=10;
b=100;
/*Vychislenie sluchainogo zerna*/
   uptime=fopen("/proc/uptime","r");
   fscanf(uptime,"%f",&time);
   fclose(uptime);
   time*=randx;
   t=time;
   time=time-t;
   randx=time*10000; /*chem bolshe mnojitel tem sluchainee zerno*/
   printf("Randx = %d; Time = %f\n",randx,time);   
for(i=0;i<10;i++)
   {
   t=a + ((randx * 25173 + 13849)%65536) % ((b-a) + 1);
   randx = (randx * 25173 + 13849)%65536;
   printf("%d\n",t);
   }
}

повторений не замечено


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 27 сен 2005, 07:34 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 26 ноя 2004, 13:21
Сообщений: 257
Откуда: Казань, КАИ, 4-ый фак. ;-)
А можно читать данные из /dev/rand (вроде так называется). Это виртуально устройство, которое генерирует ПСЕВДОСЛУЧАЙНЫЕ числа. Удобство его в том, что можно подключить аппаратный генератор, и все будет работать.

_________________
ВОЗЬМИ ОТ ЖИЗНИ ВСЕ !!!


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 28 сен 2005, 03:29 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 19 май 2005, 05:19
Сообщений: 328
Откуда: Инженер-системотехник, с 09.06.2007
]d1vEr[ писал(а):
А можно читать данные из /dev/rand (вроде так называется). Это виртуально устройство, которое генерирует ПСЕВДОСЛУЧАЙНЫЕ числа. Удобство его в том, что можно подключить аппаратный генератор, и все будет работать.

угу
из устройств
/dev/random и /dev/urandom (более случайные числа но медленней)
вот только незнаю как читать с устройства в С/С++


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 28 сен 2005, 08:06 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 26 ноя 2004, 13:21
Сообщений: 257
Откуда: Казань, КАИ, 4-ый фак. ;-)
Мошно воспользоваться стандартными Сишными функциями или системными выховами open, read, write, close и т.п.

_________________
ВОЗЬМИ ОТ ЖИЗНИ ВСЕ !!!


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 29 сен 2005, 17:56 
Не в сети
Постоянный посетитель Замечаний:1
Аватар пользователя

Зарегистрирован: 10 сен 2004, 10:35
Сообщений: 64
Откуда: Казань(Альметьевск)
А в си есть аналоги таких паскалевских команд

round? frac? exp? ln?

_________________
Здесь была реклама.

Физфак КГУ...


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 29 сен 2005, 19:17 
Не в сети
Постоянный посетитель
Аватар пользователя

Зарегистрирован: 26 ноя 2004, 13:21
Сообщений: 257
Откуда: Казань, КАИ, 4-ый фак. ;-)
Если память мне не врет, то есть. Хотя она может врать, т.к. математикой я давно уже в прогах не анимался. Максимум - это вычисление какого-нить адреса в памяти... ну, или дебета и кредита (хотя мне это не очень то интересно, указатели интереснее :) ).

_________________
ВОЗЬМИ ОТ ЖИЗНИ ВСЕ !!!


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 30 сен 2005, 05:54 
Не в сети
Ideology Admin
Аватар пользователя

Зарегистрирован: 13 ноя 2004, 12:14
Сообщений: 2256
Откуда: 4фак. славного КГТУ-КАИ!!!
Rustam88 писал(а):
А в си есть аналоги таких паскалевских команд

round? frac? exp? ln?

Лучше скажи, что ты хочешь чтоб они делали эти функции.

_________________
Только летом может быть счастливым, кто зимой по парусу тоскует


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 30 сен 2005, 06:06 
Не в сети
Ideology Admin
Аватар пользователя

Зарегистрирован: 13 ноя 2004, 12:14
Сообщений: 2256
Откуда: 4фак. славного КГТУ-КАИ!!!
doble exp(double); Описывается в math.h
ln записвыется в СИ как log: double log(double), описывается также в math.h
Остальные не знаю че делают. :?

_________________
Только летом может быть счастливым, кто зимой по парусу тоскует


Вернуться наверх
 Профиль  
 
 Заголовок сообщения:
СообщениеДобавлено: 13 мар 2006, 13:13 
Не в сети
Постоянный посетитель Замечаний:2

Зарегистрирован: 29 окт 2004, 08:52
Сообщений: 43
Антон, на 5-м курсе пора бы знать такие вещи.
На основе генератора ПСЕВДОслучайныйх чисел можно получать ПСЕВДОслучайные числа с требуемым законом распределения все 3-мя методами:
-Метод обратной функции
-Метод ступенчатой аппроксимации
-Метод Неймана
и все, других методов нет, прикинь да ;)
Береш методичку по моделированию (так она и называется их всего одна в читалке нашего фак-та) и там эти методы описны.
Инициализировать ГПСЧ, вызываемый ф-ей rand можно на основе системного времени - довольно удобно.
Антон не путай случайные величины с ПСЕВДОслучайными, ты не разграничиваешь этих понятий, отсюда все твои проблеммы.
Случайных чисел программным методом получить вообще невозможно!!!
Самое крутое, приближенное к случайности без особых заморочек - "биологический ГСЧ", т.е. нецеленаправленно водишь мышкой по экрану или дубасишь по клавиатуре не пытаясь осознавать что нажимаешь, а результат используешь как посев, правда качество такой последовательности низкое, плохая синхронность, плохая закономерность, закон распределения будет очень "плохой", на основе такого закона не получишь заданный закон.


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 20 ]  На страницу 1, 2  След.

Часовой пояс: UTC


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB