活動安排問題與貪心算法

  • 貪心算法:

在求最優解問題的過程中,依據某種貪心標準,從問題的初始狀態出發,直接去求每一步的最優解,通過若干次的貪心選擇,最終得出整個問題的最優解,這種求解方法就是貪心算法

從貪心算法的定義可以看出,貪心算法不是從整體上考慮問題,它所做的選擇只是在某種意義上的局部最優解,而由問題自身的特性決定了該題運用貪心算法可以得到最優解。

如果一個問題同時可以用幾種問題解決,貪心算法應該是最好的選擇之一。

  • 活動安排問題:

該問題要求高效地安排一系列爭用某一公共資源的活動。即在所給的活動集合中選出最大的相容活動子集合。

設有n個活動的集合E={1,2,……,n},其中每個活動都要求使用同一資源,如演講會場等,而在同一時間內只有一個活動能使用這一資源。每個活動i都有一個要求使用該資源的起始時間si和一個結束時間fi,且si<fI。如果選擇了活動i,則在它的半開時間區間[si,fi)內佔用資源。若區間[si,fi)不相交,則稱活動i和活動j是相容的。當si>=fj或sj>=fi時,活動i和j相容。

活動安排問題就是在所給的活動集合中選出最大的相容活動子集合。

數據結構

struct action{
    int s;   //起始時間
    int f;   //結束時間
    int index;  //活動編號
};

活動的集合E記爲數組:

action a[1000];

按活動的結束時間升序排序:

排序比較因子:

bool cmp(const action &a,const action &b)
{
    if(a.f<=b.f)
        return true;
    return false;
}

使用標準模板庫函數排序 (下標0未用):

sort(a,a+n+1.cmp);

按結束時間排序後的第一個活動是必選的,因爲第一個活動選了之後,舞臺所剩餘的時間最多,這也就是貪心算法的基本準則。從結束時間開始找第一個未開始的活動。

代碼:

//形參數組b用來記錄被選中的活動
void GreedySelector(int action a[],bool b[])
{
    b[1]=true; //第一個活動是必選的
    //記錄最近一次加入到集合b中的活動
    int preEnd=1;
    for(int i=2;i<=n;i++)
    {
        if(a[i].s>=a[preEnd].f)
        {
            b[i]=trur;
            preEnd=i;
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章