Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.12.2013, 00:41   #1
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию Критерий Колмогорова

Считайте, что я Дед Мороз - дарю. Кому надо может быть.
Критерий Колмогорова для проверки статистической гипотезы о виде распределения. Но здесь у меня - только для проверки равномерного распределения на интервале [a;b].
Обычно проверяют, зараваясь нужным уровнем значимости α. Например, 0,05 или 0,1. И по нему решают - принята/ не принята гипотеза.
Здесь - наоборот, вычисляет критерий и по нему вычисляет α, при котором гипотеза может быть принята.
Код:
program A_A_Kolm;

type arDouble=array of Double;

// сортировка по возрастанию
procedure Puzyrek(var x:arDouble); 
var  t:Double;
     i,j,N:Integer;
begin
 N:=Length(x);
 if N<2 then Exit;
 for i:=0 to N-2 do
  for j:=0 to N-2 do
   if x[j]>x[j+1] then
    begin
     t:=x[j+1];
     x[j+1]:=x[j];
     x[j]:=t;
    end;
end;

// вычисление критерия Колмогорова для равномерного распр.
function krKolmgr(x:arDouble;a,b:Double):Double;
var n,i:Integer;
  df,dfmax:Double;
begin
 n:=Length(x);
 krKolmgr:=-1;  
 if n<2 then Exit;
 Puzyrek(x);
 dfmax:=0;
 for i:=0 to n-1 do
  begin
    df:=Abs((i+1)/n-(x[i]-a)/(b-a));
    if df>dfmax then dfmax:=df;
  end;
 krKolmgr:=dfmax*Sqrt(n);
end;

// функция распределения Колмогорова
function Kolmogor(lam:Double):Double;    
var i,k,n:Integer;
    s:Double;
begin
  Kolmogor:=-1;
  if lam<0 then Exit;
  Kolmogor:=0;
  if lam<0.2 then Exit;
  Kolmogor:=1;
  if lam>3.5 then Exit;
  n:=Round(5.5/lam)+5;
  s:=0;
  if Odd(n)then k:=-1 else k:=1;
  for i:=-n to n do
   begin
    s:=s+k*Exp(-2*i*i*lam*lam);
    k:=-k;
   end;
  Kolmogor:=s;
end;

// пример - проверка генератора Random
// равномерно распределенные на интервале 0..1 числа  
var alph : Double;
    xrnd:arDouble;
    i:Integer;
const N=30;    
begin
  Randomize;
  SetLength(xrnd,N);
  for i:=0 to N-1 do xrnd[i]:=Random;
  alph:=1-Kolmogor(krKolmgr(xrnd,0,1));
  WriteLn(alph:0:6);  // достигнутый уровень значимости
  ReadLn;		
end.
type_Oleg вне форума Ответить с цитированием
Старый 07.01.2014, 22:23   #2
kalosha-stepa
Пользователь
 
Регистрация: 13.09.2012
Сообщений: 25
По умолчанию Критерий

Можно, следующий вопрос , я не могу понять какое а вы тут вычисляете?
kalosha-stepa вне форума Ответить с цитированием
Старый 07.01.2014, 22:46   #3
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию

Альфа - http://ru.wikipedia.org/wiki/Уровень_значимости
type_Oleg вне форума Ответить с цитированием
Старый 07.01.2014, 23:07   #4
kalosha-stepa
Пользователь
 
Регистрация: 13.09.2012
Сообщений: 25
По умолчанию

Все равно не понимаю, как мне отсюда сделать вывод, что мой генератор проходит этот критерий, если у меня альфа=0,9876
kalosha-stepa вне форума Ответить с цитированием
Старый 07.01.2014, 23:21   #5
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию

Цитата из той статьи :
..однако никакой метод статистики, ни даже науки в целом, не может «окончательно доказать» гипотезу...
Популярными уровнями значимости являются 10 %, 5 %, 1 %, и 0,1 %

То есть альфа=0,9876 (98,76 %) - очень даже хорошо.

Кстати, если генератор в самом деле случайный (или псевдослучайный), то выдавать он будет каждый раз разные числа, и альфы тоже будут всякие разные.

Последний раз редактировалось type_Oleg; 07.01.2014 в 23:23.
type_Oleg вне форума Ответить с цитированием
Старый 08.01.2014, 09:09   #6
Veryn4ik1993
Пользователь
 
Регистрация: 12.09.2012
Сообщений: 81
По умолчанию

Как можно засунуть туда мой генератор:
Код:
program r;

var
  f: array[0..1000] of integer;
  i: integer;
begin
 i := 1;
 f[0]:=1;
 f[1]:=1;
  while (i < 30) do
  begin
   f[i+1]:=(f[i]+f[i-1]) mod 10;
  write(f[i-1], ' ');
    inc(i);
  end;
end.
Veryn4ik1993 вне форума Ответить с цитированием
Старый 08.01.2014, 18:16   #7
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию

Veryn4ik1993, можно, правда у вас - дискретная (целочисленная) случайная величина, а кр. Колмогорова лучше для непрерывной. Для дискретных как раз лучше - Пирсона, но функцию хи-квадрат мудрено вычислять.

Но думаю, можно засунуть.
Только я изменю немного. Сделаю генератор в виде функции, и f[0], f[1] - чтобы можно менять, а то будет генерировать всегда одно и то же.
Код:
// проверка по критерию Колмогорова

program A_A_Kolm;

type 
  arDouble=array of Double;
  arInteger=array of Integer;
  
// проверяемый генератор
function fVeryn4ik(kol:Integer;f0,f1:Byte):arInteger;
var i:Integer;
begin
 SetLength(fVeryn4ik,kol);
 i := 1;
 fVeryn4ik[0]:=f0;
 fVeryn4ik[1]:=f1;
  while (i < (kol-1)) do
  begin
   fVeryn4ik[i+1]:=(fVeryn4ik[i]+fVeryn4ik[i-1]) mod 10;
   inc(i);
  end;
end;  

// сортировка по возрастанию
procedure Puzyrek(var x:arDouble); 
var  t:Double;
     i,j,N:Integer;
begin
 N:=Length(x);
 if N<2 then Exit;
 for i:=0 to N-2 do
  for j:=0 to N-2 do
   if x[j]>x[j+1] then
    begin
     t:=x[j+1];
     x[j+1]:=x[j];
     x[j]:=t;
    end;
end;

// вычисление критерия Колмогорова для равномерного распр.
function krKolmgr(x:arDouble;a,b:Double):Double;
var n,i:Integer;
  df,dfmax:Double;
begin
 n:=Length(x);
 krKolmgr:=-1;  
 if n<2 then Exit;
 Puzyrek(x);
 dfmax:=0;
 for i:=0 to n-1 do
  begin
    df:=Abs((i+1)/n-(x[i]-a)/(b-a));
    if df>dfmax then dfmax:=df;
  end;
 krKolmgr:=dfmax*Sqrt(n);
end;

// функция распределения Колмогорова
function Kolmogor(lam:Double):Double;    
var i,k,n:Integer;
    s:Double;
begin
  Kolmogor:=-1;
  if lam<0 then Exit;
  Kolmogor:=0;
  if lam<0.2 then Exit;
  Kolmogor:=1;
  if lam>3.5 then Exit;
  n:=Round(5.5/lam)+5;
  s:=0;
  if Odd(n)then k:=-1 else k:=1;
  for i:=-n to n do
   begin
    s:=s+k*Exp(-2*i*i*lam*lam);
    k:=-k;
   end;
  Kolmogor:=s;
end;

// пример - проверка генератора fVeryn4ik
// дискр. равномерно распределенные на интервале 0..9 числа  
var alph : Double;
    xrnd:arDouble;
    xIrnd:arInteger;
    i:Integer;
    x0,x1:Byte;
const N=30;    
begin
  ReadLn(x0,x1);  // ввод, например  1  1 
  xIrnd:=fVeryn4ik(N,x0,x1);
  SetLength(xrnd,N);
  for i:=0 to N-1 do xrnd[i]:=xIrnd[i];
  alph:=1-Kolmogor(krKolmgr(xrnd,0,9));
  WriteLn(alph:0:6);  // достигнутый уровень значимости
  ReadLn;		
end.
Изображения
Тип файла: jpg kolm.jpg (17.2 Кб, 67 просмотров)
type_Oleg вне форума Ответить с цитированием
Старый 08.01.2014, 19:20   #8
Veryn4ik1993
Пользователь
 
Регистрация: 12.09.2012
Сообщений: 81
По умолчанию

Почему он ошибку выдает
Код:
// проверяемый генератор
function fVeryn4ik(kol:Integer;f0,f1:Byte):arInteger;
var i:Integer;
begin
 SetLength(fVeryn4ik,kol);
 i := 1;
 fVeryn4ik[0]:=f0;
 fVeryn4ik[1]:=f1;
  while (i < (kol-1)) do
  begin
   fVeryn4ik[i+1]:=(fVeryn4ik[i]+fVeryn4ik[i-1]) mod 10;
   inc(i);
  end;
end;
Ошибка:Данный объект не может быть передан как var-параметр
Там по идее массив же должен
Veryn4ik1993 вне форума Ответить с цитированием
Старый 08.01.2014, 19:38   #9
type_Oleg
Старожил
 
Аватар для type_Oleg
 
Регистрация: 02.03.2008
Сообщений: 2,538
По умолчанию

Наверное, у нас разные компиляторы. У меня - fpc (Geany).
Попробуйте вместо этого
Код:
 SetLength(fVeryn4ik,kol);
вот это
Код:
 SetLength(Result,kol);
и дальше все fVeryn4ik только внутри функции заменить на Result

Там по идее массив же должен. Так результат функции - и есть массив.
type_Oleg вне форума Ответить с цитированием
Старый 08.01.2014, 19:50   #10
Veryn4ik1993
Пользователь
 
Регистрация: 12.09.2012
Сообщений: 81
По умолчанию

Спасибо большое вам, очень помогли!А вы тут заикнулись о "хи-квадрат", можно ли спросить, я делаа его для этого же генератора по формуле

для 1000 наблюдений и у меня получилось 2007,5
вот код:
Код:
program r;

var
  f: array[0..1001] of integer;
h: array[0..1001] of integer;
  i,j: integer;g: text;k:integer;
  V:real;

begin
k:=0;
 i := 1;
 f[0]:=1;
 f[1]:=1;
  while (i < 1001) do
  begin
   f[i+1]:=(f[i]+f[i-1]) mod 10;
  //writeln(g, f[i-1], ' ');
  write(f[i-1], ' ');
  write((f[i-1])*(f[i-1]), ' ');
k:=k+(f[i-1])*(f[i-1]);
 inc(i);
 writeln('   ',k);
 V:=(100*k)/1000-1000;
 writeln(V);
 end;
end.
Может ли быть такое, или я неправильно делаю
Veryn4ik1993 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ВПР критерий Artem_85 Microsoft Office Excel 10 08.11.2012 13:59
критерий Сильвестра Roman Фриланс 1 19.04.2012 19:02
критерий Сильвестра Roman Общие вопросы C/C++ 4 12.04.2012 02:30
Уравнения колмогорова ChronoCR Помощь студентам 1 07.04.2011 19:37
задать критерий: от ....до... brans Microsoft Office Excel 6 11.11.2010 17:26