求一个任意实数c的算术平方根g的算法设计思想_算法复习第四篇——贪心法
公元2020年5月5日,距離算法考試僅剩4天。
一、知識歸納
1.設計思想
- 只根據當前已有的信息就做出選擇,而且一旦做出了選擇,將來無論如何都不能更改
- 不從整體最優考慮,所做的選擇只是在某種意義上的局部最優
- 這種選擇并不總能獲得整體最優解(Optimal Solution),但通常能獲得近似最優解(Near-Optimal Solution)
貪心法則通常以自頂向下的方式做出一系列的貪心選擇。
2.示例
【找錢問題】假設有面值為5元、2元、1元、5角、2角、1角的貨幣,需要找給顧客4元6角現金,使付出的貨幣的數量最少。
【思路】
- 首先選出1張面值不超過4元6角的最大面值的貨幣,即2元,再選出1張面值不超過2元6角的最大面值的貨幣,即2元,再選出1張面值不超過6角的最大面值的貨幣,即5角,再選出1張面值不超過1角的最大面值的貨幣,即1角,總共付出4張貨幣。
- 在付款問題每一步的貪心選擇中,在不超過應付款金額的條件下,只選擇面值最大的貨幣,而不去考慮在后面看來這種選擇是否合理,而且它還不會改變決定:一旦選出了一張貨幣,就永遠選定。
- 貪心選擇策略是盡可能使付出的貨幣最快地滿足支付要求,其目的是使付出的貨幣張數最慢地增加
3.基本要素
(1) 最優量度標準(正確的貪心策略,貪心選擇性質)
- 貪心法求解問題的核心問題
- 根據該量度標準,實行多步決策進行求解
- 在該量度意義下,每步的貪心選擇是局部最優的
- 得到全局最優解
(2) 求解的問題有最優子結構性質(最優性原理)
- 一個問題的最優解包含其子問題的最優解
4.求解過程
(1) 分解
- 將原問題分解為若干相互獨立的階段;
(2) 求解
- 對于每個階段求局部最優解,即根據貪心策略進行貪心選擇;
- 在每個階段,選擇一旦做出就不可更改。
(3) 合并
- 將各個階段的解合并為原問題的一個可行解。
5.相關概念
(1) 候選解集合C
- 問題的可能解
- 問題的最終解均取自于該候選集合
(2) 解集合S
- 隨著貪心選擇的進行不斷擴展,直到構成一個滿足問題的完整解
(3) 解判定函數solution
- 檢查解集合S是否構成問題的完整解
(4) 選擇函數select
- 貪心策略,這是貪心法的關鍵
- 指出哪個候選對象最有希望構成問題的解
- 通常和目標函數有關
(5) 可行解判定函數feasible
- 檢查解集合中加入一個候選對象是否可行,即解集合擴展后是否滿足約束條件
6.貪心法的一般過程
Greedy二、組合問題中的貪心法
- 背包問題(物品可切割)
- 多機調度問題
- 活動安排問題
1.背包問題
【問題表述】給定n種物品和一個容量為C的背包,物品i的重量是wi,其價值為vi,設xi表示物品i裝入背包的情況,背包問題是如何選擇裝入背包的物品,使得裝入背包中物品的總價值最大?
【建立模型】
【貪心策略】
貪心策略一:價值最大優先因為這可以盡可能快地增加背包的總價值。但是,雖然每一步選擇獲得了背包價值的極大增長,但背包容量卻可能消耗得太快,使得裝入背包的物品個數減少,從而不能保證目標函數達到最大。貪心策略二:重量最輕優先
因為這可以裝入盡可能多的物品,從而增加背包的總價值。但是,雖然每一步選擇使背包的容量消耗的慢了,但背包的價值卻沒能保證迅速增長,從而不能保證目標函數達到最大。貪心策略三:單位重量價值最大優先
在背包價值增長和背包容量消耗兩者之間尋找平衡。
例如,有3個物品,其重量分別是{20, 30, 10},價值分別為{60, 120, 50},背包的容量為50,應用三種貪心策略裝入背包的物品和獲得的價值如圖所示。
應用第三種貪心策略,每次從物品集合中選擇單位重量價值最大的物品,如果其重量小于背包容量,就可以把它裝入,并將背包容量減去該物品的重量,然后我們就面臨了一個最優子問題——它同樣是背包問題,只不過背包容量減少了,物品集合減少了。因此背包問題具有最優子結構性質。
【算法描述】
設背包容量為C,共有n個物品,物品重量存放在數組w[n]中,價值存放在數組v[n]中,問題的解存放在數組x[n]中。
1.改變數組w和v的排列順序,使其按單位重量價值v[i]/w[i]降序排列; 2.將數組x[1:n]初始化為0; //初始化解向量 3.i=1; 4.循環直到(w[i]>C)4.1 x[i]=1; //將第i個物品放入背包4.2 C=C-w[i];4.3 i++; 5. x[i]=C/w[i]; void Knapsack(int n,float M,float v[],float w[],float x[]) {Sort(n,v,w);int i;for (i=1;i<=n;i++) x[i]=0;float c=M;for (i=1;i<=n;i++) {if (w[i]>c) break;x[i]=1;c - =w[i];}if (i<=n) x[i]=c/w[i]; }【算法時間復雜度分析】
該算法的時間主要消耗在將各種物品依其單位重量的價值從大到小排序。因此,其時間復雜性為O(nlog2n)。
注:貪心算法不能解決0/1背包問題,可通過動態規劃法解決。三、圖問題中的貪心法
- 單源最短路徑問題 - Dijkstra算法
- TSP問題
- 最小生成樹問題 - Prim算法 - Kruskal算法
- 圖著色問題
1.最小代價生成樹問題
【問題表述】設G=(V,E)是一個無向連通圖,生成樹上各邊的權值之和稱為該生成樹的代價,在G的所有生成樹中,代價最小的生成樹稱為最小生成樹(Minimal Spanning Trees)。
【貪心策略】
①最近頂點策略任選一個頂點,并以此建立起生成樹,每一步的貪心選擇是簡單地把不在生成樹中的最近頂點添加到生成樹中。②最短邊策略設G = (V,E)是一個無向連通網,令T= (V,TE)是G的最小生成樹。從TE={}開始,每一次貪心選擇都是在邊集E中選取最短邊(u,v),如果邊(u, v)加入集合TE中不產生回路,則將邊(u,v)加入邊集TE中,并將它在集合E中刪去。最近頂點策略—Prim算法
- 使生成樹以一種自然的方式生長
- 從任意頂點開始,每一步為這棵樹添加一個分枝,直到生成樹中包含全部頂點
【算法描述】
設圖G中頂點的編號為0~n-1
Prim算法1. 初始化兩個輔助數組lowcost和adjvex;2. U={u0}; 輸出頂點u0; //將頂點u0加入生成樹中3. 重復執行下列操作n-1次3.1 在lowcost中選取最短邊,取adjvex中對應的頂點序號k;3.2 輸出頂點k和對應的權值;3.3 U=U+{k};3.4 調整數組lowcost和adjvex;【算法時間復雜度分析】
設連通網中有n個頂點,則
- 第一個進行初始化的循環語句需要執行n一1次
- 第二個循環共執行n - 1次,內嵌兩個循環:
- 其一是在長度為n的數組中求最小值,需要執行n- 1次;
- 其二是調整輔助數組,需要執行n- 1次。
所以,Prim算法的時間復雜度為
。四、考點總結
1.滿足最優子結構性質一定滿足貪心性質嗎?
滿足貪心選擇性質一定滿足最優子結構性質,而滿足最優子結構性質不一定滿足貪心選擇性質,比如背包問題可以用貪心算法解決,而0-1背包問題只能用動態規劃。
2.活動選擇問題中:
?最優的貪心策略是“最早結束活動優先”
?怎么衡量兩個活動A和B是相容的?
3.背包問題的貪心算法所需的計算時間為 nlogn
4.貪心算法與動態規劃算法的主要區別是 貪心選擇性質
動態規劃法通常以自底向上的方式求解各個子問題。貪心法則通常以自頂向下的方式做出一系列的貪心選擇。
5.最大效益優先是( 貪心法 )的搜索方式
6.貪心算法的基本要素是 貪心選擇 性質和 最優子結構 性質 。
最優子結構性質是貪心算法與動態規劃算法的共同點。貪心選擇性質 是貪心算法可行的第一個基本要素,也是貪心算法與動態規劃算法的主要區別。總結
以上是生活随笔為你收集整理的求一个任意实数c的算术平方根g的算法设计思想_算法复习第四篇——贪心法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的第一个SpringBoot项目
- 下一篇: 多功能标准型计算器