問題表述:設有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
個活動的開始時間和結束時間按結束時間的非減序排列如下:
演算法greedyselector
的計算過程如下圖所示。圖中每行相應於演算法的一次迭代。陰影長條表示的活動是已選入集合
a的活動,而空白長條表示的活動是當前正在檢查相容性的活動。
若被檢查的活動i
的開始時間
si小於最近選擇的活動
j的結束時間
fi,則不選擇活動
i,否則選擇活動
i加入集合
a中。
貪心演算法並不總能求得問題的整體最優解。但對於活動安排問題,貪心演算法greedyselector
卻總能求得的整體最優解,即它最終所確定的相容活動集合
a的規模最大。這個結論可以用數學歸納法證明。
活動安排問題實現:
#include #include #include using namespace std ;
struct activitytime
activitytime ()
: m_nstart (0), m_nend (0)
friend
bool operator < (const activitytime& lth, const activitytime& rth)
public:
int m_nstart ;
int m_nend ;
} ;class activityarrange
// 活動安排
void greedyselector ()
}copy (m_bvselectflag.begin(), m_bvselectflag.end() ,ostream_iterator(cout, " "));
cout << endl ;
}private:
// 按照活動結束時間非遞減排序
void __sorttime ()
}private:
vectorm_vtimelist ; // 活動時間安排列表
vectorm_bvselectflag ;// 是否安排活動標誌
int m_ncount ; // 總活動個數
} ;int main()
貪心演算法之活動安排問題
問題描述 設有 n個活動的集合 e 其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有乙個活動能使用這一資源。每個活動 i都有乙個要求使用該資源的起始時間 si和乙個結束時間fi,且si fi。如果選擇了活動 i,則它在半開時間區間 si fi 內占用資源。若區間 si fi 與區間 ...
活動安排問題 貪心演算法
問題表述 設有n個活動的集合 e 其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有乙個活動能使用這一資源。每個活 i都有乙個要求使用該資源的起始時間 si和乙個結束時間 fi,且 si 如果選擇了活動 i,則它在半開時間區間 si,fi 內占用資源。若區間 si,fi 與區間 sj,...
活動安排問題(貪心演算法)
類似的問題是 選點問題和區間覆蓋問題。活動安排問題就是要在所給的活動集合中選出最大的相容活動子集合,是可以用貪心演算法有效求解的很好例子。該問題要求高效地安排一系列爭用某一公共資源的活動。貪心演算法提供了乙個簡單 漂亮的方法使得盡可能多的活動能相容地使用公共資源。設有n個活動的集合e 其中每個活動都...