|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 14, 2004 00:22:31 Я теорвер много косил в универе, поэтому люди добрые, помогите кто чем сможет… У нас есть rand(), равный 0 ~ RAND_MAX. Для удобства возьмем double Rnd(void) { return double(rand())/RAND_MAX; } Теперь у нас есть Rnd, равная 0 ~ 1. А теперь следующее. У нас есть double f(double x), и она является плотностью (или распределением – решайте сами, как будет проще) некоторой случайной величины. А теперь внимание вопрос: Как выразить эту случайную величину через Rnd и f ? PS: Считаем, что Rnd имеет линейное распределение. |
|
|
Дата: Июн 14, 2004 01:17:01 Не очень понял. Есть плотность вероятности, и нужно выдавать случайные значения в соответствии с этой плотностью ? (например: имеем распределение Гаусса: нужно получить набор псевдослучайных данных по этому распределению). Тогда можно разбить распределение F(x)плотности на отрезки по Xi, разбить интервал [0,1] на отрезки, пропорциональные F[Xi] и, кидая случайное число, получать соответственно значение Xi. 1514475324__ |
|
|
Дата: Июн 14, 2004 01:42:54 Ну вообщем-то ты правильно понял. Вот только аттач твой не читается :( А вот я не очень понял про твой способ... |
|
|
Дата: Июн 14, 2004 10:43:10 Для непрерывных случайных величин Чтобы сгенерировать случайную величину по функции распределения Y~F(x), нужно найти обратную к функции распределения F^(-1). Если r-равномерно распределенная величина, то y=F^(-1)(r) - распределена по заданному закону F(x). Например: экспоненциальное распредедение F(x)=1-exp(-a*x). Обратная функция F^(-1)(x)=-1/a*ln(1-x). Если r - равномерно распределенная величина, тогда Z=F^(-1)(r)=-1/a*ln(1-r) - экспоненциально распределенная величина. При вычислениях (1-r) можно заменить на r. |
|
|
Дата: Июн 14, 2004 15:28:20Ну вообщем-то ты правильно понял. Вот только аттач твой не читается :( А вот я не очень понял про твой способ... Аттача не было - это глюк какой-то. Насчет моего способа -вот, нашел - от института осталось (паскаль) - в нем я получаю множество чисел по распределению Гаусса: Начало проги. Переменные и т.п.
{$N+}
var
i,j,k,l,h:longint;
f,g:text;
fname,fresult:string;
E,dE,Sigma,z,z1,N1,N2:real;
mas:array[1..200] of longint;
gauss:array[0..2000] of double; { Набор отрезков }
label esc;
Расперделение Гаусса - это: F(N) = (1/2sqrt(pi)*Sig) * exp( - (N-Naver)^2 / 2*Sig^2 ), где Naver - среднее распределния, а Sig - ширина распределения (среднеквадратичное отклонение).
begin
{ Определяем ширину распределения }
Sigma:=10.0*125/20.00;
{ z будет суммой длин отрезков Fi }
z:=0;
{ Заполняем массив gauss значениями Fi: }
{ gauss[0] = F[N0]; }
{ gauss[1] = F[N0]+F[N1]; }
{ gauss[2] = F[N0]+F[N1]+F[N2]; }
{ ... }
{ где F - значение плотности распределения Гаусса }
gauss[0]:=0;
{ Всего будет 2000+1 отрезков }
for i:=1 to 2000 do
begin
{ Текущее значение аргумента распределения - Ni }
N1:=i*0.2;
{ Вычисляем значение плотности вероятности F(Ni) }
z1:=0.2*(1/(sigma*sqrt(2*3.14)))*exp(-(N1-200)*(N1-200)/(2*Sigma*Sigma ));
z:=z+z1;
gauss[i]:=z1+gauss[i-1];
end;
{ Выводим полученное значение суммы длин отрезков }
writeln(z);readln;
{ Получаю исходное состояние моделируемого распределения }
for i:=1 to 200 do mas[i]:=0;
{ Разогрев генератора случайных чисел }
randomize;
{ Тут я открываю какие-то файлы - наверное, с экспериментальными данными }
fname:='c:\tp\bin\mgu\15.dat';
fresult:='c:\tp\bin\mgu\all.dat';
assign(f,fname);
reset(f);
k:=0;
h:=1000;
for i:=1 to 10000 do
begin
if i=h then writeln(i);
if i=h then h:=h+1000;
{ Получение случаного значения по распределению Гаусса }
{ Получаем случайное число }
l:=random(60000);
j:=0;
repeat
j:=j+1;
{ Ищем номер отрезка - j - на котором выпало }
{ случайное число }
if ((l/60000)>=Gauss[j-1]/z) and ((l/60000)<Gauss [j]/z) then dE:=(j*0.2-200);
until (((l/60000)>=Gauss[j-1]/z) and ((l/60000)<Gauss[j]/z));
j:=0;
E:=125.0;
E:=E+dE;
if E<0 then goto esc;
repeat
j:=j+1;
if (E>=((j-1)*125/20.00)) and (E<(j*125/20.00)) then mas[j]:=mas[j]+1;
if (E>=((j-1)*125/20.00)) and (E<(j*125/20.00)) then k:=k+1;
until (E>=((j-1)*125/20.00)) and (E<(j*125/20.00));
esc:
end;
close(f);
assign(f,fresult);
rewrite(f);
for i:=1 to 200 do
begin
writeln(f,i-1,' ',2500*mas[i]/k:4:0);
end;
close(f);
end.
Вот так примерно. Честно говоря, это черновик какой-то и было это в институте. Если будут вопросы, я попробую объяснить подробнее. |
|
|
Дата: Июн 14, 2004 16:10:42 Вот. Подумал я и переписал понятнее:
{$N+}
const
Sigma: double = 2.0;
Aver: double = 5.0;
StepsNumber = 100; { Число разбиений оси X }
var
Fi: double; { Значение плотности распределения }
Ni: double; { Значение аргумента плотности распределения }
Fsum: double; { Сумма значений всех отрезков - должна быть примерно 1, }
{ поскольку распределение нормировано на 1 }
i,j: integer; { Рабочий индекс }
gauss: array[0..StepsNumber] of double;
RandVal: double; { Случайное число типа double }
begin
{ Инициализация генератора случайных чисел }
randomize;
Fsum:=0.0;
gauss[0]:=0.0;
for i:=0 to StepsNumber do
begin
{ Вычисляем аргумент распределения - N }
Ni:=((Aver*2)/StepsNumber)*i;
Fi:=(1/(Sigma*sqrt(2*3.14)))*exp(-(Ni-Aver)*(Ni-Aver)/(2*Sigma*Sigma)) ;
gauss[i]:=((Aver*2)/StepsNumber)*Fi+gauss[i-1];
Fsum:=Fsum+((Aver*2)/StepsNumber)*Fi;
end;
{ выводим сумму отрезков }
writeln('Summ of Fi=',Fsum); readln;
{ Получаем "случайные" числа по распределению Гаусса }
for j:=0 to 10 do
begin
RandVal:=random(10000)/10000;
i:=-1;
repeat
inc(i);
Ni:=((Aver*2)/StepsNumber)*i;
until RandVal < gauss[i+1];
writeln('rand val by gauss distr = ',Ni);
end;
end.
Разумееется, таблицу плотностей готовить не обязательно - можно вычислять обратное значение. Но такой метод подходит для ПРОИЗВОЛЬНОГО распределения. |
|
|
Дата: Июн 17, 2004 22:20:14 Kozyr Минуточку... А в каких пределах заключена r? Ведь бесконечных распределений не бывает. Как выразить эту случайную величину через r=[0;1] ? |
|
|
Дата: Июн 17, 2004 22:23:19 _Chingachguk_ Может я что-то не так понял, но похоже что ты выполняешь численное интегрирование плотности... Попахивает извращением... |
|
|
Дата: Июн 18, 2004 10:19:19 · Поправил: Kozyr _DEN_ Минуточку... А в каких пределах заключена r? r - равномерно распределенная величина из [0;1]. Функция распределения F(x) - принимает значения из [0;1], x~R. F^(-1)(x) принимает значения из R, а х должно быть из [0;1]. Данный метод как и вся математика: очень точный и иногда очень трудно реализуемый ;) Трудности связаны с нахождением обратной функции. На enlight.ru есть примеры генераторов. |
|
|
Дата: Июн 18, 2004 12:29:31 Kozyr Все, прочувствовал :) Спасибо за идею. По ссылочке обязательно слазию. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.047 |