Алгоритмы порождения перестановок

Также как и при генерации сочетания будем считать, что элементами множества являются целые числа от 1 до n.

Последовательность перестановок на множестве {1,2,..., n } представлена в лексикографическом порядке, если она записана в порядке возрастания получающихся чисел. Например, лексикографическая последовательность перестановок трех элементов имеет вид 123, 132, 213, 231, 312, 321.

Порождать такую последовательность можно следующим образом. Начиная с перестановки Р =(1,2,..., n), переходим к следующей, путем просмотра текущей справа налево с целью поиска самой правой позиции, в которой рi < рi +1. Найдя ее, ищем рj, наименьший элемент, расположенный справа от рi и больше его. Затем осуществляется транспозиция элементов рi и pj и отрезок рi +1,..., рn (элементы которого расположены в порядке убывания) переворачивается. Например, для n =8 имеем текущую перестановку p =(2,6,5,8,7,4,3,1), тогда рi =5 (i =3) и рj =7 (j =5). Меняя их местами и переворачивая p 4, p 5, p 6, p 7, p 8, получаем следующую перестановку (2,6,7,1,3,4,5,8). Эту процедуру реализует алгоритм представленный на рис.2.8.

Рассмотрим еще один алгоритм порождения перестановок. Этот алгоритм генерирует перестановки в порядке минимального изменения, т.е. перестановка отличается от предшествующей транспозицией двух соседних элементов.

Такую последовательность перестановок можно построить рекурсивно. Для n =1 существует единственная перестановка (1). Предположим, что построена последовательность перестановок П12,...,П( n -1)! на множестве {1,2,..., n -1} в порядке минимального изменения.

 
 


Расширим каждую из (n -1)! этих перестановок путем вставки элемента n на каждое из n возможных мест. Причем, элемент n добавляется к П i последовательно во все позиции справа налево, если i нечетное, и слева направо, если i четное. Пример такого расширения представлен на рис.2.9.

Эту же последовательность перестановок можно порождать итеративно, получая каждую перестановку из предшествующей и добавочной информации. Это делается с помощью трех векторов: текущей перестановки Р =(р 1,..., рn), обратной к ней перестановки 0 =(о 1,..., оn) (о 1 - индекс наименьшего элемента в Р, о 2 - индекс следующего по величине элемента в Р и т.д., следовательно, ) и записи направления D =(d 1,..., dn), в котором сдвигаются элементы перестановки (di =-1, если pi сдвигается влево, di =1 - вправо, di =0 - не сдвигается). Элемент сдвигается до тех пор, пока не достигнет элемента большего чем он сам; в этом случае сдвиг прекращается. В этот момент направление сдвига данного элемента изменяется на противоположное и передвигается следующий меньший его элемент, который можно сдвинуть. Поскольку хранится перестановка, обратная к Р, то в Р легко найти место следующего меньшего элемента. Эту процедуру реализует алгоритм представленный на рис.2.10.

Заметим, что в данном алгоритме Р 0 и Pn +1 инициализируются величиной n +1, чтобы прекратить передвижение n, и d 1 инициализируется нулем, чтобы в тех случаях, когда m становятся равным единице во внутреннем цикле, остаток внешнего цикла был правильно определен.

Алгоритм порождения случайных перестановок представлен на рис.2.11. Данный алгоритм аналогичен алгоритму порождения случайных сочетаний (рис.2.7).

 
 

 
 



Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: