活动安排问题(贪心)

文章介绍了如何使用贪心算法解决活动安排问题,其中活动按结束时间非减序排列,选择最早结束时间的活动以最大化资源利用率。贪心Selector算法能在O(n)时间内找到最大相容活动子集,并且对于此问题,贪心法总能得到整体最优解。
摘要由CSDN通过智能技术生成

活动安排问题(贪心)


一、问题描述

设有n个活动的集合 E = { 1 , 2 , . . . , n } E=\left \{ 1,2,...,n \right \} E={1,2,...,n},其中每个活动都要求使用同一资源(如演讲会场),而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间 s i s_{i} si和和一个结束时间 f i f_{i} fi,且 s i ≤ f i s_{i} \le f_{i} sifi。如果选了活动 i i i,则它在半开时间区间 [ s i , f i ) \left [ s_{i} ,f_{i} \right) [si,fi)内占用资源。若区间 [ s i , f i ) \left [ s_{i} ,f_{i} \right) [si,fi)与区间 [ s j , f j ) \left [ s_{j} ,f_{j} \right) [sj,fj)不相交,则称活动 i i i与活动 j j j是相容的。也就是说,当 s i ≥ f j s_{i}\ge f_{j} sifj s j ≥ f i s_{j}\ge f_{i} sjfi时,活动 i i i与活动 j j j相容。活动安排问题要求在所给的活动集合中选出最大的相容活动子集。

二、问题分析

首先给出活动安排问题的贪心算法geedySelector,各活动的起始时间和结束时间存储于数组 s s s f f f中且按活动结束时间的非减序排列。

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

贪心法求解活动安排问题的关键是如何选择贪心策略,使得按照一定的顺序选择相容活动并能够安排尽量多的活动。至少有两种看似合理的贪心策略:

(1)最早开始时间,这样可以增大资源的利用率。

(2)最早结束时间,这样可以使下一个活动尽早开始。

由于活动占用资源的时间没有限制,因此,后一种贪心选择更为合理。直观上,按这种策略选择相容活动可以为未安排的活动留下尽可能多的时间,也就是说,这种贪心选择的目的是使剩余时间段极大化,以便安排尽可能多的相容活动。

为了在每一次贪心选择时快速查找具有最早结束时间的相容活动,可以将n个活动按结束时间非减序排列。这样,贪心选择时取当前活动集合中结束时间最早的活动就归结为取当前活动集合中排在最前面的活动。

若被检查的活动 i i i的开始时间 s i s_{i} si小于最近选择的活动 j j j的结束时间 f j f_{j} fj,则不选择活动 i i i,否则选择活动 i i i加入集合 A A A中。

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值