首先必須強調的是,我是個演算法渣,多少年了~~還是渣/(ㄒoㄒ)/~~
這學期在上英文演算法課,機緣巧合選了英文,覺得老師講得還不錯,所以沒換到中文。想要通過這樣總結一下加深演算法理解,考試時也方便複習。
第一次課是對學習演算法課需要的數學基礎知識的複習,如集合以及集合的操作,函數,關係等,和一些數學證明方法的介紹,包括通過構造證明,通過對照證明(舉反例,找矛盾),通過案例證明(可以理解為分情況討論證明同一個結論對任一情況都成立),通過數學歸納法證明(包含最小反例法則,數學歸納的強法則)。
第二次課是接觸演算法必須的演算法複雜度分析,包括時間和空間上的複雜度分析。通過列舉了幾個演算法實際案例進行的分析,包括兩種搜尋方法(線性搜尋,二分搜尋),一個合并演算法(將兩個已經排好序的列表合并)和三種排序演算法(選擇排序,插入排序和合并排序)。
第一個詳細講的演算法是分治演算法,該演算法主要用於解決這樣條件下的問題:
(1) 可以被分解成若干個相同的更小的子問題,即該問題具有最優子結構性質;分解到一定的程度就會很容易解決;
(2) 可以迴圈解決這些子問題;
(3) 最後可以合適的將子問題的解合并為該問題的解;
(4) 該問題分解出的各個子問題是相互獨立的,即子問題之間不包含公用的子問題
實際問題就是逐一地解決這三個步驟:在將問題分解成子問題;在遞迴的最後一步,當問題變得足夠小的時候,可以被直接解決了;以及將子問題的答案合并。
使用分治演算法的經典例子如下:
(一) 乘法運算
(二) Merge排序
(三) 求中位元
(四) 矩陣的乘法
先就乘法操作進行一下推導。
(一) 乘法操作
該演算法是根據高斯的一個發現,將兩個複數的乘法
原本的四個乘法操作現在將其轉化為三個,
簡單看來,認為減少的複雜度並不多。但是當應用到迭代中,會發現可以大大減小複雜度。
對這個的證明可以將其從複數一般化到整型的乘法。假設x和y是兩個n位的整數,為了方便假設n都是2的冪。由以上條件,我們可以將x和y轉化為如下形式:
這樣一來,x和y的乘積可以表示為:
通過轉化後的式子來計算xy,加法操作和這裡的2的冪都是線性複雜度,因為對2求冪就是一個左移的位操作。現在,乘法操作就變成了對四個n/2位的數進行乘法操作的迭代(子問題是原來大小的一半),然後在O(n)時間內將之前的結果進行整合。這樣,使用master theorem來計算整個過程的複雜度的話就是
計算得到演算法的複雜度為O(n^2).
(備忘:master theorem如下:
為了提升演算法的運行效率,只用之前高斯提到的方法。原來的四個乘法操作可以轉化為三個,
即
這樣的話,使用master theorem來計算整個過程的複雜度的話就是
,在每一次迭代中,常量從4變為3,計算出來複雜度為。
該問題的迭代過程可以通過一棵樹來描述。
在子問題的每一次迭代中,問題的規模就減小一半。在次的迭代中,子問題的規模減小到1,迭代終止。因此,數的高度為。每一次迭代,問題的分支因子為3,也就是每次問題被分解為3個子問題,在第k層問題數目為3^k,每一個子問題的規模為在樹的第k層需要的時間為
在樹的最高層,k=0,則複雜度為O(n)。在最底層,k=,計算出來為,可以寫成,大約就是.
使用之前的思路,則這棵迭代數的分支因子為4,則計算,最後複雜度也需要這麼多。
因此,在分治演算法中,子問題的數目可以被解釋為迭代樹的分支因子(master theorem中的a),每一次問題規模的變化係數為b(減小一半就是1/2),最後將子問題的所有解合并起來的複雜度中n的冪指數即為d。
例如,二分尋找中,在一個已經排好序的序列z[0,1,…,n-1]中找到數k,首先將k與z[2/n]進行比較,根據結果在決定是在前半部分繼續比較還是後半部分繼續比較。這樣得到的迭代公式為,可以容易計算出該問題的複雜度為。
最後一部分講了關於Sorting Network的畫法,上課的時候聽得比較模糊。下來整理一下之後,過程如下:
1)首先建立一個Bitonic Sorter
先說Bitonic sequence,中文翻譯為雙調序列,也就是單調遞增和單調遞減的的序列,也可以迴圈轉換先單調遞增再單調遞減。
例如:
Half-cleaner是長度為1的比較網路,是第i個輸入與第i+n/2個輸入比較(假設n是偶數,i = 1,2,...n/2)
如下圖:
這樣得到的雙調序列上半部分是更小的值,下半部分是更大的值。上下兩部分都是雙調的。
然後就可以畫Bitonic Sorter的結構:
下面右圖為n = 8時的Bitonic Sorter
2)第二步構造一個Merger
Merger與Half-cleaner是有區別的,Merger[n]是將兩個單調的輸入序列和轉換成和..bn>, 而Half-CLeaner則是將轉換成。其區別如下圖:
於是構建的Merger如下:
3)最後一步就是構造Sorter
下面給出n=8和n=16時的sorting network:
n = 8:
n = 16: