演算法 一些演算法設計方法

2021-06-01 12:00:21 字數 2888 閱讀 9178

一、口訣

廣列深歸,分分貪動回

二、含義

廣度優先一般使用佇列實現,深度優先一般使用遞迴實現。

分治法,分支定界法,貪婪演算法,動態規劃,回溯法

分治法:一分為二

貪婪演算法:不斷嘗試

動態規劃:遞迴不重複

回溯法:深度優先

分支定界:廣度優先

三、分治法

分而治之方法與軟體設計的模組化方法非常相似。為了解決乙個大的問題,可以:

1)把它分成兩個或多個更小的問題

2)分別解決每個小問題

3)把各個小問題的解答組合起來,即可得到原問題的解答。

小問題通常與原問題相似,可以遞迴地使用分而治之策略來解決。

應用:殘缺棋盤、排序、選擇和乙個計算幾何問題--找出二維空間中距離最近的兩個點。

四、貪婪演算法

貪婪演算法採用逐步構造最優解的方法,在每個階段,都作出乙個看上去最優的決策。決策一旦作出,就不可再更改,作出貪婪決策的依據稱為貪婪準則。

應用:貨箱裝船、揹包、拓撲排序、二分覆蓋問題。最短路徑問題、最小代價生成樹。

五、動態規劃

動態規劃是建立在最優原則的基礎上,採用動態規劃方法,可以優雅而高效地解決許多用貪婪演算法或分而治之演算法無法解決的問題。

和貪婪演算法一樣,在動態規劃中,可將乙個問題的解決方案視為一系列決策的結果。不同的是,在貪婪演算法中,每採用一次貪婪準則便做出乙個不可撤回的

決策,而在動態規劃中,還要考察每個最優決策序列中是否包含乙個最優子串行。

應用:揹包、影象壓縮、矩陣乘法鏈、最短路徑問題、無交叉子集和元件摺疊。

2023年美國數學家r.bellman等人,根據一類多階段問題的特點,把多階段決策問題變換為一系列互相聯絡的單階段問題,然後逐個加以解決。一些靜態

模型,只要人為地引進「時間」因素,分成時段,就可以轉化成多階段的動態模型,用動態規劃方法去處理。與此同時,他提出了解決這類問題的「最優化原理」(principle of optimality):

「乙個過程的最優決策具有這樣的性質:即無論其初始狀態和初始決策如何,其今後諸策略對以第乙個決策所形成的狀態作為初始狀態的過程而言,必須構成最優策略」。簡言之,乙個最優策略的子策略,對於它的初態和終態而言也必是最優的。

這個「最優化原理」如果用數學化一點的語言來描述的話,就是:假設為了解決某一優化問題,需要依次作出n個決策d1,d2,…,dn,如若這個決策序列是最優的,對於任何乙個整數k,1 < k < n,不論前面k個決策是怎樣的,以後的最優決策只取決於由前面決策所確定的當前狀態,即以後的決策dk+1,dk+2,…,dn也是最優的。

最優化原理是動態規劃的基礎。任何乙個問題,如果失去了這個最優化原理的支援,就不可能用動態規劃方法計算。能採用動態規劃求解的問題都需要滿足一定的條件:

(1)問題中的狀態必須滿足最優化原理;

(2)問題中的狀態必須滿足無後效性。

所謂的無後效性是指:「下一時刻的狀態只與當前狀態有關,而和當前狀態之前的狀態無關,當前的狀態是對以往決策的總結」。

問題求解模式

動態規劃所處理的問題是乙個多階段決策問題,一般由初始狀態開始,通過對中間階段決策的選擇,達到結束狀態。這些決策形成了乙個決策序列,同時確定了完成整個過程的一條活動路線(通常是求最優的活動路線)。如圖所示。動態規劃的設計都有著一定的模式,一般要經歷以下幾個步驟:

初始狀態→│決策1│→│決策2│→…→│決策n│→結束狀態

(1)劃分階段:按照問題的時間或空間特徵,把問題分為若干個階段。在劃分階段時,注意劃分後的階段一定要是有序的或者是可排序的,否則問題就無法求解。

(2)確定狀態和狀態變數:將問題發展到各個階段時所處於的各種客觀情況用不同的狀態表示出來。當然,狀態的選擇要滿足無後效性。

(3)確定決策並寫出狀態轉移方程:因為決策和狀態轉移有著天然的聯絡,狀態轉移就是根據上一階段的狀態和決策來匯出本階段的狀態。所以如果確定了決策,狀態轉移方程也就可寫出。但事實上常常是反過來做,根據相鄰兩段各狀態之間的關係來確定決策。

(4)尋找邊界條件:給出的狀態轉移方程是乙個遞推式,需要乙個遞推的終止條件或邊界條件。

動態規劃演算法的有效性依賴於待求解問題本身具有的兩個重要性質:最優子結構性質和子問題重疊性質。

(1)最優子結構性質。如果問題的最優解所包含的子問題的解也是最優的,我們就稱該問題具有最優子結構性質(即滿足最優化原理)。最優子結構性質為動態規劃演算法解決問題提供了重要線索。

(2)子問題重疊性質。子問題重疊性質是指在用遞迴演算法自頂向下對問題進行求解時,每次產生的子問題並不總是新問題,有些子問題會被重複計算多次。動態規劃演算法正是利用了這種子問題的重疊性質,對每乙個子問題只計算一次,然後將其計算結果儲存在乙個**中,當再次需要計算已經計算過的子問題時,只是在**中簡單地檢視一下結果,從而獲得較高的解題效率。

六、回溯法

對候選解進行系統檢查的方法有多種,其中回溯和分支定界法是比較常用的兩種方法。按照這兩種方法對候選解進行系統檢查通常會使問題的求解時間大大減少。

應用:這兩種演算法可以被用來設計貨箱裝船、揹包、最大完備子圖、旅行商和電路板排列問題的求解演算法。

回溯是一種系統地搜尋問題解答的方法,為了實現回溯,首先需要為問題定義乙個解空間,這個空間必須至少包含問題的乙個解,下一步是組織解空間以便它能被容易地

搜尋,典型的組織方法是圖或樹。

七、分支定界法

分支定界法是另一種搜尋解空間的方法,與回溯法不同的是,回溯演算法使用深度優先方法搜尋樹結構,而分支定界一般用寬度優先或最小耗費方法來搜尋這些樹。

1)先進先出(fifo) 即從活節點表中取出節點的順序與加入節點的順序相同,因此活節點表的性質與佇列相同。

2)最小耗費或最大收益法 在這種模式中,每個節點都有乙個對應的耗費或收益。如果查詢乙個具有最小耗費的解,則活節點表可用最小堆來建立,下乙個e-節點就是

具有最小耗費的活節點,反之,使用最大堆來建立。

八、總結

動態規劃演算法是以上幾種演算法中難度最大的一種,需要好好參詳。

其他演算法如其名,比較容易理解。

演算法 一些線性排序演算法

一 計數排序 使用這個演算法有乙個前提,待排序的陣列a,其所有的元素分布在區間 0,k 該演算法的時間複雜度為o n k 當k o n 時,執行時間為o n 所以當k比較小的時候適合採用這個演算法 下面給出這個演算法實現的 include using namespace std void count...

一些基礎演算法

1.字串的順序反向輸出和數值的引用傳遞 public class myclass public integer aaa integer i public static string reverse string s 2.數值排序 public class test int arry test tes...

一些基本演算法

1.最大奇數約數int fun int x return x int main 2 找出第二大的數,要求用for遍歷一遍const int minnum 0x80000000 int find 2 k int arr,int n else if arr i sec return sec void m...