貪心演算法 活動選擇問題

2021-06-28 07:33:44 字數 3048 閱讀 7640

前言:貪心演算法也是用來解決最優化問題,將乙個問題分成子問題,在現在子問題最優解的時,選擇當前看起來是最優的解,期望通過所做的區域性最優選擇來產生乙個全域性最優解。書中先從活動選擇問題來引入貪心演算法,分別採用動態規劃方法和貪心演算法進行分析。本篇筆記給出活動選擇問題的詳細分析過程,並給出詳細的實現**進行測試驗證。關於貪心演算法的詳細分析過程,下次在討論。

1、活動選擇問題描述

有乙個需要使用每個資源的n個活動組成的集合s= ,資源每次只能由乙個活動使用。每個活動ai都有乙個開始時間si和結束時間fi,且 0≤si

i從圖中可以看出s中共有11個活動,最大的相互相容的活動子集為:和。

2、貪心演算法解決過程

(1)活動選擇問題的最優子結構

定義子問題解空間sij是s的子集,其中的每個獲得都是互相相容的。即每個活動都是在ai結束之後開始,且在aj開始之前結束。

為了方便討論和後面的計算,新增兩個虛構活動a0

,其中f0=0。

結論:當i≥j時,sij為空集。

如果活動按照結束時間單調遞增排序,子問題空間被用來從sij中選擇最大相容活動子集,其中0≤i<j≤n,所以其他的sij都是空集。

最優子結構為:假設sij的最優解aij包含活動ak,則對sik的解aik和skj的解akj必定是最優的。

通過乙個活動ak將問題分成兩個子問題,下面的公式可以計算出sij的解aij。

設c[i][j]為sij中最大相容子集中的活動數目,當sij為空集時,c[i][j]=0;當sij非空時,若ak在sij的最大相容子集中被使用,則則問題sik和skj的最大相容子集也被使用,故可得到c[i][j] = c[i][k]+c[k][j]+1。

當i≥j時,sij必定為空集,否則sij則需要根據上面提供的公式進行計算,如果找到乙個ak,則sij非空(此時滿足fi≤sk且fk≤sj),找不到這樣的ak,則sij為空集。

c[i][j]的完整計算公式如下所示:

(2)貪心選擇

直觀上,我們應該選擇這樣乙個活動,選出它剩下的資源應能被盡量多的其他任務所用。我們優先選擇最早結束的活動,因為它剩下的資源應能被盡量多的其他任務所用。換句話說,由於活動已經按結束時間單調遞增的順序排序,貪心選擇就是活動1,選擇最早結束的活動並不是本問題的唯一的貪心選擇方法。下面列出選擇最早結束的活動的兩種演算法。

(3)遞迴貪心演算法

假定輸入活動已按活動結束時間單調遞增順序排好序:

int recursive_activity_selector(int s[n+1],int f[n+1],int k,vector& a)

} else

return 0;

}

(4)迭代貪心演算法根據遞迴貪心演算法我們很容易將演算法轉化為迭代形式,過程greed_activity_selector是recursive_activity_selector的乙個迭代版本,假定輸入活動已按活動結束時間單調遞增順序排好序,演算法如下:

void greed_activity_selector(int s[n+1],int f[n+1],vector& a)

}}

2.貪心選擇的重要性
對於活動能夠選擇問題,並不是所有的貪心方法都能得到最大相容活動子集,例如:在剩餘相容活動中選擇持續時間最短者不能得到最大的相容集,類似的選擇最早開始的活動也不能得到最大相容集。下面我們程式設計實現這兩種貪心方法,需要注意的是:選擇結束最早的活動時,是按活動結束時間單調遞增順序排好序;那麼選擇持續時間最短時,就按活動持續時間單調遞增順序排好序;同理,選擇最早開始時,就按活動開始時間單調遞增順序排好序,程式設計實現時我們利用結構體t記錄持續時間以及活動編號,根據持續時間進行排序;利用另乙個結構體t1記錄開始時間以及活動編號,根據開始時間進行排序;之後改進greed_activity_selector演算法即可,兩個結構體組成如下
struct t

; int f[n+1]=;

vectora,a1,a2,a3;

recursive_activity_selector(s,f,0,a);

cout<

} else

return 0;}/*

選擇最早結束的活動---迭代貪心

*/void greed_activity_selector(int s[n+1],int f[n+1],vector& a) }}

/* 選擇持續最短的活動---迭代貪心

*/bool lessmark(const t &a,const t &b) }

for (int i=0;i& a) }

for (int i=0;i結果為:

**中,flag指的是活動代號,last指活動持續時間,start指的是活動開始時間,第乙個元素是我們為了方便引入的活動0,沒有實際意義。從**結果可以看出:選擇活動結束最早獲得的最大活動相容集為<1,4,8,11>,共4個活動;選擇活動持續時間最短獲得的最大活動相容集為<2,4,8,11>,共4個活動;選擇活動開始最早獲得的最大活動相容集為<3,7,11>,共3個活動;好像活動持續時間最短也可以獲得最大活動相容集,但是仔細一看知道這種貪心選擇不穩定,如下圖:

活動持續時間最短長短排序時,活動2和4持續時間一樣,如果任意選擇2和4作為第乙個元素,就會出現兩種不同的結果,所以選擇活動持續時間最短者並不是能夠獲得最大相容活動子集的貪心選擇。

那麼選擇最早結束活動也會不會出現相似的問題,結果總是最優解的一部分嗎?

由此我們可以知道選擇最早結束活動可以穩定獲得最大相容活動集.

貪心演算法 活動選擇問題

活動選擇問題 就是給定一組活動的開始時間和結束時間,然後他們都需要使用到乙個資源,這個資源每次只有乙個活動可以用,要求求出乙個最大的相互相容的活動子集。首先定義了乙個集合sij 其中s就是所有活動的集合,fi是活動ai的完成時間si是活動ai的開始時間。這道題如果是用dp來解的話,就需要找到最優解的...

貪心演算法 活動選擇問題

需要閱讀這篇 的同學應該都知道貪心演算法的定義吧,所以這裡就不贅述什麼叫貪心演算法了。如果確實不知道什麼是貪心演算法,可以去看一下 演算法導論 問度娘也是挺好的。下面簡述一下活動選擇問題 你是乙個場地管理員,你收到的很多的活動申請,每個活動的開始時間和結束時間會有交錯,也就是說有些活動不能同時舉辦,...

貪心演算法 活動選擇問題

前言 貪心演算法也是用來解決最優化問題,將乙個問題分成子問題,在現在子問題最優解的時,選擇當前看起來是最優的解,期望通過所做的區域性最優選擇來產生乙個全域性最優解。書中先從活動選擇問題來引入貪心演算法,分別採用動態規劃方法和貪心演算法進行分析。本篇筆記給出活動選擇問題的詳細分析過程,並給出詳細的實現...