日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【离散数学】高级计数技术

發布時間:2023/12/20 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【离散数学】高级计数技术 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這是離散數學的第四篇,討論高級計數技術。同步發布與個人博客,上一篇(【離散數學】計數/排列組合)討論了計數以及排列組合,二項式定理等。但是僅憑排列組合等手段依然無法解決許多計數問題。這里首先討論通過遞推關系來求解計數問題,并介紹有遞推關系引出的兩個算法范式:動態規劃和分治。這兩種算法均是通過將問題分割為一系列的子問題來求解的,區別就是前者分割出來的子問題互相重疊,后者的子問題不重疊。這是兩種很重要的算法,加上貪心、回溯、分支定界為五種很常用的算法。這里僅僅簡單討論思路,并分析其復雜度。關于具體的算法分析以及算法設計以后應該會討論。而后介紹了求解一類很常見的特定遞推關系——常系數線性齊次與非齊次遞推關系的形式解法。并且還介紹了一種求解計數問題的很重要的手段——生成函數,這是冪級數的應用。最后介紹容斥原理,對,就是集合的容斥原理。以上內容以前均有涉及,這里再次探討。


遞推關系的應用

經典問題——漢諾塔

這是一個及其經典的問題,見漢諾塔(Tower of Hanoi),三根柱子,n個盤子,從上到下盤子從小到大。將所有n個盤子從一根柱子移動到另一根柱子,移動過程中小的盤子不能放在大的盤子下面。可以求解出所需要的最小步數,還可以編寫算法打印出所有步數。

n=3的漢諾塔移動方法:

令移動n個盤子到另一個柱子所需最少次數為 HnH_nHn? ,考慮最下面一個最大的盤子,由于小的盤子不能放在大的盤子下面,所以必須首先將上面n-1個移動到另一個柱子,再將最下面的最大的一個移動到另一根柱子,再將n-1個移到其上,則完成了n個盤子的移動。則得到遞推關系 Hn=2Hn?1+1H_n = 2H_{n-1}+1Hn?=2Hn?1?+1。初始條件很容易知道:H0=0H_0 = 0H0?=0H1=1H_1=1H1?=1

求解遞推關系:容易看出 Hn+1=2(Hn?1+1)H_n+1 = 2(H_{n-1}+1)Hn?+1=2(Hn?1?+1),可以得到 Hn=2n?1H_n= 2^n-1Hn?=2n?1。可以證明這便是移動n個盤子所需的最少次數。

卡特蘭數

考慮一個在n+1個數 $x_0\cdot x_1 \cdot x_2 \cdots x_n $ 的乘積中插入括號來規定乘法次序的方式數,令其為 CnC_nCn?
這里注意到一定會有一個乘法是在括號外面的(不需要加括號),假設其在xkx_kxk?xk+1x_{k+1}xk+1?之間,則存在CkCn?k?1C_kC_{n-k-1}Ck?Cn?k?1?種方式,考慮最后一個乘號可能取n個位置,則有Cn=∑k=0n?1CkCn?k?1C_n = \sum_{k=0}^{n-1}C_kC_{n-k-1}Cn?=k=0n?1?Ck?Cn?k?1?

初始條件則為C0=1C_0 = 1C0?=1C1=1C_1 = 1C1?=1
利用生成函數的方法可以證明:Cn=C(2n,n)n+1C_n = \dfrac{C(2n,n)}{n+1}Cn?=n+1C(2n,n)?,被稱作第n個卡特蘭(Catalan)數,序列{Cn}\{C_n\}{Cn?} 被稱為卡特蘭數的序列。參見 OEIS A000108,Catalan number - Wikipedia。

動態規劃與遞推關系

動態規劃(Dynamic programming,DP)是一種算法范式,遵循動態規劃范式的算法是將原問題分解為更簡單的重疊的子問題,通過子問題的求解來求解原問題。常用于求解最短路線、庫存管理、資源分配、設備更新、排序、裝載等問題。此類問題若用分治法來解,則分解得到的子問題數目太多,有些子問題被重復計算了很多次。所以DP通過保存已解決的子問題的答案,而在需要時再找出已求得的答案,這樣就可以避免大量的重復計算,從而降低復雜度。以后單獨討論,這里推薦閱讀:動態規劃解決01背包問題,什么是動態規劃?動態規劃的意義是什么?。


求解線性遞推關系

這部分給人的感覺相當熟悉,在高等數學中有線性微分方程的求解,線性代數中有線性方程組的求解,與這里的線性遞推關系的求解十分類似,可以說是如出一轍。

求解常系數線性齊次遞推關系

一個常系數的kkk階線性齊次遞推關系指的是形如 an=c1an?1+c2an?2+?+ckan?ka_n = c_1a_{n-1}+c_2a_{n-2}+\cdots + c_ka_{n-k}an?=c1?an?1?+c2?an?2?+?+ck?an?k?,的遞推關系,其中cic_ici?為實數,ck≠0c_k \neq 0ck???=0

為了求解kkk階常系數線性齊次遞推關系,這里的基本方法是尋找形如an=rna_n = r^nan?=rn的解,其中r是常數。遞推關系要有形如an=rna_n = r^nan?=rn的解,則當且僅當rrr是方程rk?c1rk?1?c2rk?2???ck?1r?ck=0r^k-c_1r^{k-1}-c_2r^{k-2}-\cdots -c_{k-1}r-c_k=0rk?c1?rk?1?c2?rk?2???ck?1?r?ck?=0的解。
將上述方程稱為該遞推關系的特征方程。方程的解稱為特征根。(與求解常系數線性微分方程如出一轍)。特征根有可能是復數,但這里僅考慮特征根為實數的情況。

定理:假設特征方程rk?c1rk?1???ck=0r^k-c_1r^{k-1}-\cdots -c_k=0rk?c1?rk?1???ck?=0有k個不相等的根r1,r2,...,rkr_1,r_2,...,r_kr1?,r2?,...,rk?。那么遞推關系an=c1an?1+c2an?2+?+ckan?ka_n = c_1a_{n-1}+c_2a_{n-2}+\cdots + c_ka_{n-k}an?=c1?an?1?+c2?an?2?+?+ck?an?k?的解為an=α1r1n+α2r2n+?+αkrkna_n = \alpha_1r_1^n+\alpha_2r_2^n+\cdots+\alpha_kr_k^nan?=α1?r1n?+α2?r2n?+?+αk?rkn?

n∈N,α1,α2,...,αkn\in N,\alpha_1,\alpha_2,...,\alpha_knN,α1?,α2?,...,αk?是常數。
另外,對其中的每一個特征根rir_iri?,如果并非一重而是mim_imi?重時,則用 (αi,0+αi,1n+?+αi,mi?1nmi?1)rin(\alpha_{i,0}+\alpha_{i,1}n+\cdots+\alpha_{i,m_i-1}n^{m_i-1})r_i^n(αi,0?+αi,1?n+?+αi,mi??1?nmi??1)rin? 替代 上述解中的αirin\alpha_ir_i^nαi?rin?即可。

例:斐波那契數列(OEIS A000045)
遞推關系fn=fn?1+fn?2f_n = f_{n-1}+f_{n-2}fn?=fn?1?+fn?2?,初始條件f0=0,f1=1f_0 = 0,f_1=1f0?=0,f1?=1
特征方程r2?r?1=0r^2-r-1=0r2?r?1=0 根為 r1=(1+5)/2r_1 = (1+\sqrt{5})/2r1?=(1+5?)/2r2=(1?5)/2r_2 = (1-\sqrt{5})/2r2?=(1?5?)/2
fn=α1(1+52)n+α2(1?52)nf_n = \alpha_1\left(\dfrac{1+\sqrt5}{2}\right)^n + \alpha_2\left(\dfrac{1-\sqrt5}{2}\right)^nfn?=α1?(21+5??)n+α2?(21?5??)n代入f0,f1f_0,f_1f0?,f1?解出α1=15\alpha _1 = \dfrac1{\sqrt5}α1?=5?1?α2=?15\alpha _2 = -\dfrac1{\sqrt5}α2?=?5?1?
則得到斐波那契數列的顯式公式為fn=15(1+52)n?15(1?52)nf_n = \dfrac1{\sqrt5}\left(\dfrac{1+\sqrt5}{2}\right)^n-\dfrac1{\sqrt5}\left(\dfrac{1-\sqrt5}{2}\right)^nfn?=5?1?(21+5??)n?5?1?(21?5??)n

求解常系數線性非齊次遞推關系

常系數線性非齊次遞推關系:形如 an=c1an?1+c2an?2+?+ckan?k+F(n)a_n = c_1a_{n-1}+c_2a_{n-2}+\cdots + c_ka_{n-k} +F(n)an?=c1?an?1?+c2?an?2?+?+ck?an?k?+F(n),與其相伴的齊次遞推關系為 an=c1an?1+c2an?2+?+ckan?ka_n = c_1a_{n-1}+c_2a_{n-2}+\cdots + c_ka_{n-k}an?=c1?an?1?+c2?an?2?+?+ck?an?k?,很顯然 通解 = 特解+齊次解

齊次解即對應的常系數線性齊次遞推關系的解,記作an(h)a_n^{(h)}an(h)?,特解記作an(p)a_n^{(p)}an(p)?

不同形式的F(n)具有不同形式的特解

F(n)F(n)F(n)特解形式
an+ban+ban+bcn+dcn+dcn+d
α?cn\alpha\cdot c^nα?cnβ?cn\beta\cdot c^nβ?cn

F(n)F(n)F(n) 形如 (btnt+bt?1nt?1+?+b1n+b0)sn(b_tn^t+b_{t-1}n^{t-1}+\cdots+b_1n+b_0)s^n(bt?nt+bt?1?nt?1+?+b1?n+b0?)sn.
則當 sss 不是特征根時,特解形如 (ptnt+pt?1nt?1+?+p1n+p0)sn(p_tn^t+p_{t-1}n^{t-1}+\cdots+p_1n+p_0)s^n(pt?nt+pt?1?nt?1+?+p1?n+p0?)sn.
sssmmm重特征根時,特解形如 nm(ptnt+pt?1nt?1+?+p1n+p0)snn^m(p_tn^t+p_{t-1}n^{t-1}+\cdots+p_1n+p_0)s^nnm(pt?nt+pt?1?nt?1+?+p1?n+p0?)sn.


分治算法與遞推關系

與動態規劃相似,分治算法(Divide and conquer algorithm)范式也會將問題劃分為一個或者多個小問題,不過這些小問題是不重疊的。連續使用這種劃分直到可以快速找到這些小問題的解,然后將小問題的解合并為原問題的解。即三個步驟:分割原問題,解決子問題,合并得到最終解。常見簡單分治算法:歸并排序、二分查找。這里將說明怎樣用遞關系來分析分治算法的復雜度。

分治遞推關系

假設一個遞歸算法將規模為n的問題劃分為a個子問題,每個子問題規模為n/b,并且需要g(n)的額外運算來合并這些子問題。用f(n)表示求解問題規模為n的問題所需運算數,則f(n)=af(n/b)+g(n)f(n)= af(n/b)+g(n)f(n)=af(n/b)+g(n)

n=bkn = b^kn=bk,多次迭代后可以得到:
f(n)=akf(1)+∑j=0k?1ajg(n/bj)f(n)= a^kf(1)+\sum_{j=0}^{k-1}a^jg(n/b^j)f(n)=akf(1)+j=0k?1?ajg(n/bj)

很容易知道,
二分查找的分治遞推關系:f(n)=f(n/2)+2f(n)=f(n/2)+2f(n)=f(n/2)+2
歸并排序的分治遞推關系:M(n)=2M(n/2)+nM(n)=2M(n/2)+nM(n)=2M(n/2)+n

分治算法的復雜度分析

定理1:設f(n)f(n)f(n)是滿足f(n)=af(n/b)+cf(n)=af(n/b)+cf(n)=af(n/b)+c 的增函數,nnnbbb整除,a?1a\geqslant 1a?1
bbb是大于1的整數,ccc是正實數。那么
f(n)={O(nlogba)a>1O(log?n)a=1f(n) = \begin{cases} O(n^{log_ba})&a>1\\O(\log n)&a=1\end{cases}f(n)={O(nlogb?a)O(logn)?a>1a=1?證明:令n=bkn=b^kn=bk即可證得,當n≠bkn\neq b^kn??=bk時,依然成立。

很容易得出二分查找復雜度為O(log?n)O(\log n)O(logn)

主定理:若f(n)=af(n/b)+cndf(n)=af(n/b)+cn^df(n)=af(n/b)+cnd,則f(n)={O(nd)a&lt;bdO(ndlog?n)a=bdO(nlogba)a?bdf(n) = \begin{cases} O(n^d)&amp;a&lt;b^d \\O(n^d\log n)&amp; a=b^d \\O(n^{log_ba})&amp;a \succ b^d \end{cases}f(n)=??????O(nd)O(ndlogn)O(nlogb?a)?a<bda=bda?bd?

同理,令n=bkn=b^kn=bk即可證得。(ps:上面的?\succ?表示大于號,但其實這個符號并不是這個意思。這里有一個bug,hexo自帶一個功能的會把一段內連續的<>之間的內容注釋掉,于是就只好將就一下。)

根據主定理,很容易得出歸并排序復雜度為O(nlog?n)O(n\log n)O(nlogn)
可以看到,定理1只是主定理的特殊情況。
這里僅簡單分析分治算法,并解決了其復雜度的問題,并未涉及分治算法的設計及具體實現。


生成函數

表示序列的一個有效方法是生成函數,把序列的項作為形式冪級數的變量x的冪的系數。可以用生成函數解決許多類型的計數問題。拓展閱讀:Generating function - Wikipedia,什么是生成函數? | Matrix67: The Aha Moments。

定義

實數序列a0,a1,...,ak,...a_0,a_1,...,a_k,...a0?,a1?,...,ak?,...的(普通)生成函數是無窮級數G(x)=∑k=0∞akxkG(x)= \sum_{k=0}^{\infty}a_kx^kG(x)=k=0?ak?xk

例:序列{C(n,k)}\{C(n,k)\}{C(n,k)}的生成函數即是G(x)=(1+x)nG(x)=(1+x)^nG(x)=(1+x)n.

使用生成函數求解計數問題時,通常考慮形式冪級數,即不需要考慮其收斂域(對發散或收斂并不感興趣)

廣義二項式定理

廣義二項式系數:
uuu實數kkk為非負整數,廣義二項式系數定義為
(ku)={u(u?1)?(u?k?1)/k!k&gt;01k=0\Big(^u_k\Big)=\begin{cases}u(u-1)\cdots(u-k-1)/k! &amp; k&gt;0 \\1&amp;k=0\end{cases}(ku?)={u(u?1)?(u?k?1)/k!1?k>0k=0?

當u為負整數時,展開即可有下列式子成立(k?n)=(?1)rC(n+r?1,r)\Big(^{-n}_k\Big) = (-1)^rC(n+r-1,r)(k?n?)=(?1)rC(n+r?1,r)

廣義二項式定理:
xxx是實數,∣x∣&lt;1|x|&lt;1x<1uuu 是實數,那么(1+x)u=∑k=0∞(ku)xk(1+x)^u=\sum_{k=0}^{\infty}\Big(^u_k\Big)x^k(1+x)u=k=0?(ku?)xk

其實這就是(1+x)u(1+x)^u(1+x)u的冪級數展開,使用麥克勞林級數(即在x=0處泰勒展開)即可證明。

常用生成函數

這里給出一些最常用生成函數,以及其對應的序列一般項。

(1). (1+ax)n=∑k=0nC(n,k)akxk(1+ax)^n=\sum_{k=0}^nC(n,k)a^kx^k(1+ax)n=k=0n?C(n,k)akxkak=C(n,k)aka_k=C(n,k)a^kak?=C(n,k)ak,二項式定理得到
(2). 1?xr+11?x=∑k=0nxk\dfrac{1-x^{r+1}}{1-x}=\sum_{k=0}^nx^k1?x1?xr+1?=k=0n?xkak=1,k?na^k=1,k\leqslant nak=1,k?n;否則為0,幾何級數求和得到
(3). 11?ax=∑k=0∞akxk\dfrac1{1-ax}=\sum_{k=0}^{\infty}a^kx^k1?ax1?=k=0?akxkak=aka_k=a^kak?=ak,對∣x∣&lt;1|x|&lt;1x<1的幾何級數求和取極限得到
(4). 1(1?x)2=∑k=0∞(k+1)xk\dfrac 1{(1-x)^2}=\sum_{k=0}^{\infty}(k+1)x^k(1?x)21?=k=0?(k+1)xkak=k+1a_k=k+1ak?=k+1,對11?x\dfrac1{1-x}1?x1?求導得到
(5). 1(1?x)n=∑k=0∞C(n+k?1,k)xk\dfrac1{(1-x)^n}=\sum_{k=0}^{\infty}C(n+k-1,k)x^k(1?x)n1?=k=0?C(n+k?1,k)xkak=C(n+k?1,k)=C(n+k?1,n?1)a_k=C(n+k-1,k)=C(n+k-1,n-1)ak?=C(n+k?1,k)=C(n+k?1,n?1),由廣義二項式定理得到
(6). ex=∑k=0∞xkk!e^x=\sum_{k=0}^{\infty}\dfrac{x^k}{k!}ex=k=0?k!xk?ak=1/k!a_k=1/k!ak?=1/k!,泰勒展開即可得到
(7). ln?(1+x)=∑k=0∞(?1)k+1kxk\ln(1+x)=\sum_{k=0}^{\infty}\dfrac{(-1)^{k+1}}{k}x^kln(1+x)=k=0?k(?1)k+1?xkak=(?1)k+1/ka_k={(-1)^{k+1}}/{k}ak?=(?1)k+1/k,同上泰勒展開得到

生成函數可以用來求解計數問題,還可以用來求解遞推關系和證明組合恒等式。這里不想寫了,略過吧!(笑)


容斥原理及其應用

兩個集合的容斥原理是很熟悉的,∣A∪B∣=∣A∣+∣B∣?∣A∩B∣|A\cup B|=|A|+|B|-|A\cap B|AB=A+B?AB,那么對于多個幾個呢?很容易想到,但可能并不容易寫出來。Inclusion–exclusion principle。

容斥原理

A1,A2....,AnA_1,A_2....,A_nA1?,A2?....,An?是有窮集,則∣A1∪A2∪?∪An∣=∑1?i?n∣Ai∣?∑1?i&lt;j?n∣Ai∩Aj∣+∑1?i&lt;k&lt;j?n∣Ai∩Aj∩Ak∣+?+(?1)n+1∣A1∩A2∩?∩An∣|A_1\cup A_2 \cup \cdots \cup A_n|=\sum_{1\leqslant i \leqslant n}|A_i|-\sum_{1\leqslant i&lt; j \leqslant n}|A_i\cap A_j|\\ +\sum_{1\leqslant i&lt;k&lt; j \leqslant n}|A_i\cap A_j\cap A_k|+\cdots+(-1)^{n+1}|A_1\cap A_2\cap\cdots \cap A_n|A1?A2??An?=1?i?n?Ai??1?i<j?n?Ai?Aj?+1?i<k<j?n?Ai?Aj?Ak?+?+(?1)n+1A1?A2??An?

可以看到加號和減號是交替出現的,保證了沒有遺漏也沒有重復。

三個集合的容斥原理:

應用很多,此處愉快地略過。


結語

其實我只想快速看完這本書,寫完了之后,好好想一想應該怎樣去寫。還有慢慢肝算法導論,重新回顧數據結構,一堆技術書等著去肝呢!所有省略了很多內容,對自己還未掌握的東西抄上來就沒有多大意義了。給了很多鏈接,但其實大部分鏈接我都未曾去認真看過(笑)。

逐步積累,隨性記錄,知道自己要去的地方、要走的路,一直寫著就好。——201.3.7


參考資料:《離散數學及其應用》(本科教學版,Kenneth H.Rosen著,原書第七版)

總結

以上是生活随笔為你收集整理的【离散数学】高级计数技术的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。