研究演算法的目的就是以設計時間複雜度更小的演算法,但要想對演算法進行優化必須學會計算每乙個步驟的演算法大小,進而從中尋找可以縮減的位置。為了計算每一步,有必要掌握一些基本的數學知識,有句話說過:數學水平在一定程度上決定了計算機的高度。
對於大多數演算法而言,都應用到了for/while迴圈。在迴圈不斷進行的過程中,每次執行迴圈體內基本操作的執行次數都是不同的。想要將每一次的結果相加,就相當於是不規則數的相加,也就是「求和」。同時,大多數演算法使用遞迴方法,雖然遞迴有很多**的壞處,但是表達十分清晰,也常常被使用。給定遞迴式,尋找到所需總時間和輸入n的關係,也是十分重要的。對數學能力的要求也是非常高的。下面從上文提及的兩方面展開,分別談論所需要的一些數學知識。
集合是數學中基礎的概念,在集合之上定義了很多集合的操作(交,並,補)。以集合為基礎設計的演算法也有很多,例如:並查集(克魯斯卡爾演算法求解最小生成樹)等等。關係是以集合依據的,多說乙個在集合上的關係。關係的內容也有很多,例如等價關係,傳遞關係等等。相對詳細的內容可以在離散數學中學到。函式可以理解成一種二元關係(x和y之間),一定是每乙個x,有乙個y與之對應,否則不可以被稱作函式。根據像和原像的關係,函式還可以被分為單射(所有x都有對應且對應不同的y),滿射(所有的y都具有原像),同時滿足單射和滿射的叫做雙射。
證明是演算法中很常見的考察方法,例如課後題中就包括很多時間複雜度的證明。在學習演算法之前,我們已經學習了離散數學。我認為離散數學的乙個教學目標就是教如何使用符號做證明,使證明過程更清晰易懂。證明的方法大概可以分成五種:
1)直接證明法:從現有條件出發,使用定理或者公理,最終得出想要的結論。直接證明也有兩種方向,可以從條件證結論,也可以從結論證條件。要求過程中的每乙個步驟都必須是充要條件。
2)間接證明法:證明原來命題的逆否命題成立。或者從中間出發,向兩頭延伸,最終得到條件和結論。
3)反證法:是一種常用的證明方法,當結論有明顯的乙個方向的傾向時可以使用反證法。假設結論不成立,推導和條件之間的矛盾。
4) 反例證明法:反例證明法往往用於結論已經明確。舉出乙個錯誤不滿足明確的關係,即可證明。大多數情況下,反例很難被列舉出來。
5)數學歸納法:數學歸納法常用於正確結論已經知道,但是需要詳細的過程進行推導。具有相對固定的模板,已知n=1時成立,假設n=k時成立,通過n=k式子的變形推導出n=k+1也同樣成立。
在演算法分析中很多時間複雜度是和和㏒n有關的(在計算機中所有的對數函式的都是以2為底的),關於對數有計算公式如下:
在演算法中常常會對整數做除以2的操作,但此時如果不知道整數的奇偶性,就會出現小數。為了進一步明確範圍,會使用頂函式和底函式。頂函式是大於等於x的最小整數,底函式是小於等於x的最大整數。
關於頂函式和底函式有以下重要等式:
階乘**於排列,表示第乙個位置有多少種排法,進而第二個位置有多少種排法,依此類推。常用大寫p表示,階乘的時間複雜度是很高的,經常的表示公式為:
二項式係數**於組合。組合即不考慮順序,是階乘的推廣。重要的是組合數公式:
鴿巢定理講的是一定分配的必然性,比如十乙隻鴿子進入十個洞穴,必然至少有兩個鴿子在其中乙個洞穴。從至多至少兩個角度,可得如下公式:
和式有以下公式:
當被加式子不再只取整數,而變成乙個函式時,需要使用積分的知識求解。可以使用不等式來確定上下界,當左右兩式達到相同的數量級時,就證明了時間複雜度。
遞推關係用於計算遞迴函式的時間複雜度,分為以下幾類:
對於齊次和非齊次的定義是由如下式子決定的:
1)線性齊次遞推式(例項見書p53頁):
2)非齊次遞推關係(例項見書p55頁):
3)分治遞推關係:
在演算法中,對很多大規模都會採用分治思想,將時間複雜度不斷細分再將更小規模整合,其中二分法是最常見的。
分治遞推關係主要有三種方法求解:
(1)展開遞推式(具體見書p57):
將遞推式不斷展開,直到某已知項,多為f(1)/f(0)。但展開遞推式存在若干缺點:有些情況下耗時,呆板,也容易出現計算錯誤。
(2)代入法(具體見書p59)
這種方法,通常用來證明上下界,也可證明精確解。需要猜想乙個解,結合數學歸納法求出所設的引數值。對於猜想的解是依靠經驗或者之前學過的一些定理或者推論。
(3)更換變元(具體見書p62)
更換變元可以是用指數函式代替原來的分子分母式,盡力轉化成前面齊次的形式在進行求解。
知識星球 預備知識
1.tenorflow 安裝 參考 tensorflow安裝教程 tensorflow 安裝教程 tensorflownews 2.tensrflow基礎 關注圖 會話 tensor 變數 feed和fetch。使用圖 graphs 來表示計算任務 在被稱之為會話 session 的上下文 cont...
Python預備知識
02 執行python程式 2.3.3 python 的 ide pycharm 03 配置pycharm 3.1.2 安裝和啟動步驟 3.1.3 設定專業版啟 標 3.1.4 解除安裝之前版本的 pycharm 3.2 匯入配置資訊 3.3 開啟乙個 python 專案 3.4 新建乙個專案 3....
C 預備知識
一 學前基礎 學習c 最好有一定的c語言基礎,當然也可以直接學習c 但是難度肯定不一樣。建議先粗略了解c語言的語法結構等基礎概念知識,在進行系統化的學習c 二 c和c 的區別 c 在c的基礎上新增了對物件導向程式設計和泛型程式設計的支援,所以c 是c語言的超集,是c語言的擴充版本,意味著任何有效的c...