貪心算法

一. 貪心算法定義

假設一個問題比較複雜,暫時找不到全局最優解,那麼咱們能夠考慮把原問題拆成幾個小問題,分別求每一個小問題的最優解,再把這些「局部最優解」疊起來,就「看成」整個問題的最優解了。java

1.1 怎麼理解貪心

在每一步中,選擇當前最優而不是全局最優,這就是貪心。算法

1.2 貪心思想和分治思想的區別

貪心和分治都是將問題進行拆分來下降求解的複雜度,不一樣的是,分治保證每一個任務相對獨立,不考慮最不最優問題; 而貪心子任務間每每存在關聯關係,每次取捨之間都選擇當前最優。markdown

二. 貪心算法關鍵步驟

如何知道一個問題是否能夠用貪心算法解決呢,分析問題和用貪心解決問題均可以參考一下步驟:cookie

  • 分析問題的最優解
  • 分析子問題的最優解
  • 分析子問題是否可疊加當成問題最優解

三. 經典應用-餅乾問題

3.1 問題描述

每一個孩子最多隻能給一塊餅乾,對每一個孩子 i,都有一個胃口值 g[i],這是能讓孩子們知足胃口的餅乾的最小尺寸;而且每塊餅乾 j,都有一個尺寸 s[j] 。若是 s[j] >= g[i],咱們能夠將這個餅乾 j 分配給孩子 i ,這個孩子會獲得知足。你的目標是儘量知足越多數量的孩子,並輸出這個最大數值。leetcode傳送門oop

3.2 根據貪心算法步驟拆解

  • 分析問題最優解

顯而易見,知足最多數量的孩子spa

  • 分析子問題的最優解

對於每一個孩子,應該選擇能夠知足這個孩子的胃口且尺寸最小的餅乾code

  • 分析子問題是否可疊加當成問題最優解

從貪心的角度考慮,應該按照孩子的胃口從小到大的順序依次知足每一個孩子orm

3.3 推導公式

假設有 m 個孩子,胃口值分別是 g1 到 gm,有 n 塊餅乾,尺寸分別是 s1 到 sn 咱們將兩個數列由小到大排序,知足gi <= gi+1 和 sj <= sj+1排序

能夠知足第 i 個孩子的胃口的最小的餅乾是第 j 塊餅乾,即 sj是剩下的餅乾中知足 sj >= gi的最小值, 最優解是將第 j 塊餅乾分配給第 i 個孩子leetcode

3.4 代碼實現

public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int numOfChildren = g.length, numOfCookies = s.length;
        int count = 0;
        for (int i = 0, j = 0; i < numOfChildren && j < numOfCookies; i++, j++) {
            while (j < numOfCookies && g[i] > s[j]) {
                j++;
            }
            if (j < numOfCookies) {
                count++;
            }
        }
        return count;
    }
複製代碼

四. 貪心算法可能存在的問題

4.1 「全局最優」和「局部最優」

平常生活中不少狀況,全局最優和局部最優有很大的區別,盲目追求全局最優有可能和預期結果截然不同。

  • 岔路問題

看上去短的路可能岔路多,每次選則最短的路可能會繞一圈

image.png

  • 雪球問題

看上去雪多的路可能路比較短,不如雪粘、路途長的路積累的雪球大

image.png

  • 打車軟件離我最近

每次都是離乘客最近的車接單,那麼有些地方的乘客可能永遠打不到車

image.png

4.2 貪心算法存在的意義

既然貪心算法不能保證全局最優,咱們爲何還要須要它呢?

  • 當問題規模很大時,在合理的時間內找到全局最優幾乎不可能,這時候咱們每每會傾向於接受局部最優解,由於局部最優解的質量不必定都是差的。
  • 在工程應用領域,有時最優解與局優解的精度相差很小,但爲了搜索到全局最優解卻須要耗費更長的時間,在權衡計算精度以及時間成本後,決策者每每也能接受局部最優解。

五. 貪心算法應用場景

  • 根據前面的描述,咱們能夠知道貪心算法雖然不全局最優,但若是能保證局部最優極大程度趨近於全局最優,那咱們也可使用貪心算法。
  • 若是能夠證實決策既不受以前決策的影響,也不影響後續決策,則貪心算法就是肯定的最優解算法。除此以外都不能夠保證貪心算法是最優的。

好在前人的經驗總結了一些條件能夠參考:

  • 問題有限制值和指望值
  • 問題能夠經過貪心步驟拆分
  • 求全局最優解的數學模型難以創建或計算量過大
  • 沒有太大必要必定要求出全局最優解,「比較優」就能夠

常見場景有:揹包問題、分糖果、找零錢、區間覆蓋等

六. 貪心算法的優缺點

其實在前文中已經都提到了,這裏再總結一下。

  • 優勢:思路簡單、易於實現、處理高效、權衡了最佳解決方案和複雜度。
  • 缺點:須要甄別問題場景,對於局部最優和全局最優差別較大的,不能使用。

七. 如何證實貪心算法能夠趨近最優解

證實一個場景能夠知足「局部最優極大程度趨近於全局最優」每每難於使用貪心求解。
通常來講若是一個問題能夠轉化爲擬陣,那就能夠貪心求解。但不是全部能夠貪心求解的問題都能轉化成擬陣。 擬陣的推導涉及一些數學知識,有興趣能夠看看。擬陣與最優問題

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息