標籤:n個元素 wap 依次 rev 快速 def rom 遞迴 因此
python algorithm
全排列(Permutation)
排列(英語:Permutation)是將相異物件或符號根據確定的順序重排。每個順序都稱作一個排列。例如,從一到六的數字有720種排列,對應於由這些數字組成的所有不重複亦不闕漏的序列,例如4, 5, 6, 1, 2, 3 與1, 3, 5, 2, 4, 6。【From Wikipedia】從n個相異元素中取出 k個元素,k個元素的排列數量為:
\[ {P_{k}^{n}={\frac {n!}{(n-k)!}}} \]
其中P意為Permutation(排列),!表示階乘運算。全排列而取k為n,則結果為n!。
全排列產生演算法
- 字典序法
字典序,就是將元素按照字典的順序(a-z, 1-9)進行排列。以字典的順序作為比較的依據,可以比較出兩個串的大小。比如 "1" < "13"<"14"<"153", 就是按每個數字位逐個比較的結果。對於一個串“123456789”, 可以知道最小的串是“123456789”,而最大的串“987654321”。這樣針對這個串以字典序法產生全排列產生全排列,就是依次產生“123456789”->“123456798”->......->"987654312"->"987654321"這樣的串。字典序法要求這一個與下一個有儘可能長的共同首碼,也即變化限制在儘可能短的尾碼上。
- 鄰位對換法該演算法由Johnson-Trotter首先提出,是一個能快速產生全排列的演算法。它的下一個全排列總是上一個全排列對換某相鄰兩位得到的。如果已知n-1個元素的排列,將n插入到排列的不同位置,就得到了n個元素的排列。用這種方法可以產生出任意n個元素的排列。這個方法有一個缺點:為了產生n個元素的排列,我們必須知道並儲存所有n-1個元素的排列,然後才能產生出所有n階排列。
- 遞增進位製法這個演算法是基於序列的遞增進位制數[3]。遞增進位制數是指數位進位隨著位元的遞增而遞增。一般情況下,數字最右邊的進位是2,次右邊的進位是3,以此類推。n位遞增進位制數一共包含n!個數字,所以它可以與全排列產生演算法結合在一起。
- 遞減進位製法
該方法與遞增進位製法的原理相似,不同的是它定義的“遞減進位制數”是數位進位隨著位元的遞增而遞減。這種進位一般最左邊的進位是2,次左邊的進位是3。其餘原理與遞增進位製法基本相同。
---
###Python實現
#####字典序法
###### 非遞迴演算法
設P是集合{1,2,……n-1,n}的一個全排列:P=P1P2……Pj-1PjPj+1……Pn(1≤P1,P2,……,Pn≤n-1)1.從排列的右端開始,找出第一個比右邊數字小的數位序號j,即j=max{i|Pi<Pi+1,i>j}在Pj的右邊的數字中,找出所有比Pj大的數字中最小的數字Pk,即k=min{i|Pi>Pj,i>j}2.交換Pi,Pk
3.再將排列右端的遞減部分Pj+1Pj+2……Pn倒轉,因為j右端的數字是降序,所以只需要其左邊和右邊的交換,直到中間,因此可以得到一個新的排列P‘=P1P2……Pj-1PkPn……Pj+2Pj+1
###### 代碼
#!/usr/bin/env python2# -*- coding: utf-8 -*-"""@author: gsharp"""def Swap(n,a,b): n[a],n[b] = n[b],n[a] return Nonedef Reverse(n,begin): if len(n) > begin: i = begin j = len(n)-1 while i < j: Swap(n,i,j) i += 1 j -= 1 return ndef FindMin(n,i): j = len(n)-1 k = i + 1 while j > i: if n[j] > n[i] and n[j] < n[k]: k = j j -= 1 return kdef Permut(n): count = 0 j = len(n) -1 if j < 1: return n else : print n count += 1 while j >= 1: i = j - 1 if n[i] < n [j] : k = FindMin(n,i) Swap (n,i,k) Reverse (n,j) j = len(n) - 1 count += 1 print n else : j -= 1 print countn =[1,2,3,4,5,6]Permut(n)
注意:
- 這裡只能對於具有可比較值的列表排序,對於如【‘~‘,‘!‘,‘@‘,‘#‘】無法直接排序。
- 初始序列必須為最小序列,否則無法列出全部排列。可先使用快速排序來排序後作為輸入。
非遞迴全排列 python實現