寫數學筆記是源於我對matrix67的崇拜,從高二開始關注m大的博客,每次讀到那種巧妙的思維,我都想跳起來大喊大叫:簡直是太nice了。我喜歡數學,最喜歡的地方就是這裏,這和從小老師說的苦思冥想做出一道數學題的感覺一樣。哦不,是更加令人震撼!說實話吧,我也不知道我能堅持多久,雖然我的目標是寫到大學畢業再說。認識我的人都知道我這人最大的特點就是沒耐心。不過既然我喜歡摸索這種思維的巧妙,我就應該能堅持下去。我把自己的數學筆記公佈出來,一是方便自己整理,二是給我的朋友中的geek們提供一個平臺,來和我分享這些nice的思想。當我在寫第一篇筆記的時候,我還是不懂使用一些專業的數學軟件來表達我的思想,我會在近期完成這些軟件的學習。當然,如果有一些不專業的毛病也請各位朋友指出,我也是在不斷學習中進步。好了,廢話到此爲止,以下是正文。
這是我在讀richard A. brualdi的《introductory combinatorics》第四章發現的好東西。一瞬間讓我覺得之前我的排序優化簡直弱爆了。在這篇筆記裏,我會着重和大家介紹如何從逆序列到生成排列的過程。
關於排列大家都明白,但是如何生成一個排列一直是在排序算法中困擾我們的。比如一個由n個正整數構成的集合{1,2,3,……,n}就有n!個排列,就算n爲15,n!就比1 000 000 000 000還要大。這裏我貼出stirling公式:http://baike.baidu.com/view/2019233.htm用來嚇嚇大家。
當然,書中介紹了好幾個方法來生成排列,而我覺得一直到S.Even的方法都還算得上比較原始。一直引出了逆序列這個概念,從而推出了兩個相當精彩的排列生成。我也嘗試搜索了一下逆序列的資料,起碼百度的前幾頁沒有看到。那麼我先簡單介紹一下逆序列:逆序是一個老概念,我不多說。對於一個排列i1,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 |
5 |
1 |
3 |
|
6: |
4 |
|
6 |
2 |
5 |
1 |
3 |
|
7: |
4 |
|
6 |
2 |
5 |
1 |
3 |
7 |
8: |
4 |
8 |
6 |
2 |
5 |
1 |
3 |
7 |
|
(1) |
(2) |
(3) |
(4) |
(5) |
(6) |
(7) |
(8) |
這個算法的好處就是,每一個要確定的數,它的位置是絕對固定的。在程序中實現的話,我們就能避免那個很煩人的位移數字的過程。
當然,以上兩種排列的生成方法都證明了逆序列是和原數列的排列一一對應的。只要我們指定一個排列的逆序列就可以唯一確定這個排列。
我在高中的時候就接觸了逆序數,可是限制於當時的代數知識匱乏,我沒有搞清楚逆序數的原理。這次碰上了,就沒有再放過它。《introductory combinatorics》中還有部分關於逆序數的討論,我就不再提出來繼續嘮叨,《高等代數》北大版中也有詳細的關於逆序數的討論,有興趣的朋友可以嘗試去看看。