Существует ли линейный алгоритм временного перемешивания на месте? Это алгоритм, который способны выполнить некоторые особенно ловкие руки: равномерно разделить входной массив четного размера, а затем чередовать элементы двух половинок.
У Mathworld есть краткая страница о риффл-тасовке . В частности, меня интересует разновидность out-shuffle, которая преобразует входной массив 1 2 3 4 5 6 в 1 4 2 5 3 6. Обратите внимание, что в их определении длина ввода равна .
Это просто выполнить за линейное время, если у нас есть второй массив размером или более удобный. Сначала скопируйте последние n элементов в массив. Затем, предполагая индексирование на основе 0, скопируйте первые n элементов из индексов [0,1,2, ..., n-1] в [0, 2, 4, ..., 2n-2] . Затем скопируйте n элементов из второго массива обратно во входной массив, сопоставив индексы [0,1,2, ..., n-1] с [1,3,5, ..., 2n-1] . (Мы можем сделать немного меньше, чем это, потому что первый и последний элементы на входе не перемещаются.)
Один из способов сделать это на месте заключается в разложении перестановки на непересекающиеся циклы, а затем переупорядочении элементов в соответствии с каждым циклом. Опять же, при условии индексации на основе 0 перестановка, включенная в случай с 6 элементами, выглядит так:
Как и ожидалось, первый и последний элементы являются фиксированными точками, и если мы переставим средние 4 элемента, мы получим ожидаемый результат.
К сожалению, мое понимание математики перестановок (и их ) в основном основано на википедии, и я не знаю, можно ли это сделать за линейное время. Может быть, перестановки, связанные с этой перестановкой, можно быстро разложить? Кроме того, нам даже не нужно полное разложение. Достаточно просто определить один элемент каждого из непересекающихся циклов, поскольку мы можем восстановить цикл по одному из его элементов. Возможно, нужен совершенно другой подход.
Хорошие ресурсы по смежной математике так же ценны, как и алгоритм. Благодарность!
Ответы:
Проблема на удивление нетривиальна. Вот хорошее решение Эллиса и Маркова « Стабильное слияние на месте» с помощью Perfect Shuffle (раздел 7). Эллис, Кран и Фан, « Вычисление циклов в совершенной перестановке», успешно выбирают «лидеров циклов» за счет увеличения объема памяти. Также связана хорошая статья Fich, Munro и Poblete , « Перестановка на месте» , которая дает общий алгоритм времени для модели оракула. Если доступен только оракул для перестановки, алгоритм требует логарифмического пространства; если у нас также есть оракул для обратного, он требует постоянного пространства.O ( n logн )
Теперь о решении Эллиса и Маркова. Сначала предположим, что . Затем вычисление совершенного перемешивания порядка сводится к вычислению совершенного перемешивания порядков и с вращением, предшествующим им. Вот доказательство на примере ( , , ): n x y n = 5 x = 3 y = 2 012 345 67 89 012 567 34 89 051627 3849n = x + y N Икс Y п = 5 х = 3 Y= 2
Эллис и Марков нашли простой способ вычислить идеальное перемешивание при , используя постоянное пространство и линейное время. Используя это, мы получаем алгоритм для вычисления идеального перемешивания для произвольного . Сначала напишите используя двоичную кодировку , и пусть . Поверните средние биты, перемешайте правые биты. Игнорирование битов, вращение средних битов и перетасовывание правых n n = 2 k 0 + ⋯ + 2 k w n n i = 2 kп = 2К N п = 2К0+ ⋯ + 2Квес N n0Nя= 2Кя+ ⋯ + 2Квес N0 2 k 0 n 1 2 k 1 O ( n 0 + ⋯ + n w ) = O ( n ) n t + 12К0 2К0 N1 2К1 биты. И так далее. Обратите внимание, что вращение легко, поскольку первые несколько вращающихся элементов функционируют как лидеры цикла. Общая сложность вращения составляет , поскольку . Общая сложность внутренних перемешиваний составляет .O ( n0+ ⋯ + nвес) = O ( n ) O ( 2 k 0 + ⋯ + 2 k w ) = O ( n )NT + 1< пT/ 2 O ( 2К0+ ⋯ + 2Квес) = O ( n )
Осталось показать, как вычислить идеальный случайный порядок при . Фактически, мы сможем определить лидеров цикла, следуя классической работе над ожерельями (Фредриксен и Майорана, Ожерелья из бисера в цветах и хари де Брюйна ; Фредриксен и Кесслер, Алгоритм генерации ожерелий из бисера в двух цветах ).k kn =2К К К
Какая связь? Я утверждаю, что случайная перестановка соответствует сдвигу вправо двоичного представления. Вот подтверждение для : Поэтому, чтобы найти лидеров цикла, нам нужно найти одного представителя из каждого класса эквивалентности вращения двоичных строк длины . Упомянутые выше документы дают следующий алгоритм генерации всех лидеров цикла. Начните с . На каждом этапе мы находимся в некоторой точке . Найти максимальный индекс нулевого бита,000 001 010 011 100 101 110 111 000 100 001 101 010 110 011 111 kn = 8
Например, когда генерируется последовательность 0000 , 0001 , 0010 , 0011 , 0101 , 0110 , 0111 , 1111 .n = 16
Лидеры цикла выделены.
источник
Это был начальный вопрос на cs.stackexchange.com, и ответ здесь: /cs/332/in-place-algorithm-for-interleaving-an-array/400#400
Это объяснение статьи: http://arxiv.org/abs/0805.1598 .
Обратите внимание, что этот ответ имеет дело с перестановкой (т.е. Inshuffle), и наличие этого также облегчает решение этой проблемы (Outshuffle).j → 2 jмодификация2 н + 1
источник
Что произойдет, если вы запишете риффл шаффл как функцию? Если - длина всего массива, пусть - длина массива после удаления первого и последнего элемента. Тогда перетасованный индекс индекса имеет вид если и если . Затем вы можете просто «перескочить указатель» через массив, меняя местами повторное применение функции.п = т - 2 я е ( я ) = 2 ⋅ я я ≤ п / 2 е ( я ) = 2 ⋅ ( ям n=m−2 i f(i)=2⋅i i≤n/2 i > n / 2f(i)=2⋅(imodn/2)−1 i>n/2
Предполагая произвольный доступ, это будет линейное время, требующее дополнительных слов (для хранения значения массива при любом заданном индексе) и, таким образом, дополнительного пространства.O ( log n )O(1) O(logn)
источник