『演算法』general

weixin_34208283發表於2018-07-05

<a id="markdown-1-演算法" name="1-演算法"></a>

1. 演算法

定義良好的計算過程,取輸入,併產生輸出. 即演算法是一系列的計算步驟,將輸入資料轉化為輸出結果

<a id="markdown-2-可以解決哪些型別的問題" name="2-可以解決哪些型別的問題"></a>

2. 可以解決哪些型別的問題

  • 大資料的儲存,以及開發出進行這方面資料分析的工具
  • 網路資料的傳輸,尋路, 搜尋
  • 電子商務密碼, (數值演算法,數論)
  • 資源分配,最大效益
  • ...

<a id="markdown-3-演算法分析" name="3-演算法分析"></a>

3. 演算法分析

衡量演算法的優劣


7130568-d452e7efb6fb3433.jpg
  • \omicron,O,\Omega,\Theta
  • 最壞情況, 平均情況
  • 增長的量級O(1),O(logn), O(n), O(n^k), O(a^n)

<a id="markdown-4-演算法設計" name="4-演算法設計"></a>

4. 演算法設計

<a id="markdown-41-分治divide-and-conquer" name="41-分治divide-and-conquer"></a>

4.1. 分治(divide and conquer)

結構上是遞迴的,
步驟: 分解,解決, 合併
eg 快排,歸併排序

<a id="markdown-5-遞迴式" name="5-遞迴式"></a>

5. 遞迴式

T(n) = aT(\frac{n} {b})+f(n)

<a id="markdown-51-代換法" name="51-代換法"></a>

5.1. 代換法

<a id="markdown-511-步驟" name="511-步驟"></a>

5.1.1. 步驟

  • 猜測解的形式
  • 用數學歸納法找出常數

<a id="markdown-512-例子" name="512-例子"></a>

5.1.2. 例子

T(n) = 2T(\frac{n} {2})+n
猜測T(n) = O(nlogn)
證明 T(n)\leqslant cnlogn
歸納奠基 n=2,3
歸納假設 T(\frac{n} {2}) \leqslant \frac{cn}{2}
遞迴
\begin{aligned} T(n) &\leqslant 2c\frac{n}{2}log(\frac{n}{2}) + n \leqslant cnlog(\frac{n}{2}) \\ \end{aligned}

<a id="markdown-513-放縮" name="513-放縮"></a>

5.1.3. 放縮

對於 T(n) = 2T(\frac{cn}{2}) + 1
如果 直接猜測 T(n) = O (n) 不能證明,
而且不要猜測更高的界 O (n^2)
可以放縮為 n-b

<a id="markdown-514-改變變數" name="514-改變變數"></a>

5.1.4. 改變變數

對於 T(n) = 2T(\sqrt{n})+logn
可以 令 m = logn, 得到
T(2^m) = 2T(m^{\frac{m}{2}}) + m
S(m) = T(2^m)
得到 S(m) = 2S(\frac{m}{2}) + m

<a id="markdown-52-遞迴樹" name="52-遞迴樹"></a>

5.2. 遞迴樹

例如 T(n) = 3T(\frac{n}{4}) + c n^2
不妨假設 n 為4的冪, 則有如下遞迴樹

7130568-4a1b9b6ee852b725.jpg
recursive-tree.jpg

每個結點是代價, 將每層加起來即可

<a id="markdown-53-主方法master-method" name="53-主方法master-method"></a>

5.3. 主方法(master method)

對於 T(n) = aT(\frac{n} {b})+f(n)
\begin{aligned} T(n)=\begin{cases} \Theta(n^{log_b a}),\quad f(n)=O(n^{ {log_b a}-\epsilon}) \\ \Theta(n^{log_b a}logn),\quad f(n)=\Theta(n^{log_b a}) \\ \Theta(f(n)),\quad f(n)=\Omega(n^{ {log_b a}+ \epsilon}),af(\frac{n}{b})\leqslant cf(n) \\ \qquad \qquad \quad \text{其中常數c<1,變數n任意大} \\ unknown, \quad others \end{cases} \end{aligned}
<a id="markdown-531-記憶" name="531-記憶"></a>

5.3.1. 記憶

直觀上, 比較 n^{log_b a}f(n), 誰大就是誰,
這裡的大是多項式上的比較, 即比較次數, 而不是漸近上的
比如 nnlogn 漸近上後者大, 但多項式上是不能比較的

<a id="markdown-532-證明" name="532-證明"></a>

5.3.2. 證明

<a id="markdown-5321-證明當-n-為-b-的正合冪時成立" name="5321-證明當-n-為-b-的正合冪時成立"></a>

5.3.2.1. 證明當 n 為 b 的正合冪時成立

  • 用遞迴樹可以得到 總代價為 \sum_{j=0}^{log_b n-1} a^j f(\frac{n}{b^j})
  • 決定上式的漸近界
  • 結合前兩點

<a id="markdown-5322-分析擴充套件至所有正整數-n-都成立" name="5322-分析擴充套件至所有正整數-n-都成立"></a>

5.3.2.2. 分析擴充套件至所有正整數 n 都成立

主要是應用數學技巧來解決 floor, ceiling 函式的處理問題

<a id="markdown-6-隨機演算法" name="6-隨機演算法"></a>

6. 隨機演算法

<a id="markdown-61-隨機排列陣列shuffle" name="61-隨機排列陣列shuffle"></a>

6.1. 隨機排列陣列(shuffle)

<a id="markdown-611-permute-by-sorting" name="611-permute-by-sorting"></a>

6.1.1. PERMUTE-BY-SORTING

給出初始陣列, eg A={1,2,3}, 選擇隨機的優先順序 P={16,4,10}
則得出 B={2,3,1},因為第二個(2)優先順序最小, 為4, 接著第三個,最後第1個.
優先順序陣列的產生, 一般在 RANDOM(1,n^3), 這樣優先順序各不相同的概率至少為 1-1/n

由於要排序優先順序陣列, 所以時間複雜度 O(nlogn)

如果優先順序唯一, 則此演算法可以 shuffle 陣列
應證明 同樣排列的概率是 \frac{1}{n!}

<a id="markdown-612-randomize-in-place" name="612-randomize-in-place"></a>

6.1.2. RANDOMIZE-IN-PLACE

# arr: array to be shuffled
n = len(arr)
for i in range(n):
    swap(arr[i],arr[random(i,n-1)])

時間複雜度 O(n)
證明
定義迴圈不變式: 對每個可能的 A_n^{i-1} 排列, 其在 arr[1..i-1] 中的概率為 \frac{1}{A_n^{i-1}}
初始化: i=1 成立
保持 : 假設 在第 i-1 次迭代之前,成立, 證明在第 i 次迭代之後, 仍然成立,
終止: 在 結束後, i=n+1, 得到 概率為 \frac{1}{n!}

<a id="markdown-7-組合方程的近似演算法" name="7-組合方程的近似演算法"></a>

7. 組合方程的近似演算法

  • Stiring's approximation: n! \approx \sqrt{2\pi n}\left(\frac{n}{e}\right)^n
  • 對於 C_n^x=a, 有 x=\frac{ln^2 a}{n}
  • 對於 C_x^n=a, 有 x=(a*n!)^{\frac{1}{n}}+\frac{n}{2}

<a id="markdown-8-概率分析與指示器變數例子" name="8-概率分析與指示器變數例子"></a>

8. 概率分析與指示器變數例子

<a id="markdown-81-球與盒子" name="81-球與盒子"></a>

8.1. 球與盒子

把相同的秋隨機投到 b 個盒子裡,問在每個盒子裡至少有一個球之前,平均至少要投多少個球?
稱投入一個空盒為擊中, 即求取得 b 次擊中的概率
設投 n 次, 稱第 i 個階段包括第 i-1 次擊中到 第 i 次擊中的球, 則第 i 次擊中的概率為 p_i=\frac{b-i+1}{b}
n_i表示第 i 階段的投球數,則 n=\sum_{i=1}^b n_i
n_i服從幾何分佈, E(n_i)=\frac{b}{b-i+1},
則由期望的線性性,
E(n)=E(\sum_{i=1}^b n_i)=\sum_{i=1}^b E(n_i)=\sum_{i=1}^b \frac{b}{b-i+1}=b\sum_{i=1}^b \frac{1}{i}=b(lnb+O(1))
這個問題又被稱為 贈券收集者問題(coupon collector's problem),即集齊 b 種不同的贈券,在隨機情況下平均需要買 blnb 張
<a id="markdown-82-序列" name="82-序列"></a>

8.2. 序列

拋 n 次硬幣, 期望看到的連續正面的次數
答案是 \Theta(logn)
記 長度至少為 k 的正面序列開始與第 i 次拋, 由於獨立, 所有 k 次拋擲都是正面的 概率為
P(A_{ik})=\frac{1}{2^k},對於 k=2\lceil lgn\rceil

7130568-780b9795b6d9a2bd.jpg
coin1.jpg

7130568-7d112b304e2d78b6.jpg
coin2.jpg
7130568-f104d530f2a57c99.jpg
coin3.jpg
7130568-be0fd1b57a5ff305.jpg
coin4.jpg

相關文章