免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
編程5大算法總結(jié)

一、基本概念

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

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

分解(Divide):將原問題分解成一系列子問題;
解決(conquer):遞歸地解各個子問題。若子問題足夠小,則直接求解;
合并(Combine):將子問題的結(jié)果合并成原問題的解。
合并排序(merge sort)是一個典型分治法的例子。其對應(yīng)的直觀的操作如下:


分解:將n個元素分成各含n/2個元素的子序列;
解決:用合并排序法對兩個子序列遞歸地排序;
合并:合并兩個已排序的子序列以得到排序結(jié)果。

二、基本思想及策略

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

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

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

三、分治法適用的情況

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

1) 該問題的規(guī)??s小到一定的程度就可以容易地解決

2) 該問題可以分解為若干個規(guī)模較小的相同問題,即該問題具有最優(yōu)子結(jié)構(gòu)性質(zhì)。

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

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

第一條特征是絕大多數(shù)問題都可以滿足的,因為問題的計算復(fù)雜性一般是隨著問題規(guī)模的增加而增加;

第二條特征是應(yīng)用分治法的前提它也是大多數(shù)問題可以滿足的,此特征反映了遞歸思想的應(yīng)用;、

第三條特征是關(guān)鍵,能否利用分治法完全取決于問題是否具有第三條特征,如果具備了第一條和第二條特征,而不具備第三條特征,則可以考慮用貪心法或動態(tài)規(guī)劃法。

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

四、分治法的基本步驟

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

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

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

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

它的一般的算法設(shè)計模式如下:

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的規(guī)模;n0為一閾值,表示當問題P的規(guī)模不超過n0時,問題已容易直接解出,不必再繼續(xù)分解。ADHOC(P)是該分治法中的基本子算法,用于直接解小規(guī)模的問題P。因此,當P的規(guī)模不超過n0時直接用算法ADHOC(P)求解。算法MERGE(y1,y2,...,yk)是該分治法中的合并子算法,用于將P的子問題P1 ,P2 ,...,Pk的相應(yīng)的解y1,y2,...,yk合并為P的解。

實例:

 [找出偽幣] 給你一個裝有1 6個硬幣的袋子。1 6個硬幣中有一個是偽造的,并且那個偽造的硬幣比真的硬幣要輕一些。你的任務(wù)是找出這個偽造的硬幣。

為了幫助你完成這一任務(wù),將提供一臺可用來比較兩組硬幣重量的儀器,利用這臺儀器,可以知道兩組硬幣的重量是否相同。比較硬幣1與硬幣2的重量。假如硬幣1比硬幣2輕,則硬幣1是偽造的;假如硬幣2比硬幣1輕,則硬幣2是偽造的。這樣就完成了任務(wù)。假如兩硬幣重量相等,則比較硬幣3和硬幣4。同樣,假如有一個硬幣輕一些,則尋找偽幣的任務(wù)完成。假如兩硬幣重量相等,則繼續(xù)比較硬幣5和硬幣6。按照這種方式,可以最多通過8次比較來判斷偽幣的存在并找出這一偽幣。 

另外一種方法就是利用分而治之方法。假如把1 6硬幣的例子看成一個大的問題。第一步,把這一問題分成兩個小問題。隨機選擇8個硬幣作為第一組稱為A組,剩下的8個硬幣作為第二組稱為B組。這樣,就把1 6個硬幣的問題分成兩個8硬幣的問題來解決。第二步,判斷A和B組中是否有偽幣。可以利用儀器來比較A組硬幣和B組硬幣的重量。假如兩組硬幣重量相等,則可以判斷偽幣不存在。假如兩組硬幣重量不相等,則存在偽幣,并且可以判斷它位于較輕的那一組硬幣中。最后,在第三步中,用第二步的結(jié)果得出原先1 6個硬幣問題的答案。若僅僅判斷硬幣是否存在,則第三步非常簡單。無論A組還是B組中有偽幣,都可以推斷這1 6個硬幣中存在偽幣。因此,僅僅通過一次重量的比較,就可以判斷偽幣是否存在。 

現(xiàn)在假設(shè)需要識別出這一偽幣。把兩個或三個硬幣的情況作為不可再分的小問題。注意如果只有一個硬幣,那么不能判斷出它是否就是偽幣。在一個小問題中,通過將一個硬幣分別與其他兩個硬幣比較,最多比較兩次就可以找到偽幣。這樣,1 6硬幣的問題就被分為兩個8硬幣(A組和B組)的問題。通過比較這兩組硬幣的重量,可以判斷偽幣是否存在。如果沒有偽幣,則算法終止。否則,繼續(xù)劃分這兩組硬幣來尋找偽幣。假設(shè)B是輕的那一組,因此再把它分成兩組,每組有4個硬幣。稱其中一組為B1,另一組為B2。比較這兩組,肯定有一組輕一些。如果B1輕,則偽幣在B1中,再將B1又分成兩組,每組有兩個硬幣,稱其中一組為B1a,另一組為B1b。比較這兩組,可以得到一個較輕的組。由于這個組只有兩個硬幣,因此不必再細分。比較組中兩個硬幣的重量,可以立即知道哪一個硬幣輕一些。較輕的硬幣就是所要找的偽幣。

五、分治法的復(fù)雜性分析

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

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

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

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

 

六、可使用分治法求解的一些經(jīng)典問題

(1)二分搜索

(2)大整數(shù)乘法

(3)Strassen矩陣乘法

(4)棋盤覆蓋

(5)合并排序

(6)快速排序

(7)線性時間選擇

(8)最接近點對問題

(9)循環(huán)賽日程表

(10)漢諾塔

 

七、依據(jù)分治法設(shè)計程序時的思維過程

實際上就是類似于數(shù)學(xué)歸納法,找到解決本問題的求解方程公式,然后根據(jù)方程公式設(shè)計遞歸程序。

1、一定是先找到最小問題規(guī)模時的求解方法

2、然后考慮隨著問題規(guī)模增大時的求解方法

3、找到求解的遞歸函數(shù)式后(各種規(guī)?;蛞蜃樱O(shè)計遞歸程序即可。

應(yīng)用之歸并排序:

  1. package sort;
  2. public class mergerSort2 {
  3. static void merge(int arr[], int L, int M, int R) {//合并算法
  4. int LEFT_SIZE = M - L;//left array size
  5. int RIGHT_SIZE = R - M + 1;
  6. // int left[LEFT_SIZE];
  7. // int right[RIGHT_SIZE];
  8. int left[] = new int[LEFT_SIZE];
  9. int right[] = new int[RIGHT_SIZE];
  10. int i, j, k;
  11. // 1. Fill in the left sub array
  12. for (i=L; i<M; i++) {
  13. left[i-L] = arr[i];//sub array begin from 0
  14. }
  15. // 2. Fill in the right sub array
  16. for (i=M; i<=R; i++) {
  17. right[i-M] = arr[i];//sub array begin from 0
  18. }
  19. // 3. Merge into the original array
  20. i = 0; j = 0; k = L;//k point to the left array
  21. while (i < LEFT_SIZE && j < RIGHT_SIZE) {//沒有到達子矩陣的頂端,這時比較左右矩陣如果左面小arr[k]位置放入左面值,即達到取曉得放入新的矩陣,i,j,k指針各自加上1
  22. if (left[i] < right[j]) {
  23. arr[k] = left[i];
  24. i++;
  25. k++;
  26. }
  27. else {
  28. arr[k] = right[j];
  29. j++;
  30. k++;
  31. }
  32. }
  33. while (i < LEFT_SIZE) {//一邊到達了頂端,那么如果另一方還沒到直接放入新矩陣
  34. arr[k] = left[i];
  35. i++;
  36. k++;
  37. }
  38. while (j < RIGHT_SIZE) {
  39. arr[k] = right[j];
  40. j++;
  41. k++;
  42. }
  43. }
  44. static void mergeSort(int arr[], int L, int R) {//分治+歸并?。。?!
  45. if (L == R) {//分支的結(jié)束為只有一個
  46. return;
  47. }
  48. else {
  49. int M = (L + R) / 2;
  50. mergeSort(arr, L, M);
  51. mergeSort(arr, M+1, R);
  52. merge(arr, L, M+1, R);
  53. }
  54. }
  55. public static void main(String[] args)
  56. {
  57. int arr[] = {6, 8, 10, 9, 4, 5, 2, 7,3};
  58. int L = 0;
  59. int R = arr.length;
  60. mergeSort(arr, L, R);
  61. int i;
  62. for (i=0; i<=R; i++) {
  63. System.out.println(arr[i]);
  64. }
  65. }
  66. }


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
傳統(tǒng)基本算法(迭代、遞歸、分治)
一文看懂編程中的基本數(shù)據(jù)結(jié)構(gòu)與算法思想
萬字長文,佩奇算法八大思想!
優(yōu)化 | 淺談什么是分治算法
一文講透【遞歸】與【動態(tài)規(guī)劃】!
Python|利用遞歸輕松解決數(shù)的乘方問題
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服