4.1 活动选择问题
1.问题的理解与描述
假定有n个需要使用同一个这样的资源的活动,每次只能有一个活动使用该资源。每一个活动有一个开始时间 si,一个完成时间 fi,其中0 ≤ si < fi < ∞。如果区间[si , fi)和[sj , fj)不相交,活动ai和aj是相容的(即如果si≥ fj 或 sj ≤ fi,ai和aj相容)。活动选择问题是选取一个由相容活动构成的最大集合。
输入:按完成时间排好序的活动开始时间数组s,完成时间数组 f。
输出:表示一个最大的相容活动组的向量{x1, x2, …, xn},其中
xi={01第i个活动在此最大相容活动组中否则,i1,2,...,n。
2.最优子结构
定义集合
Sij=ak∈S:fi≤sk
定理4-1
考虑任一非空子问题Sij,并设am为Sij中最早完成的一个活动:
fm=minfk:ak∈Sij 。
则
(1)活动 am 包含在 Sij 的一个最大相容活动子集合中。
(2)子问题 Sim 是空的,所以选择 am 将使得 Smj 成为仅有的非空子问题。
4.算法的伪代码描述
RECURSIVE-ACTIVITY-SELECTOR (s, f, i, j)
1 m ← i + 1
2 while m < j 且 sm < fi 求Sij中的第一个活动
3 do xm←0
4 m ← m + 1
5 if m < j
6 then xm←1
7 RECURSIVE-ACTIVITY-SELECTOR (s, f, m, j)
算法运行时间:Θ(n)
5 C++代码实现
#ifndef _GREEDYACTIVITYSELECT_H
#define _GREEDYACTIVITYSELECT_Hint* RecusiveActivitySelector(int* s, int* f,int i,int j);
#endif
#include "GreedyActivitySelect.h"int* RecusiveActivitySelector(int* s, int* f,int i,int j)
{static int * x=new int[j];int m=i+1;while(m
#include "GreedyActivitySelect.h"
#include
#include
using namespace std;int main(int argc,char** argv)
{int* x;int s[]={0,1,3,0,5,3,5,6,8,8,2,12,numeric_limits::max()},f[]={0,4,5,6,7,8,9,10,11,12,13,14,numeric_limits::max()};x=RecusiveActivitySelector(s,f,0,12);for(int i=1;i<12;i++)cout<
运行结果:1 0 0 1 0 0 0 1 0 0 1
上一篇:关于春光的诗句
下一篇:关于绿的词语(颜色)