【算法设计与分析】-- 贪心法
目錄
一、基本思想
二、兩個例子說明貪心算法的適用場景:
背包問題:
0-1背包問題:
三、活動安排問題(選擇、調(diào)度問題)
問題描述
算法設(shè)計
算法復(fù)雜度
算法正確性證明
四、最優(yōu)裝載問題
問題描述
算法設(shè)計
算法描述
算法復(fù)雜度
五、背包問題
貪心策略
算法描述
算法復(fù)雜度
一、基本思想
求解組合優(yōu)化問題的貪心算法包含一系列步驟。每一步都在一組選擇中做出在當(dāng)前看來最好的選擇,希望通過做出局部優(yōu)化選擇達(dá)到全局優(yōu)化選擇,但貪心算法不一定總產(chǎn)生優(yōu)化解,所以一個貪心算法是否產(chǎn)生優(yōu)化解,需要嚴(yán)格證明。
貪心選擇性:每一步都在一組選擇中做出在當(dāng)前看來最好的選擇。
二、兩個例子說明貪心算法的適用場景:
背包問題:
給定n種物品和一個背包。物品i的重量是wi,其價值為vi,背包的容量為c。問應(yīng)如何選擇物品裝入背包,使得裝入背包中的物品的總價值最大?在選擇物品i裝入背包時,可以選擇物品i的一部分,而不一定要全部。用貪心算法,每次選單位重量價值vi/ wi最大的物品i放進包中。背包問題具有最優(yōu)子結(jié)構(gòu)性質(zhì),它可以用動態(tài)規(guī)劃算法來解。但用貪心算法更簡單,解題效率更高。貪心算法總是做出在當(dāng)前看來是最好的選擇。也就是說貪心算法并不從整體最優(yōu)上加以考慮,所以貪心算法不是對所有問題都能得到整體最優(yōu)解。
0-1背包問題:
????????給定n種物品和- -個背包。物品i的重量是wi,其價值為vi,背包的容量為C。問應(yīng)如何選擇物品裝入背包,使得裝入背包中的物品的總價值最大?在選擇物品裝入背包時,對每種物品i只有兩種選擇,要么裝入,要么不裝入,不能將物品i裝入背包多次,也不能只裝入物品i的一部分。因此,該問題稱為0-1背包問題。
????????設(shè)有3物品,這3個物品的重量W={3,5,7},價值為V={9,10,12},背包容量c=10。用貪心法會將物品1和2裝包,獲得的價值為19,但最優(yōu)解是將物品1和3裝包,獲得的價值為21。
????????0-1背包問題也具有最優(yōu)子結(jié)構(gòu)性質(zhì)。但是0-1背包問題卻不能用貪心算法求解。對于0-1背包問題,貪心選擇之所以不能得到最優(yōu)解是因為在這種情況下,它無法保證最終將背包裝滿,背包部分空間的閑置使每單位重量背包空間所具有的價值降低了(該問題不具有貪。心選擇性)。事實上,在考慮0-1背包問題的物品選擇時,應(yīng)比較選擇該物品和不選擇該物品所導(dǎo)致的最終結(jié)果,然后再做出最好的選擇。
貪心算法求解的問題必須具有最優(yōu)質(zhì)子結(jié)構(gòu)和貪心選擇性。
三、活動安排問題(選擇、調(diào)度問題)
問題描述
設(shè)有n個活動的集合S三_ {1. 2. . n},其中每個活動都要求以獨占的方式使用同一資源,如演講會場等,而在同一時間內(nèi)只允許一個活動使用這一資源。每個活動i都有一個要求使用該資
源的起始時間si和一個結(jié)束時間fi,且si<fi。如果選擇了活動i,則它在半開的時間區(qū)間[si,fi)內(nèi) 占用資源。若區(qū)間[si, fi)與區(qū)間[sj,fj)不相交,則稱活動i與活動j是相容的。也就是說,當(dāng)si≥fj或Sj 近時,活動i與活動j是相容。活動安排問題是要在所給的活動集合中選出最大的(兩兩)相容活動子集合。
算法設(shè)計
貪心思想:為了選擇最多的相容活動,每次選fi最小的活動,使剩余的可安排時間段極大化,以便接待盡可能多的相容活動。
例:
設(shè)活動集S = {1,2,.....,11}中的活動已按結(jié)束時間非降序排列。
第1步,選活動1;
第2步,在剩余相容活動子集{4,6,7,8,9,11}中選結(jié)束時間最早的活動4.
第3步,在剩余相容活動子集{8,9,11}中選結(jié)束時間最早的活動8.
第4步,在剩余相容活動子集{11}中選結(jié)束時間最早的活動11.
這時,剩余相容活動子集{}變?yōu)榭占?#xff0c;從而得S的一個最優(yōu)解A = {1,4,8,11}
void GreedySelector(int n,Type s[],Type f[],bool A[]){A[1] = true;//選擇活動1int j = 1;// j記錄最近一次添加到A中的活動for(int i = 2;i<=n;i++){if(s[i]>=f[j]){//找到相容活動 A[i] = true;j = i;}else A[i] = false} }算法復(fù)雜度
按結(jié)束時間已排序:O(n)
按結(jié)束時間未排序:O(nlogn)
算法正確性證明
①證明問題具有優(yōu)化子結(jié)構(gòu)
②證明問題具有貪心選擇性
③活動安排問題的貪心算法是按選擇性進行局部優(yōu)化
四、最優(yōu)裝載問題
問題描述
????????有一批集裝箱要裝_上一艘載重量為c的輪船。其中,集裝箱i的重量為wi。最優(yōu)裝載問題要求確定,在裝載體積不受限制的情況下,應(yīng)如何裝載才能將盡可能多的集裝箱裝,上輪船。
????????設(shè)n是集裝箱總數(shù)。該問題可形式化地描述為:求一個n維的0-1向量(X1, X2, . , Xn) (x,∈{0,1},i = 1,2,3...,n.在滿足wixi<=c(i從1開始到n結(jié)束)時,使xi(i從1開始到n結(jié)束)最大,其中xi = 0表示不裝入集裝箱i,xi = 1表示裝入集裝箱i。
算法設(shè)計
貪心思想:用重量最輕者先裝的貪心選擇策略,由此可產(chǎn)生裝載問題的最優(yōu)解。
算法描述
假設(shè)集裝箱已按重量遞增的次序排序。
void Loading(int x[],Type w[],Type c,int n){for(int i = 1;i<=n;i++)x[i] = 0;//初始化全部為0,數(shù)組元組X[i] = 0表示 不裝入集裝箱ifor(int i = 1;i<=n&&w[i]<=c;i++){x[i] = 1;c -= w[i];} }算法復(fù)雜度
當(dāng)集裝箱已按重量從小到大排序:O(n)
未排序:O(nlogn)
五、背包問題
問題前面已描述,這里省略.....
貪心策略
????????選擇單位重量價值vi/ wi最大的物品。每次從物品集合中.選擇單位重量價值最大的物品,如果其重量小于背包容量,就可以把它裝入,并將背包價值增加該物品的價值,同時背包容量減去該物品的重量,然后就面臨了一個最優(yōu)子問題一一它 同樣是背包問題,只不過背包容量減少了,物品集合減少了。因此可以證明背包問題,具有最優(yōu)子結(jié)構(gòu)性質(zhì)。
算法描述
//n為物品數(shù)量,c為背包容量,v存放物品價值, w存放物品重量 ,x存放物品是否裝的狀態(tài),value為得到的最終總價值 void Knapsack(int n,float c,float v[],float w[],float x[],float &value){ // 假設(shè)已將各種物品依其單位重量的價值 vi/wi從大到小排序float value = 0;// 最大價值for(int i = 1;i<=n;i++)x[i] = 0;//初始化 for(int i = 1;i<=n&&w[i]<=c;i++){x[i] = 1;//裝入背包 c -= w[i];//減少背包能裝入 的余下重量 value += v[i];//累計總價值 }if(i<=n){//當(dāng)w[i]>c時,即不能完整放入下面的物品時 x[i] = c/w[i];//將物品i 的一部分裝入value += x[i]*v[i] } }算法復(fù)雜度
已排序:O(n)
未排序:O(nlogn)
總結(jié)
以上是生活随笔為你收集整理的【算法设计与分析】-- 贪心法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FP5207 外置MOS大功率升压芯片
- 下一篇: 拉线位移传感器拆卸的顺序不要颠倒,小编来