查ICP網(wǎng):全新的綜合網(wǎng)站備案信息查詢網(wǎng)
Copyright ? 2008-2028 www.mshuangcha.com [ 查icp] All Rights Reserved.
計算機常用算法有哪些?馬上要開始投簡歷找實習了,自己還是毛都不會,慌得一筆,從今天開始每天刷2道以上的leetcode然后總結(jié),并且總結(jié)各種面試題的知識點,以后常復習,加油。
在刷leetcode時經(jīng)常看到有人說DP,然后去百度了DP是個啥,才知道DP是五大經(jīng)典算法之一,今天開始總結(jié)一下五大經(jīng)典算法。
五大經(jīng)典算法:
1、分治法:把一個復雜的問題分成兩個或更多的相同或相似的子問題,再把子問題分成更小的子問題……直到最后子問題可以簡單的直接求解,原問題的解即子問題的解的合并。
2、動態(tài)規(guī)劃法:每次決策依賴于當前狀態(tài),又隨即引起狀態(tài)的轉(zhuǎn)移。一個決策序列就是在變化的狀態(tài)中產(chǎn)生出來的,所以,這種多階段最優(yōu)化決策解決問題的過程就稱為動態(tài)規(guī)劃。
3、貪心算法:在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優(yōu)上加以考慮,他所做出的僅是在某種意義上的局部最優(yōu)解。 常見的貪心算法有:Prim算法、Kruskal算法(都是求最小生成樹的)。
基本思路:將問題分解為若干個小問題,逐漸求得各個子問題的局部最優(yōu)解,最后合并為原來問題的解。
4、回溯法:回溯算法實際上一個類似枚舉的搜索嘗試過程,主要是在搜索嘗試過程中尋找問題的解,當發(fā)現(xiàn)已不滿足求解條件時,就“回溯”返回,嘗試別的路徑。深度優(yōu)先;
回溯法是一種選優(yōu)搜索法,按選優(yōu)條件向前搜索,以達到目標。但當探索到某一步時,發(fā)現(xiàn)原先選擇并不優(yōu)或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法,而滿足回溯條件的某個狀態(tài)的點稱為“回溯點”。
5、分支限界法:類似于回溯法,也是一種在問題的解空間樹T上搜索問題解的算法。但在一般情況下,分支限界法與回溯法的求解目標不同。回溯法的求解目標是找出T中滿足約束條件的所有解,而分支限界法的求解目標則是找出滿足約束條件的一個解,或是在滿足約束條件的解中找出使某一目標函數(shù)值達到極大或極小的解,即在某種意義下的最優(yōu)解。
一、分治法
分治法所能解決的問題一般具有以下幾個特征:
1) 該問題的規(guī)模縮小到一定的程度就可以容易地解決 2) 該問題可以分解為若干個規(guī)模較小的相同問題,即該問題具有最優(yōu)子結(jié)構(gòu)性質(zhì)。 3) 利用該問題分解出的子問題的解可以合并為該問題的解;
4) 該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。
若不具備第三條特征,可考慮采用動態(tài)規(guī)劃法(DP)或者貪心法。
若不具備第四條特征,可考慮采用動態(tài)規(guī)劃法。
分治法基本步驟:
step1 分解:將原問題分解為若干個規(guī)模較小,相互獨立,與原問題形式相同的子問題; step2 解決:若子問題規(guī)模較小而容易被解決則直接解,否則遞歸地解各個子問題
step3 合并:將各個子問題的解合并為原問題的解。
二、動態(tài)規(guī)劃法
與分治法最大的差別是:適合于用動態(tài)規(guī)劃法求解的問題,經(jīng)分解后得到的子問題往往不是互相獨立的(即下一個子階段的求解是建立在上一個子階段的解的基礎上,進行進一步的求解)。
適用條件:
能采用動態(tài)規(guī)劃求解的問題的一般要具有3個性質(zhì):
(1) 最優(yōu)化原理:如果問題的最優(yōu)解所包含的子問題的解也是最優(yōu)的,就稱該問題具有最優(yōu)子結(jié)構(gòu),即滿足最優(yōu)化原理。 (2) 無后效性:即某階段狀態(tài)一旦確定,就不受這個狀態(tài)以后決策的影響。也就是說,某狀態(tài)以后的過程不會影響以前的狀態(tài),只與當前狀態(tài)有關。
(3)有重疊子問題:即子問題之間是不獨立的,一個子問題在下一階段決策中可能被多次使用到。(該性質(zhì)并不是動態(tài)規(guī)劃適用的必要條件,但是如果沒有這條性質(zhì),動態(tài)規(guī)劃算法同其他算法相比就不具備優(yōu)勢)
案例:
有n級臺階,一個人每次上一級或者兩級,問有多少種走完n級臺階的方法。分析:動態(tài)規(guī)劃的實現(xiàn)的關鍵在于能不能準確合理的用動態(tài)規(guī)劃表來抽象出 實際問題。在這個問題上,我們讓f(n)表示走上n級臺階的方法數(shù)。
那么當n為1時,f(n) = 1,n為2時,f(n) =2,就是說當臺階只有一級的時候,方法數(shù)是一種,臺階有兩級的時候,方法數(shù)為2。那么當我們要走上n級臺階,必然是從n-1級臺階邁一步或者是從n-2級臺階邁兩步,所以到達n級臺階的方法數(shù)必然是到達n-1級臺階的方法數(shù)加上到達n-2級臺階的方法數(shù)之和。即f(n) = f(n-1)+f(n-2),我們用dp[n]來表示動態(tài)規(guī)劃表,dp[i],i>0,i0){ int length = value.length; for(int i=0;i=value[i]){ money=money-value[i]; count++; //System.out.println(money); } } } return count;} }
四、回溯法
回溯法是一種系統(tǒng)地搜索問題解答的方法。在搜索的過程中嘗試找到問題的解,如果發(fā)現(xiàn)找不到了,就退一步,往上回溯(剪枝過程)。對于許多復雜問題和大規(guī)模問題都可以使用回溯法。 回溯法的基本思想是按照深度優(yōu)先搜索的策略,從根節(jié)點開始搜索,當?shù)侥硞€節(jié)點時要判斷是否是包含問題的解,如果包含就從該節(jié)點繼續(xù)搜索下去,如果不包含,就向父節(jié)點回溯。若用回溯法求問題的所有解時,要回溯到根,且根結(jié)點的所有可行的子樹都要已被搜索遍才結(jié)束。而若使用回溯法求任一個解時,只要搜索到問題的一個解就可以結(jié)束。
回溯法常用的剪枝函數(shù):(1)約束函數(shù):在節(jié)點處減去不滿足約束的子樹。(2)界限函數(shù):減去得不到最優(yōu)解的子樹。
一般步驟:
1、針對所給問題,確定問題的解空間2、利用適于搜索的方法組織解空間3、利用深度優(yōu)先搜索解空間
4、在搜索過程中用剪枝函數(shù)避免無效搜索。
五、分支限界法
類似于回溯法,也是一種在問題的解空間樹T上搜索問題解的算法。但在一般情況下,分支限界法與回溯法的求解目標不同。回溯法的求解目標是找出T中滿足約束條件的所有解,而分支限界法的求解目標則是找出滿足約束條件的一個解,或是在滿足約束條件的解中找出使某一目標函數(shù)值達到極大或極小的解,即在某種意義下的最優(yōu)解。
(1)分支搜索算法
所謂“分支”就是采用廣度優(yōu)先的策略,依次搜索E-結(jié)點的所有分支,也就是所有相鄰結(jié)點,拋棄不滿足約束條件的結(jié)點,其余結(jié)點加入活結(jié)點表。然后從表中選擇一個結(jié)點作為下一個E-結(jié)點,繼續(xù)搜索。
選擇下一個E-結(jié)點的方式不同,則會有幾種不同的分支搜索方式。
1)FIFO搜索
2)LIFO搜索
3)優(yōu)先隊列式搜索
(2)分支限界搜索算法
分支限界法的一般過程
由于求解目標不同,導致分支限界法與回溯法在解空間樹T上的搜索方式也不相同。回溯法以深度優(yōu)先的方式搜索解空間樹T,而分支限界法則以廣度優(yōu)先或以最小耗費優(yōu)先的方式搜索解空間樹T。
分支限界法的搜索策略是:在擴展結(jié)點處,先生成其所有的兒子結(jié)點(分支),然后再從當前的活結(jié)點表中選擇下一個擴展對點。為了有效地選擇下一擴展結(jié)點,以加速搜索的進程,在每一活結(jié)點處,計算一個函數(shù)值(限界),并根據(jù)這些已計算出的函數(shù)值,從當前活結(jié)點表中選擇一個最有利的結(jié)點作為擴展結(jié)點,使搜索朝著解空間樹上有最優(yōu)解的分支推進,以便盡快地找出一個最優(yōu)解。
分支限界法常以廣度優(yōu)先或以最小耗費(最大效益)優(yōu)先的方式搜索問題的解空間樹。問題的解空間樹是表示問題解空間的一棵有序樹,常見的有子集樹和排列樹。在搜索問題的解空間樹時,分支限界法與回溯法對當前擴展結(jié)點所使用的擴展方式不同。在分支限界法中,每一個活結(jié)點只有一次機會成為擴展結(jié)點。活結(jié)點一旦成為擴展結(jié)點,就一次性產(chǎn)生其所有兒子結(jié)點。在這些兒子結(jié)點中,那些導致不可行解或?qū)е路亲顑?yōu)解的兒子結(jié)點被舍棄,其余兒子結(jié)點被子加入活結(jié)點表中。此后,從活結(jié)點表中取下一結(jié)點成為當前擴展結(jié)點,并重復上述結(jié)點擴展過程。這個過程一直持續(xù)到找到所求的解或活結(jié)點表為空時為止。
回溯法和分支限界法的一些區(qū)別
有一些問題其實無論用回溯法還是分支限界法都可以得到很好的解決,但是另外一些則不然。也許我們需要具體一些的分析——到底何時使用分支限界而何時使用回溯呢?
回溯法和分支限界法的一些區(qū)別:
方法對解空間樹的搜索方式 存儲結(jié)點的常用數(shù)據(jù)結(jié)構(gòu) 結(jié)點存儲特性常用應用。
回溯法深度優(yōu)先搜索堆棧活結(jié)點的所有可行子結(jié)點被遍歷后才被從棧中彈出找出滿足約束條件的所有解。
分支限界法廣度優(yōu)先或最小消耗優(yōu)先搜索隊列、優(yōu)先隊列每個結(jié)點只有一次成為活結(jié)點的機會找出滿足約束條件的一個解或特定意義下的最優(yōu)解。