問題表述:
設有n個活動的集合
e = ,其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有乙個活動能使用這一資源。每個活
i都有乙個要求使用該資源的起始時間
si和乙個結束時間
fi,且
si 。如果選擇了活動
i,則它在半開時間區間
[si, fi)
內占用資源。若區間
[si, fi)
與區間[sj, fj)
不相交,則稱活動
i與活動
j是相容的。也就是說,當
si >= fj
或sj >= fi
時,活動
i與活動
j相容。
由於輸入的活動以其完成時間的非減序排列,所以演算法greedyselector
每次總是選擇具有最早完成時間的相容活動加入集合
a中。直觀上,按這種方法選擇相容活動為未安排活動留下盡可能多的時間。也就是說,該演算法的貪心選擇的意義是使剩餘的可安排時間段極大化,以便安排盡可能多的相容活動。
演算法greedyselector
的效率極高。當輸入的活動已按結束時間的非減序排列,演算法只需
o(n)
的時間安排
n個活動,使最多的活動能相容地使用公共資源。如果所給出的活動未按非減序排列,可以用
o(nlogn)
的時間重排。
例:設待安排的11
個活動的開始時間和結束時間按結束時間的非減序排列如下:
若被檢查的活動i
的開始時間
si小於最近選擇的活動
j的結束時間
fi,則不選擇活動
i,否則選擇活動
i加入集合
a中。
貪心演算法並不總能求得問題的整體最優解。但對於活動安排問題,貪心演算法卻總能求得的整體最優解,即它最終所確定的相容活動集合
a的規模最大。這個結論可以用數學歸納法證明。
**如下:
#include #include using namespace std;
ifstream fin("in.txt");
struct activity
;void sort(activity *a,int n)
a[j+1]=t; }}
int main()
{ int n;
fin>>n;
activity *a = (activity *)malloc(sizeof(activity)*n);
for(int i=0;i>a[i].start>>a[i].finish;
sort(a,n);
int *t=(int *)malloc(sizeof(int)*n);
memset(t,0,sizeof(int)*n);
t[0]=0;
int j=0;
for(i=1;i"
輸入檔案: in.txt
112 13
5 78 11
3 85 9
12 14
1 48 12
3 50 6
6 10
12 14
輸出結果:
1 - <3,5>
2 - <0,6>
3 - <5,7>
4 - <3,8>
5 - <5,9>
6 - <6,10>
7 - <8,11>
8 - <8,12>
9 - <2,13>
10 - <12,14>
0: <1,4>
3: <5,7>
7: <8,11>
10: <12,14>
press any key to continue
活動安排問題(貪心演算法)
類似的問題是 選點問題和區間覆蓋問題。活動安排問題就是要在所給的活動集合中選出最大的相容活動子集合,是可以用貪心演算法有效求解的很好例子。該問題要求高效地安排一系列爭用某一公共資源的活動。貪心演算法提供了乙個簡單 漂亮的方法使得盡可能多的活動能相容地使用公共資源。設有n個活動的集合e 其中每個活動都...
活動安排問題 貪心演算法
活動安排問題就是要在所給的活動集合中選出最大的相容活動子集合,是可以用貪心演算法有效求解的很好例子。該問題要求高效地安排一系列爭用某一公共資源的活動。貪心演算法提供了乙個簡單 漂亮的方法使得盡可能多的活動能相容地使用公共資源。設有n個活動的集合e 其中每個活動都要求使用同一資源,如演講會場等,而在同...
貪心演算法 活動安排問題
貪心演算法 活動安排問題 具體求解思路 首先將活動按照結束時間從小到大排序,然後將starttime i 大於finishtime i 1 的活動安排進去,由於活動結束時間是事前排好序的 具體排序方法可以看我之前的部落格 所以按照此方法,安排的活動相對於來說總是先結束的,這樣來說就可以盡量最大化的利...