Вот процедура на python с эмпирическим тестом на однородность.
Сначала случайный генератор целых чисел в диапазоне 1..5:
>>> def r5(): return randrange(5) + 1
>>> bins = dict((i, 0) for i in range(9))
>>> pp(bins)
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0}
>>> for i in range(999999): bins[r5()] += 1
>>> pp(bins)
{0: 0, 1: 199752, 2: 200378, 3: 200452, 4: 199580, 5: 199837, 6: 0, 7: 0, 8: 0}
Обратите внимание на то, что бин имеет значение длязначения 1..5.
Используемый алгоритм состоит в том, что, если вы сгенерируете два числа r5 () по порядку, то их 5 * 5 = 25 возможных перестановок, которые имеют равную вероятность появления.если мы возьмем какую-либо константу 21 из этих перестановок, мы сможем увидеть, находится ли сгенерированная нами пермь в этой 21 и превратить каждые три значения в одно из семи целых чисел для возврата.Если мы генерируем перестановку не в 21, то нам нужно получить еще два значения r5 () и повторить.
Код для r7 зависит от некоторых констант, которые я сделал глобальными для скорости:
>>> list5 = [1,2,3,4,5]
>>> perm21 = [(x,y) for x in list5 for y in list5 ][:21]
>>> set21 = set(perm21)
>>> def r7():
r = (6,6)
while r not in set21:
r = (r5(), r5())
return (perm21.index(r) // 3) + 1
>>> bins = dict((i, 0) for i in range(9))
>>> for i in range(999999): bins[r7()] += 1
>>> pp(bins)
{0: 0,
1: 142857,
2: 143558,
3: 143046,
4: 142699,
5: 142786,
6: 142439,
7: 142614,
8: 0}
>>>
Давайте попробуем взглянуть на разброс в 10 раз больше проб:
>>> bins = dict((i, 0) for i in range(9))
>>> for i in range(9999999): bins[r7()] += 1
>>> pp(bins)
{0: 0,
1: 1429821,
2: 1429851,
3: 1427350,
4: 1428478,
5: 1425243,
6: 1429618,
7: 1429638,
8: 0}
Мне кажется, хорошо: -)