摘要:1.計算領域的核心理念2.漸進記法3.圖與樹的實現4.提防黑盒子html
1.計算領域的核心理念python
算法---一個執行過程,包含了可以解決某個特定問題的有限步驟集。(圖靈機能夠理解爲是這個待解決問題的正規描述形式)git
圖靈機---計算領域的理論核心,圖靈機有着各類不一樣的具體實現,但每種實現均可以看作一個有限狀態機:由一個有限的狀態集(包括已完成部分)與各類用於觸發讀寫操做及不一樣狀態切換的潛在符號共同組成。(能夠將其看作機器運行所需的規則)。github
隨機存取機---適用於更細粒度上的算法分析,從標準單處理器計算機中簡化出的一種抽象模型,比如有一塊能夠直接存取的內存,而不是同圖靈機那樣的可滾動的紙帶。算法
應具有的屬性:數據庫
問題---就目標而言,問題實際就是輸入與輸出之間的某種關係,更精確的講,就是指一組集合對之間的數學意義上的關係,而且藉由指定這種關係的過程,問題會被肯定下來。編程
編碼---對輸入 0 1 編碼,問題實例的大小,能夠簡單當作編碼它所需的內存大小(一般與編碼自己的確切屬性沒太大關係)。網絡
2.漸進記法數據結構
append insert 的例子;併發
研究算法分析時要關注的重點:常數單位上的差距(一般取決於一些特定事物如通用編程語言的性能,硬件速度等);焦點 集中在那些可以獨立於具體實現以外的屬性。
2.1. 漸進記法是用於分析算法與數據結構的重要工具,核心思想爲提供一種資源保護形式,主要用於分析某項功能在應對必定規模參數輸入時所須要的資源(時間 內存 等)
漸進記法使用由希臘字母構成的記號體系。Ο記法表明漸進上界,Ω記法表明漸進下界,Θ記法表明前兩種記法的交集。
2.2. 漸進記法 簡化了咱們面臨的數學問題。
時間複雜度 | 相關名稱 | 相關示例及說明 |
Θ(1) | 常數級 | 哈希表的查詢與修改 |
Θ(lgn) | 對數級 | 二分搜索 |
Θ(n) | 線性級 | 列表遍歷 |
Θ(nlgn) | 線性對數級 | 任意值得最優化排序,其複雜度等同於Θ(lgn!) |
Θ(n2) | 平方級 | 拿n個對象進行相互比對 |
Θ(n3) | 立方級 | Floyd-Warshall算法 |
Ο(nk) | 多項式級 | 基於n的k層嵌套循環(k爲整數,k>0) |
Ω(kn) | 指數級 | 每n項產生一個子集(k>1) |
Θ(n!) | 階乘級 | 對n個值執行全排列操做 |
多項式級與指數級分割着易處理問題和難處理問題,僅通常而言。
幾條簡單規則:加法運算中,只以階數最高的被加數爲準;乘法運算中,常數因子忽略不計;保持相關上下界的嚴謹性;Θ(f) + Θ(g) = Θ(f+g);Θ(f) * Θ(g) = Θ(f*g)。
三種重要狀況:1.最好狀況(理想輸入時的運行時間)2.最壞狀況(所能給的最佳保證)3.平均狀況(迴避)
實證式算法評估:1.當沒有把握時,就把可能的解決方案都試一遍。2.用timeit模塊進行計時:
import timeit timeit.timeit("x = 2 + 2") $命令行環境調用 $ python -m timeit -s"omport mymodule as m" "m.myfunction()"
3.使用profiler找出瓶頸:給出關於執行時間都都花在哪裏的詳細信息,從而肯定代碼中須要優化的部分。當主函數是main()時,執行下列代碼,能夠給出各個函數的運行時間。(可使用Python Call Graph 工具可視化的看到代碼的調用狀況)
import cProfile cProfile.run('main()')
4.繪製出結果。matplotlib繪製工具包
5.根據計時比對結果作出判斷
6.經過相關實驗對漸進時間作出判斷
3.圖Graph與樹Tree的實現
圖結構能夠用來表現彷佛全部類型的結構與系統,而樹結構只是圖結構的一種特殊狀況但至關廣泛。若是咱們的問題能夠用樹結構來描述時,基本上已經有了有效的解決方案。
從七橋問題開始:全面介紹圖論 https://www.jiqizhixin.com/articles/2018-03-11-2 (https://medium.freecodecamp.org/i-dont-understand-graph-theory-1c96572a1401)
數據結構與算法 圖論 https://zhuanlan.zhihu.com/p/25498681
入門圖論與網絡分析 含python代碼 https://www.jiqizhixin.com/articles/2018-08-07-16
3.1鄰接列表
#簡單明瞭的鄰接集表示方法 a,b,c,d,e,f,g,h = range(8) N = [ {b,c,d,e,f}, #a {c,e}, #b {d}, #c {e}, #d {f}, #e {c,g,h}, #f {f,h}, #g {f,g}, #h ] >>>b in N[a] True >>>len(N[f]) 3
若是某些代碼存在於某個源文件裏,而咱們又想在交互解釋其中研究的話,使用python的 - i 開關來運行:
python -i listing.py
#其餘表示方法 #鄰接列表 成員檢測時速度放緩 a,b,c,d,e,f,g,h = range(8) N = [ [b,c,d,e,f], #a [c,e], #b [d], #c [e], #d [f], #e [c,g,h], #f [f,h], #g [f,g], #h ] #加權鄰接字典 a,b,c,d,e,f,g,h = range(8) N = [ {b:2,c:1,d:3,e:9,f:4], #a {c:4,e:3}, #b {d:5}, #c {e:1}, #d {f:2}, #e {c:5,g:6,h:7}, #f {f:2,h:6}, #g {f:3,g:4}, #h ] #鄰接集的字典表示法 相似字符類的鄰接列表(成本略低) a,b,c,d,e,f,g,h = range(8) N = { 'a': set('bcdef'), #a 'b': set('ce'), #b 'c': set('d'), #c 'd': set('e'), #d 'e': set('f'), #e 'f': set('cgh'), #f 'g': set('fh'), #g 'h': set('fg'), #h } #一個圖的最佳表示法 取決於 咱們要用它作什麼
3.2鄰接矩陣
節點編號從0 到V-1,用0 和1 來充當真值(無權圖中),對角線上的值全爲0 ,在無向圖鄰接矩陣關於對角線對稱相等,
#用嵌套list實現的鄰接矩陣 a,b,c,d,e,f,g,h = range(8) N = [ [0,1,1,1,1,1,0,0], #a [0,0,1,0,1,0,0,0], #b [0,0,0,1,0,0,0,0], #c [0,0,0,0,1,0,0,0], #d [0,0,0,0,0,1,0,0], #e [0,0,1,0,0,1,0,0], #f [0,0,0,0,0,1,0,1], #g [0,0,0,0,0,1,1,0], #h ] #能夠更改不一樣的權值 #非法的權值就設置爲極大值, float('inf') inf = float('inf') #權值爲 inf
3.3樹的實現
樹自己就是圖的特殊狀況,但許多特定問題用特定的樹結構更容易實現。
#簡單的樹結構 表示爲二叉列表 >>>T = [["a","b"],["c"],["d",["e","f"]]] >>>T[0][1] 'b' >>>T[2][1][0] 'e' #二叉樹類 class Tree: def __init__(self,left,right): self.left = left self.right = right >>>t = Tree(Tree("a","b"),Tree("c","d")) >>>t.right.left 'c' #多路搜索類 class Tree: def __init__(self,kids,next=None): self.kids = self.val = kids self.next = next >>>t = Tree(Tree("a"),Tree("b",Tree("c",Tree("d"))))) >>>t.kids.next.next.val 'c'
參考:Bunch模式 http://www.javashuo.com/article/p-tjuduhxl-cz.html
3.4存在多種表示法
空泛的判斷句子沒有,咱們更應該針對具體問題思考該任務的漸進性能。
最主要的爲以上介紹的兩種。另外,需注意編程中沒有注意就用到的圖實現(隱式)
參考:圖結構庫
python-graph : https://github.com/pmatiello/python-graph
Graph-tool : https://graph-tool.skewed.de/
此外還有 Pygr 基於圖結構的數據庫 Gato基於圖結構的動畫工具箱 PADS基於圖結構的算法集
4.提防黑箱子
編程時,咱們必須依賴一些並非本身編寫的組件,稱爲黑箱子。不注意的話,Python和機器自己的不少機制會成爲咱們的絆腳石。
4.1隱性平方級操做
4.2浮點運算的麻煩
5.小結
基礎概念,漸進記法與圖結構,黑箱子......
加油 嘿嘿嘿!