對動態規劃和貪心演算法的一點理解

2021-04-13 08:17:09 字數 1935 閱讀 5567

一直很模糊的感覺這兩個重要的演算法應該有些聯絡。首先都是求解最優問題的很有效的方法,其次都有明顯的最優判定:通過對某些值的max和min 運算來決定下一步的步驟。具體的異同自己就說不清楚了,關鍵是對動態規劃演算法本身也不是特別理解。今天看了一下mit的演算法導論的相關章節,算是有了個大 概認識。

(題外話:演算法導論看得不多,但只就這兩章而言,可以看出這本教材和國內的演算法教材大不一樣。國內的教材很多都直接的「由易而難」先介紹貪心然 後介紹動態規劃,感覺似乎有很重的「競賽」氣息。而演算法導論是先介紹動態規劃,再介紹貪心,從學術的角度考慮,動態規劃是基礎而貪心是特例,這麼說來,似 乎國內的教材過於功利化,而缺少純理論上的培養價值。)

求最優解的問題,從根本上說是一種對解空間的遍歷。最直接的暴力分析容易得到,最優解的解空間通常都是以指數階增長,因此暴力窮舉都是不可行的。

最優解問題大部分都可以拆分成乙個個的子問題,把解空間的遍歷視作對子問題樹的遍歷,則以某種形式對樹整個的遍歷一遍就可以求出最優解,如上面的分析,這是不可行的。

貪心和動態規劃本質上是對子問題樹的一種修剪。兩種演算法要求問題都具有的乙個性質就是「子問題最優性」。即,組成最優解的每乙個子問題的解,對 於這個子問題本身肯定也是最優的。如果以自頂向下的方向看問題樹(原問題作根),則,我們每次只需要向下遍歷代表最優解的子樹就可以保證會得到整體的最優 解。形象一點說,可以簡單的用乙個值(最優值)代表整個子樹,而不用去求出這個子樹所可能代表的所有值。

動態規劃方法代表了這一類問題的一般解法。我們自底向上(從葉子向根)構造子問題的解,對每乙個子樹的根,求出下面每乙個葉子的值,並且以其中 的最優值作為自身的值,其它的值捨棄。動態規劃的代價就取決於可選擇的數目(樹的叉數)和子問題的的數目(樹的節點數,或者是樹的高度?)。

貪心演算法是動態規劃方法的乙個特例。貪心特在,可以證明,每乙個子樹的根的值不取決於下面葉子的值,而只取決於當前問題的狀況。換句話說,不需 要知道乙個節點所有子樹的情況,就可以求出這個節點的值。通常這個值都是對於當前的問題情況下,顯而易見的「最優」情況。因此用「貪心」來描述這個演算法的 本質。由於貪心演算法的這個特性,它對解空間樹的遍歷不需要自底向上,而只需要自根開始,選擇最優的路,一直走到底就可以了。這樣,與動態規劃相比,它的代 價只取決於子問題的數目,而選擇數目總為1。

以揹包問題為例。貪心演算法的思路是,直接選擇當前**/重量比最大的物品放入揹包,力圖保持揹包內的物品的總的**/重量比總是最大的,以得到 最優的值。動態規劃的思路是,對於每一種物品,都要考慮「放它」和「不放它」兩種情況,並取最優的一種作為解。動態規劃對解空間的遍歷要比貪心完全。

顯然,如果能保證揹包總是滿的,則貪心演算法是正確的。但0-1揹包問題不能保證揹包總是滿的,這樣就降低了整體揹包的**/重量比。這種情況,就只能用動態規劃來解。

感覺揹包問題似乎是個特例,問題當前的狀況(剩餘的物品)就可以決定當前的選擇,但其它的限制(揹包的總重量)使得貪心是錯誤的。

其餘的問題,如矩陣連乘,子串匹配等,則顯然不具備貪心的要求,只能用動態規劃來解。

http://www.answers.com,集合了非常棒的定義、資料,下面的文字出自這個**。

揹包問題的動態規劃解法是乙個「偽多項式階」演算法。如果總重量的整數值c作為規模,它是多項式階的(o(nc))。而如果用c的二進位制位數作為 規模,則它是指數階的。因此,最優形式解形式(optimization)的揹包問題仍是乙個np完全問題,但它有偽多項式階的解。

關於「偽多項式階」,有乙個形象的例子:求整數n的因數。顯然至多只要從2~n-1挨個除一遍就可以得到所有的因數,似乎這是o(n)階的,但其實若從n的位數來考慮,它就成為了指數階而變得不可求解。這恰巧就是現在網路加密演算法的基礎。

而揹包問題的判定形式(decision)則是真正的np完全問題:

對於一組物品,給定價值和重量,在滿足重量限制的前提下,能否選出物品的一組子集,使得總價值恰好等於某乙個給定值c。

這又被稱為「子集和(subset sum)」問題。

http://www.answers.com/topic/knapsack-problem,以防我理解有誤。

關於動態規劃與貪心演算法的一點理解

關於動態規劃演算法的應用,是有迭代的,而且不能有後效性,即後面的狀態不能影響到當前。例子 關於應用動態規劃演算法的乙個例子,就是何時 問題利潤最大化問題 每走一步都記錄出現的最小值,並檢查下利潤否大於當前的最優值 關於貪心演算法的應用,當單個子問題就可以決定父問題,可以用貪心法 例子 最長無重複子串...

動態規劃和貪心演算法

動態規劃 通過組合子問題的解來求解原問題,常用來求解最優化問題。常用來解決以下幾類問題,但不是說遇到類似問題必須用動態規劃來解決,可以往這方面去想 1.計數問題,如有多少種方式走到右下角,有多少種方法選出k個數使得和是sum 2.求最大最小值,如從左上角走到右下角路徑的最大數字和 3.求存在性,如取...

貪心演算法和動態規劃

貪心演算法 在求解問題時,總是做出在當前看來做好的選擇,所以它是區域性最優解,試圖通過區域性最優推出全域性最優。需要注意的是貪心演算法沒有固定的演算法框架,演算法設計的關鍵是選擇貪心策略,其必須具備無後效性,即某個狀態以後的過程不會影響以前的狀態,只與當前狀態有關。常見的用貪心演算法解決的問題,比如...