设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当si≥fj或sj≥fi时,活动i与活动j相容。
下面给出贪心算法的程序框架:
Greedy(C)//C是问题的输入集合,及候选集合
{
S={};//初始解集合为空
While(not solution(s))//集合S没有构成问题的解
{
X=Select(C); 在候选的集合C上做贪心选择
If feasible(s,x); 判断集合S加入x后的解是否可行
{
S=S+{x}; //加入解集 S
C=C-{x};// 从问题集合中删除 S
}
}
ReturnS; //返回解集合
}
下面给出解活动安排问题的贪心算法GreedySelector
void GreedySelector (int n,Type s[], Type f[], bool A[])
{
A[1]=true; //解集合初始为1
int j=1;
for (int i=2; i<=n; i++) {
if (s[i]>=f[j]) { A[i]=true; j=i;}//在候选集合上C上搜索
//符合条件的解I,如果合适 就加入解集合A
else A[i]=false;
}
}
S是活动开始的起始时间,f是活动开始的结束时间。N是活动的个数。A是活动i是否被选取的标志。要求f已经按照非递减顺序排列过的。
完整的实例程序:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
typedef struct LActive
{
int s;
int f;
}node;
#define N 10
vector<node> col;
void init(vector<node>&col)
{
for(int i=0;i<N;++i)
{
node s;
cout<<"input the start and end timeplease:"<<endl;
cin>>s.s;
cin>>s.f;
col.push_back(s);
}
}
bool Compare(node elem1,nodeelem2)
{
return elem1.f<elem2.f;
}
voidsort(vector<node>& col)
{
sort(col.begin(),col.end(),Compare);
}
void GreedySelector(intn,vector<node>& col,bool* A)
{
A[0]=true;
int j=0;
for(int i=1;i<n;++i)
{
if(col.at(j).f<=col.at(i).s)
{
A[i]=true;
j=i;
}
else
{
A[i]=false;
}
}
}
/*
安排活动的贪心算法
*/
//其中s表示活动的开始时间,f是活动的结束时间
//A 表示是否选择活动i
//n表示有n个活动
//注意f是按照非递减的顺序来存储的
/*
void GreedySelector(intn,Type s[],Type f[],bool A[])
{
A[1]=true;
int j=1;
for(int i=2;i<=n;i++)
{
if(s[i]>=f[j])
{
A[i]=true;
j=i;
}
else
A[i]=false;
}
}*/
int main()
{
init(col);
sort(col);
bool *A=(bool*)malloc(sizeof(bool)*N);
GreedySelector(N,col,A);
for(int i=0;i<N;++i)
{
cout<<col.at(i).s<<""<<col.at(i).f<<" ";
}
cout<<endl;
for(int i=0;i<N;++i)
{
if(A[i])
{
cout<<"true"<<" ";
}
else
cout<<"false"<<" ";
}
delete A;
return 0;
}