導航:首頁 > 源碼編譯 > 演算法ADHOC

演算法ADHOC

發布時間:2023-09-20 01:24:30

Ⅰ 計算機分治法

一、基本概念

在計算機科學中,分治法是一種很重要的演算法。字面上的解釋是「分而治之」,就是把一個復雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合並。這個技巧是很多高效演算法的基礎,如排序演算法(快速排序,歸並排序),傅立葉變換(快速傅立葉變換)……

任何一個可以用計算機求解的問題所需的計算時間都與其規模有關。問題的規模越小,越容易直接求解,解題所需的計算時間也越少。例如,對於n個元素的排序問題,當n=1時,不需任何計算。n=2時,只要作一次比較即可排好序。n=3時只要作3次比較即可,…。而當n較大時,問題就不那麼容易處理了。要想直接解決一個規模較大的問題,有時是相當困難的。

二、基本思想及策略

分治法的設計思想是:將一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。

分治策略是:對於一個規模為n的問題,若該問題可以容易地解決(比如說規模n較小)則直接解決,否則將其分解為k個規模較小的子問題,這些子問題互相獨立且與原問題形式相同,遞歸地解這些子問題,然後將各子問題的解合並得到原問題的解。這種演算法設計策略叫做分治法。

如果原問題可分割成k個子問題,1<k≤n,且這些子問題都可解並可利用這些子問題的解求出原問題的解,那麼這種分治法就是可行的。由分治法產生的子問題往往是原問題的較小模式,這就為使用遞歸技術提供了方便。在這種情況下,反復應用分治手段,可以使子問題與原問題類型一致而其規模卻不斷縮小,最終使子問題縮小到很容易直接求出其解。這自然導致遞歸過程的產生。分治與遞歸像一對孿生兄弟,經常同時應用在演算法設計之中,並由此產生許多高效演算法。

三、分治法適用的情況

分治法所能解決的問題一般具有以下幾個特徵:

1) 該問題的規模縮小到一定的程度就可以容易地解決

2) 該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質。

3) 利用該問題分解出的子問題的解可以合並為該問題的解;

4) 該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。

第一條特徵是絕大多數問題都可以滿足的,因為問題的計算復雜性一般是隨著問題規模的增加而增加;

第二條特徵是應用分治法的前提它也是大多數問題可以滿足的,此特徵反映了遞歸思想的應用;、

第三條特徵是關鍵,能否利用分治法完全取決於問題是否具有第三條特徵,如果具備了第一條和第二條特徵,而不具備第三條特徵,則可以考慮用貪心法或動態規劃法。

第四條特徵涉及到分治法的效率,如果各子問題是不獨立的則分治法要做許多不必要的工作,重復地解公共的子問題,此時雖然可用分治法,但一般用動態規劃法較好。

四、分治法的基本步驟

分治法在每一層遞歸上都有三個步驟:

step1 分解:將原問題分解為若干個規模較小,相互獨立,與原問題形式相同的子問題;

step2 解決:若子問題規模較小而容易被解決則直接解,否則遞歸地解各個子問題

step3 合並:將各個子問題的解合並為原問題的解。

它的一般的演算法設計模式如下:

Divide-and-Conquer(P)

1. if |P|≤n0

2. then return(ADHOC(P))

3. 將P分解為較小的子問題 P1 ,P2 ,…,Pk

4. for i←1 to k

5. do yi ← Divide-and-Conquer(Pi) △ 遞歸解決Pi

6. T ← MERGE(y1,y2,…,yk) △ 合並子問題

7. return(T)

其中|P|表示問題P的規模;n0為一閾值,表示當問題P的規模不超過n0時,問題已容易直接解出,不必再繼續分解。ADHOC(P)是該分治法中的基本子演算法,用於直接解小規模的問題P。因此,當P的規模不超過n0時直接用演算法ADHOC(P)求解。演算法MERGE(y1,y2,…,yk)是該分治法中的合並子演算法,用於將P的子問題P1 ,P2 ,…,Pk的相應的解y1,y2,…,yk合並為P的解。

五、分治法的復雜性分析

一個分治法將規模為n的問題分成k個規模為n/m的子問題去解。設分解閥值n0=1,且adhoc解規模為1的問題耗費1個單位時間。再設將原問題分解為k個子問題以及用merge將k個子問題的解合並為原問題的解需用f(n)個單位時間。用T(n)表示該分治法解規模為|P|=n的問題所需的計算時間,則有:

T(n)= k T(n/m)+f(n)

通過迭代法求得方程的解:

遞歸方程及其解只給出n等於m的方冪時T(n)的值,但是如果認為T(n)足夠平滑,那麼由n等於m的方冪時T(n)的值可以估計T(n)的增長速度。通常假定T(n)是單調上升的,從而當mi≤n<mi+1時,T(mi)≤T(n)<T(mi+1)。

六、可使用分治法求解的一些經典問題

(1)二分搜索
(2)大整數乘法
(3)Strassen矩陣乘法
(4)棋盤覆蓋
(5)合並排序
(6)快速排序
(7)線性時間選擇
(8)最接近點對問題
(9)循環賽日程表
(10)漢諾塔
七、依據分治法設計程序時的思維過程

實際上就是類似於數學歸納法,找到解決本問題的求解方程公式,然後根據方程公式設計遞歸程序。
1、一定是先找到最小問題規模時的求解方法
2、然後考慮隨著問題規模增大時的求解方法
3、找到求解的遞歸函數式後(各種規模或因子),設計遞歸程序即可。

Ⅱ 幾種經典演算法回顧

今天無意中從箱子里發現了大學時學演算法的教材《演算法設計與分析》,雖然工作這么幾年沒在什麼地方用過演算法,但演算法的思想還是影響深刻的,可以在系統設計時提供一些思路。大致翻了翻,重溫了一下幾種幾種經典的演算法,做一下小結。分治法動態規劃貪心演算法回溯法分支限界法分治法1)基本思想將一個問題分解為多個規模較小的子問題,這些子問題互相獨立並與原問題解決方法相同。遞歸解這些子問題,然後將這各子問題的解合並得到原問題的解。2)適用問題的特徵該問題的規模縮小到一定的程度就可以容易地解決該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子問題3)關鍵如何將問題分解為規模較小並且解決方法相同的問題分解的粒度4)步驟分解->遞歸求解->合並 divide-and-conquer(P) { if ( | P | <= n0) adhoc(P); //解決小規模的問題 divide P into smaller subinstances P1,P2,...,Pk;//分解問題 for (i=1,i<=k,i++) yi=divide-and-conquer(Pi); //遞歸的解各子問題 return merge(y1,...,yk); //將各子問題的解合並為原問題的解 }google的核心演算法MapRece其實就是分治法的衍生5)分治法例子:合並排序規約過程:動態規劃1)基本思想將待求解問題分解成若干個子問題,但是經分解得到的子問題往往不是互相獨立的,如果能夠保存已解決的子問題的答案,而在需要時再找出已求得的答案,就可以避免大量重復計算2)適用問題的特徵最優子結構在遞歸計算中,許多子問題被重復計算多次3)步驟找出最優解的性質,並刻劃其結構特徵。遞歸地定義最優值。以自底向上的方式計算出最優值。根據計算最優值時得到的信息,構造最優解。貪心演算法1)基本思想貪心演算法總是作出在當前看來最好的選擇。也就是說貪心演算法並不從整體最優考慮,它所作出的選擇只是在某種意義上的局部最優選擇2)適用問題的特徵貪心選擇性質,即所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。最優子結構性質3)步驟:不斷尋找局部最優解4)例子:找硬幣,哈夫曼編碼,單源最短路徑,最小生成樹(Prim和Kruskal) 最小生成樹圖示:回溯法1)基本思想在問題的解空間樹中,按深度優先策略,從根結點出發搜索解空間樹。演算法搜索至解空間樹的任意一點時,先判斷該結點是否包含問題的解。如果肯定不包含,則跳過對該結點為根的子樹的搜索,逐層向其祖先結點回溯;否則,進入該子樹,繼續按深度優先策略搜索2)適用問題的特徵:容易構建所解問題的解空間3)步驟定義問題的解空間 確定易於搜索的解空間結構以深度優先方式搜索解空間,並在搜索過程中用剪枝函數避免無效搜索 4)回溯法例子:N皇後問題分支限界法1)基本思想分支限界法常以廣度優先或以最小耗費(最大效益)優先的方式搜索問題的解空間樹。 在分支限界法中,每一個活結點只有一次機會成為擴展結點。活結點一旦成為擴展結點,就一次性產生其所有兒子結點。在這些兒子結點中,導致不可行解或導致非最優解的兒子結點被舍棄,其餘兒子結點被加入活結點表中。此後,從活結點表中取下一結點成為當前擴展結點,並重復上述結點擴展過程。這個過程一直持續到找到所需的解或活結點表為空時為止。2)分支限界法例子:單源最短路徑問題問題描述:在下圖所給的有向圖G中,每一邊都有一個非負邊權。

Ⅲ 分治演算法時間復雜度

一:分治演算法和遞歸
1.簡述遞歸

我們要講到分治演算法,我覺得有必要說一下遞歸,他們就像一對孿生兄弟,經常同時應用在演算法設計中,並由此產生許多高效的演算法。
直接或間接的調用自身的演算法稱為遞歸演算法。用函數自身給出定義的函數稱為遞歸函數。

int fibonacci(int n){
if (n <= 1) return 1;
return fibonacci(n-1)+fibonacci(n-2);
}
先簡單看一下經典的遞歸例子,博主會找個時間系統詳細的總結一下關於遞歸的內容。

2.簡述分治

分治法的設計思想是:

分–將問題分解為規模更小的子問題;
治–將這些規模更小的子問題逐個擊破;
合–將已解決的子問題合並,最終得出「母」問題的解;
一個先自頂向下,再自底向上的過程。

凡治眾如治寡,分數是也。—孫子兵法

3.分治法與遞歸的聯系

由分治法產生的子問題往往是原問題的較小模式,這就為使用遞歸技術提供了方便。在這種情況下,反復應用分治手段,可以使子問題與原問題類型一致而其規模卻不斷縮小,最終使子問題縮小到很容易直接求出其解。這自然導致遞歸過程的產生。

二:分治法的適用條件
分治法所能解決的問題一般具有以下幾個特徵:

1) 該問題的規模縮小到一定的程度就可以容易地解決
2) 該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質。
3) 利用該問題分解出的子問題的解可以合並為該問題的解;
4) 該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。

第一條特徵是絕大多數問題都可以滿足的,因為問題的復雜性一般是隨著問題規模的增加而增加;

第二條特徵是應用分治法的前提它也是大多數問題可以滿足的,此特徵反映了遞歸思想的應用;、

第三條是關鍵,能否利用分治法完全取決於問題是否具有第三條特徵,如果具備了第一條和第二條特徵,而不具備第三條特徵,則可以考慮用貪心法或動態規劃法。

第四條特徵涉及到分治法的效率,如果各子問題是不獨立的則分治法要做許多不必要的工作,重復地解公共的子問題,此時雖然可用分治法,但一般用動態規劃法較好

三:分治法的基本步驟
分解問題:將原問題分解為若干個規模較小,相互獨立,與原問題形式相同的子問題;(自頂向下)
這里涉及到一個平衡子問題的思想:人們從大量實踐中發現,在用分治法設計演算法時,最好使子問題的規模大致相同。即將一個問題分成大小相等的k個子問題的處理方法是行之有效的。這種使子問題規模大致相等的做法是出自一種平衡子問題的思想,它幾乎總是比子問題規模不等的做法要好。

解決問題:如果問題規模較小而容易被解決則直接解,否則遞歸地解各個子問題,以得到小問題的解。
合並結果:將各個子問題的解合並為原問題的解:(自底向上)。
它的一般演算法設計模式如下:
divide-and-conquer(P){
if ( | P | <= n0) adhoc(P); //(2)解決問題:遞歸到小問題,則解決小規模的問題(自頂向下)
divide P into smaller subinstances P1,P2,...,Pk;//(1)分解問題
for (i=1,i<=k,i++)
yi=divide-and-conquer(Pi); //利用遞歸的解各子問題
return merge(y1,...,yk); //將各子問題的解合並為原問題的解(自底向上)
}
四:分治法的復雜性分析
從分治法的一般設計模式可以看出,用他設計出的程序一般是遞歸演算法。因此分治法的計算效率通常可以用遞歸方程來進行分析。
一個分治法將規模為n的問題分成k個規模為n/m的子問題去解。設分解閥值(表示當問題P規模不超過n0時,問題已容易解出,不必再繼續分解)n0=1,且adhoc解規模為1的問題耗費1個單位時間。再設將原問題分解為k個子問題以及用merge將k個子問題的解合並為原問題的解需用f(n)個單位時間。用T(n)表示該分治法解規模為|P|=n的問題所需的計算時間,則有:

通常可以用展開遞歸式的方法來解這類遞歸方程,反復帶入求解得

閱讀全文

與演算法ADHOC相關的資料

熱點內容
明日之後安卓太卡怎麼辦 瀏覽:502
如何使用命令方塊找到村莊 瀏覽:766
泛函壓縮映像原理 瀏覽:521
win10清除文件夾瀏覽記錄 瀏覽:964
如何查看伺服器域中所有服務 瀏覽:384
學mastercam91編程要多久 瀏覽:999
如何查伺服器地址和埠 瀏覽:911
教學雲平台app怎麼下載 瀏覽:389
單片機510教學視頻 瀏覽:624
陝西信合app怎麼查看自己的存款 瀏覽:663
風冷冰箱有壓縮機 瀏覽:274
android實現wifi連接wifi 瀏覽:669
飛豬app怎麼幫別人值機 瀏覽:924
筆記本開我的世界伺服器地址 瀏覽:546
怎樣隱藏bat命令 瀏覽:127
android開發創意 瀏覽:138
京劇貓為什麼進不去伺服器 瀏覽:784
怎麼自己免費製作一個手機app 瀏覽:582
python同時迭代兩個變數 瀏覽:740
好分數app家長版怎麼刪除孩子 瀏覽:426