Обновить

Комментарии 3

Можно не делать перестановки, а брать каждый раз случайный номер в уже уменьшенном массиве. Это вроде будет быстрее

Насчет быстрее не знаю, но это ещё и будет правильно, потому что дает истинно равновероятные итоговые перестановки. А в представленном коде получается n^(n-1) исходов, которые довольно хорошо, но не идеально распределяются по n! перестановкам (одно на другое не делится). Собственно, автор почти открыл "тасование Фишера-Йетса", и его ошибка даже упомянута в статье на Википедии.

Классическое тасование Фишера - Йетса (оно же тасование Кнута) обеспечивает лучшую равномерность:

for(let n = arr.length - 1; n > 0; --n) {
	let rnd = Math.floor(Math.random() * (n + 1));
    [arr[n], arr[rnd]] = [arr[rnd], arr[n]];
}

Смысл в том, что ячейка, в которую записываем выбранное случайное значение, не участвует в дальнейшем тасовании.

Источник: https://ru.wikipedia.org/wiki/Тасование_Фишера_—_Йетса#Современный_алгоритм

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации