1. 程式人生 > >貪心-活動安排問題

貪心-活動安排問題

顧名思義,貪心演算法總是做出當前看來最好的選擇。也就是說貪心演算法並不從整體最優考慮,它所做的選擇只是在某種意義上的區域性最優選擇。

當然,希望貪心演算法得到的最終結果也是整體最優解。

雖然貪心演算法不能對所有問題都得到整體最優解,但對許多問題它能產生整體最優解

在一些情況下,即使貪心演算法不能得到整體最優解,其最終結果卻是最優解的整體近似。

貪心演算法的一般框架:

GreedyAlgorithm(parameters)

{

初始化;

重複執行以下的操作: 

       選擇當前可以選擇的最優解;

       將當前所選擇的區域性最優解加入到問題的全域性解(區域性最優解是全域性解的一部分)中去;

直至滿足問題求解的結束條件。

}

活動安排問題

活動安排問題就是要在所給的活動集合中選出最大的相容活動子集合,是可以用貪心演算法有效求解的很好例子。

該問題要求高效地安排一系列爭用某一公共資源的活動

貪心演算法使得儘可能多的活動能相容(多個活動使用資源的時間不衝突)地使用公共資源。

設有n個活動的集合E={1,2,…,n},其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有一個活動能使用這一資源

每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi, si <fi

如果選擇了活動i,則它在[si, fi)內佔用資源。

[si, fi)[sj, fj)不相交,則稱活動ij相容的。即當si≥fjsj≥fi時,活動i與活動j相容。

活動安排問題就是求E的最大相容活動子集。

輸入:活動的數目n,各個活動的開始時間與結束時間

輸出:各個活動是否安排,安排的話輸出1,反之輸出0.

執行結果:

用陣列s,f,A分別存放所有活動的起始時間,結束時間以及是否予以安排的標記。

某項活動結束時間愈早,安排其他活動的剩餘區間愈大,所以貪心策略為儘量選擇結束時間早的活動來安排

為此,將陣列中的活動按結束時間的非減順序排序,即f1 <= f2 <= ... fn

顯然排序需要的時間為O(nlogn).

template <class Type>
void GreedySelector(int n, Type *s, Type *f, bool *A)
{
    int i, j;

    A[1] = true;
    j = 1;
    for(i = 2; i <= n; i++)
    {
        if(s[i] >= f[j])
        {
            A[i] = true;
            j = i;
        }
        else
            A[i] = false;
    }
}

由於輸入的活動以其完成時間的非減序排列,所以演算法greedySelector每次總是選擇具有最早完成時間的相容活動加入集合A中。

演算法貪心選擇的意義是使剩餘的可安排時間段極大化,以便安排儘可能多的相容活動。

當輸入的活動已按結束時間的非減序排列,演算法只需O(n)的時間安排n個活動,使最多的活動能相容地使用公共資源。

如果所給出的活動未按非減序排列,可以用O(nlogn)的時間重排。

若被檢查的活動i的開始時間si小於最近選擇的活動j的結束時間fi,則不選擇活動i,否則選擇活動i加入集合A中。

貪心演算法並不總能求得問題的整體最優解。但對於活動安排問題,greedySelector卻總能求得的整體最優解,即它最終所確定的相容活動集合A的規模最大。這個結論可以用數學歸納法證明。

貪心演算法也能獲得最優解:

n設活動集合E={1, 2, …, n}已經按結束時間的非減順序排列,活動1具有最早結束時間。

n首先,必定有一個最優解包含活動1

不然設AÍE最優解且A中最早結束的活動是k。若k = 1,則最優解包含活動1。若k1則活動1必與A中除k以外的活動相容。令B=A–{k})∪{1},則B也是一個最優解。

n其次,若A是原問題的包含活動1的最優解,則A¢=A – {1}是活動集合E¢={i∈Esi≥f1}的一個最優解。

不然設B¢E¢的解且|B¢||A¢|,則B¢∪{1}E的解且|B¢| + 1|A|。此與A是最優解矛盾。

n對貪心選擇次數用數學歸納法即知,貪心演算法最終產生原問題的最優解。

貪心演算法的基本要素:

從許多用貪心演算法求解的問題中看到,這類問題一般具有2個重要性質:貪心選擇性質最優子結構性質

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

動態規劃演算法通常以自底向上的方式解各子問題

貪心演算法則通常以自頂向下的方式進行,以迭代方式作出相繼的貪心選擇,每作一次貪心選擇就將所求問題簡化為規模更小的子問題

對具體問題,要確定它是否具有貪心選擇性質,必須證明每一步所作的貪心選擇最終導致問題的整體最優解

當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質

問題的最優子結構性質是該問題可用動態規劃演算法或貪心演算法求解的關鍵特徵.

結論:

1.問題能用動態規劃法解的不一定能用貪心演算法解;

2.反之能用貪心法一定能用動態規劃法,但是,貪心演算法的效率一般高於動態規劃法,因而還是應用貪心演算法。