一、問題描述
有乙個n個活動的集合s=,這些活動使用同乙個資源,而這個資源在某個時刻只能供乙個活動使用。每個活動ai都有乙個開始時間si和乙個結束時間fi,其中0≤si<fi<∞。如果被選中,任務ai佔據半開區間時間
[si, fi)。如果兩個活動[)和[)不重疊,則稱它們是相容的。該問題就是要找出最大相容子集。例如下表所示的活動集合s,其中各項活動按照結束時間的單調遞增順序排序:
二、動態規劃解決過程
(1)活動選擇問題的最優子結構
定義sij是s的子集,其中每個活動都是在ai結束之後開始,且在aj開始之前結束。sij= (當i≥j時,sij為空集)
最優子結構為:假設sij的最優解aij包含活動ak,則對sik的解aik和skj的解akj必定是最優的。
通過乙個活動ak將問題分成兩個子問題,下面的公式可以計算出sij的解aij。
aij=aik∪∪akj
(2)乙個遞迴解:
設c[i][j]為sij中最大相容子集中的活動數目,當sij為空集時,c[i][j]=0;當sij非空時,若ak在sij的最大相容子集中被使用,則子問題sik和skj的最大相容子集也被使用,故可得到c[i][j] = c[i][k]+c[k][j]+1。
c[i][j]的完整計算公式如下:
(3)c語言實現
/*
動態規劃求解過程:採用自底向下的策略進行計算c[i][j],引入複雜陣列ret[n][n]儲存中間劃分的k值
設c[i][j]為sij中最大相容子集中的活動數目,當sij為空集時,c[i][j]=0;
當sij非空時,若ak在sij的最大相容子集中被使用,則子問題sik和skj的最大相容子集也被使用,
故可得到c[i][j] = c[i][k]+c[k][j]+1。
*/void dynamic_activity_selector(int *s, int *f, int num, int **c, int **ret)
//當ifor (j = 2; j <= num; j++)}}}}}
三、貪心演算法解決過程針對活動選擇問題,認真分析可以得出以下定理:對於任意非空子問題sij,設am是sij中具有最早結束時間的活動,那麼:
(1)活動am在sij中的某最大相容活動子集中被使用。
(2)子問題sim為空,所以選擇am將使子問題smj為唯一可能非空的子問題。
有這個定理,就簡化了問題,使得最優解中只使用乙個子問題,在解決子問題sij時,在sij中選擇最早結束時間的那個活動。
貪心演算法自頂向下地解決每個問題,解決子問題sij,先找到sij中最早結束的活動am,然後將am新增到最優解活動集合中,再來解決子問題smj。
基於這種思想可以採用遞迴和迭代進行實現。
遞迴實現過程如下所示:
void recursive_activity_selector(int *s, int* f, int k, int n, int *set)
}
迭代實現過程如下:
/*
迭代貪心演算法
*/void greedy_activity_selector(int *s, int *f, int num, int *set)}}
測試**如下:
int main()
; int f[length] = ;
intset[length] = ;
for (int i = 0; i < length; i++)
greedy_activity_selector(s, f, length - 1, set);
for (int i = 0; i < length; i++)
printf("\n");
return
0;}
四、總結四、總結
活動選擇問題分別採用動態規劃和貪心演算法進行分析並實現。動態規劃的執行時間為o(n^3),貪心演算法的執行時間為o(n)。動態規劃解決問題時全域性最優解中一定包含某個區域性最優解,但不一定包含前乙個區域性最優解,因此需要記錄之前的所有最優解。貪心演算法的主要思想就是對問題求解時,總是做出在當前看來是最好的選擇,產生乙個區域性最優解。
貪心演算法 活動選擇問題
活動選擇問題 就是給定一組活動的開始時間和結束時間,然後他們都需要使用到乙個資源,這個資源每次只有乙個活動可以用,要求求出乙個最大的相互相容的活動子集。首先定義了乙個集合sij 其中s就是所有活動的集合,fi是活動ai的完成時間si是活動ai的開始時間。這道題如果是用dp來解的話,就需要找到最優解的...
貪心演算法 活動選擇問題
前言 貪心演算法也是用來解決最優化問題,將乙個問題分成子問題,在現在子問題最優解的時,選擇當前看起來是最優的解,期望通過所做的區域性最優選擇來產生乙個全域性最優解。書中先從活動選擇問題來引入貪心演算法,分別採用動態規劃方法和貪心演算法進行分析。本篇筆記給出活動選擇問題的詳細分析過程,並給出詳細的實現...
貪心演算法 活動選擇問題
需要閱讀這篇 的同學應該都知道貪心演算法的定義吧,所以這裡就不贅述什麼叫貪心演算法了。如果確實不知道什麼是貪心演算法,可以去看一下 演算法導論 問度娘也是挺好的。下面簡述一下活動選擇問題 你是乙個場地管理員,你收到的很多的活動申請,每個活動的開始時間和結束時間會有交錯,也就是說有些活動不能同時舉辦,...