第一章筆記:基礎知識

摘要: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.小結

基礎概念,漸進記法與圖結構,黑箱子......

加油 嘿嘿嘿!

相關文章
相關標籤/搜索