關於生成排列

2021-06-15 02:47:58 字數 3101 閱讀 9076

寫數學筆記是源於我對

matrix67

的崇拜,從高二開始關注

m大的部落格,每次讀到那種巧妙的思維,我都想跳起來大喊大叫:簡直是太

nice

了。我喜歡數學,最喜歡的地方就是這裡,這和從小老師說的苦思冥想做出一道數學題的感覺一樣。哦不,是更加令人震撼!說實話吧,我也不知道我能堅持多久,雖然我的目標是寫到大學畢業再說。認識我的人都知道我這人最大的特點就是沒耐心。不過既然我喜歡摸索這種思維的巧妙,我就應該能堅持下去。我把自己的數學筆記公布出來,一是方便自己整理,二是給我的朋友中的

geek

們提供乙個平台,來和我分享這些

nice

的思想。當我在寫第一篇筆記的時候,我還是不懂使用一些專業的數學軟體來表達我的思想,我會在近期完成這些軟體的學習。當然,如果有一些不專業的毛病也請各位朋友指出,我也是在不斷學習中進步。好了,廢話到此為止,以下是正文。

這是我在讀

richard a. brualdi

的《introductory combinatorics

》第四章發現的好東西。一瞬間讓我覺得之前我的排序優化簡直弱爆了。在這篇筆記裡,我會著重和大家介紹如何從逆序列到生成排列的過程。

關於排列大家都明白,但是如何生成乙個排列一直是在排序演算法中困擾我們的。比如乙個由

n個正整數構成的集合就有n

!個排列,就算n為

15,n!就比

1 000 000 000 000

還要大。這裡我貼出

stirling

公式:用來嚇嚇大家。

當然,書中介紹了好幾個方法來生成排列,而我覺得一直到

s.eveni1,

i2,i3……

in,我們令

aj表示第二個成分是

j的逆序的數量。通俗的說,

aj等於排列中在

j前面又大於

j的數的個數,用來度量

j的無序程度。

數值串行: a1

,a2,……,an

叫做排列

i1.i2

,……,

in的逆序列。當然他們的和就是用來度量原數列無序程度的逆序數。

好了,到此為止可以切入正題了,逆序列的性質就暗示了我它的作用。假設數列{b1,

b2……,

bn}是一組數列的逆序列,那麼必然0≤

b1≤n-1,0≤

b2≤n-2,……,0≤

b(n-1)≤1,

bn=0.

很明顯,整數序列{

bn}的序列個數正式n*(

n-1)*……

*2*1=n!

。好了,這就自然而然的想到了,原數列所有的排列正是

n!,那麼和逆序列是不是有著一一對應的情況呢?答案是肯定的,證明方法也就是我接下來說的演算法。

先確定乙個數列,為了方便我就引用了書中的例子{1,

2,3,

4,5,

6,7,

8},使其逆序列為5,

3,4,

0,2,

1,1,

0. 演算法一:

首先確定

n,然後確定

n-1,

n-1的位置就是根據b(

n-1)來確定的,如果b(

n-1)為

1,那麼原序列為{

n,n-1

},如果b(

n-1)為

0,那麼原序列為{

n-1,

n}。顯然在這一步,b(

n-1)只有兩個情況。我們來考慮下一般步驟,在確定

n-k這一步時,前面步驟的n到

n-k+1

的順序已經確定,而

n-k一定是比之前確定的任意乙個數還要小,也就是

n-k所對應的逆序就能找到它所在的位置。我拿例子模擬一遍。 8

:8 7

:87 6

:867 5

:8657 4

:48657 3

:486537 2

:4862537 1

:48625137

因此排列就出來了,當然演算法一雖然能夠實現還原原排列,但是之前所確定的數,它的位置不是絕對固定,而是相對的。在用計算機模擬的時候,會造成乙個不必要的位移過程。

j.csima

向作者推薦了另外乙個演算法。

演算法二:

和之前的不同,我們先確定原數列

1的位置,因為

1之前有

b1個整數,(除了0,

1任何乙個整數都大於

1不是嗎?)所以

1是放在

b1+1

的空位置上。那麼

2就放在第

b2+1

個空位置上。而一般來說,當我們要確定

k的時候,就需要把

k放在第

bk+1

個空位置上,因為

k後面要放的數必然大於

k,插入在

k前面就會形成逆序。可能文字表達有點吃力,畢竟我這是第一篇數學筆記,不能理解的同學就看我下面的舉例,依舊是拿上面的數列。

1:

1

2:

2 1

3: 2

1 3 4

: 4

2 1 3

5:4

2 51 3

6:4

6 2

5 1

3 7

: 4

6 25 1

3 78:

4 8

6 2

5 1

3 7

(1)(2)

(3)(4)

(5)(6)

(7)(8)

這個演算法的好處就是,每乙個要確定的數,它的位置是絕對固定的。在程式中實現的話,我們就能避免那個很煩人的位移數字的過程。

當然,以上兩種排列的生成方法都證明了逆序列是和原數列的排列一一對應的。只要我們指定乙個排列的逆序列就可以唯一確定這個排列。

我在高中的時候就接觸了逆序數,可是限制於當時的代數知識匱乏,我沒有搞清楚逆序數的原理。這次碰上了,就沒有再放過它。《

introductory combinatorics

》中還有部分關於逆序數的討論,我就不再提出來繼續嘮叨,《高等代數》北大版中也有詳細的關於逆序數的討論,有興趣的朋友可以嘗試去看看。

排列生成 遞迴

對於給定的n 1的集合,需要列印出該集合所有可能的排列。例如,如果這個集合是 a,b,c 那麼所有可能得排列是 1.a b c 2.a c b 3.b c a 4.b a c 5.c a b 6.c b a 即 a 加上 b,c 的所有排列 b 加上 a,c 的所有排列 c 加上 a,b 的所有排列...

排列的生成

題目描敘 description 輸出p n,m 的排列 n,m 10 input n,m output 每方案!sample input 3 2sample output 1 21 3 2 12 3 3 13 2 演算法分析 本題完全屬於數學排列問題,用搜尋與回溯 search 本題與全排列基本相...

生成排列程式

第一篇,不知怎麼寫.剛剛在看 組合數學 在第57頁講到了生成排列的演算法.於是乎就實現了一下.具體的可以參考 include include define num 5 typedef enum directdirect typedef struct data sdata t 填充資料 void fu...