贪心算法总结

来源:互联网 发布:mac系统顿号怎么打 编辑:程序博客网 时间:2024/06/07 11:25

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

注意:贪心算法不是从整体上考虑问题,它所做出的选择只是在某种意义上的局部最优解。

基本思想:通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每一次的贪心选择将所求问题简化为规模更小的子问题。

一般流程:

//A是问题的输入集合即候选集合
Greedy(A)
{
  S={ };           //初始解集合为空集
  while (not solution(S))      //集合S没有构成问题的一个解
  {
    x = select(A);     //在候选集合A中做贪心选择
    if feasible(S, x)     //判断集合S中加入x后的解是否可行
    { 

                      S = S+{x};
      A = A-{x};

               }             
  }
  return S;
}

(1)候选集合A:问题的最终解均取自于候选集合A。
(2)解集合S:解集合S不断扩展,直到构成满足问题的完整解。
(3)解决函数solution:检查解集合S是否构成问题的完整解。
(4)选择函数select:贪心策略,这是贪心算法的关键。
(5)可行函数feasible:解集合扩展后是否满足约束条件。

经典问题(活动安排问题)

1.问题描述:设有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相容。活动安排问题就是在所给的活动集合中选                      出最大的相容活动子集合。

2.思路:利用贪心算法,每次总选择具有最早完成时间的相容活动加入解集合,为未安排的的活动留下尽可能多的时                 间。即使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。

3.代码:

#include<iostream>
using namespace std;
struct action{
int s; //起始时间
int f; //结束时间
int index; //活动的编号
};
action a[1000];     //活动的集合E记为数组
//按活动的结束时间升序排序
bool cmp(const action &a,const action &b){
    if(a.f<=b.f) return true;
return false;
}
//形参数组b用来记录被选中的活动
void GreedySelector(int n,action a[],bool b[]){
    b[a[1].index]=true;              //排序后第1个活动是必选的
    //记录最近一次加入到集合b中的活动
    int preEnd=1;
    for(int i=2;i<=n;i++){
        if (a[i].s>=a[preEnd].f){
            b[a[i].index]=true;
            preEnd=i;
        }
    }
    for(int i=1;i<=n;i++){
        if(b[i]==true){
            cout<<i<<" ";
        }
    }
    cout<<endl;
}
int main(){
    int n;
    action a[100];
    bool b[100];
    cin>>n;
    int s,f,index;
    //初始化a,b数组
    for(int i=1;i<=n;i++){
        cin>>s>>f;
        a[i].s=s;
        a[i].f=f;
        a[i].index=i;
        b[i]=false;
    }
    sort(a+1,a+n+1,cmp);
    GreedySelector(n,a,b);
}


原创粉丝点击