贪心算法之活动安排问题

来源:互联网 发布:mac版本老装不了xcode 编辑:程序博客网 时间:2024/06/07 07:55

问题表述:设有n个活动的集合E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活i都有一个要求使用该资源的起始时间si和一个结束时间fi,si < fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当si >= fjsj >= fi时,活动i与活动j相容。

由于输入的活动以其完成时间的非减序排列,所以算法greedySelector每次总是选择具有最早完成时间的相容活动加入集合A中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也就是说,该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。

算法greedySelector的效率极高。当输入的活动已按结束时间的非减序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。如果所给出的活动未按非减序排列,可以用O(nlogn)的时间重排。

例:设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:


算法greedySelector 的计算过程如下图所示。图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条表示的活动是当前正在检查相容性的活动。


若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。 

贪心算法并不总能求得问题的整体最优解。但对于活动安排问题,贪心算法greedySelector却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。

活动安排问题实现:

#include <iostream>#include <vector>#include <algorithm>using namespace std ;struct ActivityTime{public:    ActivityTime (int nStart, int nEnd)         : m_nStart (nStart), m_nEnd (nEnd)     { }    ActivityTime ()        : m_nStart (0), m_nEnd (0)    { }    friend     bool operator < (const ActivityTime& lth, const ActivityTime& rth)     {        return lth.m_nEnd < lth.m_nEnd ;    }public:    int m_nStart ;    int m_nEnd ;} ;class ActivityArrange {public:    ActivityArrange (const vector<ActivityTime>& vTimeList)     {        m_vTimeList = vTimeList ;        m_nCount = vTimeList.size () ;        m_bvSelectFlag.resize (m_nCount, false) ;    }    // 活动安排    void greedySelector ()     {        __sortTime () ;        // 第一个活动一定入内        m_bvSelectFlag[0] = true ;            int j = 0 ;        for (int i = 1; i < m_nCount ; ++ i) {            if (m_vTimeList[i].m_nStart > m_vTimeList[j].m_nEnd) {                m_bvSelectFlag[i] = true ;                j = i ;            }        }                copy (m_bvSelectFlag.begin(), m_bvSelectFlag.end() ,ostream_iterator<bool> (cout, " "));        cout << endl ;    }private:    // 按照活动结束时间非递减排序    void __sortTime ()     {        sort (m_vTimeList.begin(), m_vTimeList.end()) ;        for (vector<ActivityTime>::iterator ite = m_vTimeList.begin() ;                ite != m_vTimeList.end() ;                 ++ ite) {            cout << ite->m_nStart << ", "<< ite ->m_nEnd << endl ;        }    }private:    vector<ActivityTime>    m_vTimeList ;    // 活动时间安排列表    vector<bool>            m_bvSelectFlag ;// 是否安排活动标志    int    m_nCount ;    // 总活动个数} ;int main(){    vector<ActivityTime> vActiTimeList ;    vActiTimeList.push_back (ActivityTime(1, 4)) ;    vActiTimeList.push_back (ActivityTime(3, 5)) ;    vActiTimeList.push_back (ActivityTime(0, 6)) ;    vActiTimeList.push_back (ActivityTime(5, 7)) ;    vActiTimeList.push_back (ActivityTime(3, 8)) ;    vActiTimeList.push_back (ActivityTime(5, 9)) ;    vActiTimeList.push_back (ActivityTime(6, 10)) ;    vActiTimeList.push_back (ActivityTime(8, 11)) ;    vActiTimeList.push_back (ActivityTime(8, 12)) ;    vActiTimeList.push_back (ActivityTime(2, 13)) ;    vActiTimeList.push_back (ActivityTime(12, 14)) ;    ActivityArrange aa (vActiTimeList) ;    aa.greedySelector () ;    return 0 ;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 暴风雨夜与妻子朋友独处 年轻的女老板3中文字 兄弟侵犯大嫂中文字幕迅雷视频 大香煮蕉伊在线网视频推手 91青青城线在人线免费人人人 91青青城人线在人线 95青青成线人人 青青成线小说 青青成线人线免 第一成一肉区免 费91 欧洲第一肉场 欧洲第一成肉区免 费91ap 免费欧洲第一成肉区免 费91 欧洲第一成一肉区免 费9 欧洲第一成一肉区免 费91人雨马 欧洲笫一肉区l1041 久碰人人澡人人澡人人澡人人澡 看欧洲第一成肉区免 免费在 线人擦人人搞人视频人人人 人人差人人搞人视频 人人看人人揉人人捏动漫 超越人人夜人人看视频 人人玩人人弄人槽视频动漫 草人人拍人人躁 人人人人看人谢97 免费在 线人擦人人搞人视频动漫视频 人人看人人揉人人捏视频 青青成线人线免费公开 亚成区1216成线人 青青成年在人线免费人人拍人人 人玩人人弄人人 人人看人人揉人人捏免费线看 人上人人玩人人与人意义 人在人上人在肉中 人下人人上人捧人 八人来人人上人个草人 人捧人 人上人 人踩人 人上人捧人上人人下人踩人下人 上人 上口人人人 人上人 人上人玩人人与人人 人捧人人上人 人踩人人下人