算法七——分治算法
文章出處:極客時間《數(shù)據(jù)結(jié)構(gòu)和算法之美》-作者:王爭。該系列文章是本人的學(xué)習(xí)筆記。
MapReduce本質(zhì)就是一個分值算法。
什么是分治算法
分治算法的核心是:分而治之。也就是將原問題分解為n個規(guī)模較小,并且結(jié)構(gòu)與原問題相似的子問題,遞歸地解決這些子問題,并且合并子問題的結(jié)果得到原問題的解。
與遞歸的區(qū)別:遞歸是一種編程技巧,分治是一種算法思想。
使用分治法的步驟:
1 分解:將原問題分解為一系列子問題;
2 解決:遞歸地解決各個子問題,當(dāng)問題足夠小,可以直接求解;
3 合并:將子問題的結(jié)果合并為原問題的解。
分治算法能解決的問題的特征:
1 原問題與分解后的子問題具有相同的模式。
2 子問題可以獨立求解,子問題之間沒有相關(guān)性;這點與動態(tài)規(guī)劃是有區(qū)別的。動態(tài)規(guī)劃分解后的子問題可能是重復(fù)的,需要把結(jié)果保存下來,避免重復(fù)計算。
3 具有分解終止條件。當(dāng)子問題足夠小,可以直接求解。
4 子問題的解合并為原問題的解,合并操作不能太復(fù)雜,否則起不到降低復(fù)雜度的效果。
計算數(shù)組的逆序度
假設(shè)我們有n個數(shù)據(jù),希望從小到大排序。當(dāng)數(shù)組完全有序的時候,有序度為n(n?1)2\dfrac{n(n-1)}{2}2n(n?1)?,逆序度為0。當(dāng)數(shù)組是按照從大到小排序的時候,那有序度是0,無序度是n(n?1)2\dfrac{n(n-1)}{2}2n(n?1)?。除了這兩種極端情況,我們計算數(shù)組逆序?qū)Φ膫€數(shù)表示逆序度。
如何編程求出一組數(shù)組中逆序?qū)Φ膫€數(shù)呢?
直觀的想法就是從第0個元素開始,算一個后面有幾個元素比它小,計數(shù)為k0。再從第1個元素開始,算一個后面有幾個元素比它小,計數(shù)為k1…一直算到最后一個元素。這幾個計數(shù)(k0,k1…)加和,就是逆序?qū)Φ膫€數(shù)。時間復(fù)雜度是O(n^2)。是不是可以改進呢?
我們試著用分治思想解決。求數(shù)組A的逆序?qū)€數(shù),可以分解為前后兩個部分?jǐn)?shù)組分別標(biāo)記為A1,A2。遞歸求解A1,A2逆序?qū)€數(shù)K1,K2,再求出A1與A2之間逆序?qū)€數(shù)K3。K1+K2+K3就是原問題的解。
當(dāng)數(shù)組中只有兩個元素的時候,就可以知道K1,K2的值。
如何求K3。我們可以參考歸并排序的合并操作。將數(shù)組A1,A2排序。假設(shè)數(shù)組A1={1,5,6},A2={2,3,4}。A1長度為3。
合并排序:
1(來自A1數(shù)組,不用管)
1,2 (來自A2數(shù)組,此時A1數(shù)組還有3-1個元素沒有排序,所以2小于A1數(shù)組中的2個元素)
1,2,3(來自A2數(shù)組,此時A1數(shù)組還有3-1個元素沒有排序,所以2小于A1數(shù)組中的2個元素)
1,2,3,4(來自A2數(shù)組,此時A1數(shù)組還有3-1個元素沒有排序,所以2小于A1數(shù)組中的2個元素)
1,2,3,4,5(來自A1數(shù)組,不用管)
1,2,3,4,5,6(來自A1數(shù)組,不用管)
最終:此次合并操作發(fā)現(xiàn)逆序?qū)€數(shù)是2+2+2=6。
合并為原問題的解:K1+K2+6。
合并操作是一個O(n)的時間復(fù)雜度。
經(jīng)典練習(xí)題目
二維平面上有 n 個點,如何快速計算出兩個距離最近的點對?
有兩個 nn 的矩陣 A,B,如何快速求解兩個矩陣的乘積 C=AB?
自己練習(xí)
分治思想處理海量數(shù)據(jù)
前面學(xué)到的一些算法和數(shù)據(jù)結(jié)構(gòu),都是基于內(nèi)存存儲和單機處理的。如果要處理的數(shù)據(jù)量大,沒有辦法一次加載到內(nèi)存中。這時候這些算法和數(shù)據(jù)結(jié)構(gòu)就不能發(fā)揮作用了。但我們可以使用分治思想來處理這個問題。
例如我們需要對10G的訂單按照金額排序。單機只有3G內(nèi)存。那么,我們可以把這10G訂單掃描一遍,找到訂單金額的最小值和最大值。將這10G訂單按照訂單金額從小到大分成幾個區(qū)間。例如1-100放入一個小文件,101-200放入另外一個文件。以此類推。這樣形成的一個一個小文件可以加載到內(nèi)存中。對單個文件最排序,排序之后再合并排序結(jié)果。
如果訂單數(shù)據(jù)是放在GFS這樣的分布式文件系統(tǒng)上。被分成的多個小文件可以同時被不同的機器加載處理,最后再合并結(jié)果集。這樣并行處理速度就快多了。這里需要注意一點:數(shù)據(jù)存儲的機器與處理的機器需要在同一個網(wǎng)段內(nèi)或者局域網(wǎng)。否則數(shù)據(jù)傳輸速度會是最大的時間開銷。反而會慢。
Mapreduce 與 分治算法
這也就是MapReduce的原理。單個機器的性能不足以完成任務(wù),就把任務(wù)分配到多臺服務(wù)器 。最后再合并結(jié)果。MapReduce是一個任務(wù)調(diào)度 框架。數(shù)據(jù)依賴GFS存儲,依賴Borg管理機器。它從 GFS 中拿數(shù)據(jù),交給 Borg 中的機器執(zhí)行,并且時刻監(jiān)控機器執(zhí)行的進度,一旦出現(xiàn)機器宕機、進度卡殼等,就重新從 Borg 中調(diào)度一臺機器執(zhí)行。
總結(jié)
- 上一篇: 李开西老师 安全生产实战专家
- 下一篇: Tomcat原理整理