活动安排问题与贪心算法

  • 贪心算法:

在求最优解问题的过程中,依据某种贪心标准,从问题的初始状态出发,直接去求每一步的最优解,通过若干次的贪心选择,最终得出整个问题的最优解,这种求解方法就是贪心算法

从贪心算法的定义可以看出,贪心算法不是从整体上考虑问题,它所做的选择只是在某种意义上的局部最优解,而由问题自身的特性决定了该题运用贪心算法可以得到最优解。

如果一个问题同时可以用几种问题解决,贪心算法应该是最好的选择之一。

  • 活动安排问题:

该问题要求高效地安排一系列争用某一公共资源的活动。即在所给的活动集合中选出最大的相容活动子集合。

设有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;
        }
    }
}

 

发布了93 篇原创文章 · 获赞 45 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_41431406/article/details/102217419