貪婪演算法回顧

牛牛的程式設計之路發表於2019-05-29

回顧

還記的貪婪演算法麼? 如果你不記得了, 看了下面這個例子你一定會想起來, 因為這個例子太普遍了, 幾乎每個將貪婪演算法的地方, 第一個例子都是它, 言歸正傳.

問題: 現在有如下課程表, 要將這些課儘可能多的安排在教室A內.

課程名開始時間結束時間
語文課 9:00 10:00
數學課 9:30 10:30
音樂課 10:00 11:00
政治課 10:30 11:30
美術課 11:00 12:00

首先將所有課程都安排在教師A是不現實的, 因為時間上存在衝突. 那改怎麼安排呢?

這個問題很難, 對吧. 算了, 至少我第一次看的時候, 完全沒有頭緒. 但看了下面的思路, 你又會發現, 啊?這麼簡單麼?

具體思路

  1. 選出結束時間最早的課程, 將它加到教室A的第一節課

  2. 找出在當前教室A最後一節課的結束時間之後開始, 並且結束時間最早的課程, 將其加到教室A的課表中

  3. 重複步驟2

經過上面的步驟, 得出的課表為:

課程名開始時間結束時間
語文課 9:00 10:00
音樂課 10:00 11:00
美術課 11:00 12:00

如何, 是不是感覺這個演算法太簡單了, 簡單到我都不敢相信最終的結果是正確的.

但是這正是貪婪演算法的優點, 簡單, 容易實施.

貪婪演算法的思想就是(個人理解), 每一步都找到當前狀態的最優解, 繼續.

顯然,貪婪演算法並不總是能夠找到最優解

來了, 又來了, 又是一個被用爛了的例子, 但我就是要用, 哼.

問題: 現在有一個小偷, 帶著一個可以裝35kg重東西的包包, 他要將最貴重的東西帶走, 那麼, 貪婪演算法思路如下:

  1. 將可裝下的最貴的東西裝入揹包

  2. 重複步驟1

但是, 如果物品如下:

  1. 物品A: 價值300, 重量30kg

  2. 物品B: 價值200, 重量20kg

  3. 物品C: 價值150, 重量15kg

按照上面的思路, 裝入的內容為: 物品A, 總價值300

但是, 很顯然, 如果裝入的是: 物品B+物品C, 總價值350

這時, 貪婪演算法找出的就不是最優解了.

如果換一種思路呢?

  1. 將可裝下的最輕的東西裝入揹包

  2. 重複步驟2

你很驚喜的發現, 結果就是我們要的, 但是, 不好意思, 這只是這種情況下的滿足.

如果換一種情況呢? 如果物品A價值是500, 其它條件不變呢?

很顯然, 在這裡, 物品有價值和重量兩個值需要考量, 並不能夠單單拿出一個來進行判斷(之前的教室問題只需要考慮時間), 需要綜合考慮.

其實我個人覺得, 這個例子舉得並不恰當, 這種問題本就不適合使用貪婪演算法來進行求解. 但是到處都用這個例子, 那我就用吧, 因為我也想不出更好的例子了.......

最終的結果雖然不是最優解, 但是也比較接近了. 主要是演算法簡單啊

總結

貪婪演算法是不是感覺優點動態規劃的意思? 沒錯, 貪婪演算法可以說是動態規劃的一種特例,也就是說, 所有使用貪婪演算法能夠解決的問題都可以通過動態規劃來解決, 但是反過來並不成立.

其實, 貪婪演算法個人感覺並不能叫做貪婪演算法, 應該叫貪婪思想, 嘿嘿. 因為它並不是一個具體的演算法, 而是一種解決問題的思路:

每一步都尋找當前狀態的最有解(區域性最優解), 最終得到的就是由所有區域性最優解組成的全域性最優解, 或接近全域性最優解的解

有點只顧眼前利益, 不看長遠利益的感覺哈. 這種思路聽起來, 簡單、容易實現, 甚至簡單到讓人懷疑他的正確性, 你的懷疑是對的, 並不是每次區域性最優解的組合就是全域性最優解, 但他的優點就是簡單啊, 而且對於上面第一個例子中這樣的方法就很好的解決了.

最後, 貪婪演算法, 重點在於一個貪字, 哈哈, 請記住貪婪演算法的精髓就是

 

相關文章