全排列的演算法
A. 全排列的公式
全排列數f(n)=n!(定義0!=1) 1,2,3
1,3,2
2,1,3
2,3,1
3,2,1
3,1,2
這是由於演算法只是考慮到了如何輸出全排列,而沒有考慮到換位是否有問題。
所以我提出了解決方案,就是換位函數修改下
如 1 2 3 換位的話 ,不應該直接 3 2 1這樣 ,
讓3和1直接換位; 而是讓3排在最前後 ,1 2 依次向後 以下介紹全排列演算法四種:
(A)字典序法
(B)遞增進位制數法
(C)遞減進位制數法
(D)鄰位對換法 對給定的字元集中的字元規定了一個先後關系,在此基礎上規定兩個全排列的先後是從左到右逐個比較對應的字元的先後。
[例]字元集{1,2,3},較小的數字較先,
這樣按字典序生成的全排列是:123,132,213,231,312,321。
[注意] 一個全排列可看做一個字元串,字元串可有前綴、後綴。
1)生成給定全排列的下一個排列 所謂一個的下一個就是這一個與下一個之間沒有其他的。這就要求這一個與下一個有盡可能長的共同前綴,也即變化限制在盡可能短的後綴上。
[例]839647521是1--9的排列。
1—9的排列最前面的是123456789,最後面的是987654321,從右向左掃描若都是增的,就到987654321,也就沒有下一個了。否則找出第一次出現下降的位置。 1)由排列求中介數 在字典序法中,中介數的各位是由排列數的位決定的.中介數位的下標與排列的位的下標一致。
在遞增進位制數法中,中介數的各位是由排列中的數字決定的。即中介數中各位的下標與排列中的數字(2—n)一致。可看出n-1位的進位鏈。 右端位逢2進1,右起第2位逢3進1,…,
右起第i位逢i+1進1,i=1,2,…,n-1. 這樣的中介數我們稱為遞增進位制數。 上面是由中介數求排列。
由序號(十進制數)求中介數(遞增進位制數)如下:
m=m1,0≤m≤n!-1
m1=2m2+kn-1,0≤kn-1≤1
m2=3m3+kn-2,0≤kn-2≤2
……………
mn-2=(n-1)mn-1+k2,0≤k2≤n-2
mn-1=k1,0≤k1≤n-1
p1p2…pn←→(k1k2…kn-1)↑←→m
在字典序法中由中介數求排列比較麻煩,我們可以通過另外定義遞增進位制數加以改進。
為方便起見,令ai+1=kn-1,i=1,2,…,n-1
(k1k2…kn-1)↑=(anan-1…a2)↑
ai:i的右邊比i小的數字的個數
在這樣的定義下,
有839647521←→(67342221)↑
(67342221)↑+1=(67342300)↑←→849617523
6×8+7)×7+3)×6+4)×5+2)×4+2)×3+2)×2+1 =279905
由(anan-1…a2)↑求p1p2…pn。
從大到小求出n,n-1,…,2,1的位置
_ ... _ n _ _ …_ (an個空格)
n的右邊有an個空格。
n-1的右邊有an-1個空格。
…………
2的右邊有a2個空格。
最後一個空格就是1的位置。 在遞增進位制數法中,中介數的最低位是逢2進1,進位頻繁,這是一個缺點。
把遞增進位制數翻轉,就得到遞減進位制數。 (anan-1…a2)↑→(a2a3…an-1an)↓
839647521→ (12224376)↓
(12224376)↓=1×3+2)×4+2)×5+2)×6+4)×7+3)×8+7)×9+6=340989
[注意]求下一個排列十分容易 遞減進位制數法的中介數進位不頻繁,求下一個排列在不進位的情況下很容易。
這就啟發我們,能不能設計一種演算法,下一個排列總是上一個排列某相鄰兩位對換得到的。
遞減進位制數字的換位是單向的,從右向左,而鄰位對換法的換位是雙向的。 這個演算法可描述如下:
對1—n-1的每一個偶排列,n從右到左插入n個空檔(包括兩端),生成1—n的n個排列。
對1—n-1的每一個奇排列,n從左到右插入n個空檔,生成1—n的n個排列。
對[2,n]的每個數字都是如此。
839647521
字典序法 遞增進位製法 遞減進位製法 鄰位對換法
下一個 839651247 849617523 893647521 836947521
中介數 72642321↑ 67342221↑ 12224376↓ 10121372↓
序 號 297191 279905 340989 203393
B. 全排列計算公式是什麼
公式:全排列數f(n)=n!(定義0!=1)。
從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的一個排列。當m=n時所有的排列情況叫全排列。
排列指從給定個數的元素中取出指定個數的元素進行排序。
比如從m個元素中取出n個進行排列,通常用符號A(m,n)表示,計算式為A(m,n)=m!/(m-n)!,其中!表示階乘。
組合指從給定個數的元素中僅僅取出指定個數的元素,不考慮排序。
比如從m個元素中取出n個,不考慮排序,通常用符號C(m,n)表示,計算式為C(m,n)=m!/(n!(m-n)!)。
排列和組合的區別:
看問題是否和順序有關。有關就是排列,無關就是組合。 排列:比如說排隊問題甲乙兩人排隊,先排甲,那麼站法是甲乙,先排乙,那麼站法乙甲,是兩種不同的排法,和先排還是後排的順序有關,所以是A(2,2)=2種。
組合:從甲乙兩個球中選2個,無論先取甲,在是先取乙,取到的兩個球都是甲和乙兩個球,和先後取的順序無關,所以是C(2,2)=1種。
C. 全排列計算公式是什麼
全排列公式:全排列數f(n)=n!(定義0!=1)。
全排列是從從N個元素中取出M個元素,並按照一定的規則將取出元素排序,我們稱之為從N個元素中取M個元素的一個排列,當M=N時,即從N個元素中取出N個元素的排列。
以最常見的全排列為例,用 S(A)表示集合 A 的元素個數。用 1、2、3、 4、5、6、7、8、9 組成數字不重復的九位數。
則每一個九位數都是集合 A 的一個元素,集合 A 中共有 9個元素,即 S(A)=9。如果集合 A 可以分為若干個不相交的子集,則 A 的元素等於各子集元素之和。
鄰位對換法
遞減進位制數法的中介數進位不頻繁,求下一個排列在不進位的情況下很容易。
這就啟發我們,能不能設計一種演算法,下一個排列總是上一個排列某相鄰兩位對換得到的。
遞減進位制數字的換位是單向的,從右向左,而鄰位對換法的換位是雙向的。 這個演算法可描述如下:
對1—n-1的每一個偶排列,n從右到左插入n個空檔(包括兩端),生成1—n的n個排列。
對1—n-1的每一個奇排列,n從左到右插入n個空檔,生成1—n的n個排列。
對[2,n]的每個數字都是如此。
D. 求遍歷全排列的演算法
全排列的生成演算法就是對於給定的字元集,用有效的方法將所有可能的全排列無重復無遺漏地枚舉出來。
常見的有四種全排列演算法:
(A)字典序法
(B)遞增進位制數法
(C)遞減進位制數法
(D)鄰位對換法
這里著重介紹字典序法
對給定的字元集中的字元規定了一個先後關系,在此基礎上規定兩個全排列的先後是從左到右逐個比較對應的字元的先後。
[例]字元集{1,2,3},較小的數字較先,這樣按字典序生成的全排列是:123,132,213,231,312,321。
[注意] 一個全排列可看做一個字元串,字元串可有前綴、後綴。
1)生成給定全排列的下一個排列 所謂一個的下一個就是這一個與下一個之間沒有其他的。這就要求這一個與下一個有盡可能長的共同前綴,也即變化限制在盡可能短的後綴上。
[例]839647521是1--9的排列。1—9的排列最前面的是123456789,最後面的是987654321,從右向左掃描若都是增的,就到了987654321,也就沒有下一個了。否則找出第一次出現下降的位置。
E. 關於全排列遞歸演算法
這個演算法,是把每一個數與末尾的數逐一交換,
k>m 說明已交換完畢,就輸出了,這是遞歸的結束條件。
要學到一定的基本功才能明白。
---------------------------------------------------------------------------
我這個程序,我也編過,放在西祠C++BUILDER論壇里。
你先要掌握,排列的方法才能看懂這個程序。
在這知道里,也答過兩次。
為了增加可理解性,我略改了一下方法,我的方法
與你的方法遞歸方向不同。
http://www.xici.net/d190786398.htm
此演算法為遞歸法顯示排列數,沒發現比這更簡單、明了的遞
歸演算法。此演算法只要練智商的作用,沒有其它實用價值,階
乘級的佔用時間、空間,數一大,堆棧很快暴了。
演算法的要點:
1.列N個數的排列,可化為N個的N-1階排列:
最末一個數是 D[n-1],把這個位置的N個數的可能性列出,
就是每一個數 與末尾逐一交換位置,就是N種情況,每一種
情況再求N-1的全排列,就是遞歸調用了;
交換位置後,就調用自已,但必須恢復剛才的交換,以便下一次
交換;
2.當階數遞歸到1時,就直接輸出這N個數;
F. 關於全排列的演算法問題
最低0.27元/天開通網路文庫會員,可在文庫查看完整內容>
原發布者:ON9V4Xr2gU9J7
全排列以及相關演算法在程序設計過程中,我們往往要對一個序列進行全排列或者對每一個排列進行分析。全排列演算法便是用於產生全排列或者逐個構造全排列的方法。當然,全排列演算法不僅僅止於全排列,對於普通的排列,或者組合的問題,也可以解決。本文主要通過對全排列以及相關演算法的介紹和講解、分析,讓讀者更好地了解這一方面的知識,主要涉及到的語言是C和C++。本文的節數:1.全排列的定義和公式:2.時間復雜度:3.列出全排列的初始思想:4.從第m個元素到第n個元素的全排列的演算法:5.全排列演算法:6.全排列的字典序:7.求下一個字典序排列演算法:8.C++STL庫中的next_permutation()函數:(#include)9.字典序的中介數,由中介數求序號:10.由中介數求排列:11.遞增進位制數法:12.遞減進位制數法:13.鄰位對換法:14.鄰位對換法全排列:15.鄰位對換法的下一個排列:16.鄰位對換法的中介數:17.組合數的字典序與生成:由於本文的,內容比較多,所以希望讀者根據自己的要求閱讀,不要一次性讀完,有些章節可以分開讀。第1節到第5節提供了全排列的概念和一個初始的演算法。第6節到第8節主要講述了字典序的全排列演算法。第9到第10節講了有關字典序中中介數的概念。第11到第12節主要介紹了不同的中介數方法,僅供擴展用。第13節到15節介紹了鄰位對換法的全排的有關知識。16節講了有關鄰位對換法的中介數,僅供參考。第17節講了
G. 全排列計算公式是什麼
公式:全排列數f(n)=n!(定義0!=1)。
從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的一個排列。當m=n時所有的排列情況叫全排列。
鄰位對換法
遞減進位制數法的中介數進位不頻繁,求下一個排列在不進位的情況下很容易。
這就啟發我們,能不能設計一種演算法,下一個排列總是上一個排列某相鄰兩位對換得到的。
遞減進位制數字的換位是單向的,從右向左,而鄰位對換法的換位是雙向的。 這個演算法可描述如下:
對1—n-1的每一個偶排列,n從右到左插入n個空檔(包括兩端),生成1—n的n個排列。
對1—n-1的每一個奇排列,n從左到右插入n個空檔,生成1—n的n個排列。
對[2,n]的每個數字都是如此。