![軟件設(shè)計(jì)師專題_算法分析與設(shè)計(jì)_[文檔在線提供]_第1頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/7/d8f315fc-7217-4991-9d93-1a1a4b767e25/d8f315fc-7217-4991-9d93-1a1a4b767e251.gif)
![軟件設(shè)計(jì)師專題_算法分析與設(shè)計(jì)_[文檔在線提供]_第2頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/7/d8f315fc-7217-4991-9d93-1a1a4b767e25/d8f315fc-7217-4991-9d93-1a1a4b767e252.gif)
![軟件設(shè)計(jì)師專題_算法分析與設(shè)計(jì)_[文檔在線提供]_第3頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/7/d8f315fc-7217-4991-9d93-1a1a4b767e25/d8f315fc-7217-4991-9d93-1a1a4b767e253.gif)
![軟件設(shè)計(jì)師專題_算法分析與設(shè)計(jì)_[文檔在線提供]_第4頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/7/d8f315fc-7217-4991-9d93-1a1a4b767e25/d8f315fc-7217-4991-9d93-1a1a4b767e254.gif)
![軟件設(shè)計(jì)師專題_算法分析與設(shè)計(jì)_[文檔在線提供]_第5頁](http://file3.renrendoc.com/fileroot_temp3/2022-3/7/d8f315fc-7217-4991-9d93-1a1a4b767e25/d8f315fc-7217-4991-9d93-1a1a4b767e255.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、軟考:算法分析與設(shè)計(jì)1常用的算法設(shè)計(jì)方法:1.1 迭代法1.2 窮舉搜索法1.3 遞推法1.4 遞歸法1.5 貪婪法1.6 分治法1.7 動(dòng)態(tài)規(guī)劃法1.8 回溯法算法基礎(chǔ)部分:算法是對(duì)特定問題求解步驟的一種描述,算法是指令的有限序列,其中每一條指令表示一個(gè)或多個(gè)操作。算法具有以下5個(gè)屬性:有窮性:一個(gè)算法必須總是在執(zhí)行有窮步之后結(jié)束,且每一步都在有窮時(shí)間內(nèi)完成。確定性:算法中每一條指令必須有確切的含義。不存在二義性。只有一個(gè)入口和一個(gè)出口可行性:一個(gè)算法是可行的就是算法描述的操作是可以通過已經(jīng)實(shí)現(xiàn)的基本運(yùn)算執(zhí)行有限次來實(shí)現(xiàn)的。輸入:一個(gè)算法有零個(gè)或多個(gè)輸入,這些輸入取自于某個(gè)特定對(duì)象的集合。輸
2、出:一個(gè)算法有一個(gè)或多個(gè)輸出,這些輸出同輸入有著某些特定關(guān)系的量。所以對(duì)應(yīng)的算法設(shè)計(jì)的要求:正確性:算法應(yīng)滿足具體問題的需求;可讀性:算法應(yīng)該好讀,以有利于讀者對(duì)程序的理解;健壯性:算法應(yīng)具有容錯(cuò)處理,當(dāng)輸入為非法數(shù)據(jù)時(shí),算法應(yīng)對(duì)其作出反應(yīng),而不是產(chǎn)生莫名其妙的輸出結(jié)果。效率與存儲(chǔ)量需求:效率指的是算法執(zhí)行的時(shí)間;存儲(chǔ)量需求指算法執(zhí)行過程中所需要的最大存儲(chǔ)空間。一般這兩者與問題的規(guī)模有關(guān)。1.1 迭代法:迭代法是用于求方程或方程組近似根的一種常用的算法設(shè)計(jì)方法。設(shè)方程為f(x)=0,用某種數(shù)學(xué)方法導(dǎo)出等價(jià)的形式x=g(x),然后按以下步驟執(zhí)行:(1)選一個(gè)方程的近似根,賦給變量x0
3、;(2)將x0的值保存于變量x1,然后計(jì)算g(x1),并將結(jié)果存于變量x0;(3)當(dāng)x0與x1的差的絕對(duì)值還小于指定的精度要求時(shí),重復(fù)步驟(2)的計(jì)算。若方程有根,并且用上述方法計(jì)算出來的近似根序列收斂,則按上述方法求得的x0就認(rèn)為是方程的根。上述算法用C程序的形式表示為:【算法】迭代法求方程的根 x0=初始近似根; do x1=
4、x0; x0=g(x1); /*按特定的方程計(jì)算新的近似根*/ while ( fabs(x0-x1)>Epsilon); printf(“方程的近似根是%fn”,x0);迭
5、代算法也常用于求方程組的根,令 X=(x0,x1,xn-1)設(shè)方程組為: xi=gi(X) (I=0,1,n-1)則求方程組根的迭代算法可描述如下:【算法】迭代法求方程組的根
6、60; for (i=0;i<n;i+) xi=初始近似根; do
7、0; for (i=0;i<n;i+) yi=xi; &
8、#160; for (i=0;i<n;i+) xi=gi(X);&
9、#160; for (delta=0.0,i=0;i<n;i+)if (fabs(yi-xi)>delta) delta=fabs(yi-xi);
10、 while (delta>Epsilon); for (i=0;i<n;i+)
11、160; printf(“變量x%d的近似根是 %f”,I,xi); printf(“n”); 具體使用迭代法求根時(shí)應(yīng)注意以下兩種可能發(fā)生的情況:(1)如果方程無解,算法求出的近似根序列就不會(huì)收斂,迭代過程會(huì)變成死循環(huán),因此在使用迭代算法前應(yīng)先考察方程是否有解,并在程序中對(duì)迭代的次數(shù)給予限制;(2
12、)方程雖然有解,但迭代公式選擇不當(dāng),或迭代的初始近似根選擇不合理,也會(huì)導(dǎo)致迭代失敗。1.2 窮舉搜索法:窮舉搜索法是對(duì)可能是解的眾多候選解按某種順序進(jìn)行逐一枚舉和檢驗(yàn),并從中找出那些符合要求的候選解作為問題的解。要解決的問題只有有限種可能,在沒有更好算法時(shí)總可以用窮舉搜索的辦法解決,即逐個(gè)的檢查所有可能的情況??梢韵胂螅闆r較多時(shí)這種方法極為費(fèi)時(shí)。實(shí)際上并不需要機(jī)械的檢查每一種情況,常常是可以提前判斷出某些情況不可能取到最優(yōu)解,從而可以提前舍棄這些情況。這樣也是隱含的檢查了所有可能的情況,既減少了搜索量,又保證了不漏掉最優(yōu)解。【問題】 將A、B、C、D、E、F這六個(gè)變量排成如圖所示的
13、三角形,這六個(gè)變量分別取1,6上的整數(shù),且均不相同。求使三角形三條邊上的變量之和相等的全部解。如圖就是一個(gè)解。程序引入變量a、b、c、d、e、f,并讓它們分別順序取1至6的整數(shù),在它們互不相同的條件下,測(cè)試由它們排成的如圖所示的三角形三條邊上的變量之和是否相等,如相等即為一種滿足要求的排列,把它們輸出。當(dāng)這些變量取盡所有的組合后,程序就可得到全部可能的解。細(xì)節(jié)見下面的程序。# include <stdio.h>void main() int a,b,c,d,e,f;
14、; for (a=1;a<=6;a+) /a,b,c,d,e依次取不同的值 for (b=1;b<=6;b+)
15、0; if (b=a) continue; for (c=1;c<=6;c+)
16、 if (c=a)|(c=b) continue;
17、0; for (d=1;d<=6;d+)
18、 if (d=a)|(d=b)|(d=c) continue;for (e=1;e<=6;e+) &
19、#160; if (e=a)|(e=b)|(e=c)|(e=d) continue;f=21-(a+b+c+d+e);/最后一個(gè)用減法算if (a+b+c=c+d+e)&&(a+b+c=e+f+a)
20、printf(“%6d,a); printf(“%4d%4d”,b,f); printf(“%2d%4d%4d”,c,d,e); scanf(“%c”); &
21、#160;
22、
23、0; 按窮舉法編寫的程序通常不能適應(yīng)變化的情況。如問題改成有9個(gè)變量排成三角形,每條邊有4個(gè)變量的情況,程序的循環(huán)重?cái)?shù)就要相應(yīng)改變,循環(huán)的重?cái)?shù)和變量的個(gè)數(shù)相關(guān)。從上述問題解決的方法中,最重要的因素就是確定某種方法來確定所有的候選解。下1.3 遞推法: 遞推法是利用問題本身所具有的一種遞推關(guān)系求問題解的一種方法。設(shè)要求問題規(guī)模為N的解,當(dāng)N=1時(shí),解或?yàn)橐?/p>
24、知,或能非常方便地得到解。能采用遞推法構(gòu)造算法的問題有重要的遞推性質(zhì),即當(dāng)?shù)玫絾栴}規(guī)模為i-1的解后,由問題的遞推性質(zhì),能從已求得的規(guī)模為1,2,i-1的一系列解,構(gòu)造出問題規(guī)模為I的解。這樣,程序可從i=0或i=1出發(fā),重復(fù)地,由已知至i-1規(guī)模的解,通過遞推,獲得規(guī)模為i的解,直至得到規(guī)模為N的解?!締栴}】 階乘計(jì)算問題描述:編寫程序,對(duì)給定的n(n100),計(jì)算并輸出k的階乘k?。╧=1,2,n)的全部有效數(shù)字。由于要求的整數(shù)可能大大超出一般整數(shù)的位數(shù),程序用一維數(shù)組存儲(chǔ)長(zhǎng)整數(shù),存儲(chǔ)長(zhǎng)整數(shù)數(shù)組的每個(gè)元素只存儲(chǔ)長(zhǎng)整數(shù)的一位數(shù)字。如有m位成整數(shù)N用數(shù)組a 存儲(chǔ):
25、0; N=am×10m-1+am-1×10m-2+ +a2×101+a1×100并用a0存儲(chǔ)長(zhǎng)整數(shù)N的位數(shù)m,即a0=m。按上述約定,數(shù)組的每個(gè)元素存儲(chǔ)k的階乘k!的一位數(shù)字,并從低位到高位依次存于數(shù)組的第二個(gè)元素、第三個(gè)元素。例如,5!=120,在數(shù)組中的存儲(chǔ)形式為:3021 首元素3表示長(zhǎng)整數(shù)是一個(gè)3位數(shù),接著是低位到高位依次是0、2、1,表示成整數(shù)120。 計(jì)算階乘k!可采用對(duì)已求得的階乘(k-1
26、)!連續(xù)累加k-1次后求得。例如,已知4!=24,計(jì)算5!,可對(duì)原來的24累加4次24后得到120。細(xì)節(jié)見以下程序。# include <stdio.h># include <malloc.h># define MAXN 1000void pnext(int a ,int k)/已知a中的(k-1)!,求出k!在a中。 int *b,m=a0,i,j,r,carry; b=(int * ) malloc(
27、sizeof(int)* (m+1); for ( i=1;i<=m;i+) bi=ai; for ( j=1;j<k;j+) /控制累加k-1次 for ( carry=0,i=1;i&l
28、t;=m;i+)/i存放的是整數(shù)的位數(shù) r=(i<a0?ai+bi:ai)+carry;/進(jìn)位標(biāo)志 ai=r%1
29、0; carry=r/10; if
30、 (carry) a+m=carry; free(b); a0=m;void write(int *a,int k)/功能是輸出累加K次后的數(shù)組的各個(gè)位 int i; printf(“%4d!=”,k);
31、; for (i=a0;i>0;i-) printf(“%d”,ai);printf(“nn”);void main() int aMAXN,n,k; printf(“Enter the number n: “);
32、0; scanf(“%d”,&n); a0=1; a1=1; write(a,1); for (k=2;k<=n;k+) pnext(a,k
33、); write(a,k);/輸出長(zhǎng)整數(shù)的各位 getchar(); 1.4 遞歸法 遞歸是設(shè)計(jì)和描述算法的
34、一種有力的工具,由于它在復(fù)雜算法的描述中被經(jīng)常采用,為此在進(jìn)一步介紹其他算法設(shè)計(jì)方法之前先討論它。 能采用遞歸描述的算法通常有這樣的特征:為求解規(guī)模為N的問題,設(shè)法將它分解成規(guī)模較小的問題,然后從這些小問題的解方便地構(gòu)造出大問題的解,并且這些規(guī)模較小的問題也能采用同樣的分解和綜合方法,分解成規(guī)模更小的問題,并從這些更小問題的解構(gòu)造出規(guī)模較大問題的解。特別地,當(dāng)規(guī)模N=1時(shí),能直接得解?!締栴}】編寫計(jì)算斐波那契(Fibonacci)數(shù)列的第n項(xiàng)函數(shù)fib(n)。斐波那契數(shù)列為:0、1、1、2、3、,即:
35、; fib(0)=0; fib(1)=1; fib(n)=fib(n-1)+fib(n-2)
36、160; (當(dāng)n>1時(shí))。寫成遞歸函數(shù)有: int fib(int n) if (n=0) return 0; if (n=1) return 1; if (n>1)
37、0; return fib(n-1)+fib(n-2); 遞歸算法的執(zhí)行過程分遞推和回歸兩個(gè)階段。在遞推階段,把較復(fù)雜的問題(規(guī)模為n)的求解推到比原問題簡(jiǎn)單一些的問題(規(guī)模小于n)的求解。例如上例中,求解fib(n),把它推到求解fib(n-1)和fib(n-2)。也就是說,為計(jì)算fib(n),必須先計(jì)算fib(n-1)和fib(n-2),而計(jì)算fib(n-1)和fib(n-2),又必須先計(jì)算fib(n-3)和fib(n-4)。依次類推,直至計(jì)算fib(1)和fi
38、b(0),分別能立即得到結(jié)果1和0。在遞推階段,必須要有終止遞歸的情況。例如在函數(shù)fib中,當(dāng)n為1和0的情況。 在回歸階段,當(dāng)獲得最簡(jiǎn)單情況的解后,逐級(jí)返回,依次得到稍復(fù)雜問題的解,例如得到fib(1)和fib(0)后,返回得到fib(2)的結(jié)果,在得到了fib(n-1)和fib(n-2)的結(jié)果后,返回得到fib(n)的結(jié)果。 在編寫遞歸函數(shù)時(shí)要注意,函數(shù)中的局部變量和參數(shù)只是局限于當(dāng)前調(diào)用層,當(dāng)遞推進(jìn)入“簡(jiǎn)單問題”層時(shí),原來層次上的參數(shù)和局部變量便被隱蔽起來。在一系列“簡(jiǎn)單問題”層,它們各有自己的參數(shù)和局部變
39、量。 由于遞歸引起一系列的函數(shù)調(diào)用,并且可能會(huì)有一系列的重復(fù)計(jì)算,遞歸算法的執(zhí)行效率相對(duì)較低。當(dāng)某個(gè)遞歸算法能較方便地轉(zhuǎn)換成遞推算法時(shí),通常按遞推算法編寫程序。例如上例計(jì)算斐波那契數(shù)列的第n項(xiàng)的函數(shù)fib(n)應(yīng)采用遞推算法,即從斐波那契數(shù)列的前兩項(xiàng)出發(fā),逐次由前兩項(xiàng)計(jì)算出下一項(xiàng),直至計(jì)算出要求的第n項(xiàng)?!締栴}】背包問題問題描述:有不同價(jià)值、不同重量的物品n件,求從這n件物品中選取一部分物品的選擇方案,使選中物品的總重量不超過指定的限制重量,但選中物品的價(jià)值之和最大。設(shè)n件物品的重量分別為w0、w1、wn-1,物品的價(jià)值分別為v0、v1、vn-1
40、。采用遞歸尋找物品的選擇方案。設(shè)前面已有了多種選擇的方案,并保留了其中總價(jià)值最大的方案于數(shù)組option ,該方案的總價(jià)值存于變量maxv。當(dāng)前正在考察新方案,其物品選擇情況保存于數(shù)組cop 。假定當(dāng)前方案已考慮了前i-1件物品,現(xiàn)在要考慮第i件物品;當(dāng)前方案已包含的物品的重量之和為tw;至此,若其余物品都選擇是可能的話,本方案能達(dá)到的總價(jià)值的期望值為tv。算法引入tv是當(dāng)一旦當(dāng)前方案的總價(jià)值的期望值也小于前面方案的總價(jià)值maxv時(shí),繼續(xù)考察當(dāng)前方案變成無意義的工作,應(yīng)終止當(dāng)前方案,立即去考察下一個(gè)方案。因?yàn)楫?dāng)方案的總價(jià)值不比maxv大時(shí),該方案不會(huì)被再考察,這同時(shí)保證函數(shù)后找到的方案一定會(huì)比
41、前面的方案更好。對(duì)于第i件物品的選擇考慮有兩種可能:(1)考慮物品i被選擇,這種可能性僅當(dāng)包含它不會(huì)超過方案總重量限制時(shí)才是可行的。選中后,繼續(xù)遞歸去考慮其余物品的選擇。(2)考慮物品i不被選擇,這種可能性僅當(dāng)不包含物品i也有可能會(huì)找到價(jià)值更大的方案的情況。按以上思想寫出遞歸算法如下:try(物品i,當(dāng)前選擇已達(dá)到的重量和,本方案可能達(dá)到的總價(jià)值tv) /*考慮物品i包含在當(dāng)前方案中的可能性*/ if(包含物品i是可以接受的) &
42、#160; 將物品i包含在當(dāng)前方案中; if (i<n-1) try(i+1,tw+物品i的重量,tv);
43、60; else /*又一個(gè)完整方案,因?yàn)樗惹懊娴姆桨负?,以它作為最佳方?/以當(dāng)前方案作為臨時(shí)最佳方案保存;
44、0; 恢復(fù)物品i不包含狀態(tài); /*考慮物品i不包含在當(dāng)前方案中的可能性*/
45、0; if (不包含物品i僅是可考慮的) if (i<n-1)
46、160; try(i+1,tw,tv-物品i的價(jià)值); else
47、0; /*又一個(gè)完整方案,因它比前面的方案好,以它作為最佳方案*/以當(dāng)前方案作為臨時(shí)最佳方案保存; 為了理解上述算法,特舉以下實(shí)例。設(shè)有4件物品,它們的重量和價(jià)值見表:物品0123重量5321價(jià)值4431 并設(shè)限制重量為7。則按以上算法,下圖表示找解過程。由圖知,一旦找到一個(gè)解,算法就進(jìn)一步找更好
48、的解。如能判定某個(gè)查找分支不會(huì)找到更好的解,算法不會(huì)在該分支繼續(xù)查找,而是立即終止該分支,并去考察下一個(gè)分支。 Try(物品號(hào),總重,價(jià)值)按上述算法編寫函數(shù)和程序如下:【程序】# include <stdio.h># define N 100double limitW,totV,maxV;int optionN,copN;struct
49、 double weight; double value;
50、 aN;int n;void find(int i,double tw,double tv) int k; /*考慮物品i包含在當(dāng)前方案中的可能性*/ if (tw+ai.weight<=limitW)
51、0; copi=1; if (i<n-1) find(i+1,tw+ai.weight,tv); else
52、60; for (k=0;k<n;k+) optionk=copk;
53、0; maxv=tv; copi=0; /*考慮物品i不包含在當(dāng)前方案中的可能性*/ if (
54、tv-ai.value>maxV) if (i<n-1) find(i+1,tw,tv-ai.value); else
55、 for (k=0;k<n;k+) optionk=copk;
56、160; maxv=tv-ai.value; void main() int k; double w,v; printf(“輸入物品種數(shù)n”);
57、 scanf(“%d”,&n); printf(“輸入各物品的重量和價(jià)值n”); for (totv=0.0,k=0;k<n;k+) scanf(“%1f%1f”,&w,&v);
58、60; ak.weight=w; ak.value=v; totV+=V;
59、0; printf(“輸入限制重量n”); scanf(“%1f”,&limitV); maxv=0.0; for (k=0;k<n;k+) copk=0; find(0,0.0,totV); for (k=0;k
60、<n;k+) if (optionk) printf(“%4d”,k+1); printf(“n總價(jià)值為%.2fn”,maxv);作為對(duì)比,下面以同樣的解題思想,考慮非遞歸的程序解。為了提高找解速度,程序不是簡(jiǎn)單地逐一生成所有候選解,而是從每個(gè)物品對(duì)候選解的影響來形成值得進(jìn)一步考慮的候選解,一個(gè)候選解是通過依次考察每個(gè)物品形成的。對(duì)物品i的
61、考察有這樣幾種情況:1 當(dāng)該物品被包含在候選解中依舊滿足解的總重量的限制,該物品被包含在候選解中是應(yīng)該繼續(xù)考慮的;2 反之,該物品不應(yīng)該包括在當(dāng)前正在形成的候選解中。3 僅當(dāng)物品不被包括在候選解中,還是有可能找到比目前臨時(shí)最佳解更好的候選解時(shí),才去考慮該物品不被包括在候選解中;4 該物品不包括在當(dāng)前候選解中的方案也不應(yīng)繼續(xù)考慮。5 對(duì)于任意一個(gè)值得考慮的餓方案,程序就去進(jìn)一步考慮下一個(gè)物品;【程序】# include <stdio.h># define
62、 N 100double limitW;int copN;struct ele double weight;
63、; double value; aN;int k,n;struct
64、60; int flg; double tw;
65、; double tv; twvN;void next(int i,double tw,double tv) twvi.flg=1;
66、 twvi.tw=tw; twvi.tv=tv;double find(struct ele *a,int n) int i,k,f; double maxv,tw,tv,totv; maxv=0; for (tot
67、v=0.0,k=0;k<n;k+) totv+=ak.value; next(0,0.0,totv); i=0; While (i>=0)
68、160; f=twvi.flg; tw=twvi.tw; tv=twvi.tv; switch(
69、f) case 1: twvi.flg+;
70、160; if (tw+ai.weight<=limitW)
71、60; if (i<n-1)
72、 next(i+1,tw+ai.weight,tv);
73、60; i+;
74、0; else
75、; maxv=tv; &
76、#160; for (k=0;k<n;k+)
77、; copk=twvk.flg!=0;
78、;
79、0; break; case 0: i-;
80、60; break; d
81、efault: twvi.flg=0; if (tv-ai.value>maxv)
82、0; if (i<n-1)
83、160; next(i+1,tw,tv-ai.value);
84、; i+; &
85、#160;
86、 else
87、 maxv=tv-ai.value;
88、; for (k=0;k<n;k+)
89、60; copk=twvk.flg!=0;
90、60;
91、160; break; return maxv;void main() double maxv; printf(“輸入物品種數(shù)n”);
92、60; scanf(“%d”,&n); printf(“輸入限制重量n”); scanf(“%1f”,&limitW);printf(“輸入各物品的重量和價(jià)值n”); for (k=0;k<n;k+)
93、60; scanf(“%1f%1f”,&ak.weight,&ak.value); maxv=find(a,n); printf(“n選中的物品為n”);for (k=0;k<n;k+) if (optionk) printf(“%4d”,k
94、+1); printf(“n總價(jià)值為%.2fn”,maxv);1.5 貪婪法 貪心法是求解關(guān)于獨(dú)立系統(tǒng)組合優(yōu)化問題的一種簡(jiǎn)單算法,求最小生成樹的Kruskal算法就是一種貪心算法。貪心法的基本思路是:從問題的某一個(gè)初始解出發(fā)逐步逼近給定的目標(biāo),以盡可能快的地求得更好的解。當(dāng)達(dá)到某算法中的某一步不能再繼續(xù)前進(jìn)時(shí),算法停止。 該算法存在問題: 1. 不能保證求得的最后解是最佳的; 2. 不能用來求最大或最小解問題; 3. 只能求滿足某些約束條件的可行解的范圍。 實(shí)現(xiàn)該
95、算法的過程: 從問題的某一初始解出發(fā); while 能朝給定總目標(biāo)前進(jìn)一步 do 求出可行解的一個(gè)解元素; 由所有解元素組合成問題的一個(gè)可行解;貪婪法是一種不追求最優(yōu)解,只希望得到較為滿意解的方法。貪婪法一般可以快速得到滿意的解,因?yàn)樗∪チ藶檎易顑?yōu)解要窮盡所有可能而必須耗費(fèi)的大量時(shí)間。貪婪法常以當(dāng)前情況為基礎(chǔ)作最優(yōu)選擇,而不考慮各種可能的整體情況,所以貪婪法不要回溯。 例如平時(shí)購物找錢時(shí),為使找回的零錢的硬幣數(shù)最少,不考慮找零錢的所有各種發(fā)表方案,而是從最大面值的幣種開始,按遞減的順序考慮各幣種,先盡量用大面值的幣種,當(dāng)不足大面值幣
96、種的金額時(shí)才去考慮下一種較小面值的幣種。這就是在使用貪婪法。這種方法在這里總是最優(yōu),是因?yàn)殂y行對(duì)其發(fā)行的硬幣種類和硬幣面值的巧妙安排。如只有面值分別為1、5和11單位的硬幣,而希望找回總額為15單位的硬幣。按貪婪算法,應(yīng)找1個(gè)11單位面值的硬幣和4個(gè)1單位面值的硬幣,共找回5個(gè)硬幣。但最優(yōu)的解應(yīng)是3個(gè)5單位面值的硬幣?!締栴}】裝箱問題問題描述:裝箱問題可簡(jiǎn)述如下:設(shè)有編號(hào)為0、1、n-1的n種物品,體積分別為v0、v1、vn-1。將這n種物品裝到容量都為V的若干箱子里。約定這n種物品的體積均不超過V,即對(duì)于0in,有0viV。不同的裝箱方案所需要的箱子數(shù)目可能不同。裝箱問題要求使裝盡這n種物品
97、的箱子數(shù)要少。 若考察將n種物品的集合分劃成n個(gè)或小于n個(gè)物品的所有子集,最優(yōu)解就可以找到。但所有可能劃分的總數(shù)太大。對(duì)適當(dāng)大的n,找出所有可能的劃分要花費(fèi)的時(shí)間是無法承受的。為此,對(duì)裝箱問題采用非常簡(jiǎn)單的近似算法,即貪婪法。該算法依次將物品放到它第一個(gè)能放進(jìn)去的箱子中,該算法雖不能保證找到最優(yōu)解,但還是能找到非常好的解。不失一般性,設(shè)n件物品的體積是按從大到小排好序的,即有v0v1vn-1。如不滿足上述要求,只要先對(duì)這n件物品按它們的體積從大到小排序,然后按排序結(jié)果對(duì)物品重新編號(hào)即可。裝箱算法簡(jiǎn)單描述如下:
98、160; 輸入箱子的容積; 輸入物品種數(shù)n; 按體積從大到小順序,輸入各物品的體積; 預(yù)置已用箱子鏈為空; 預(yù)置已用箱子計(jì)數(shù)器box_count為0; for (i=0;i<n;i+) &
99、#160; 從已用的第一只箱子開始順序?qū)ふ夷芊湃胛锲穒 的箱子j; if (已用箱子都不能再放物品i) 另用一個(gè)箱子j,并將物品i放入該箱子;
100、; box_count+; else
101、; 將物品i放入箱子j; 上述算法能求出需要的箱子數(shù)box_count,并能求出各箱子所裝物品。下面的例子說明該算法不一定能找到最優(yōu)解,設(shè)有6種物品,它們的體積分別為:60、45、35、20、20和20單位體積,箱子的容積為100個(gè)單位體積。按上述算法計(jì)算,需三只箱子,各箱
102、子所裝物品分別為:第一只箱子裝物品1、3;第二只箱子裝物品2、4、5;第三只箱子裝物品6。而最優(yōu)解為兩只箱子,分別裝物品1、4、5和2、3、6。 若每只箱子所裝物品用鏈表來表示,鏈表首結(jié)點(diǎn)指針存于一個(gè)結(jié)構(gòu)中,結(jié)構(gòu)記錄尚剩余的空間量和該箱子所裝物品鏈表的首指針。另將全部箱子的信息也構(gòu)成鏈表。以下是按以上算法編寫的程序?!境绦颉? include <stdio.h># include <stdlib.h>typedef struct ele i
103、nt vno; struct ele *link; ELE;typedef struct hnode int remainder; ELE *head; Struct hnode
104、*next; HNODE;void main() int n, i, box_count, box_volume, *a; HNODE *box_h, *box_t, *j; ELE *p, *q; P
105、rintf(“輸入箱子容積n”); Scanf(“%d”,&box_volume); Printf(“輸入物品種數(shù)n”); Scanf(“%d”,&n); A=(int *)malloc(sizeof(int)*n); Pr
106、intf(“請(qǐng)按體積從大到小順序輸入各物品的體積:”); For (i=0;i<n;i+) scanf(“%d”,a+i); Box_h=box_t=NULL; Box_count=0; For (i=0;i<n;i+)
107、0; p=(ELE *)malloc(sizeof(ELE); p->vno=i; for (j=box_h;j!=NULL;j=j->next)
108、0; if (j->remainder>=ai) break; if (j=NULL)
109、; j=(HNODE *)malloc(sizeof(HNODE); j->remainder=box_volume-ai;
110、 j->head=NULL; if (box_h=NULL) box_h=box_t=j;
111、 else box_t=boix_t->next=j; j->next=NULL;
112、 box_count+; else j->remainder-=ai;
113、60; for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link); if (q=NULL) p->
114、link=j->head; j->head=p;
115、; else p->link=NULL; q->link=p;
116、0; printf(“共使用了%d只箱子”,box_count); printf(“各箱子裝物品情況如下:”); for (j=box_h,i=1;j!=NULL;j=j->next,i+)
117、160; printf(“第%2d只箱子,還剩余容積%4d,所裝物品有;n”,I,j->remainder); for (p=j->head;p!=NULL;p=p->link)
118、60; printf(“%4d”,p->vno+1); printf(“n”); 1.6 分治法1分治法的基本思想任何一個(gè)可以用計(jì)算機(jī)求解的問題所需的計(jì)算時(shí)間都與其規(guī)模N有關(guān)。問題的規(guī)模越小,越容易直接求解,解題所需的計(jì)算時(shí)間也越少。例如,對(duì)于n個(gè)元素的排序問題,當(dāng)n=1時(shí),不需任何計(jì)算;n=
119、2時(shí),只要作一次比較即可排好序;n=3時(shí)只要作3次比較即可,。而當(dāng)n較大時(shí),問題就不那么容易處理了。要想直接解決一個(gè)規(guī)模較大的問題,有時(shí)是相當(dāng)困難的。分治法的設(shè)計(jì)思想是,將一個(gè)難以直接解決的大問題,分割成一些規(guī)模較小的相同問題,以便各個(gè)擊破,分而治之。如果原問題可分割成k個(gè)子問題(1<kn),且這些子問題都可解,并可利用這些子問題的解求出原問題的解,那么這種分治法就是可行的。由分治法產(chǎn)生的子問題往往是原問題的較小模式,這就為使用遞歸技術(shù)提供了方便。在這種情況下,反復(fù)應(yīng)用分治手段,可以使子問題與原問題類型一致而其規(guī)模卻不斷縮小,最終使子問題縮小到很容易直接求出其解。這自然導(dǎo)致遞歸過程的產(chǎn)生。分治與遞歸像一對(duì)孿生兄弟,經(jīng)常同時(shí)應(yīng)用在算法設(shè)計(jì)之中,并由此產(chǎn)生許多高效算法。2分治法的適用條件分治法所能解決的問題一般具有以下幾個(gè)特征:(1)該問題的規(guī)??s小到一定的程度就可以容易地解決;(2)該問題可以分解為若干個(gè)規(guī)模較小的相同問題,即該問題具有最優(yōu)子結(jié)構(gòu)性質(zhì);(3)利用該問題分解出的子問題的解可以合并為該問題的解;(4)該問題所分解出的各個(gè)子問題是相互獨(dú)立的,即子問題之間不包含公共的子問題。 第一條特征是絕大多數(shù)問題都可以滿足的,因?yàn)閱栴}的計(jì)算復(fù)雜性一般是隨著問題規(guī)模的增加而增加;第二條特征是應(yīng)用分治法的前提,它也是大
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年數(shù)據(jù)科學(xué)與大數(shù)據(jù)技術(shù)考核試卷及答案
- 2025年公路工程項(xiàng)目管理考試題及答案
- 動(dòng)作題材劇本改編授權(quán)及電影制作合同
- 文化創(chuàng)意園區(qū)招商運(yùn)營管理合同
- 綠色建筑項(xiàng)目碳排放總量控制合同
- 跨境藝術(shù)品運(yùn)輸綜合保險(xiǎn)服務(wù)協(xié)議
- 潛水器材租賃及國際市場(chǎng)拓展服務(wù)合同
- 房地產(chǎn)虛擬現(xiàn)實(shí)銷售培訓(xùn)與市場(chǎng)推廣執(zhí)行合同
- 線上線下融合帶貨分成協(xié)議補(bǔ)充條款
- 婚姻出軌防范與賠償保障協(xié)議書
- 2025年全國學(xué)生愛眼護(hù)眼、預(yù)防近視知識(shí)考試題與答案
- 2025年四川省德陽市中考模擬地理試題四套附參考答案
- 特種設(shè)備崗位試題及答案
- 2025年北京市東城區(qū)九年級(jí)初三一模英語試卷(含答案)
- 國開2024年秋《機(jī)械制圖》形考作業(yè)1-4答案
- 個(gè)人工勞務(wù)分包合同
- MOOC 創(chuàng)業(yè)管理-江蘇大學(xué) 中國大學(xué)慕課答案
- 2024年四川省自然資源投資集團(tuán)有限責(zé)任公司招聘筆試參考題庫附帶答案詳解
- 鈑金報(bào)價(jià)計(jì)算表(強(qiáng))
- IATF16949過程審核檢查表模版
- 單相半橋逆變電路
評(píng)論
0/150
提交評(píng)論