РЕДАКТИРОВАТЬ:
Как Пол Ханкин в комментариях, мой оригинальный тест только проверил, что вероятность попадания каждого элемента в каждую позицию, но не всеперестановки одинаково вероятны, что является более строгим требованием.Приведенный ниже фрагмент подсчитывает частоту каждой перестановки, на что мы и должны смотреть:
import math
import random
def knuth_shuffle(ar):
num = len(ar)
for i in range(num):
index = random.randint(0, i)
ar[i], ar[index] = ar[index], ar[i]
return ar
# This function computes a unique index for a given permutation
# Adapted from https://www.jaapsch.net/puzzles/compindx.htm#perm
def permutation_index(permutation):
n = len(permutation)
t = 0
for i in range(n):
t = t * (n - i)
for j in range(i + 1, n):
if permutation[i] > permutation[j]:
t += 1
return t
N = 6 # Test list size
T = 1000 # Trials / number of permutations
random.seed(100)
n_perm = math.factorial(N)
trials = T * n_perm
ar = list(range(N))
freq = [0] * n_perm
for _ in range(trials):
ar_shuffle = ar.copy()
knuth_shuffle(ar_shuffle)
freq[permutation_index(ar_shuffle)] += 1
Если случайный порядок равен, значения результирующего вектора freq
должны быть распределены в соответствии с биномиальнымраспределение с T * N!
испытаниями и вероятностью успеха 1 / (N!)
.Вот график оценки распределения для предыдущего примера (с Seaborn ), где значения частоты должны быть около 1000:
Что, мне кажется, выглядит хорошо , но для количественного результата вам потребуется более глубокий статистический анализ, такой как критерий хи-квадрат Пирсона , как предлагает ДэвидEisenstat .
ОРИГИНАЛЬНЫЙ ОТВЕТ:
Я собираюсь изложить здесь некоторые основные идеи, но у меня нет сильнейшего фона длястатистика, так что кто-то может захотеть дополнить или исправить все, что не так.
Вы можете составить матрицу частот каждого значения, попадающего в каждую позицию для ряда испытаний:
def knuth_shuffle(ar):
num = len(ar)
for i in range(num):
index = random.randint(0, i)
ar[i], ar[index] = ar[index], ar[i]
return ar
N = 100 # Test list size
T = 10000 # Number of trials
ar = list(range(N))
freq = [[0] * N for _ in range(N)]
for _ in range(T):
ar_shuffle = ar.copy()
kunth_shuffle(ar_shuffle)
for i, j in enumerate(ar_shuffle):
freq[i][j] += 1
Один разВы можете сделать это, есть несколько подходов, которые вы можете использовать.Простая идея состоит в том, что если перемешивание равномерно, freq / T
должно стремиться к 1 / N
, поскольку T
стремится к бесконечности.Таким образом, вы можете просто использовать «очень большое» значение T
и увидеть, что эти значения «достаточно близки».Или проверьте, что стандартное отклонение freq / T - 1 / N
является «достаточно маленьким».
Эти «достаточно близкие» и «достаточно маленькие», хотя и не очень твердые понятия.Обоснованный анализ требует большего количества статистических инструментов.Я думаю, вам нужно будет проверить гипотезу , что каждое значение частоты выбирается из биномиального распределения с T
испытаниями с 1 / N
вероятностью успеха.Как я уже сказал, у вас нет предыстории для полного объяснения этого, и это, вероятно, не место для этого, но если вам действительно нужен тщательный анализ, вы можете прочитать эту тему.