全排列的四種生成算法

1.字典序法

 

字典序法中,對於數字1、2、3......n的排列,不同排列的先後關係是從左到右逐個比較對應的數字的先後來決定的。例如對於5個數字的排列 12354和12345,排列12345在前,排列12354在後。按照這樣的規定,5個數字的所有的排列中最前面的是12345,最後面的是 54321。

字典序算法如下:


設P是1~n的一個全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn


1)從排列的右端開始,找出第一個比右邊數字小的數字的序號j(j從左端開始計算),即  j=max{i|pi
2)在pj的右邊的數字中,找出所有比pj大的數中最小的數字pk,即 k=max{i|pi>pj}(右邊的數從右至左是遞增的,因此k是所有大於pj的數字中序號最大者)
3)對換pi,pk
 4)再將pj+1......pk-1pkpk+1pn倒轉得到排列p''=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,這就是排列p的下一個下一個排列。


例如839647521是數字1~9的一個排列。從它生成下一個排列的步驟如下:
 自右至左找出排列中第一個比右邊數字小的數字4            839647521
在該數字後的數字中找出比4大的數中最小的一個5        839647521
將5與4交換     839657421
將7421倒轉    839651247
所以839647521的下一個排列是839651247。


2.遞增進位數製法


在遞增進位制數法中,從一個排列求另一個排列需要用到中介數。如果用 ki表示排列p1p2...pi...pn中元素pi的右邊比pi小的數的個數,則排列的中介數就是對應的排列k1 ...... ki...... kn-1。
例如排列839647521的中介數是72642321,7、2、6、......分別是排列中數字8、3、9、......的右邊比它小的數字個數。


中介數是計算排列的中間環節。已知一個排列,要求下一個排列,首先確定其中介數,一個排列的後繼,其中介數是原排列中介數加1,需要注意的 是,如果中介數的末位kn-1+1=2,則要向前進位,一般情形,如果ki+1=n-i+1,則要進位,這就是所謂的遞增進位制。例如排列 839647521的中介數是72642321,則下一個排列的中介數是67342221+1=67342300(因爲1+1=2,所以向前進 位,2+1=3,又發生進位,所以下一個中介數是67342300)。
得到中介數後,可根據它還原對應得排列。

 

算法如下:


中介數k1、k2、......、kn-1的各位數字順序表示排列中的數字n、n-1、......、2在排列中距右端的的空位數,因此, 要按k1、k2、......、kn-1的值從右向左確定n、n-1、......、2的位置,並逐個放置在排列中:i放在右起的ki+1位,如果某位已 放有數字,則該位置不算在內,最後一個空位放1。
因此從67342300可得到排列849617523,它就是839647521的後一個排列。因爲9最先放置,k1=6,9放在右起第7位,空出6個空位,然後是放8,k2=7,8放在右起第8位,但9佔用一位,故8應放在右起第9位,餘類推。

 

3.遞減進位制數法


在遞增進位制數法中,中介數的最低位是逢2進1,進位頻繁,這是一個缺點。把遞增進位制數翻轉,就得到遞減進位制數。
 839647521 的中介數是67342221(k1k2...kn-1),倒轉成爲12224376(kn-1...k2k1),這是遞減進位制數的中介 數:ki(i=n-1,n-2,...,2)位逢i向ki-1位進1。給定排列p,p的下一個排列的中介數定義爲p的中介數加1。例如 p=839647521,p的中介數爲12224376,p的下一個排列的中介數爲12224376+1=12224377,由此得到p的下一個排列爲 893647521。

給定中介數,可用與遞增進位制數法類似的方法還原出排列。但在遞減進位制數中,可以不先計算中介數就直接從一個排列求出下一個排列。具體算法如下:

1)如果p(i)=n且i<>1,則p(i)與p(i-1)交換
2)如果p(1)=n,則找出一個連續遞減序列9、8、......、i,將其從排列左端刪除,再以相反順序加在排列右端,然後將i-1與左邊的數字交換
例 如p=893647521的下一個排列是983647521。求983647521的下一個排列時,因爲9在最左邊且第2位爲8,第3位不是7,所以將8 和9從小到大排於最右端364752189,再將7與其左方數字對調得到983647521的下一個排列是367452189。又例如求 987635421的下一個排列,只需要將9876從小到大排到最右端並將5與其左方數字3對調,得到534216789。

4、鄰位對換法

      1)如果一個元素的移動方向所指向的那個鄰位比它小,此元素就是可移的;相反,如果一個元素的移動方向所指向的那個鄰位比它大,此元素就是不可移的。如果一個元素的移動方向上沒有鄰位,此元素也是不可移的。
  2)每次都是先尋找最大的可移元素 max,把它與移動方向所指向的那個鄰位交換,然後把所有比 max 大的元素的移動方向反轉。
  3)不斷重複(2),直到所有元素都不可移爲止。

       以 1234數列爲例。

       初始使,所有元素移動方向向左。

        故4爲2)步驟選出的max,移動;變爲1243

        重複2)步驟直到選不出可移動元素停止。

        即可得出1234的12種全排列。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章