算法設(shè)計(jì)與分析 課件全套 楊紅云 第1-8章 緒論、蠻力法 - 線性規(guī)劃_第1頁(yè)
算法設(shè)計(jì)與分析 課件全套 楊紅云 第1-8章 緒論、蠻力法 - 線性規(guī)劃_第2頁(yè)
算法設(shè)計(jì)與分析 課件全套 楊紅云 第1-8章 緒論、蠻力法 - 線性規(guī)劃_第3頁(yè)
算法設(shè)計(jì)與分析 課件全套 楊紅云 第1-8章 緒論、蠻力法 - 線性規(guī)劃_第4頁(yè)
算法設(shè)計(jì)與分析 課件全套 楊紅云 第1-8章 緒論、蠻力法 - 線性規(guī)劃_第5頁(yè)
已閱讀5頁(yè),還剩360頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

計(jì)算機(jī)算法設(shè)計(jì)與分析第1章概述例1.1求兩個(gè)正整數(shù)的最大公約數(shù)方法一:利用質(zhì)因數(shù)分解法求解最大公約數(shù),其具體步驟描述如下:(1)輸入兩個(gè)正整數(shù)a和b。(2)將a和b分別進(jìn)行質(zhì)因數(shù)分解,得到它們的所有質(zhì)因數(shù)的乘積形式。(3)將a和b中相同的所有質(zhì)因數(shù)乘積計(jì)算出來(lái),得到的結(jié)果即為a和b的最大公約數(shù)。若a或b無(wú)質(zhì)因數(shù)(除1和該數(shù)本身外),則最大公約數(shù)為1。例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)以具體計(jì)算為例,假設(shè)需要求解的兩個(gè)整數(shù)為42和28,42=2×3×7,28=2×2×7共同的質(zhì)因數(shù)2和7,因此,42和28的最大公約數(shù)為2×7=14利用方法一可以快速求出兩個(gè)整數(shù)的最大公約數(shù),但方法一的描述過(guò)程不能稱為一個(gè)正真意義上的算法,因?yàn)榈?2)步?jīng)]有明確如何將正整數(shù)a和b進(jìn)行質(zhì)因數(shù)分解,且質(zhì)因數(shù)分解是一個(gè)NP類問(wèn)題,目前尚未找到有效的解決方法。第(3)步也沒(méi)有明確定義在兩個(gè)質(zhì)因數(shù)序列中如何找到相同的質(zhì)因數(shù)元素。因此方法一描述不滿足算法的確定性和可行性。例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)方法二:利用蠻力窮舉法求解最大公約數(shù),具體步驟描述如下:(1)輸入a和b。(2)將a和b中的較小者賦值給r。(3)若a、b除以r的余數(shù)同時(shí)等于0,轉(zhuǎn)(5),否則往下執(zhí)行(4)。(4)執(zhí)行r=r-1,轉(zhuǎn)(3)。(5)輸出r,執(zhí)行結(jié)束。主要思想:是從兩個(gè)整數(shù)中較小者開(kāi)始,去逐步尋找能被兩整數(shù)同時(shí)整除的數(shù),一旦發(fā)現(xiàn)則終止尋找,并將該數(shù)作為兩整數(shù)的最大公約數(shù)。例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)r=2842%28=14,28%28=0,r=28-1=2742%27=15,28%27=1,r=27-1=2642%26=16,28%26=2,r=26-1=2542%25=17,28%25=3,r=25-1=2442%24=18,28%24=4,r=24-1=2342%23=19,28%23=5,r=23-1=2242%22=20,28%22=6,r=22-1=2142%21=0,28%21=7,r=21-1=2042%20=2,28%20=8,r=20-1=1942%19=4,28%19=9,r=19-1=1842%18=6,28%18=10,r=18-1=1742%17=8,28%17=11,r=17-1=1642%16=10,28%16=12,r=16-1=1542%15=12,28%15=13,r=15-1=1442%14=0,28%14=0輸出r,結(jié)果為14。以具體計(jì)算為例,設(shè)a=42和b=28,則計(jì)算過(guò)程為:例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)在a=42,b=28的情況下,窮舉法運(yùn)行了15步才計(jì)算出結(jié)果。方法二窮舉法非常簡(jiǎn)單,計(jì)算過(guò)程易于理解,但窮舉法的效率非常低。例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)方法三:利用輾轉(zhuǎn)相除法(也稱歐幾里得算法)求解最大公約數(shù),具體步驟描述如下:(1)輸入兩個(gè)整數(shù)a和b。(2)若a<b則將a,b的值互換,以保持a是兩個(gè)整數(shù)中較大者,b為較小者。(3)將a除以b的余數(shù)賦值給r,若余數(shù)r等于0,則執(zhí)行(5),否則往下執(zhí)行(4)(4)將除數(shù)b賦值給a,將余數(shù)r賦值給b,轉(zhuǎn)(3)重復(fù)執(zhí)行(5)b為所求最大公約數(shù),輸出b,執(zhí)行結(jié)束。例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)以具體計(jì)算為例,設(shè)a=42和b=28,則計(jì)算過(guò)程為:r=42%28=14,a=28,b=14r=28%14=0輸出b,結(jié)果為14。在a=42,b=28的情況下,輾轉(zhuǎn)相除法只運(yùn)行了2步就計(jì)算出結(jié)果。例1.1求任意兩個(gè)正整數(shù)的最大公約數(shù)算法:輾轉(zhuǎn)相除法;輸入:兩個(gè)正整數(shù)a,b;

輸出:最大公約數(shù)Max_common_divisor(a,b)beginifa<bthena與b互換endramodbwhiler≠0doab,br,ramodbendprintbend計(jì)算機(jī)算法設(shè)計(jì)與分析第一章緒論一個(gè)快遞小哥從快遞中心點(diǎn)出發(fā),到周邊四個(gè)小區(qū)送快遞,要求經(jīng)過(guò)每個(gè)小區(qū)且只能每個(gè)小區(qū)僅經(jīng)過(guò)一次,最后回到快遞中心點(diǎn)。問(wèn)快遞小哥應(yīng)如何安排派送路線較好?例1.3快遞員路線安排問(wèn)題起

終ABCDEA03456B30265C42043D56405E65350(1)問(wèn)題分析與問(wèn)題抽象,這是一個(gè)典型的TSP問(wèn)題將小區(qū)抽象為下圖的頂點(diǎn),兩個(gè)小區(qū)之間有路直達(dá),則對(duì)應(yīng)的兩個(gè)頂點(diǎn)之間有邊關(guān)聯(lián),邊的權(quán)值為兩個(gè)小區(qū)之間的距離。則將快遞員路線安排問(wèn)題抽象為從頂點(diǎn)A(設(shè)A為快遞中心)出發(fā)經(jīng)過(guò)圖中其余頂點(diǎn)后回到頂點(diǎn)A的最短簡(jiǎn)單回路問(wèn)題。例1.3快遞員路線安排問(wèn)題3365456542EBDCA(2)數(shù)學(xué)建模:例1.3快遞員路線安排問(wèn)題3365456542EBDCA(3)方法一蠻力法:列出每一條可供選擇的路線,計(jì)算出每條路線的距離長(zhǎng)度,最后從中選擇出一條最短路線。最短路程為:A-->B-->C-->E-->D-->A或者A-->D-->E-->C-->B-->A,最短路徑長(zhǎng)度為:18。例1.3快遞員路線安排問(wèn)題3365456542EBDCA(3)蠻力法算法效率分析:使用蠻力法列舉除出發(fā)小區(qū)外所有小區(qū)的排列,然后選取路徑最短的路線。n-1個(gè)小區(qū)的排列數(shù)為(n-1)!,當(dāng)n=20時(shí),遍歷路線總數(shù)約為1.216×1017,計(jì)算機(jī)以每秒1000萬(wàn)條路線的檢索速度計(jì)算,則約需要386年才能完成。故蠻力法的時(shí)間復(fù)雜度太高,當(dāng)頂點(diǎn)數(shù)過(guò)多時(shí)并不適用。例1.3快遞員路線安排問(wèn)題(3)方法二貪心法:每次在選擇下一個(gè)小區(qū)時(shí),只考慮當(dāng)前情況。在沒(méi)有經(jīng)過(guò)的小區(qū)中,選擇距離當(dāng)前小區(qū)最近的一個(gè),直到經(jīng)過(guò)所有小區(qū),最后回到快遞中心。A例1.3快遞員路線安排問(wèn)題3365456542EBDCA貪心法的優(yōu)點(diǎn)是效率很高,只要n-1步判斷就能得到結(jié)果。但缺點(diǎn)是不一定能找到問(wèn)題的最優(yōu)解。算法:貪心法—偽代碼描述輸入:小區(qū)數(shù)量n,鄰接矩陣e[i,j],頂點(diǎn)v[i],出發(fā)小區(qū)編號(hào)go_city,index當(dāng)前小區(qū)編號(hào)。輸出:最短路線上的頂點(diǎn)信息,最短路徑長(zhǎng)度min_l。Greedy(index):beginfori

1tondo ifi不是出發(fā)頂點(diǎn)go_citythen forj

1tondo if沒(méi)有經(jīng)過(guò)小區(qū)jthen

篩選與當(dāng)前出發(fā)點(diǎn)最短的頂點(diǎn),并標(biāo)記為cur_j endifendfor min_l

min_l+e[index,cur_j] index

cur_j//從出發(fā)點(diǎn)cur_j,繼續(xù)下一步求解

并置cur_j頂點(diǎn)為經(jīng)過(guò)標(biāo)記

endifend for

min_lmin_l+e[index,go_city]//加上最后一個(gè)小區(qū)到go_city小區(qū)的距離end例1.3快遞員路線安排問(wèn)題計(jì)算機(jī)算法設(shè)計(jì)與分析第一章概述1.4.1算法的效率分析目的評(píng)估算法體現(xiàn)算法運(yùn)行時(shí)所需要消耗的計(jì)算機(jī)資源占用CPU的計(jì)算時(shí)間量稱為時(shí)間復(fù)雜度占用內(nèi)存的存儲(chǔ)空間量稱為空間復(fù)雜度算法復(fù)雜度分析一般采用事前分析方式而是不事后統(tǒng)計(jì)法算法的效率分析算法的時(shí)間復(fù)雜度T和空間復(fù)雜度S的函數(shù):T=T(N,I)S=S(N,I)N表示問(wèn)題規(guī)模,I表示算法輸入在實(shí)際應(yīng)用中,關(guān)注時(shí)間效率多于空間效率。算法時(shí)間復(fù)雜度分析評(píng)估算法時(shí)間復(fù)雜度,應(yīng)盡量做到客觀反映算法的本質(zhì)特征和屬性。所以,算法時(shí)間復(fù)雜度分析應(yīng)該要有一個(gè)不依賴于計(jì)算機(jī)硬件配置、問(wèn)題規(guī)模和輸入實(shí)例的抽象表示。算法時(shí)間復(fù)雜度分析假設(shè)在一臺(tái)抽象的計(jì)算機(jī)上提供了k種元運(yùn)算O1,O2,…,Ok,每個(gè)元運(yùn)算執(zhí)行的時(shí)間分別為t1,t2,...,tk。元運(yùn)算通常指的是算法中最基本的操作步驟,一個(gè)元運(yùn)算可以是基本的算術(shù)運(yùn)算(如加法、減法、乘法、除法)、比較操作、賦值操作、數(shù)組訪問(wèn)或迭代循環(huán)等。算法時(shí)間復(fù)雜度分析T(N,I)表示算法在這臺(tái)抽象計(jì)算機(jī)上運(yùn)行所需要的的時(shí)間,設(shè),在算法中

元運(yùn)算Oi被調(diào)用的次數(shù)為ei,ei=ei(N,I),因此,T(N,I)一般化的表示:算法時(shí)間復(fù)雜度分析為消除公式中ti表示的元運(yùn)算執(zhí)行的具體時(shí)間,不妨假設(shè)所有的元運(yùn)算都在一個(gè)單位時(shí)間內(nèi)完成或者將ti抽象表示為一條執(zhí)行語(yǔ)句或表達(dá)式所用時(shí)間,則計(jì)算T(N,I)的工作就變?yōu)榻y(tǒng)計(jì)計(jì)算語(yǔ)句的頻度,從而簡(jiǎn)化復(fù)雜度的求解。例1.4插入排序問(wèn)題時(shí)間復(fù)雜度計(jì)算

算法:插入排序(升序排序)

輸入:數(shù)組元素array,元素個(gè)數(shù)n

輸出:升序的數(shù)組元素array

InsertSort(array,n):begin1fori

1ton–1do2key

array[i]3j

i–14whilej>=0andarray[j]>keydo5array[j+1]

array[j]//往后移動(dòng)元素6 j

j–17 end8 array[j+1]

key9

endend當(dāng)輸入數(shù)據(jù)為1,2,3,4,5時(shí),語(yǔ)句2、3、8被執(zhí)行4次,語(yǔ)句5、6被執(zhí)行0次。當(dāng)輸入數(shù)據(jù)為5,4,3,2,1時(shí),語(yǔ)句2、3、8被執(zhí)行4次,語(yǔ)句5、6被執(zhí)行10次。算法時(shí)間復(fù)雜度分析對(duì)同一個(gè)算法,運(yùn)行不同的輸入實(shí)例時(shí),算法語(yǔ)句執(zhí)行的次數(shù)差異明顯。實(shí)際上,在統(tǒng)計(jì)時(shí)間復(fù)雜度時(shí),我們不可能對(duì)規(guī)模N的每一種合法輸入都去統(tǒng)計(jì)各個(gè)算法語(yǔ)句執(zhí)行的次數(shù),這時(shí)就需要對(duì)輸入實(shí)例做一個(gè)合理簡(jiǎn)化,即將輸入實(shí)例進(jìn)行特化。算法時(shí)間復(fù)雜度分析(1)最壞情況下的時(shí)間復(fù)雜度:IN是規(guī)模為N的合法輸入集合,I*是IN中使T(N,I)達(dá)到Tmax(N)的合法輸入。最壞情況下的時(shí)間復(fù)雜度就是將所有的合法輸入實(shí)例中最壞的那個(gè)輸入實(shí)例I*找出來(lái),統(tǒng)計(jì)在輸入實(shí)例I*時(shí)算法語(yǔ)句執(zhí)行的次數(shù)來(lái)評(píng)估算法時(shí)間復(fù)雜度。算法時(shí)間復(fù)雜度分析(2)最好情況下的時(shí)間復(fù)雜度:I'是IN中使T(N,I)達(dá)到Tmin(N)的合法輸入,將所有的合法輸入實(shí)例中最好的那個(gè)輸入實(shí)例I'找出來(lái),統(tǒng)計(jì)在輸入實(shí)例I'時(shí)算法語(yǔ)句執(zhí)行的次數(shù)來(lái)評(píng)估算法時(shí)間復(fù)雜度。算法時(shí)間復(fù)雜度分析(3)平均情況下的時(shí)間復(fù)雜度:P(I)是算法應(yīng)用中出現(xiàn)輸入實(shí)例I的概率,全部合法輸入實(shí)例的概率總和為1。平均時(shí)間復(fù)雜度是用每一個(gè)輸入實(shí)例出現(xiàn)的概率,計(jì)算其數(shù)學(xué)期望。在分析算法時(shí)間復(fù)雜度的時(shí)候,往往關(guān)注的是最壞情況下算法的時(shí)間復(fù)雜度。例1.4插入排序問(wèn)題時(shí)間復(fù)雜度計(jì)算

算法:插入排序(升序排序)

輸入:數(shù)組元素array,元素個(gè)數(shù)n

輸出:升序的數(shù)組元素array

InsertSort(array,n):begin1fori

1ton–1do2key

array[i]3j

i–14whilej>=0andarray[j]>keydo5array[j+1]

array[j]//往后移動(dòng)元素6 j

j–17 end8 array[j+1]

key9

endend語(yǔ)句2,3,8分別執(zhí)行N-1次語(yǔ)句5,6執(zhí)行的次數(shù)分為1,2,3,...,N-1次算法時(shí)間復(fù)雜度分析語(yǔ)句2,3,8分別執(zhí)行N-1次,語(yǔ)句5,6執(zhí)行的次數(shù)分為1,2,3,...,N-1次,所以:當(dāng)N比較大時(shí),N2/2為主要因素,后面項(xiàng)為次要因素忽略次要因素,簡(jiǎn)化時(shí)間復(fù)雜度函數(shù)的表示。計(jì)算機(jī)算法設(shè)計(jì)與分析第一章概述漸近時(shí)間復(fù)雜度分析設(shè)T(N)是算法A的時(shí)間復(fù)雜度函數(shù),N是問(wèn)題規(guī)模,N≥0,且N∈Z。當(dāng)N

∞時(shí),T(N)

∞。對(duì)于T(N),如果存在T'(N),使得當(dāng)N

∞時(shí)有那么,我們就說(shuō)T'(N)是算法A當(dāng)N

∞的漸近復(fù)雜度。漸近時(shí)間復(fù)雜度分析在漸近復(fù)雜度函數(shù)T'(N)中,階與T'(N)中的常數(shù)因子沒(méi)有關(guān)系,所以T'(N)可進(jìn)一步簡(jiǎn)化,省略常數(shù)因子。例1.4中的T'(N)可取值N2即可。需要注意的是,函數(shù)簡(jiǎn)化并不是一種精確計(jì)算復(fù)雜度的方法,而是一種近似評(píng)估的方式。例1.4中的T'(N)=N2/2+5N/2-3漸近時(shí)間復(fù)雜度分析定義1.1設(shè)f(N)和g(N)是正整數(shù)集上的函數(shù)。如果?c≥0和自然數(shù)N0,使得當(dāng)N≥N0時(shí)有0≤f(N)≤cg(N),則稱函數(shù)f(N)充分大時(shí)上有界,g(N)是f(N)的一個(gè)上界,記為f(N)=O(g(N)),即f(N)的階不高于g(N)的階,如圖所示。不是直接比較f(N)和g(N)的數(shù)值大小,O表示的只是一個(gè)充分大的上界,上界的階越低則算法時(shí)間復(fù)雜度的評(píng)估越精確,結(jié)果值越有價(jià)值N0cg(N)f(N)漸近時(shí)間復(fù)雜度分析例1.5求5n+4,n2+nlogn,2n+n2,10000的上界。n≥4時(shí),5n+4≤6n,則5n+4=O(n)n≥1時(shí),n2+nlogn≤2n2,則n2+nlogn=O(n2)n≥1時(shí),2n+n2≤2*2n,則2n+n2=O(2n)對(duì)于常整數(shù)10000,算法執(zhí)行時(shí)間與問(wèn)題規(guī)模無(wú)關(guān),無(wú)論問(wèn)題規(guī)模多大,算法都在固定時(shí)間內(nèi)完成。因此無(wú)論是10000還是其他任何常數(shù)輸入,它的時(shí)間復(fù)雜度是一個(gè)常數(shù)級(jí)別的復(fù)雜度,即O(1)。漸近時(shí)間復(fù)雜度分析例1.6給定多項(xiàng)式函數(shù):

試證明T(n)=O(nm)。證明:設(shè)n0=1,對(duì)于任意的n,若n≥n0=1,則:存在c≥0和自然數(shù)n0=1,使得當(dāng)n≥n0時(shí)有T(n)≤cnm,故T(n)=O(nm)成立。漸近時(shí)間復(fù)雜度分析根據(jù)定義1.1,我們有如下O(n)的性質(zhì):(1)O(f)+O(g)=O(max(f,g));算法最復(fù)雜的部分運(yùn)行時(shí)間就是算法的時(shí)間復(fù)雜度。(2)O(f)+O(g)=O(f+g);算法中并行語(yǔ)句的時(shí)間復(fù)雜度等于各個(gè)語(yǔ)句運(yùn)行時(shí)間之和。(3)O(f)×O(g)=O(f×g);循環(huán)的時(shí)間復(fù)雜度等于循環(huán)體運(yùn)行時(shí)間與循環(huán)次數(shù)的乘積。(4)O(cf(n))=O(f(n)),c∈Z+;算法的時(shí)間復(fù)雜度是運(yùn)行時(shí)間函數(shù)的數(shù)量級(jí)。(5)如果g(n)=O(f(n)),則O(f)+O(g)=O(f);算法的時(shí)間復(fù)雜度是運(yùn)行時(shí)間函數(shù)的最高階。(6)f=O(f)。漸近時(shí)間復(fù)雜度分析定義1.2設(shè)f(N)和g(N)是正整數(shù)集上的函數(shù)。如果?c≥0和自然數(shù)N0,使得當(dāng)N≥N0時(shí)有f(N)≥cg(N),則稱函數(shù)f(N)當(dāng)N充分大時(shí)下有界,且g(N)是f(N)的一個(gè)下界,記為f(N)=Ω(g(N)),即f(N)的階不低于g(N)的階,如圖所示。N0cg(N)f(N)漸近時(shí)間復(fù)雜度分析例1.8求5n+1,n2+nlogn的下界。當(dāng)n≥1時(shí),5n+1≥5n,則5n+1=Ω(n)當(dāng)n≥1時(shí),n2+nlogn≥n2,則n2+

nlogn

=Ω(n2);n2+

nlogn

≥nlogn,則n2+

nlogn

=Ω(nlogn),但nlogn≠Ω(n2)。根據(jù)定義1.2可知,n2+nlogn=Ω(n2)和n2+

nlogn

=Ω(nlogn)都成立,算法時(shí)間復(fù)雜度一般取最大下界。下界的階越高,評(píng)估越精確,結(jié)果越有價(jià)值,Ω通常也表示求解問(wèn)題的最好情況下的時(shí)間復(fù)雜度。漸近時(shí)間復(fù)雜度分析定義1.3設(shè)f(N)和g(N)是正整數(shù)集上的函數(shù)。如果?c1≥0、?c2≥0和自然數(shù)N0,使得當(dāng)N≥N0時(shí)有0≤c1g(N)≤f(N)≤c2g(N),則稱g(N)是f(N)的緊確界。記為f(N)=θ(g(N)),如圖1.7所示。若f(N)=θ(g(N)),則當(dāng)且僅當(dāng)f(n)=O(g(N))且f(N)=Ω(g(N)),也稱g(N)和f(N)同階。N0c1g(N)f(N)c2g(N)漸近時(shí)間復(fù)雜度分析例1.9

求n2+nlogn的緊確界。由例1.5和例1.8可知:n2+nlogn=O(n2),n2+nlogn=Ω(n2),因此n2+nlogn=θ(n2)。計(jì)算機(jī)算法設(shè)計(jì)與分析第一章概述非遞歸算法的時(shí)間復(fù)雜度分析在分析非遞歸算法時(shí),主要遵循如下步驟:(1)確定核心操作:比如算法中的賦值、比較、算術(shù)運(yùn)算、邏輯運(yùn)算、變量輸入輸出等操作,一般稱為基本操作。也可以將內(nèi)層循環(huán)的若干個(gè)基本操作構(gòu)成的程序塊整體看成一個(gè)稍大一點(diǎn)的基本操作。(2)計(jì)算核心操作總的執(zhí)行次數(shù):計(jì)算核心基本操作的執(zhí)行次數(shù),一般是多項(xiàng)式和的形式。(3)求解其漸近解:對(duì)核心操作總執(zhí)行次數(shù)表達(dá)式進(jìn)行計(jì)算化簡(jiǎn),并用O(?)形式表示。非遞歸算法的時(shí)間復(fù)雜度分析例1.10查找元素t在數(shù)組a中第一次出現(xiàn)的位置,若查找失敗返回-1。分析順序查找算法時(shí)間復(fù)雜度。本算法描述中的核心操作是語(yǔ)句3,最好的情況下,時(shí)間復(fù)雜度T(n)=O(1)。最壞的情況是整個(gè)循環(huán)語(yǔ)句1執(zhí)行完畢,即語(yǔ)句3被執(zhí)行n次而結(jié)束,此時(shí)T(n)=O(n)非遞歸算法的時(shí)間復(fù)雜度分析例1.11查找元素t在升序數(shù)組a中第一次出現(xiàn)的位置,若查找失敗返回-1。分析二分查找算法時(shí)間復(fù)雜度。非遞歸算法的時(shí)間復(fù)雜度分析核心操作是語(yǔ)句3~6,最好的情況下,執(zhí)行到語(yǔ)句4直接結(jié)束,時(shí)間復(fù)雜度T(n)=O(1)。最壞情況是每次進(jìn)入while循環(huán),搜索范圍a[left]~a[right]減少一半,直到最后只剩下1個(gè)元素比較最后一遍查找成功返回位置或者返回-1結(jié)束算法函數(shù)。不妨假設(shè)起始數(shù)組元素個(gè)數(shù)n=2m第1次執(zhí)行后,搜索數(shù)組范圍2m-1第2次執(zhí)行后,搜索數(shù)組范圍2m-2,...,第m次執(zhí)行后,搜索數(shù)組范圍剩下1個(gè)元素而結(jié)束。最壞情況下的程序塊總執(zhí)行次數(shù)為m次,算法時(shí)間復(fù)雜度T(n)=m=logn=O(logn)計(jì)算機(jī)算法設(shè)計(jì)與分析第一章概述遞歸算法的時(shí)間復(fù)雜度分析分析遞歸算法時(shí)間復(fù)雜度的主要步驟如下:(1)確定算法的核心操作:確定每一邏輯塊的時(shí)間復(fù)雜度,若是非遞歸的程序塊,則用非遞歸方法分析程序塊的時(shí)間復(fù)雜度;若是遞歸的程序塊,則分析遞歸程序塊的結(jié)構(gòu),根據(jù)其問(wèn)題規(guī)模遞推的形式來(lái)表示復(fù)雜度。(2)構(gòu)造時(shí)間復(fù)雜度函數(shù)的遞推方程:非遞歸程序塊的時(shí)間加上遞歸程序塊的時(shí)間。(3)求解遞歸方程和漸近階,并用O(?)表示算法時(shí)間復(fù)雜度。遞歸算法的時(shí)間復(fù)雜度分析例1.12

求n!算法描述核心操作遞歸算法的時(shí)間復(fù)雜度分析核心操作為n*FN(n-1),是一次乘法操作遞推方程:遞歸算法的時(shí)間復(fù)雜度分析例1.13

快速排序問(wèn)題遞歸求解算法描述:核心操作1核心操作2遞歸算法的時(shí)間復(fù)雜度分析非遞歸程序塊的執(zhí)行次數(shù)為n-1次,最壞的情況遞歸函數(shù)語(yǔ)句14每次范圍為0,則遞歸函數(shù)語(yǔ)句15的范圍則是n-1,則快速排序問(wèn)題的時(shí)間復(fù)雜度:最壞的情況快速排序問(wèn)題的漸近時(shí)間復(fù)雜度為T(mén)(n)=O(n2)遞歸算法的時(shí)間復(fù)雜度分析平均情況下,不妨設(shè)兩個(gè)遞歸函數(shù)語(yǔ)句14,15的元素個(gè)數(shù)差不多各占一半即n/2,也不妨設(shè)n=2m,則快速排序問(wèn)題的時(shí)間復(fù)雜度平均情況下的快速排序問(wèn)題的漸近時(shí)間復(fù)雜度為T(mén)(n)=O(nlogn)遞歸算法的時(shí)間復(fù)雜度分析MasterTheorem主定理,遞推方程其中a≥1,b>1,且a,b為常數(shù),則有如下結(jié)果:遞歸算法的時(shí)間復(fù)雜度分析例1.13求解遞推方程a=4,b=2,c=3,k=1;a=4>bk=2;由定理第一種情況可知,T(n)=O(n2)計(jì)算機(jī)算法設(shè)計(jì)與分析第二章

蠻力法學(xué)習(xí)目標(biāo)了解蠻力法的適用場(chǎng)景掌握蠻力法的設(shè)計(jì)思想掌握蠻力法解決實(shí)際問(wèn)題。2.1蠻力法概述蠻力法(BruteForce),又稱暴力法、窮舉法,它遍歷解空間的所有可能解,然后一一驗(yàn)證,直到找到問(wèn)題的解或所有可能解都驗(yàn)證完畢。該方法是一種簡(jiǎn)單直接地解決問(wèn)題的方法,常常直接基于問(wèn)題的描述和所涉及的概念定義。它完全依靠計(jì)算機(jī)的算力來(lái)直接對(duì)問(wèn)題進(jìn)行求解。隨著計(jì)算機(jī)硬件技術(shù)的不斷進(jìn)步,計(jì)算機(jī)的算力也在不斷提高。蠻力法借助于計(jì)算機(jī)強(qiáng)大的計(jì)算能力就能夠解決很大一部分問(wèn)題。雖然它顯得過(guò)于愚笨,但往往卻能以最簡(jiǎn)單直接的方式來(lái)解決問(wèn)題,甚至有些問(wèn)題只能用蠻力法求解。2.1蠻力法概述雖然巧妙和高效的算法很少來(lái)自于蠻力法,但不應(yīng)該忽略它作為一種重要的算法設(shè)計(jì)策略的地位。主要體現(xiàn)在以下幾個(gè)方面:(1)蠻力法的使用范圍廣,幾乎沒(méi)什么限制,可以解決廣闊領(lǐng)域的各種問(wèn)題。實(shí)際上,它可能是唯一一種幾乎什么問(wèn)題都能解決的一般性方法。(2)對(duì)于一些重要的問(wèn)題(如排序、查找、字符串匹配等)來(lái)說(shuō),規(guī)模不大時(shí),蠻力法可以產(chǎn)生一些合理的算法。2.1蠻力法概述雖然巧妙和高效的算法很少來(lái)自于蠻力法,但不應(yīng)該忽略它作為一種重要的算法設(shè)計(jì)策略的地位。主要體現(xiàn)在以下幾個(gè)方面:(3)如果要解決的問(wèn)題規(guī)模不大,從某種意義上說(shuō)蠻力法是最劃算的一種算法。(4)即使計(jì)算效率通常較低,但仍可使用蠻力法解決一些小規(guī)模的問(wèn)題實(shí)例。(5)蠻力法可作為研究或教學(xué)目的服務(wù),比如可以以它作為參照標(biāo)準(zhǔn),來(lái)衡量解決相同問(wèn)題的其他算法是否更為高效,如把蠻力法作為計(jì)算最壞時(shí)間復(fù)雜度。2.2蠻力法的設(shè)計(jì)思想蠻力法本質(zhì)是先有策略地進(jìn)行窮舉,然后一一驗(yàn)證。蠻力法的設(shè)計(jì)的需要從三個(gè)方面進(jìn)行:?jiǎn)栴}解的表示形式及范圍;使用何種方法將其窮舉,要求不能重復(fù)也不能遺漏;將每個(gè)列舉的可能解代入具體問(wèn)題的各個(gè)條件進(jìn)行比對(duì)。這三個(gè)方面中最為核心的是第二個(gè),也就是窮舉方法。為了避免陷入重復(fù)驗(yàn)證,應(yīng)保證驗(yàn)證過(guò)的可能解不再被驗(yàn)證。對(duì)于線性問(wèn)題來(lái)說(shuō),處理次序依次即可,而對(duì)于非線性問(wèn)題,就需要用到一些特定的方法,比如樹(shù)形結(jié)構(gòu)的前序遍歷、中序遍歷和后序遍歷;圖結(jié)構(gòu)的寬度優(yōu)先搜索和深度優(yōu)先搜索等。在設(shè)計(jì)時(shí)一般都是用循環(huán)語(yǔ)句和判斷語(yǔ)句來(lái)實(shí)現(xiàn)。使用循環(huán)是枚舉所有的情況,使用判斷是驗(yàn)證當(dāng)前的狀態(tài)是否滿足問(wèn)題的所有條件。若滿足,則找到問(wèn)題的一個(gè)解,可以結(jié)束,如需要求其他解,則繼續(xù)循環(huán);若不滿足,則繼續(xù)循環(huán)驗(yàn)證其他狀態(tài)。2.2蠻力法的設(shè)計(jì)思想2.2蠻力法的設(shè)計(jì)思想基本格式:for(循環(huán)變量x取所有可能的值){┇

if(x滿足指定的條件)

輸出x;┇}2.2蠻力法的設(shè)計(jì)思想使用蠻力法通常有如下幾種情況:搜索所有的解空間:?jiǎn)栴}的解存在于規(guī)模不大的解空間中。搜索所有的路徑:這類問(wèn)題中不同的路徑對(duì)應(yīng)不同的解。直接計(jì)算:按照基于問(wèn)題的描述和所涉及的概念定義,直接進(jìn)行計(jì)算。往往是一些簡(jiǎn)單的題,不需要算法技巧的。模擬和仿真:按照求解問(wèn)題的要求直接模擬或仿真即可。2.2蠻力法的設(shè)計(jì)思想編寫(xiě)一個(gè)程序,輸出2~1000之間的所有完全數(shù)。完全數(shù)定義:該數(shù)的各因子(除該數(shù)本身外)之和正好等于該數(shù)本身,例如:6=1+2+3,28=1+2+4+7+14分析:解的范圍:2~1000,范圍小,適合采用蠻力法窮舉方法:依次即可條件比對(duì):1到n/2中依次驗(yàn)證是否為n的約數(shù),如是則累加,最終判斷是否和n相等2.2蠻力法的設(shè)計(jì)思想偽代碼:PerfectNum(N)輸入:整數(shù)N,表示尋找2~N之間所有的完全數(shù)。輸出:2~N中所有的完全數(shù)forn←2toNdo

//解空間的范圍sum←1fori←2ton/2doifi整除nthensum←sum+i

//若是約數(shù),則累加endifendforifsum=nthen

//若約數(shù)之和與原數(shù)相等,則是完全數(shù)輸出nendifendfor2.2蠻力法的設(shè)計(jì)思想C源代碼:#include<stdio.h>#include<math.h>voidPerfectNum(intN){intsum,n,i; for(n=2;n<=N;n++){

sum=1; for(i=2;i<sqrt(n);i++){ if(n%i==0){ sum+=i; if(n/i!=i)

sum+=n/i; }} if(sum==n){ printf("%d\t",n); } }}voidmain(){ PerfectNum(1000);}2.3蠻力法的典型實(shí)例蠻力法適用于很多場(chǎng)景,具體來(lái)說(shuō),包括這幾類:搜索所有的解空間。問(wèn)題的解存在于規(guī)模不大的解空間中。解決這類問(wèn)題一般是找出某些滿足特定條件或要求的解。使用蠻力法就是把所有的解都列舉出來(lái),從中選出符合要求的解。搜索所有的路徑。這類問(wèn)題中不同的路徑對(duì)應(yīng)不同的解,需要找出特定解。使用蠻力法搜索所有可能的路徑并計(jì)算路徑對(duì)應(yīng)的解,找出特定解。直接計(jì)算?;趩?wèn)題的描述直接進(jìn)行計(jì)算。模擬和仿真。根據(jù)問(wèn)題要求直接模擬或仿真。2.3.1蠻力法的典型實(shí)例——0-1背包問(wèn)題1.問(wèn)題描述給定n種物品和一個(gè)背包。物品i的重量是Wi,其價(jià)值為Vi,背包的承重量為C。應(yīng)如何選擇裝入背包的物品,使得裝入背包中的物品重量在不超過(guò)C的前提下,總價(jià)值最大?附加條件:在選擇裝入背包的物品時(shí),對(duì)每種物品i只有2種選擇,即裝入背包或不裝入背包(1或0)。每種物品只有一份,不能將物品i裝入背包多次,也不能將物品i分割只裝入其的一部分。2.問(wèn)題分析確定解的表示形式:每種物品要么裝入背包,要么不裝入背包,分別用1和0表示,總共有n種物品,因此解的表示形式為n維的0-1向量,解的范圍有2n種組合。窮舉方法:當(dāng)n比較小時(shí),規(guī)模不大,使用蠻力法是可行的。用一個(gè)0~2n-1中的整數(shù)的二進(jìn)制形式來(lái)代表某種組合,二進(jìn)制對(duì)應(yīng)位數(shù)為1的表示裝入對(duì)應(yīng)的第i個(gè)物品。比如,假設(shè)n=5,用6=(00110)2,它的第2,3位為1,則代表裝入第2,3種物品。約束條件:裝入的物品重量和要≤背包的承重量C。目標(biāo)是在滿足條件情況下總價(jià)值最大。對(duì)于每種符合條件的物品組合其總價(jià)值可以很方便計(jì)算出來(lái),然后判斷是否大于前面驗(yàn)證過(guò)的組合物品總價(jià)值,若是,則將最大值更新,否則,最大值不變。2.3.1蠻力法的典型實(shí)例——0-1背包問(wèn)題2.3.1蠻力法的典型實(shí)例——0-1背包問(wèn)題3.算法實(shí)現(xiàn)KnapSack_BruteForce(W,V,n,C)輸入:n個(gè)物品的重量數(shù)組W[],價(jià)值數(shù)組V[],背包的承重量C輸出:背包能容下的價(jià)值最大的物品組合及總價(jià)值w←0,v←0 //包中初始沒(méi)放入任何物品,重量為0,價(jià)值為0fori←1to2n-1do //窮舉所有組合j←0temp←0whilej<ndo

if(i的第j位是1)//i的第j位為1,表示第i種組合將第j個(gè)物品裝入背包

w←w+W[j]

temp←temp+V[j]

endifendwhileifw<=C且temp>vthen //如果滿足條件,且背包中價(jià)值更大,則更新最大價(jià)值v←tempk←iendifendfor2.3.1蠻力法的典型實(shí)例——0-1背包問(wèn)題#include<stdio.h>intmax_w=0,

max_v=0,

ans=-1;voidKnapSack_BruteForce(intW[],intV[],intn,intC){ intw,v,i,j,k,f,N=1<<n; for(i=1;i<N;i++){ k=i;j=n-1;

w=0;v=0; while(k!=0){ f=k&1;

w+=f*W[j];

v+=f*V[j]; j--;

k>>=1; } if(w<=C&&v>max_v){max_w=w;

max_v=v;

ans=i; } }}voidmain(){ intW[]={2,3,4,7},V[]={1,3,5,9}; intC=10; KnapSack_BruteForce(W,V,4,C); printf("max_w=%d,max_v=%d,ans=%d\n",max_w,max_v,ans);}4.算法效率分析該算法時(shí)間復(fù)雜度為,當(dāng)n的規(guī)模較小時(shí),該算法有效。當(dāng)n較大時(shí),蠻力法比較難以在規(guī)定時(shí)間內(nèi)得出結(jié)果。當(dāng)然上述的算法還可以優(yōu)化,比如當(dāng)某個(gè)物品組合超過(guò)承重量C時(shí),那么包含以上組合的肯定都超過(guò)C,因此這樣的組合就不必驗(yàn)證,直接跳過(guò),這樣可以減少一些驗(yàn)證,提高效率。但無(wú)論如何,蠻力法求解0-1背包問(wèn)題總有局限性,其實(shí)求解該問(wèn)題還有更好的方法,比如動(dòng)態(tài)規(guī)劃法,這個(gè)在后續(xù)的章節(jié)里介紹。2.3.1蠻力法的典型實(shí)例——0-1背包問(wèn)題2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題1.問(wèn)題描述全排列就是一個(gè)序列所有可能的排序。例如,有1,2,3三個(gè)元素,其全排列的結(jié)果就是[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1],一共6種。根據(jù)數(shù)學(xué)公式,我們知道含有n個(gè)元素的全排列的個(gè)數(shù)為n!。所以生成全排列算法的時(shí)間復(fù)雜度不會(huì)低于O(n!)。給定正整數(shù)n,生成1~n的全排列。2.問(wèn)題分析算法一:增量法。假設(shè)n=3,增量法產(chǎn)生1~3的全排列過(guò)程如下:首先初始化數(shù)列為[1],然后將2插入到1的前后兩個(gè)位置得數(shù)列[1,2]和[2,1],繼續(xù)將3插入以上兩個(gè)數(shù)列的3個(gè)位置得到6個(gè)數(shù)列[1,2,3],[1,3,2],[3,1,2],[2,1,3],[2,3,1],[3,2,1]。過(guò)程如下圖所示。雖然增量法思路簡(jiǎn)單,但需要存儲(chǔ)大量的中間結(jié)果,所以空間復(fù)雜度比較高。2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題11,21,2,31,3,23,1,22,12,1,32,3,13,2,1初始化為1將2插入各位將3插入各位2.問(wèn)題分析算法二:遞歸法。對(duì)于給定的數(shù)組,先確定序列的第一個(gè)元素,剩余的序列又可以看成是一個(gè)不包含第一個(gè)元素的全排列。對(duì)剩余的序列重復(fù)這樣的操作,直到剩余序列中只一個(gè)元素為止。這樣就獲得了所有的可能序列。這是一個(gè)遞歸的過(guò)程。整個(gè)過(guò)程如下圖所示:2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題1231322132313213121231232133213.總結(jié)遞歸算法求全排列(蠻力法)(1)

n個(gè)元素的全排列=(一個(gè)元素作為前綴)+(剩下n-1個(gè)元素的全排列);(2)

結(jié)束:如果只有一個(gè)元素的全排列,說(shuō)明已經(jīng)排完,輸出數(shù)組;(3)

不斷將每個(gè)元素放作第一個(gè)元素,然后將這個(gè)元素作為前綴,并將其余元素繼續(xù)全排列,等到結(jié)束。出去后還需要還原數(shù)組。2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題voidPerm(intarr[],intbegin,intend){//如果遍歷到begin==end,則全排列已經(jīng)做完,只需輸出即可 if(begin==end) Print(arr); //輸出整個(gè)排列,需實(shí)現(xiàn) else{

//遞歸,生成剩余元素的排列 for(inti=begin;i<=end;i++){//將當(dāng)前元素與第一個(gè)元素交換,需實(shí)現(xiàn)

Swap(arr[begin],arr[i]);//遞歸調(diào)用,保持第一個(gè)元素固定并生成其余元素的排列

Perm(arr,begin+1,end);

//進(jìn)行回溯

Swap(arr[begin],arr[i]);}}}例2.2五星填數(shù)。在五星圖案結(jié)點(diǎn)填上數(shù)字1~12,不包括7和11。要求每條直線上數(shù)字和相等。如圖2.3就是一個(gè)恰當(dāng)?shù)奶罘?。?qǐng)搜索所有可能的填法有多少種。注意:旋轉(zhuǎn)或鏡像后相同的算同一種填法。2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題310121492865分析:上述問(wèn)題將1~12,不包括7和11,按不同順序填入圓圈中,其實(shí)是一個(gè)以上10個(gè)數(shù)的一種排列,如果驗(yàn)證5條線的數(shù)字和相等就是一種正確的填法。把所有的排列一一驗(yàn)證,這樣就可以統(tǒng)計(jì)出全部正確的填法。所以該問(wèn)題的核心就是一個(gè)全排列的問(wèn)題。解:經(jīng)過(guò)上述的分析,整個(gè)求解過(guò)程分為3步:①寫(xiě)出1~12不包括7和11的全排列;②判斷每條線上的4個(gè)數(shù)字和是否相等,若都相等則是正確的填法,其填法的計(jì)數(shù)加1;③剔除旋轉(zhuǎn)和鏡像,因?yàn)槲褰切切D(zhuǎn)和鏡像都屬于同一種填法,因此,最終應(yīng)該在全部正確的填法種數(shù)上除以10。2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題具體實(shí)現(xiàn)過(guò)程如下:(1)先來(lái)定義五星數(shù)組,因?yàn)槿帕兄袥](méi)用到數(shù)字0,所以定義數(shù)組時(shí)下標(biāo)為0的不用。intstar[]={0,1,2,3,4,5,6,8,9,10,12};//0不用(2)定義5條直線數(shù)字的和。#defineA(star[1]+star[3]+star[6]+star[9])#defineB(star[1]+star[4]+star[7]+star[10])#defineC(star[2]+star[3]+star[4]+star[5])#defineD(star[2]+star[6]+star[8]+star[10])#defineE(star[5]+star[7]+star[8]+star[9])2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題具體實(shí)現(xiàn)過(guò)程如下:(3)寫(xiě)出1~12不包括7和11的全排列,這步借鑒前面全排列的算法。(4)驗(yàn)證5條線上的數(shù)字和是否相等。if((A==B)&&(A==C)&&(A==D)&&(A==E))count++;(5)剔除旋轉(zhuǎn)和鏡像。count/=10;2.3.2蠻力法的典型實(shí)例——全排列問(wèn)題2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題1.問(wèn)題描述在進(jìn)行文本編輯處理時(shí),經(jīng)常會(huì)對(duì)文本內(nèi)容進(jìn)行查找工作,如Word中文本編輯的查找操作,在查找對(duì)話框中輸入需要查找的文本字符,可以精準(zhǔn)找到被查字符內(nèi)容在文本中的位置。這個(gè)問(wèn)題稱為字符串匹配問(wèn)題,即給定兩個(gè)串S="s1s2...sn"和T="t1t2...tm",在主串S中查找子串T的過(guò)程,也稱為模式匹配問(wèn)題,子串T又稱為模式串。2.算法設(shè)計(jì)BF(Brute-Force)串匹配算法是一種簡(jiǎn)單直觀的字符串匹配蠻力求解算法。它的基本思想是,第一次匹配過(guò)程,主串S的第一字符與模式串T的第一個(gè)字符對(duì)齊進(jìn)行比較。若相等,則比較主串S和模式串T的后續(xù)字符。若不等,則進(jìn)行下一次匹配過(guò)程,主串S本次比較起始字符的下一個(gè)字符與模式串T的第一個(gè)字符對(duì)齊進(jìn)行比較。重復(fù)上述過(guò)程,直到進(jìn)行第k次匹配過(guò)程,主串S的第k個(gè)字符開(kāi)始的m個(gè)字符與模式串T的m個(gè)字符全部相等,匹配查找成功。若主串S中字符全部比較完畢也沒(méi)有匹配成功,則匹配失敗。2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題舉例說(shuō)明:如主串S="abcababcabc",模式串T="abcabc",BF算法的匹配過(guò)程下所示。第一次匹配過(guò)程:主串和模式串第一個(gè)不等字符:s6≠t6,則i回到本次比較起始字符下一個(gè)位置2,j回到1位置。第二次匹配過(guò)程:主串和模式串第一個(gè)不等字符:s2≠t1,則i回到本次比較起始字符下一個(gè)位置3,j回到1位置。2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題舉例說(shuō)明:如主串S="abcababcabc",模式串T="abcabc",BF算法的匹配過(guò)程下所示。第三次匹配過(guò)程:主串和模式串第一個(gè)不等字符:s3≠t1,則i回到本次比較起始字符下一個(gè)位置4,j回到1位置。第四次匹配過(guò)程:主串和模式串第一個(gè)不等字符:s6≠t3,則i回到本次比較起始字符下一個(gè)位置5,j回到1位置。2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題舉例說(shuō)明:如主串S="abcababcabc",模式串T="abcabc",BF算法的匹配過(guò)程下所示。第五次匹配過(guò)程:主串和模式串第一個(gè)不等字符:s5≠t1,則i回到本次比較起始字符下一個(gè)位置6,j回到1位置。第六次匹配過(guò)程:主串和模式串完全匹配,則模式串在主串的6位置匹配成功。2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題3.算法設(shè)計(jì)輸入:主串文本S,模式串T輸出:模式串在主串中匹配成功的位置,若不成功為-1。BFSearch(S,T)begini←1,j←1while

i<S.length

and

j<T.length

doifS[i]=T[j]theni←i+1j←j+1elsei←i-j+2j←1endifendwhileif

j=T.lengththenv←i-T.length+1elsev←-1endifreturnvend2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題#include<stdio.h>#include<string.h>intBFStringMatch(char*S,char*T){inti=0,j=0;

//字符串下標(biāo)從0開(kāi)始while(S[i]!='\0'&&T[j]!='\0')

if(S[i]==T[j]){i++;

j++; }else{

i=i-j+1;

//主串回溯的位置

j=0;

//模式串回溯位置總是從第一個(gè)字符開(kāi)始 } if(j==strlen(T)) returni-j; else

return

-1;}voidmain(){ charS[]="abcababcabc"; charT[]="abcabc"; printf("模式串T在主串S中的位置:%d\n",BFStringMatch(S,T)); }4.算法效率分析設(shè)主串長(zhǎng)度為n,模式串長(zhǎng)度為m,最壞情況下為前n-m次匹配過(guò)程都是主串與模式串匹配到模式串的最后一個(gè)位置出現(xiàn)不等,即每次匹配過(guò)程都比較了m次發(fā)現(xiàn)不等回溯的,主串與模式串最后的m位也各比較了1次??偙容^次數(shù)為:(n-m+1)×m,若m遠(yuǎn)小于n,則BF算法時(shí)間復(fù)雜度為O(n*m)。2.3.3蠻力法的典型實(shí)例——串匹配問(wèn)題2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題對(duì)于非線性解空間,要想窮舉所有情況,就必須用到特定的搜索順序。在解決實(shí)際問(wèn)題中,最常見(jiàn)的有兩種搜索順序:寬度優(yōu)先搜索(BFS)和深度優(yōu)先搜索(DFS)。寬度優(yōu)先搜索寬度優(yōu)先搜索(BreadthFirstSearch,BFS),簡(jiǎn)稱寬搜,又稱廣度優(yōu)先搜素或廣搜。它從初始結(jié)點(diǎn)開(kāi)始,應(yīng)用產(chǎn)生式規(guī)則和控制策略生成第一層結(jié)點(diǎn),同時(shí)檢查目標(biāo)結(jié)點(diǎn)是否在這些生成的結(jié)點(diǎn)中。若沒(méi)有,再用產(chǎn)生式規(guī)則將所有第一層結(jié)點(diǎn)逐一拓展,得到第二層結(jié)點(diǎn),并逐一檢查第二層結(jié)點(diǎn)是否包含目標(biāo)結(jié)點(diǎn)。若沒(méi)有,再用產(chǎn)生式規(guī)則拓展第二層結(jié)點(diǎn)。如此依次拓展,檢查下去,直至發(fā)現(xiàn)目標(biāo)結(jié)點(diǎn)為止。如果拓展完所有結(jié)點(diǎn),都沒(méi)有發(fā)現(xiàn)目標(biāo)結(jié)點(diǎn),則問(wèn)題無(wú)解。BFS屬于盲目搜索,最糟糕的情況下算法時(shí)間復(fù)雜度為O(n!)。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題舉例說(shuō)明:如圖所示,一個(gè)長(zhǎng)方形的房間里鋪著方磚,每塊磚是“#”或黑點(diǎn)“?”。一個(gè)人站在黑磚上,可以按上、下、左、右方向移動(dòng)到相鄰的磚。要求他只能在“?”黑點(diǎn)磚上移動(dòng),而不能在“#”的磚上移動(dòng)。起點(diǎn)是@。問(wèn)題:遍歷所有能走的黑點(diǎn)磚。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題分析:可以用寬度優(yōu)先搜索來(lái)解決這個(gè)問(wèn)題。如圖所示2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題BFS算法一般用隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn),其步驟為:(1)把起始結(jié)點(diǎn)S放到queue(隊(duì)列)中;(2)如果queue為空,則失敗退出,否則繼續(xù);(3)在queue中取最前面的結(jié)點(diǎn)node移到CLOSED表中(出隊(duì));(4)擴(kuò)展node結(jié)點(diǎn),若沒(méi)有后繼(即葉結(jié)點(diǎn)),則轉(zhuǎn)向(2);(5)把node的所有后繼結(jié)點(diǎn)放在queue表的末端,即入隊(duì);(6)若后繼結(jié)點(diǎn)中某一個(gè)是目標(biāo)結(jié)點(diǎn),則找到一個(gè)解,成功退出。否則轉(zhuǎn)向(2)。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題BFS算法優(yōu)缺點(diǎn)寬度優(yōu)先搜索的優(yōu)點(diǎn):①對(duì)于解決最短或最少問(wèn)題特別有效,而且尋找深度小;②每個(gè)結(jié)點(diǎn)只訪問(wèn)一遍,結(jié)點(diǎn)總是以最短路徑被訪問(wèn),所以第二次路徑確定不會(huì)比第一次短。寬度優(yōu)先搜索的缺點(diǎn):一般需要存儲(chǔ)產(chǎn)生的所有結(jié)點(diǎn),內(nèi)存耗費(fèi)量大(需要開(kāi)大量的數(shù)組單元用來(lái)存儲(chǔ)狀態(tài)),因此程序設(shè)計(jì)中,必須考慮溢出和節(jié)省內(nèi)存空間的問(wèn)題。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題深度優(yōu)先搜索深度優(yōu)先搜索(DepthFirstSearch,DFS),簡(jiǎn)稱深搜,是一種用于遍歷或搜索樹(shù)或圖的算法。沿著樹(shù)的深度遍歷樹(shù)的結(jié)點(diǎn),盡可能深的搜索樹(shù)的分支。當(dāng)結(jié)點(diǎn)v的所在邊都己被探尋過(guò)或者在搜尋時(shí)結(jié)點(diǎn)不滿足條件,搜索將回溯到發(fā)現(xiàn)結(jié)點(diǎn)v的那條邊的起始結(jié)點(diǎn)。整個(gè)進(jìn)程反復(fù)進(jìn)行直到所有結(jié)點(diǎn)都被訪問(wèn)為止。DFS也屬于盲目搜索,最糟糕的情況下算法時(shí)間復(fù)雜度為O(n!)。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題分析:也可以用深度優(yōu)先搜索來(lái)解決這個(gè)問(wèn)題。如圖所示2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題DFS算法一般用棧這種數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn),其步驟為:(1)把起始結(jié)點(diǎn)S放到stack(棧)中;(2)如果stack為空,則失敗退出,否則繼續(xù);(3)在stack中把棧頂?shù)慕Y(jié)點(diǎn)node移到CLOSED表中(出棧);(4)若結(jié)點(diǎn)node的深度等于最大深度,則轉(zhuǎn)向(2);(5)擴(kuò)展node結(jié)點(diǎn),若沒(méi)有后繼(即葉結(jié)點(diǎn)),則轉(zhuǎn)向(2),否則把node的所有后繼結(jié)點(diǎn)進(jìn)棧;(6)若后繼結(jié)點(diǎn)中某一個(gè)是目標(biāo)結(jié)點(diǎn),則找到一個(gè)解,成功退出。否則轉(zhuǎn)向(2)。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題DFS算法優(yōu)缺點(diǎn)深度優(yōu)先搜索的優(yōu)點(diǎn):①能找出所有解決方案;②優(yōu)先搜索一棵子樹(shù),然后是另一棵,所以和廣搜對(duì)比,有著內(nèi)存需要相對(duì)較少的優(yōu)點(diǎn)。深度優(yōu)先搜索的缺點(diǎn):①要多次遍歷,搜索所有可能路徑,標(biāo)識(shí)做了之后還要取消;②在深度很大的情況下效率不高;③從輸出結(jié)果可看出,深度優(yōu)先搜索找到的第一個(gè)解并不一定是最優(yōu)解。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題3.廣度優(yōu)先搜索和深度優(yōu)先搜索區(qū)別廣度優(yōu)先搜索與深度優(yōu)先搜索的控制結(jié)構(gòu)和產(chǎn)生系統(tǒng)很相似,唯一的區(qū)別在于對(duì)擴(kuò)展結(jié)點(diǎn)選取上。這兩種算法每次都擴(kuò)展一個(gè)結(jié)點(diǎn)的所有子結(jié)點(diǎn)。而不同的是,深度優(yōu)先搜索下一次擴(kuò)展的是本次擴(kuò)展出來(lái)的子結(jié)點(diǎn)中的一個(gè),而廣度優(yōu)先搜索擴(kuò)展的則是本次擴(kuò)展的結(jié)點(diǎn)的兄弟結(jié)點(diǎn)。在具體實(shí)現(xiàn)上為了提高效率,各自采用了不同的數(shù)據(jù)結(jié)構(gòu),廣度優(yōu)先搜索使用的是隊(duì)列的數(shù)據(jù)結(jié)構(gòu),而深度優(yōu)先搜索使用的是棧的數(shù)據(jù)結(jié)構(gòu)。廣度優(yōu)先搜索是一個(gè)分層的搜索過(guò)程,沒(méi)有回退過(guò)程,是非遞歸的。只是每次都盡可能地?cái)U(kuò)展當(dāng)前結(jié)點(diǎn)的鄰居結(jié)點(diǎn),之后再向其子結(jié)點(diǎn)進(jìn)行擴(kuò)展。深度優(yōu)先搜索是一個(gè)遞歸過(guò)程,有回退過(guò)程。盡可能“深”地搜索圖。在深度優(yōu)先搜索中,對(duì)于最新發(fā)現(xiàn)的頂點(diǎn),如果它還有以此為起點(diǎn)而未探測(cè)到的邊,就沿此邊繼續(xù)搜索下去。當(dāng)結(jié)點(diǎn)V的所有邊都已被探尋過(guò),搜索將回溯到發(fā)現(xiàn)結(jié)點(diǎn)V有那條邊的始結(jié)點(diǎn),則選擇其中一個(gè)作為源結(jié)點(diǎn)并重復(fù)以上過(guò)程,整個(gè)進(jìn)程反復(fù)進(jìn)行直到所有結(jié)點(diǎn)都被發(fā)現(xiàn)為止。2.3.4蠻力法的典型實(shí)例——圖搜索問(wèn)題計(jì)算機(jī)算法設(shè)計(jì)與分析第三章

分治法學(xué)習(xí)目標(biāo)掌握分治法的基本思想掌握分治法的特點(diǎn)和基本框架掌握分治法解決實(shí)際問(wèn)題3.1分治法基本思想孫子兵法兵勢(shì)篇曰:凡治眾如治寡,分?jǐn)?shù)是也。其大致意思就是管理大規(guī)模部隊(duì)和管理小股部隊(duì)是一樣的,分開(kāi)治理就是了。這就是分治法在軍事上的運(yùn)用。分治法的基本思想就是將一個(gè)較難以解決的規(guī)模大的問(wèn)題,分割成多個(gè)相似的規(guī)模較小的子問(wèn)題,先求出小規(guī)模子問(wèn)題的解,然后將各小規(guī)模子問(wèn)題的解組合起來(lái)就是規(guī)模大的問(wèn)題的解。其中的一個(gè)關(guān)鍵點(diǎn)是分割的子問(wèn)題一定要相似,這樣就可以采取同樣的方法來(lái)求解,從而將問(wèn)題簡(jiǎn)化。例3.1

二分查找問(wèn)題。在一個(gè)升序的含n個(gè)元素的數(shù)組a[]中查找x,輸出x在數(shù)組a中的下標(biāo)位置,若沒(méi)查到返回-1。分析:可以考慮使用分治思想來(lái)解決,具體做法是設(shè)計(jì)三個(gè)變量left,mid和right將整個(gè)數(shù)組分成3個(gè)部分a[left,mid-1],a[mid],a[mid+1,right]。如果a[mid]>x,則使用相同的辦法在較小范圍[left,mid-1]中查找;如果a[mid]=x,則已查找到,返回mid即可;如果a[mid]<x,則使用相同的辦法在較小范圍[mid+1,right]中查找。以上過(guò)程都沒(méi)查找到的話,則數(shù)組中不存在x,返回-1。3.1分治法基本思想例3.2

二分歸并排序。將含有n個(gè)元素的數(shù)組a[]按關(guān)鍵字大小升序排列。以數(shù)組a[8]={8,4,5,7,1,3,6,2}為例來(lái)分析。3.1分治法基本思想3.2分治法的特點(diǎn)和基本框架當(dāng)采用分治法時(shí),一般原問(wèn)題都需要具備以下幾個(gè)特征:(1)難度遞降:即原問(wèn)題的解決難度,隨著數(shù)據(jù)的規(guī)模的縮小而降低,當(dāng)降低到一定程度時(shí),問(wèn)題很容易解決。(2)問(wèn)題可分:原問(wèn)題可以分解為若干個(gè)規(guī)模較小的同類型問(wèn)題,即該問(wèn)題具有最優(yōu)子結(jié)構(gòu)性質(zhì)。這是應(yīng)用分治法的前提。(3)解可合并:利用所有子問(wèn)題的解,可合并出原問(wèn)題的解。這個(gè)特征很關(guān)鍵,能否利用分治法完全取決于這個(gè)特征。(4)相互獨(dú)立:各個(gè)子問(wèn)題之間相互獨(dú)立,某個(gè)子問(wèn)題的求解不會(huì)影響到另一個(gè)子問(wèn)題。如果子問(wèn)題之間不獨(dú)立,則分治法需要重復(fù)地解決公共的子問(wèn)題,造成效率低下的結(jié)果。設(shè)P是要求解的問(wèn)題,|P|為問(wèn)題P的輸入規(guī)模,現(xiàn)將分治法求解問(wèn)題的基本框架描述如下:Divide-and-Conquer(P):if|P|≤cthenS(P)

//當(dāng)問(wèn)題規(guī)模較小時(shí),很容易求出解endifdividePintoP1,P2,...,Pk//將原問(wèn)題分割為規(guī)模小的子問(wèn)題fori=1tokdoxi=Divide-and-Conquer(Pi)//遞歸求解每個(gè)子問(wèn)題endforreturnMerge(x1,x2,...,xk)//將子問(wèn)題的解合并成原問(wèn)題的解3.2分治法的特點(diǎn)和基本框架3.3分治法的時(shí)間復(fù)雜度分析分治法的實(shí)現(xiàn)一般都是采用遞歸算法。分析分治法的時(shí)間復(fù)雜度需要使用其遞推公式來(lái)推導(dǎo)。分治法中通常的遞推方程有以下兩種類型:第一類是歸約后子問(wèn)題規(guī)模比原問(wèn)題規(guī)模呈常數(shù)級(jí)減少。遞推方程為如Hanoi塔問(wèn)題使用分治法,將n個(gè)圓盤(pán)的問(wèn)移動(dòng)題歸約為兩個(gè)n-1圓盤(pán)移動(dòng)子問(wèn)題,也就是歸約后的子問(wèn)題規(guī)模只比原問(wèn)題規(guī)模少1。遞推方程為解得:第二類是歸約后子問(wèn)題規(guī)模比原問(wèn)題規(guī)模呈倍數(shù)減少。該算法的時(shí)間復(fù)雜度可以通過(guò)以下遞推公式求出:根據(jù)1.4.4節(jié)介紹的MasterTheorem主定理結(jié)論可知:3.3分治法的時(shí)間復(fù)雜度分析3.4.1分治法的典型實(shí)例——快速排序快速排序是數(shù)據(jù)結(jié)構(gòu)中經(jīng)典且高效的一種排序算法,它在實(shí)踐中應(yīng)用非常廣泛。設(shè)待排的數(shù)組為A,快速排序的基本思想為:用數(shù)組的首元素作為標(biāo)準(zhǔn)將A劃分為前、后兩部分,前部分元素都比首元素小,后部分元素都比首元素大,這兩部分就構(gòu)成兩個(gè)新的子問(wèn)題。算法接著分別對(duì)這兩部分遞歸地進(jìn)行排序,各子問(wèn)題排序完成后自然整個(gè)數(shù)組也就排序完成。算法的關(guān)鍵在于怎樣劃分?jǐn)?shù)組A而將其歸約成兩個(gè)相同結(jié)構(gòu)的子問(wèn)題。3.4.1分治法的典型實(shí)例——快速排序快速排序算法Quicksort(A,p,r) //p和r分別為數(shù)組A的首元素和尾元素的下標(biāo)輸入:數(shù)組A[p..r],1≤p≤r≤n輸出:從A[p]到A[r]按照升序排好序的數(shù)組Aifp<rthenq←Partition(A,p,r) //劃分?jǐn)?shù)組,找到首元素A[p]在排好序后的位置qA[p]?A[q] //交換A[p],A[q]中元素的值Quicksort(A,p,q-1) //對(duì)前部分繼續(xù)遞歸地用快速排序算法Quicksort(A,q+1,r) //對(duì)后部分繼續(xù)遞歸地用快速排序算法endif其算法中的Partition函數(shù)是劃分的過(guò)程函數(shù),它實(shí)現(xiàn)的就是以A[p..r]的首元素A[p]作為標(biāo)準(zhǔn),輸出q表示A[p]應(yīng)該處在的正確位置,即排好序后A[p]應(yīng)該放在數(shù)組下標(biāo)為q的位置。過(guò)程如下:(1)先從后向前掃描數(shù)組A,找到第一個(gè)不大于A[p]的元素A[j](2)從前向后掃描A找到第一個(gè)大于A[p]的元素A[i](3)當(dāng)i<j時(shí),交換A[i]與A[j]。這時(shí)A[j]后面的元素都大于A[p],A[i]前面的元素都小于或等于A[p]。(4)接著對(duì)數(shù)組A從i到j(luò)之間的部分繼續(xù)上面的掃描過(guò)程,直到i和j相遇,當(dāng)i>j時(shí),j就代表了A在排好序的數(shù)組中的正確位置q。此刻在q位置之前的元素都不大于A[p],在q位置后面的元素都大于A[p]。3.4.1分治法的典型實(shí)例——快速排序3.4.1分治法的典型實(shí)例——快速排序劃分算法Partition(A,p,r)輸入:數(shù)組A[p..r],1≤p≤r≤n輸出:數(shù)組首元素A[p]在排好序的數(shù)組中的位置x←A[p]i←pj←r+1whiletruedorepeatj←j-1untilA[j]≤x//從后往前找到不大于x的元素repeati←i+1untilA[i]>x//從前往后找到大于x的元素ifi<jthenA[i]?A[j]//交換A[i],A[j]中元素的值elsereturnj //i,j相遇,返回相遇的位置即為數(shù)組首元素A[p]的正確位置endifendwhile舉例說(shuō)明一趟劃分的過(guò)程數(shù)組A[6]={64,57,86,42,12,53},第一趟劃分以64為標(biāo)準(zhǔn),p=1i=2j=5交換A[2]和A[5]的值,繼續(xù)循環(huán)。j=4i=5i<j不成立,一趟劃分結(jié)束,返回值為4。在Quicksort中q=4,交換A[p],A[q]中元素的值,就得到一次劃分后的結(jié)果。在一趟快速排序結(jié)束后,繼續(xù)對(duì)兩個(gè)子數(shù)組{12,57,53,42}和{86}實(shí)施相同的操作。3.4.1分治法的典型實(shí)例——快速排序第1次循環(huán)645786421253第2次循環(huán)645753421286劃分后1257534264863.4.2分治法的典型實(shí)例——大整數(shù)乘法1.問(wèn)題描述采用分治法設(shè)計(jì)一個(gè)有效的算法,計(jì)算兩個(gè)n位大整數(shù)的乘法。(n=2k,k=1,2,3....)。2.問(wèn)題分析根據(jù)分治法的思想,可以將兩個(gè)大的整數(shù)乘法分而治之。將大整數(shù)按位數(shù)的一半分成兩個(gè)小整數(shù),轉(zhuǎn)換成稍簡(jiǎn)單的小整數(shù)乘法,再進(jìn)行合并。上述的過(guò)程可以重復(fù)進(jìn)行,直到得到最簡(jiǎn)單的兩個(gè)1位數(shù)的乘法,從而解決上述問(wèn)題。

3.4.2分治法的典型實(shí)例——大整數(shù)乘法3.4.2分治法的典型實(shí)例——大整數(shù)乘法3.算法設(shè)計(jì)BigIntMul(X,Y,n)輸入:大整數(shù)X,Y和位數(shù)n輸出:X與Y的乘積結(jié)果sx←sign(X),sy←sign(Y) //取X,Y的符號(hào)s←sx*sy //求出X×Y的符號(hào)ifs=0thenreturn0endifX←|X|,Y←|Y|ifn=1thenreturns*X*YendifA←X的左邊n/2位, B←X的右邊n/2位C←Y的左邊n/2位, D←Y的右邊n/2位m1←BigIntMul(A,C,n/2), m2←BigIntMul((A-B),(D-C),n/2)m3←BigIntMul(B,D,n/2)S←m1*10^n+(m1+m2+m3)*10^(n/2)+m3returnS舉例:以計(jì)算3141×5247為例來(lái)說(shuō)明。將3141分拆成31和41,5247分拆成52和47。然后計(jì)算31×52,-10×-5,41×47。當(dāng)出現(xiàn)兩個(gè)數(shù)位數(shù)不等時(shí),可以將位數(shù)小的高位補(bǔ)0再進(jìn)行計(jì)算。如:-10×-5=10×05=(1×10+0)×(0×10+5)=1×0×100+(1×5+1×0+0×5)×10+0×5=0+50+0=50其他兩個(gè)個(gè)同理算出:31×52=1612,41×47=1927。帶入原來(lái)的算式得:3141×5247=16120000+(50+1612+1927)×100+1927=16480827。3.4.2分治法的典型實(shí)例——大整數(shù)乘法4.算法效率分析根據(jù)上述的計(jì)算過(guò)程得到遞推方程。改進(jìn)前:根據(jù)主定理理論可得:改進(jìn)后:根據(jù)主定理可得:

,有較大的改進(jìn)。3.4.3分治法的典型實(shí)例——平面內(nèi)最近點(diǎn)問(wèn)題

3.4.3分治法的典型實(shí)例——平面內(nèi)最近點(diǎn)問(wèn)題

2.問(wèn)題分析如果采用蠻力法,就需要遍歷平面上任意兩個(gè)點(diǎn)之間的距離,然后比較得出最小的值。很顯然其時(shí)間復(fù)雜度是O(n2)。那有沒(méi)有更快的方法呢?考慮分治法,如圖3.2所示,用一條垂直的直線l將整個(gè)平面中的點(diǎn)分為左半平面PL和右半平面PR兩部分,使得兩部分的點(diǎn)數(shù)近似相等。

3.4.3分治法的典型實(shí)例——平面內(nèi)最近點(diǎn)問(wèn)題

3.4.3分治法的典型實(shí)例——平面內(nèi)最近點(diǎn)問(wèn)題

3.4.4分治法的典型實(shí)例——選擇第k小問(wèn)題

3.4.3分治法的典型實(shí)例——平面內(nèi)最近點(diǎn)問(wèn)題平面上最臨近點(diǎn)對(duì)算法MinDistance(P,X,Y)輸入:n()個(gè)點(diǎn)集合P,X,Y分別表示n個(gè)點(diǎn)的x,y坐標(biāo)的值輸出:最近的兩個(gè)點(diǎn)以及距離ifn≤

3then直接計(jì)算n個(gè)點(diǎn)之間的最短距離endifSort(n,X,Y) //把所有的點(diǎn)按照橫坐標(biāo)X排序

l←mid(X) //用一條豎直的線L將所有的點(diǎn)分成兩等份MinDistance(PL,XL,YL)d1←PL中最短距離MinDistance(PR,XR,YR)d2←PR中最短距離d←min(d1,d2)while(PL中的點(diǎn)andXL≥l-d)dowhile(PR中的點(diǎn)andXR≤l+d)doifdistance(XL,YL,XR,YR)<dthen存儲(chǔ)點(diǎn)對(duì)(XL,YL),(XR,YR)d←distance(XL,YL,XR,YR)endifendwhileendwhile該算法是遞歸算法,且里面有排序,為了提高效率,可以把排序操作放到遞歸算法的外面。另外在直線l兩邊距離不超過(guò)d的區(qū)域內(nèi)檢查與所取點(diǎn)的距離是否小于d的點(diǎn)不超過(guò)7個(gè)即可。

3.4.3分治法的典型實(shí)例——平面內(nèi)最近點(diǎn)問(wèn)題

3.4.4分治法的典型實(shí)例——選擇第k小問(wèn)題1.問(wèn)題描述設(shè)A是含有n個(gè)元素的數(shù)組,從A中選出第k小的元素,其中1≤k≤n。所以選最小就是k=1;選最大就是k=n;選次大就是k=n-1;選中位數(shù)就是k=n/2。

3.4.4分治法的典型實(shí)例——選擇第k小問(wèn)題

3.4.4分治法的典型實(shí)例——選擇第k小問(wèn)題

計(jì)算機(jī)算法設(shè)計(jì)與分析第四章

動(dòng)態(tài)規(guī)劃學(xué)習(xí)目標(biāo)了解動(dòng)態(tài)規(guī)劃法的基本概念。掌握動(dòng)態(tài)規(guī)劃法的基本思想。掌握動(dòng)態(tài)規(guī)劃法解決實(shí)際問(wèn)題。4.1動(dòng)態(tài)規(guī)劃的提出在現(xiàn)實(shí)生活中,有一類活動(dòng)的過(guò)程,由于它的特殊性,可將過(guò)程分成若干個(gè)互相聯(lián)系的階段,在它的每一階段都需要作出決策,從而使整個(gè)過(guò)程達(dá)到最好的活動(dòng)效果。當(dāng)然,各個(gè)階段決策的選取不是任意確定的,它依賴于當(dāng)前面臨的狀態(tài),又影響以后的發(fā)展,當(dāng)各個(gè)階段決策確定后,就組成一個(gè)決策序列,因而也就確定了整個(gè)過(guò)程的一條活動(dòng)路線,如下圖所示。這種把一個(gè)問(wèn)題看作是一個(gè)前后關(guān)聯(lián)具有鏈狀結(jié)構(gòu)的多階段過(guò)程就稱為多階段決策過(guò)程,這種問(wèn)題就稱為多階段決策問(wèn)題。1狀態(tài)決策2狀態(tài)狀態(tài)決策n狀態(tài)狀態(tài)...決策4.1動(dòng)態(tài)規(guī)劃的提出在多階段決策問(wèn)題中,各個(gè)階段采取的決策,一般來(lái)說(shuō)是與時(shí)間有關(guān)的,決策取決于當(dāng)前的狀態(tài),然后又會(huì)引起狀態(tài)的轉(zhuǎn)移,一個(gè)決策序列就是在不斷變化的狀態(tài)中依次產(chǎn)生出來(lái)的,故有動(dòng)態(tài)的含義。因此,把處理它的方法稱為動(dòng)態(tài)規(guī)劃方法。但是,一些與時(shí)間沒(méi)有關(guān)系的靜態(tài)規(guī)劃,如線性規(guī)劃、非線性規(guī)劃等問(wèn)題,只要人為地引進(jìn)時(shí)間因素,也可把它視為多階段決策問(wèn)題,用動(dòng)態(tài)規(guī)劃方法去處理。4.2動(dòng)態(tài)規(guī)劃基本概念1.階段動(dòng)態(tài)規(guī)劃方法求解的問(wèn)題都屬于多階段決策問(wèn)題。因此需要將所求問(wèn)題劃分為若干個(gè)階段。把描述階段的變量稱為階段變量,用k來(lái)表示。在劃分階段時(shí),要求劃分后的階段按照時(shí)間或空間特征是有序的,否則問(wèn)題就無(wú)法求解。在下圖中,階段可以劃分為5個(gè),即k=1,2,3,4,5。2.狀態(tài)每個(gè)階段所處的客觀條件稱為狀態(tài),它描述了研究問(wèn)題過(guò)程的中間狀況。狀態(tài)就是某階段的出發(fā)位置,既是該階段某支路的起點(diǎn),又是前一階段某支路的終點(diǎn)。通常一個(gè)階段有若干狀態(tài)。在下圖中,第一階段只有狀態(tài){A},第二階段有狀態(tài){B1,B2},第三階段有狀態(tài){C1,C2,C3,C4}。描述狀態(tài)的變量稱為狀態(tài)變量。通常用Sk表示第k階段的狀態(tài)變量。在圖中,S3={C1,C2,C3,C4},該集合就稱為第三階段的可達(dá)狀態(tài)集。4.2動(dòng)態(tài)規(guī)劃基本概念2.狀態(tài)這里的狀態(tài)必須滿足無(wú)后效性(

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論