Генератор равномерных случайных величин по технологии полного вихревого массива
ISSN 0236-3933. Вестник МГТУ им. Н.Э. Баумана. Сер. Приборостроение. 2017. № 2
91
чисел 101, 011 и 110. В то же время отрицательным результатом является то, что
во всех полученных последовательностях числа повторяются неравномерно.
Ситуацию можно исправить, если учитывать следующее ограничение.
Чтобы добиться вихря без повторений, необходимо воспользоваться кон-
груэнтным генератором
(
)
(
)
+
= +
−
1
& 2 1
w
i
i
x
ax c
на полной последовательности
чисел, каждое длиной
w
бит. Полные последовательности содержат
2
w
N
=
чи-
сел, т. е. каждая случайная величина
0,
1 0, 2 1
w
x N
∈ − =
−
. Поскольку в вих-
ре сдвиг выполняется
w
раз, то объединение начальной конгруэнтной последо-
вательности с остальными вихревыми последовательностями дает
2
w
w N w
⋅ = ⋅
последовательностей. Возникает вопрос, сколько уникальных (неповторяющих-
ся) последовательностей можно создать, объединяя технологии конгруэнтной и
вихревой генерации?
Далее приведен программный код, позволяющий с помощью функции
MatrixAdd()
расположить генерируемые конгруэнтные и вихревые последова-
тельности в вспомогательной матрице
MS
. В каждой строке находится одна после-
довательность и три вспомогательных элемента. Затем функция
MatrixCheck()
сравнивает последовательность в каждой строке матрицы со всеми остальными
строками. Если последовательность в текущей строке совпадает с любой предыду-
щей строкой, то номер предыдущей строки заносится в первый вспомогательный
элемент. Второй и третий вспомогательные элементы содержат константы конгру-
энтности
a
и
c
. Когда все строки будут проверены, тогда распечатка матрицы поз-
волит обнаружить повторяющиеся последовательности, поскольку их первый
вспомогательный элемент будет отличен от нуля.
static void Main ( string[] args )
{ int w = 3; // битовая длина числа
int N = 8; // длина последовательности
int maskW = 0x7; // маска числа
int maskU = 0x4; // маска старшего бита
Console.WriteLine ( "w = {0} N = {1}", w, N);
int[] x = new int[N]; // случайная последовательность
int[,] MS = new int[2000, N + 3]; // матрица
int M = 0;// количество последовательностей в матрице
int k = 0; // номер полной последовательности
int a = 5, c = 1; // конгруэнтные константы
for ( int x0 = 1; x0 < N; x0++ )
{ Cong_Start( x, N, a, c, x0, maskW );
if ( Repeating ( x, N ) ) continue; // повторение
MatrixAdd ( MS, ref M, x, N, a, c );
Console.WriteLine ( "a = {0} c = {1}", a, c );
k++; // номер последовательности
Console.Write ( "k = {0,4} ", k );
qWrite ( "x = ", x, N, true );
for ( int i = 1; i < 24; i++ )
{ Twist ( x, w, N, maskW, maskU ); // вихрь
if (Repeating(x, N)) continue;
MatrixAdd ( MS, ref M, x, N, a, c );