計算機五大經典演算法:1、分治法,把一個複雜的問題分成兩個或更多的相同或相似的子問題;2、動態規劃法;3、貪心演算法;4、回溯法,一種選優搜尋法,依選優條件向前搜索,以達到目標;5、分支限界法。
本教學操作環境:windows10系統、Dell G3電腦。
馬上要開始投履歷找實習了,自己還是毛都不會,慌得一筆,從今天開始每天刷2道以上的leetcode然後總結,並且總結各種面試題的知識點,以後常複習,加油。
在刷leetcode時常常看到有人說DP,然後去百度了DP是個啥,才知道DP是五大經典演算法之一,今天開始總結五大經典演算法。
五大經典演算法分成
1、分治法:把一個複雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最後子問題可以簡單的直接求解,原問題的解即子問題的解的合併。
2、動態規劃法:每次決策依賴目前狀態,又隨即引起狀態的轉移。一個決策序列就是在變化的狀態中產生出來的,所以,這種多階段最優化決策解決問題的過程就稱為動態規劃。
3、貪心演算法:在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優加以考慮,他所做的僅是在某種意義上的局部最優解。常見的貪心演算法有:Prim演算法、Kruskal演算法(都是求最小生成樹的)。
基本想法:將問題分解為若干個小問題,逐漸求出各個子問題的局部最優解,最後合併為原來問題的解。
4、回溯法:回溯演算法實際上一個類似枚舉的搜尋嘗試過程,主要是在搜尋嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就「回溯」返回,嘗試別的路徑。深度優先;
回溯法是一種選優搜尋法,依選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇並不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態的點稱為“回溯點”。
5、分支限界法:類似回溯法,也是一種在問題的解空間樹T上搜尋問題解的演算法。但在一般情況下,分支限界法與回溯法的解目標不同。回溯法的求解目標是找出T中滿足限制條件的所有解,而分支限界法的求解目標則是找出滿足限制條件的一個解,或是在滿足限制條件的解中找出使某一目標函數值達到極大或極小的解,即在某種意義下的最優解。
一、分治法
分治法所能解決的問題一般具有以下幾個特徵:
# 1) 此問題的規模縮小到一定的程度就可以容易地解決
2) 該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質。
3) 利用該問題分解出的子問題的解可以合併為此問題的解;
4) 此問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。
若不具備第三條特徵,可考慮採用動態規劃法(DP)或貪心法。
若不具備第四條特徵,可考慮採用動態規劃法。
分治法基本步驟:
step1 分解:將原問題分解為若干規模較小,相互獨立,與原問題形式相同的子問題;
step2 解決:若子問題規模較小且容易被解決則直接解,否則遞歸地解各子問題
step3 合併:將各子問題的解合併為原問題的解。
二、動態規劃法
# 與分治法最大的差異是:適合用動態規劃法解的問題,經分解後得到的子問題往往不是互相獨立的(即下一個子階段的求解是建立在上一個子階段的解的基礎上,進行進一步的求解)。
適用條件:
能採用動態規劃求解的問題的一般要具有3個性質:
(1) 最佳化原理:如果問題的最優解所包含的子問題的解也是最優的,就稱該問題具有最優子結構,即滿足最佳化原理。
(2) 無後效性:即某階段狀態一旦確定,就不受這個狀態以後決策的影響。也就是說,某狀態以後的過程不會影響以前的狀態,只與目前狀態有關。
(3)有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被多次使用。 (該性質並不是動態規劃適用的必要條件,但是如果沒有這條性質,動態規劃演算法與其他演算法相比就不具備優勢)
案例:
有n級台階,一個人每次上一級或兩級,問有多少種走完n級台階的方法。
分析:動態規劃的實現的關鍵在於能不能準確合理的用動態規劃表來抽象化 實際問題。在這個問題上,我們讓f(n)表示走上n級階梯的方法數。
那麼當n為1時,f(n) = 1,n為2時,f(n) =2,就是說當台階只有一級的時候,方法數是一種,階梯有兩級的時候,方法數為2。那麼當我們要走上n級台階,必然是從n-1級台階邁一步或是從n-2級台階邁兩步,所以到達n級台階的方法數必然是到達n-1級台階的方法數加上到達n-2級台階的方法數和。即f(n) = f(n-1) f(n-2),我們用dp[n]來表示動態規劃表,dp[i],i>0,i<=n,表示到達i級台階的方法數。
int fun(int n){ if (n==1||n==2) return n; /*判断n-1的状态有没有被计算过*/ if (!dp[n-1]) dp[n-1] = fun(n-1); if(!dp[n-2]) dp[n-2]=fun(n-2); return dp[n-1]+dp[n-2]; }
三、貪心演算法
#貪心演算法是指在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優加以考慮,只做出在某種意義上的局部最優解。貪心演算法不是對所有問題都能得到整體最優解,關鍵是貪心策略的選擇,選擇的貪心策略必須具備無後效性,即某個狀態以前的過程不會影響以後的狀態,只與當前狀態有關。
解題的一般步驟是:
1.建立數學模型來描述問題;
2.把求解的問題分成若干個子問題;
3.對每一子問題求解,得到子問題的局部最優解;
4.把子問題的局部最優解合成原來問題的一個解。
範例:錢幣找零問題
這個問題在我們的日常生活中就更普遍了。假設1元、2元、5元、10元、20元、50元、100元的紙幣分別有c0, c1, c2, c3, c4, c5, c6張。現在要用這些錢來支付K元,至少要用多少張紙幣?用貪心演算法的思想,很顯然,每一步盡可能用面值大的紙幣即可。在日常生活中我們自然而然也是這麼做的。在程式中已經事先將Value依照從小到大的順序排好。
public class charge { public static void main(String[] args) { // TODO 自动生成的方法存根 int res = charge(84); System.out.println(res); } private static int charge(int money) { int count = 0; int value[] = {50,20,10,5,2,1}; while(money>0){ int length = value.length; for(int i=0;i=value[i]){ money=money-value[i]; count++; //System.out.println(money); } } } return count; } } 四、回溯法
# 回溯法是一種系統性搜尋問題解答的方法。在搜尋的過程中嘗試找出問題的解,如果發現找不到了,就退一步,往上回溯(剪枝過程)。對於許多複雜問題和大規模問題都可以使用回溯法。
回溯法的基本思想是按照深度優先搜索的策略,從根節點開始搜索,當到某個節點時要判斷是否是包含問題的解,如果包含就從該節點繼續搜索下去,如果不包含,就向父節點回溯。若用回溯法求問題的所有解時,要回溯到根,且根結點的所有可行的子樹都要已被搜尋遍才結束。而若使用回溯法求任一個解時,只要搜尋到問題的一個解就可以結束。回溯法常用的剪枝函數:(1)約束函數:在節點處減去不符合約束的子樹。 (2)界限函數:減去得不到最佳解的子樹。
一般步驟:
1、針對所給問題,確定問題的解空間
2、利用適於搜尋的方法組織解空間
3、利用深度優先搜索解空間4、在搜尋過程中用剪枝函數避免無效搜尋。
五、分支限界法
類似於回溯法,也是一種在問題的解空間樹T上搜尋問題解的演算法。但在一般情況下,分支限界法與回溯法的解目標不同。回溯法的求解目標是找出T中滿足限制條件的所有解,而分支限界法的求解目標則是找出滿足限制條件的一個解,或是在滿足限制條件的解中找出使某一目標函數值達到極大或極小的解,即在某種意義下的最優解。
(1)分支搜尋演算法
所謂「分支」就是採用廣度優先的策略,依序搜尋E-結點的所有分支,也就是所有相鄰結點,拋棄不滿足約束條件的結點,其餘結點加入活結點表。然後從表格中選擇一個結點作為下一個E-結點,繼續搜尋。
選擇下一個E-結點的方式不同,則會有幾種不同的分支搜尋方式。
1)FIFO搜尋
2)LIFO搜尋
3)優先佇列式搜尋
(2)分支限界搜尋演算法
分支限界法的一般過程
#由於解目標不同,導致分支限界法與回溯法在解空間樹T上的搜尋方式也不相同。回溯法以深度優先的方式搜尋解空間樹T,而分支限界法則以廣度優先或以最小耗費優先的方式搜尋解空間樹T。
分支限界法的搜尋策略是:在擴展結點處,先生成其所有的兒子結點(分支),然後再從目前的活結點表中選擇下一個擴展對點。為了有效地選擇下一擴展結點,以加速搜尋的進程,在每一活結點處,計算一個函數值(限界),並根據這些已計算出的函數值,從目前活結點表中選擇一個最有利的結點作為擴展結點,使搜尋朝著解空間樹上有最優解的分支推進,以便盡快找出一個最優解。
分支限界法常以廣度優先或以最小耗費(最大效益)優先的方式搜尋問題的解空間樹。問題的解空間樹是表示問題解空間的一棵有序樹,常見的有子集樹和排列樹。在搜尋問題的解空間樹時,分支限界法與回溯法對目前擴展結點所使用的擴展方式不同。在分支限界法中,每一個活結點只有一次機會成為擴展結點。活結點一旦成為擴展結點,就一次產生其所有兒子結點。在這些兒子結點中,那些導致不可行解或導致非最優解的兒子結點被捨棄,其餘兒子結點被子加入活結點表中。此後,從活結點表中取下一結點成為目前擴展結點,並重複上述結點擴展過程。這個過程一直持續到找到所求的解或活結點表為空時為止。
回溯法與分支限界法的一些差異
有一些問題其實無論用回溯法或分支限界法都可以得到很好的解決,但是另外一些則不然。也許我們需要具體一些的分析──到底何時使用分支限界而何時使用回溯呢?
回溯法與分支限界法的一些差異:
方法對解空間樹的搜尋方式 儲存結點的常用資料結構 結點儲存特性常用應用
回溯。法深度優先搜尋堆疊活結點的所有可行子結點被遍歷後才被從堆疊中彈出找出滿足約束條件的所有解
分支限界法廣度優先或最小消耗優先搜尋佇列、優先佇列每個結點只有一次成為活結點的機會找出滿足約束條件的一個解或特定意義下的最優解
#更多相關知識,請訪問常見問題欄目!
以上是計算機五大經典演算法是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!