Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 73, средняя оценка - 4.82
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
#1

Моделирование случайных чисел с экспоненциальным законом распределения - C++

03.04.2012, 00:11. Просмотров 12612. Ответов 28
Метки нет (Все метки)

Программирования случайных чисел с экспоненциальным законом распределения. Товарищи помогите пожалуйста.
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.04.2012, 00:11
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Моделирование случайных чисел с экспоненциальным законом распределения (C++):

Сгенерировать последовательность 60 случайных чисел с экспоненциальным законом распределения с параметром
Сгенерировать последовательность 60 случайных чисел с экспоненциальным законом...

Как подобрать последовательность 100 случайных чисел с экспоненциальным законом на C++
Сгенерировать последовательность 100 случайных чисел с экспоненциальным законом...

Моделирование случайной величины с заданным законом распределения
нужна программка на с++ сгенерировать x по заданным законам распределения...

Генератор случайных чисел, закон распределения задан
Генерация случайных чисел заданным законом распределения. Разработать...

Генерация выборки с заданным законом распределения
Нужна помощь с собственно сабжем, сгенерить выборку распределенную по...

Написание своего генератора случайных чисел с различными плотностями распределения
Помогите найти статьи/книги, где рассматривается написание своего генератора...

28
Kuzia domovenok
2215 / 1984 / 447
Регистрация: 25.03.2012
Сообщений: 6,971
Записей в блоге: 1
03.04.2012, 00:52 #2
Лучший ответ Сообщение было отмечено как решение

Решение

Логарифмическая функция распределения
F=1-exp(-lx)
Тебе нужна обратная ей функция. То есть по оси F откладываем случайные числа от 0 до 1 с равномерным распределением, а соответствующие им значения на оси x будут случайными, распределёнными по нужному нам закону.

Функция распределения F=1-exp(-lx)
Обратная ей будет x=ln(1-F)/(-l)
В итоге получаем
F=rand()/RAND_MAX;//нецелочисленное деление
x=ln(1-F)/(-l)
1-F распределена точно так же, как F, поэтому
x=ln(F)/-l=ln( rand()/RAND_MAX )/-l=( ln(rand()) - ln(RANDMAX))/(-l)

Итог:
C
1
2
3
4
#define LOFFSET ln(RAND_MAX)
double getLrand(double l){
   return (ln(rand()+1)-LOFFSET)/(-l);
}
3
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
03.04.2012, 17:13  [ТС] #3
както слишком просто)

Добавлено через 4 минуты
Компилятор на всё ето говорит ерор
0
Kuzia domovenok
2215 / 1984 / 447
Регистрация: 25.03.2012
Сообщений: 6,971
Записей в блоге: 1
03.04.2012, 17:32 #4
Ну наверное надо ещё добавить, какой еррор.
1
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
03.04.2012, 17:36  [ТС] #5
1>c:\users\славiк\documents\visual studio 2010\projects\slavik15\slavik15\slavik15.cpp(7): error C2601: getLrand: недопустимые локальные определения функций
1> c:\users\славiк\documents\visual studio 2010\projects\slavik15\slavik15\slavik15.cpp(5): эта строка содержит "{", которая пока не имеет парной
1>c:\users\славiк\documents\visual studio 2010\projects\slavik15\slavik15\slavik15.cpp(8): error C2065: RAND_MAX: необъявленный идентификатор
1>c:\users\славiк\documents\visual studio 2010\projects\slavik15\slavik15\slavik15.cpp(8): error C3861: ln: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavik15\slavik15\slavik15.cpp(8): error C3861: rand: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavik15\slavik15\slavik15.cpp(8): error C3861: ln: идентификатор не найден

Добавлено через 1 минуту
И как ещо вывести на екран примерно 100 результатов?
0
Kuzia domovenok
2215 / 1984 / 447
Регистрация: 25.03.2012
Сообщений: 6,971
Записей в блоге: 1
03.04.2012, 18:16 #6
Так ты это не тупо копируй в программу.
Я думал ты умеешь хоть что-то программировать.
Когда ты заговорил о числах с экспоненциальным законом распределения, я подумал: ну уж наверное он знает, что такое случайные числа и может написать в программе простейший генератор равномерно распределённых на интервале чисел.
А это оказывается твоя первая программа! Брось её и пиши Hello World! Приди к тому кто тебе дал задание и скажи "для меня это сложно, научи меня программировать сначала".
Ты хоть понимаешь, что если я напишу её целиком, у тебя умений от этого всё равно не прибавится?
Открой Шилдта или Страуструппа и читай!

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//По теме: надо подключить библиотеки 
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
//Далее пишем наше изобретение
#define LOFFSET ln(RAND_MAX)
double getLrand(double l){
   return (ln(rand()+1)-LOFFSET)/(-l);
}
 
//Затем надо написать главную функцию!
int main(){
  // В главной функции выводишь на экран текст
  printf("Enter size of random sample:");//"введите размер выборки"
  int N;//в этой переменной будем хранить размер выборки
  scanf("%d", &N);//считываем с клавиатуры десятичное целое число и запоминаем его в переменной N
  printf("Enter lambda of distribution");//"Введите лямбду"
  double lambda;//это параметр твоего логарифмического распределения
  scanf("%f", &lambda);//считываем с клавиатуры десятичную дробь и запоминаем её в lambda
  //мы не будем даже массивов использовать или условий проверять - сразу выводим выборку
 //правда для генерации псевдослучайных чисел надо сначало задать seed
  srand ( time(NULL) );
//Итак: цикл вывода
  while (N>0) {//начало цикла. повторения будут происходить пока оставшееся число повторений не 
                  //дойдёт до 0
       printf("%f ", getLrand(lambda));//генерируем элемент выборки и тут же выводим
       N=N-1;//цикл подходит к концу, нам его осталось повторять на один раз меньше, поэтому N-1
   }             ///конец цикла, повторяем всё с места, обозначенного "начало цикла"
 
  getch();//в конце работы программа останавливается и ждёт ввода с клавиатуры, чтобы
 //ты увидел результат перед выходом из программы
  return 0;//возврат  из программы.
}
3
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
03.04.2012, 18:29  [ТС] #7
Очень болшое спасибо. Я уже умею немного, просто с генератором перый раз столкнулся.
0
alexey31415
59 / 59 / 7
Регистрация: 16.05.2010
Сообщений: 632
03.04.2012, 18:57 #8
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
#define LOFFSET ln(RAND_MAX)
double getLrand(double l){
* *return (ln(rand()+1)-LOFFSET)/(-l)
RAND_MAX - это символическая константа или определяемое нами число?а то не сталкивался с RAND_MAX прежде
0
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
03.04.2012, 19:56  [ТС] #9
а ln ето логарифм натуральный? А то мне ошыбку выдает
0
Kuzia domovenok
2215 / 1984 / 447
Регистрация: 25.03.2012
Сообщений: 6,971
Записей в блоге: 1
03.04.2012, 20:01 #10
Цитата Сообщение от alexey31415 Посмотреть сообщение
RAND_MAX - это символическая константа или определяемое нами число?а то не сталкивался с RAND_MAX прежде
из stdlib оттуда же, откуда и rand

Добавлено через 3 минуты
Цитата Сообщение от slavikg Посмотреть сообщение
а ln ето логарифм натуральный? А то мне ошыбку выдает
Нет такой функции ln, надо писать log вместо ln. Это уж я лоханулся.
2
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
03.04.2012, 20:09  [ТС] #11
если я делаю замену на log то мне выбивает
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(7): error C2668: log: неоднозначный вызов перегруженной функции
1> e:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(575): может быть "long double log(long double)"
1> e:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(527): или "float log(float)"
1> e:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(120): или "double log(double)"
1> при попытке сопоставить список аргументов "(int)"
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(7): error C2668: log: неоднозначный вызов перегруженной функции
1> e:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(575): может быть "long double log(long double)"
1> e:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(527): или "float log(float)"
1> e:\program files (x86)\microsoft visual studio 10.0\vc\include\math.h(120): или "double log(double)"
1> при попытке сопоставить список аргументов "(int)"
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(13): error C3861: printf: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(15): error C3861: scanf: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(16): error C3861: printf: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(18): error C3861: scanf: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(21): warning C4244: аргумент: преобразование "time_t" в "unsigned int", возможна потеря данных
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(25): error C3861: printf: идентификатор не найден
1>c:\users\славiк\documents\visual studio 2010\projects\slavi16\slavi16\slavik16.cpp(29): error C3861: getch: идентификатор не найден
0
panicwassano
594 / 562 / 104
Регистрация: 07.11.2010
Сообщений: 2,004
03.04.2012, 20:14 #12
так надо подключить библиотеки
stdio.h
conio.h
math.h
0
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
03.04.2012, 20:19  [ТС] #13
подключены
0
Kuzia domovenok
2215 / 1984 / 447
Регистрация: 25.03.2012
Сообщений: 6,971
Записей в блоге: 1
04.04.2012, 00:18 #14
Вот такой вариант однозначно работает
C++
1
2
3
4
#define LOFFSET log((float)RAND_MAX)
float getLrand(float l){
  return (log(rand()+1.0)-LOFFSET)/(-l);
}
Поставил float перед RAND_MAX. Вообще дефайны, макросы такая тема, в которых я ошибки ищу в последнюю очередь. Ведь компилятор ругается на совершенно другую строчку. А зря, иногда очень неочевидные вещи происходят.
1
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
04.04.2012, 00:50 #15
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Вот такой вариант однозначно работает
C++
1
2
3
4
#define LOFFSET log((float)RAND_MAX)
float getLrand(float l){
  return (log(rand()+1.0)-LOFFSET)/(-l);
}
Зачем несколько раз логарифм брать?
C++
1
-1.0/lambda+log(rand()*1.0/RAND_MAX);
http://upload.wikimedia.org/wikipedi...7bc3280b86.png
2
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
04.04.2012, 16:00  [ТС] #16
А почему мне всегда видает результат -0,0000 ?
0
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
04.04.2012, 16:36 #17
Цитата Сообщение от slavikg Посмотреть сообщение
А почему мне всегда видает результат -0,0000 ?
потому что для double надо в считывании\вводе писать "%lf", а не "%f"
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
 
double getLrand(double l)
{
 return -log((double)(rand())/RAND_MAX)/l;
}
 
int main()
{
 printf("Enter size of random sample:");
 int N;
 scanf("%d", &N);
 printf("Enter lambda of distribution");
 double lambda;
 scanf("%lf", &lambda);
 srand ( time(NULL) );
 while (N>0) 
 {
  printf("%lf ", getLrand(lambda));
  N=N-1;
 }             
 getch();
 return 0;
}
1
alexey31415
59 / 59 / 7
Регистрация: 16.05.2010
Сообщений: 632
04.04.2012, 19:36 #18
Цитата Сообщение от Nekto Посмотреть сообщение
(float)RAND_MAX
а разве и так можно привести переменную к типу float?
0
slavikg
0 / 0 / 3
Регистрация: 03.04.2012
Сообщений: 71
04.04.2012, 21:35  [ТС] #19
а какой вариант правилный тот который ты дал или тамтой что выше ? Ато результати разные
0
Nekto
342 / 287 / 37
Регистрация: 23.03.2012
Сообщений: 838
04.04.2012, 21:36 #20
Цитата Сообщение от slavikg Посмотреть сообщение
а какой вариант правилный тот который ты дал или тамтой что выше ? Ато результати разные
последний. В том я формулу не ту задал.
1
04.04.2012, 21:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.04.2012, 21:36
Привет! Вот еще темы с решениями:

Написать датчик случайных чисел с таблично заданной функцией распределения
Здравствуйте! у меня есть просто текст задачи и не чего больше((может...

ГСЧ для равномерного распределения случайных чисел на заданном интервале
Доброго всем времени суток. Мне нужно получить последовательность случайных...

Запишите шесть строк, состоящих из двух случайных чисел типа int, которые не больше 10 и трех случайных чисел
Запишите шесть строк, состоящих из двух случайных чисел типа int, которые не...

Моделирование случайных величин
С помощью датчика случайных чисел получить 50 целых чисел, равных 0 или 1, и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru