求解活动安排问题

问题描述:
假设有一个需要使用某一资源的由n个活动所组成的集合S,S=(1,…,n)。该资源在任何时刻只能被一个活动所占用,活动i有一个开始时间bi和结束时间ei(bi<ei),其执行时间为ei-bi,假设最早活动执行时间为0。一旦某个活动开始执行,就不能被打断,直到其执行完毕。若活动i和活动j有bi≥ej或bj≥ei,则称这两个活动兼容。设计一种最优活动安排方案,使得所有安排的活动个数最多。
问题求解:
采用贪心算法的策略是每一步总是选择这样一个活动来占用资源,它能够使得余下的未调度的时间最大化,使得兼容的活动尽可能多。为此先按活动结束时间递增排序,再从头开始依次选择兼容活动(用B集合表示),从而得到最大兼容活动子集(包含兼容活动个数最多的子集)。由于活动按结束时间递增排序,每次总是选择具有最早完成的兼容活动加入集合B中,所以选择的兼容活动为未安排的活动留下尽可能多的时间,也就是使得剩余的可安排时间段极大化,以便安排尽可能多的兼容活动。

#include<iostream>
#include<string.h>
#include<algorithm>
#define MAXN 51
using namespace std;

int n=11;//表示11个活动待安排
struct Action{
    int b;//活动开始时间
    int e;//活动结束时间
    bool operator < (const Action &s)const{
        return e<=s.e;
    }
};
Action A[]={{0},{1,4},{3,5},{0,6},{5,7},{3,8},{5,9},{6,10},{8,11},{8,12},{2,13},{12,15}};
int flag[MAXN];//记录选择的活动
int Count=0;//记录选取活动个数

void solve();
void output();

int main()
{
    solve();
    output();
    return 0;
}
void solve()
{
    int i;
    int preend=0;
    for(i=1;i<=n;i++){
        if(A[i].b>=preend){
            flag[i]=true;
            preend=A[i].e;
        }
    }
}
void output()
{
    int i;
    cout<<"求解结果:\n";
    cout<<"选取的活动:";
    for(i=1;i<=n;i++){
        if(flag[i]==1){
            cout<<"["<<A[i].b<<','<<A[i].e<<']'<<' ';
            Count++;
        }
    }
    cout<<'\n'<<"共选取了"<<Count<<"个活动"<<endl;
}

#include<iostream>
#include<string.h>
#define MAXN 51
using namespace std;

int n=11;//表示11个活动待安排
int b[]={0,1,3,0,5,3,5,6,8,8,2,12};
int e[]={0,4,5,6,7,8,9,10,11,12,13,15};
int cnt=0;
int B[MAXN];
int E[MAXN];

void solve();
void output();

int main()
{
    memset(B,0,sizeof(B));
    memset(E,0,sizeof(E));
    solve();
    output();
    return 0;
}
void solve()
{
    int i,j=0;
    B[0]=b[0];
    E[0]=e[0];
    for(i=1;i<=n;i++){
        if(b[i]>=e[j]){
            j=i;
            cnt++;
            B[cnt]=b[j];
            E[cnt]=e[j];
        }
    }
}
void output()
{
    int i;
    cout<<"求解结果为:"<<endl;
    cout<<"选取的活动为:";
    for(i=1;i<=cnt;i++){
        cout<<'['<<B[i]<<','<<E[i]<<']'<<' ';
    }
    cout<<"\n共选取"<<cnt<<"个活动"<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DrmBee#

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值