在求最優解問題的過程中,依據某種貪心標準,從問題的初始狀態出發,直接去求每一步的最優解,通過若干次的貪心選擇,最終得出整個問題的最優解,這種求解方法就是貪心演算法。
從貪心演算法的定義可以看出,貪心演算法不是從整體上考慮問題,它所做出的選擇只是在某種意義上的區域性最優解,而由問題自身的特性決定了該題運用貪心演算法可以得到最優解。
如果乙個問題可以同時用幾種方法解決,貪心演算法應該是最好的選擇之一。
活動安排問題就是要在所給的活動集合中選出最大的相容活動子集合,是可以用貪心演算法有效求解的很好例子。
該問題要求高效地安排一系列爭用某一公共資源的活動。
貪心演算法提供了乙個簡單、漂亮的方法使得盡可能多的活動能相容地使用公共資源。
設有n個活動的集合e=,其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有乙個活動能使用這一資源。
每個活動i都有乙個要求使用該資源的起始時間si和乙個結束時間fi,且si<fi。如果選擇了活動i,則它在半開時間區間[si ,fi )內占用資源。若區間[si ,fi )與區間[sj,fj )不相交,則稱活動i與活動j是相容的。當 si ≥ fj 或 sj ≥ fi 時,活動i與活動j相容。
活動安排問題就是在所給的活動集合中選出最大的相容活動子集合。
//資料結構
struct action
;action a[
1000];
//活動的集合e記為陣列
bool
cmp(
const action &a,
const action &b)
//按活動的結束時間公升序排序
//排序比較因子
sort
(a, a+n+
1, cmp)
;//使用標準模板庫函式排序(下標0未用)
//形引數組b用來記錄被選中的活動
void
greedyselector
(int n, action a,
bool b)
}
貪心演算法是一種在每一步選擇中都採取在當前狀態下最好或最優的選擇,希望得到結果是最好或最優的演算法。
貪心演算法是一種能夠得到某種度量意義下的最優解的分級處理方法,通過一系列的選擇得到乙個問題的解,而它所做的每一次選擇都是當前狀態下某種意義的最好選擇。即希望通過問題的區域性最優解求出整個問題的最優解。
這種策略是一種很簡潔的方法,對許多問題它能產生整體最優解,但不能保證總是有效,因為它不是對所有問題都能得到整體最優解。
利用貪心策略解題,需要解決兩個問題:
(1)該題是否適合於用貪心策略求解;
(2)如何選擇貪心標準,以得到問題的最優/較優解。
貪心選擇性質是指所求問題的整體最優解可以通過一系列區域性最優的選擇,即貪心選擇來達到。
這是貪心演算法可行的第乙個基本要素,也是貪心演算法與動態規劃演算法的主要區別。
(1)在動態規劃演算法中,每步所做的選擇往往依賴於相關子問題的解,因而只有在解出相關子問題後,才能做出選擇。
(2)在貪心演算法中,僅在當前狀態下做出最好選擇,即區域性最優選擇,然後再去解出這個選擇後產生的相應的子問題。
當乙個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。
運用貪心策略在每一次轉化時都取得了最優解。問題的最優子結構性質是該問題可用貪心演算法或動態規劃演算法求解的關鍵特徵。
貪心演算法的每一次操作都對結果產生直接影響,而動態規劃則不是。
貪心演算法對每個子問題的解決方案都做出選擇,不能回退;動態規劃則會根據以前的選擇結果對當前進行選擇,有回退功能。
動態規劃主要運用於二維或三維問題,而貪心一般是一維問題。
greedy
(a);
//初始解集合為空集
while
(not
solution
(s))
//集合s沒有構成問題的乙個解
; a = a-;}
return s;
}
給定乙個載重量為m的揹包,考慮n個物品,其中第i個物品的重量 ,價值wi (1≤i≤n),要求把物品裝滿揹包,且使揹包內的物品價值最大。
有兩類揹包問題(根據物品是否可以分割),如果物品不可以分割,稱為0—1揹包問題(動態規劃);如果物品可以分割,則稱為揹包問題(貪心演算法)。
假設xi是物品i裝入揹包的部分(0≤xi≤1),當xi=0時表示物品i沒有被裝入揹包;當xi= 1時表示物品i被全部裝入揹包。
有3種方法來選取物品:
(1)當作0—1揹包問題,用動態規劃演算法,獲得最優值220;
(2)當作0—1揹包問題,用貪心演算法,按價效比從高到底順序選取物品,獲得最優值160。由於物品不可分割,剩下的空間白白浪費。
(3)當作揹包問題,用貪心演算法,按價效比從高到底的順序選取物品,獲得最優值240。由於物品可以分割,剩下的空間裝入物品3的一部分,而獲得了更好的效能。
struct baga[
1001];
bool
cmp(bag a, bag b)
sort
(a, a+n, cmp)
;//形參n是物品的數量,c是揹包的容量m,陣列a是按物品的價效比降序排序
double
knapsack
(int n, bag a,
double c)
//裝滿揹包的剩餘空間
if(i=1.0
*a[i]
.v*cleft/a[i]
.w;return b;
}
struct baga[
1001];
double
knapsack
(int n, bag a,
double c)
if(ireturn b;
}
演算法期末備考 第6練 貪心演算法
主要內容 找硬幣活動安排問題 題目描述 有四種硬幣,分別是25分 10分 5分和1分,給顧客找六角三分。題解 貪心策略是 從大到小找零即可。1 include2 3 int coin 4int num 4 5 6 intmain 713 for int i 0 i 4 i 1617 return0 ...
資料結構與演算法(6)貪心法
貪心法 greedymethod 是把乙個複雜問題分解為一系列較為簡單的區域性最優選擇,每一步選擇都是對當前解的乙個擴充套件,直到獲得問題的完整解。正如其名字一樣,貪心法在解決問題的策略上目光短淺,只根據當前已有的資訊做出選擇,而且一旦做出了選擇,不管將來有什麼結果,這個選擇都不會改變。例如用貪心法...
貪心演算法6 排隊接水問題
題目描述 有n個人排隊到r個水龍頭去打水,他們裝滿水桶的時間t1,t2 tn為整數且各不相同,應如何安排他們的打水順序才能使他們花費的總時間最少?只有一組輸入資料哦。輸入4 2 2 6 4 5 輸出23 所有人的花費時間總和 樣例輸入 4 22 6 4 5 樣例輸出 int a maxn 每個人打水...