1. 程式人生 > >貪心(一)——活動安排問題

貪心(一)——活動安排問題

時間 mst font 行高 規模 ont str ron 不變

  求最優解的問題可看作是通過一系列步驟,每一步有一選擇的集合,對於較簡單的問題,動態規劃顯得過於復雜,可用較簡單有效的算法求解之,如貪心。貪心算法總是在當前步驟上選取最好的方案,即它是一種局部最優的選擇,並希望它導致一個全局最優(但有時是不可能導致全局最優,例如,求v到w的一條最短路徑,若從v搜索到鄰點t最短,未必是v到w最短)。但是,仍有許多問題貪心法將產生全局最優解,如MST,單源最短路徑等。

貪心算法的思想

  貪心算法的基本思路是從問題的某一個初始解出發一步一步地進行,根據某個優化測度,每一步都要確保能獲得局部最優解。

  每一步只考慮一個數據,他的選取應該滿足局部優化的條件。

  若下一個數據和部分最優解連在一起不再是可行解時,就不把該數據添加到部分解中,直到把所有數據枚舉完,或者不能再添加算法停止。

活動安排問題

  活動安排問題是用貪心算法有效求解的一個典型的例子,進行高效地安排一系列爭用某一公共資源的活動。

  設待安排的11個活動的開始與結束時間按結束時間增序排列如下:

  技術分享圖片

  問題的解:A1={a3,a9,a11},A2={a1,a4, a8,a11},A3={a2,a4,a9,a11}

  最優解: A2 和 A3

  此問題可用叠代方法直接給出貪心算法,但為比較和動態規劃之關系,下面先考慮動態規劃解法

活動選擇問題的最優子結構(貪心算法的要素一
)

  子問題空間可描述為:技術分享圖片

  Sij 是 S 的子集,它包含那些 (在 ai 完成後開始)&&(在 aj 開始前完成) 的活動 ak

  亦即:Sij中所有活動ak與活動 ai、aj 相容,不妨稱 ai、aj 和子集 Sij 相容,因此 ak 也與所有不遲於 fi 完成的活動以及與所有不早於 sj 開始的活動相容。(Sij中可能有沖突的活動)

  為方便處理,設有兩個虛擬的活動 a0an+1,並且假定技術分享圖片,因此,技術分享圖片

  為了更嚴格定義 i 和 j 的範圍,假定所有活動已按完成時間的單調增有序:技術分享圖片

  分解問題:

  設子問題 技術分享圖片。若 Sij 的解中選擇了ak

,使用 ak 產生 Sij 的兩個子問題 Sik 和 Skj

  Sik是包括在 ai 完成之後開始,在 ak 開始之前完成的那些活動;Skj 包括在 ak 完成之後開始,在 aj 開始之前完成的那些活動。兩者均是 Sij 的子集,這兩子集與 ak 相容。

  Sij 的解顯然是 Sik 和 Skj 解的並,再加上ak (Sik和Skj已去掉了那些與ak沖突的活動,而這些活動原來可能在Sij中)

  最優子結構:

  當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。運用貪心策略在每一次轉化時都取得了最優解。問題的最優子結構性質是該問題可用貪心算法或動態規劃算法求解的關鍵特征。貪心算法的每一次操作都對結果產生直接影響,而動態規劃則不是。貪心算法對每個子問題的解決方案都做出選擇,不能回退;動態規劃則會根據以前的選擇結果對當前進行選擇,有回退功能。動態規劃主要運用於二維或三維問題,而貪心一般是一維問題。

  設 Sij 的最優解是 Aijak∈Aij,則兩子問題的解 Aik 和 Akj 也必須是最優的(反證法易證)

  用問題的最優子結構構造原問題的最優解:把子問題的解、局部最優解合成原來解問題的一個解。

  技術分享圖片

一個遞歸解

  設C[i,j] 表示 Sij 的最優解的值,即 Sij 中相容活動最大子集的 size:C[i,j] = |Aij|

  技術分享圖片

動態規劃到貪心法的轉化

  到了這裏,就可以用動態規劃進行求解。

  當然,可以通過下面的定理化簡其解,同時也可以說明貪心算法的正確性。

  定理:設 Sij 是任一非空子問題,am 是 Sij 中具有最早完成時間的活動:fm = min{ fk: ak∈Sij} ,則:

    ①活動 am 必定被包含在 Sij 的某個最優解中;

    ②子問題 Sim 是空集,使Smj 是唯一可能的非空集。 ?am的目的

  在動態規劃求解時,原問題Sij 分解為兩個子問題Sik 和 Skj 求解,且這種分解有 j-i-1 種可能。

  該定理將其簡化為:

    ①求Sij 的最優解時只用到一個子問題,另一個子問題為空;

    ②只須考慮一種選擇:即選Sij中最早完成的活動。

  該定理帶來的另一個好處是:能以自頂向下的方式解每一個子問題:

  技術分享圖片

貪心選擇:

  貪心選擇是指所求問題的整體最優解可以通過一系列局部最優的選擇,即貪心選擇來達到。這是貪心算法可行的又一個基本要素,也是貪心算法與動態規劃算法的主要區別。

  貪心選擇是采用從頂向下、以叠代的方法做出相繼選擇,每做一次貪心選擇就將所求問題簡化為一個規模更小的子問題對於一個具體問題,要確定它是否具有貪心選擇的性質,我們必須證明每一步所作的貪心選擇最終能得到問題的最優解。通常可以首先證明問題的一個整體最優解,是從貪心選擇開始的,而且作了貪心選擇後,原問題簡化為一個規模更小的類似子問題。然後,用數學歸納法證明,通過每一步貪心選擇,最終可得到問題的一個整體最優解。

  當某個 ami 加入解集合後,我們總是在剩余的活動中選擇第一個不與 ami 沖突的活動加入解集合,該活動是能夠最早完成且與 ami 相容。這種選擇為剩余活動的調度留下了盡可能多的機會。即留出盡可能多的時間給剩余的尚未調度的活動,以使解集合中包含的活動最多。每次選一個最早完成並與剛加入解集元素相容的活動。

遞歸的貪心算法

  輸入:向量 s f ,並假定已按 f 單調增有序、子問題 Sij 的下標。
  輸出:Sij 的最優解。
  算法:

  技術分享圖片

叠代的貪心算法

  上述遞歸很接近於尾遞歸,只是結束前多了一個Union操作,易轉換為叠代算法:

    ① j 始終不變,j = n+1。

    ②當一個活動 ai 加入解集合之後,我們只要從 ai 依次往後找到第一個不與 ai 沖突的活動 am,由於活動事先按完成時間單調增有序,故 am 是最早完成且與 ai 相容的活動,它也是 Sij 中的第一個活動。

  技術分享圖片

貪心(一)——活動安排問題