一、基本概念:
所謂貪心演算法是指,在對問題求解時,總是做出在
當前看來是最好的選擇
。也就是說,不從整體最優上加以考慮,他所做出的僅是在某種意義上的
區域性最優解 。
貪心演算法沒有固定的演算法框架,演算法設計的關鍵是貪心策略的選擇。必須注意的是,貪心演算法不是對所有問題都能得到整體最優解,選擇的貪心策略必須具備無後效性,即某個狀態以後的過程不會影響以前的狀態,只與當前狀態有關。
所以對所採用的貪心策略一定要仔細分析其是否滿足無後效性。
二、貪心演算法的基本思路:
1.建立數學模型來描述問題。
2.把求解的問題分成若干個子問題。
3.對每一子問題求解,得到子問題的區域性最優解。
4.把子問題的解區域性最優解合成原來解問題的乙個解。
三、貪心演算法適用的問題
貪心策略適用的前提是:區域性最優策略能導致產生全域性最優解。
實際上,貪心演算法適用的情況很少。一般,對乙個問題分析是否適用於貪心演算法,可以先選擇該問題下的幾個實際資料進行分析,就可做出判斷。
四、貪心演算法的實現框架
從問題的某一初始解出發;
while (能朝給定總目標前進一步)
由所有解元素組合成問題的乙個可行解;
五、貪心策略的選擇
因為用貪心演算法只能通過解區域性最優解的策略來達到全域性最優解,因此,一定要注意判斷問題是否適合採用貪心演算法策略,找到的解是否一定是問題的最優解。
六、例題分析
下面是乙個可以試用貪心演算法解的題目,貪心解的確不錯,可惜不是最優解。
[揹包問題]有乙個揹包,揹包容量是m=150。有7個物品,物品可以分割成任意大小。
要求盡可能讓裝入揹包中的物品總價值最大,但不能超過總容量。
物品 a b c d e f g
重量 35 30 60 50 40 10 25
價值 10 40 30 50 35 40 30
分析:目標函式: ∑pi最大
約束條件是裝入的物品總重量不超過揹包容量:∑wi<=m( m=150)
(1)根據貪心的策略,每次挑選價值最大的物品裝入揹包,得到的結果是否最優?
(2)每次挑選所佔重量最小的物品裝入是否能得到最優解?
(3)每次選取單位重量價值最大的物品,成為解本題的策略。
值得注意的是,貪心演算法並不是完全不可以使用,貪心策略一旦經過證明成立後,它就是一種高效的演算法。
貪心演算法還是很常見的演算法之一,這是由於它簡單易行,構造貪心策略不是很困難。
可惜的是,它需要證明後才能真正運用到題目的演算法中。
一般來說,
貪心演算法的證明圍繞著:整個問題的最優解一定由在貪心策略中存在的子問題的最優解得來的。
對於例題中的3種貪心策略,都是無法成立(無法被證明)的,解釋如下:
(1)貪心策略:選取價值最大者。反例:
w=30
物品:a b c
重量:28 12 12
價值:30 20 20
根據策略,首先選取物品a,接下來就無法再選取了,可是,選取b、c則更好。
(2)貪心策略:選取重量最小。它的反例與第一種策略的反例差不多。
(3)貪心策略:選取單位重量價值最大的物品。反例:
w=30
物品:a b c
重量:28 20 10
價值:28 20 10
根據策略,三種物品單位重量價值一樣,程式無法依據現有策略作出判斷,如果選擇a,則答案錯誤。
/**
* 揹包貪心法
* * @author ***
* */
public class greedy
system.out
.println("now, please enter the value of these objects(現在請輸入這些物品的價值:)");
for (int i = 0; i < n; i++)
system.out
.println("now, please enter the capacity of the pack(現在請輸入揹包的容量:)");
int c = in.nextint();
/**
* 按單位重量價值r[i] = v[i] / w[i]降序排列
* * ps:排序用到了選擇排序,詳情請檢視選擇排序
*/
double starttime = system.currenttimemillis();
double r = new double[n];
int index = new int[n];
for (int i = 0; i < n; i++)
double temp = 0;
for (int i = 0; i < n - 1; i++)
} }
/**
* 排序後的重量和價值分別存到w1和v1中
*/
int w1 = new int[n];
int v1 = new int[n];
for (int i = 0; i < n; i++)
/**
* 初始化解向量x[n]
*/
int x = new int[n];
for (int i = 0; i < n; i++)
/**
* 求解並列印解向量
*/
for (int i = 0; i < n; i++)
} system.out
.println("the solution vector is(解向量是:)" + arrays.tostring(x));
/**
* 根據解向量求出揹包中存放物品的最大價值並列印
*/
int maxvalue = 0;
for (int i = 0; i < n; i++)
double endtime = system.currenttimemillis();
system.out
.println("now, the largest values of objects in the pack is(揹包中物品的最大價值為:)"
+ maxvalue);
system.out.println("basic statements take(基本語句用時)"
+ (endtime - starttime) + " milliseconds!");
} }
五大常用演算法 三 貪心演算法
貪心演算法是指在對問題求解時,總是做出在當前看來是最好的選擇。不從整體最優考慮,只做出在某種意義上的區域性最優選擇。貪心演算法不是對所有問題都能得到整體最優解,但對許多問題它能產生整體最優解。如單源最短路徑問題,最小生成樹問題等。在一些情況下,即使貪心演算法不能得到整體最優解,其最終結果卻是最優解的...
五大常用演算法 貪心演算法
一 基本概念 所謂貪心演算法是指,在對問題求解時,總是做出在 當前看來是最好的選擇 也就是說,不從整體最優上加以考慮,他所做出的僅是在某種意義上的 區域性最優解 貪心演算法沒有固定的演算法框架,演算法設計的關鍵是貪心策略的選擇。必須注意的是,貪心演算法不是對所有問題都能得到整體最優解,選擇的貪心策略...
五大常用演算法 貪心演算法
貪心演算法是指 在每一步求解的步驟中,它要求 貪婪 的選擇最佳操作,並希望通過一系列的最優選擇,能夠產生乙個問題的 全域性的 最優解。貪心演算法每一步必須滿足一下條件 1 可行的 即它必須滿足問題的約束。2 區域性最優 他是當前步驟中所有可行選擇中最佳的區域性選擇。3 不可取消 即選擇一旦做出,在演...