Второй тест, который мы проведем, - тест на пропуски - несколько сложнее первого. Тест на пропуски гарантирует, что последовательность случайных чисел не будет попадать сначала в один поддиапазон, а затем в другой, третий и т.д., несмотря на то, что в целом значения будут распределены равномерно по всему диапазону. Определим в диапазоне поддиапазон, скажем, первую половину - от 0.0 до 0.5. Сформируем набор случайных чисел. Для каждого генерируемого числа будем проверять, попадает ли оно в выбранный поддиапазон (попадание) или нет (промах). В результате проверок будет получена последовательность попаданий и промахов. Найдите последовательности из одного и большего количества промахов (такие последовательности называются пропусками, отсюда и название теста - тест на пропуски). Вы получите последовательности из одного, двух и даже большего количества промахов. Разбейте длины пропусков на категории. Если известно, что вероятность попадания равна р (в нашем случае она будет равна длине выбранного поддиапазона), то вероятность промаха будет (1 -р). На основе этих данных можно определить вероятность возникновения пропуска из одного промаха - (1 -р)р, двух промахов - (1 -р)2р, п промахов - (1 -р)пр, а, следовательно, вычислить ожидаемое количество пропусков любой длины. После этого применим тест по критерию хи-квадрат. Будем использовать 10 категорий пропусков (поскольку вероятность возникновения пропусков длиной 11 и более промахов очень мала, все пропуски длиной 10 и более будут учитываться в последней категории; при этом, конечно, следует учитывать реальную вероятность попадания длины пропуска в эту последнюю категорию), следовательно, мы получим девять степеней свободы. Как правило, тест на пропуски проводится пять раз: для первой и второй половины диапазона, а также для первой, второй и третьей третей диапазона.

Листинг 6.6. Тест на пропуски

procedure GapTest(RandGen : TtdBasePRNG;
Lower, Upper : double;
var ChiSquare : double;
var DegsFreedom : integer);
var
NumGaps : integer;
GapLen : integer;
i : integer;
p : double;
Expected : double;
ChiSqVal : double;
R : double;
Bucket : array [0. .pred(GapBucketCount) ] of integers-begin
{вычислить длины пропусков и определить количество пропусков в каждой категории) FillChar(Bucket, sizeof(Bucket), 0);
GapLen := 0; NumGaps := 0;
while (NumGaps <
GapsCount) do begin R :== RandGen. As Double;
if (Lower <= R) and (R <
Upper) then begin
if (GapLen >= GapBucketCount) then GapLen := pred(GapBucketCount);
inc(Bucket[GapLen]);
inc(NumGaps);
GapLen := 0; end else
if (GapLen <
GapBucketCount) then inc(GapLen);
end;
p := Upper - Lower;
ChiSqVal := 0.0;
{обработать все категории, кроме последней) for i : = 0 to GapBucketCount-2 do begin Expected := p * IntPower(1-p, i) * NumGaps;
ChiSqVal := ChiSqVal + (Sqr (Expected - Bucket [i]) / Expected) ;
end;
{обработать последнюю категорию)
i : = pred (GapBucketCount) ;
Expected IntPower (1-p, i) * NumGaps;
ChiSqVal := ChiSqVal + (Sqr (Expected - Bucket [i]) / Expected) ; {вернуть значения) ChiSquare := ChiSqVal ; DegsFreedom : = pred(GapBucketCount); •nd;

Тест на однородность || Оглавление || Тест "покер"


Фундаментальные алгоритмы и структуры данных в Delphi



Новости за месяц

  • Сентябрь
    2019
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс