算法基础(5) 贪心算法

1.贪心算法:贪心算法是通过一系列选择找到最优解,每一个决策点都是做一个在当时看来最优的选择,所以贪心算法不一定总是能找到最优解,但通常可以找到最优解。(敝人理解,找到局部最优解而非全局最优解)。

2.适用于贪心算法问题具有的特点:

 贪心选择性质:一个全局最优解可以通过贪心选择来表达。

最优子结构:一个问题的最优解也包含了它的子问题的最优解。

(一个问题是否具备这两个性质,都可以通过证明得到,在下不精于此道,就不证明了啊)

3.贪心算法解题基本步骤:

首先,从问题的一个初始解出发;

然后,采用循环,当可以向最终求解目标前进一步时,采用局部最优策略,得到一个部分解。缩小问题的范围或规模;

最后,综合所有部分解,得到最终解。

下面举几个栗子(好吃啊好吃)

4.活动安排问题

假设有一个资源(比如教室),有n个活动竞争使用,其中一个活动如果竞争成功则将占用该资源[si,fi)时间段,si为活动i开始的时间,fi为活动i结束的时间。如果两个活动i和j,si>fj或sj>fi(即两个活动发生的时间没有重叠),则称活动i,j兼容。活动安排问题就是选择一个由兼容活动组成的最大集合。

首先将所有活动,按照fi非递减的顺序排列

排好序后,按照编号由小到大,选择符合兼容条件的加入集合。最后这个集合为{1,4,8,11}

void GreedySelector(T s[],T f[],bool A[],int n)
{ //f[]为排好序的数组
     A[0] = true;
     int i,j=0;
     for(i=1;i<n,i++)
     {
          if(s[i]<f[j])
          {
                A[i]=true;
                j=i;
           }
           else
               A[i] = false;
      }
}                                                

再贴一个完整可编译代码(较复杂,大概看看)

* 主题:活动安排问题
* 作者:chinazhangjie
* 邮箱:chinajiezhang@gmail.com
* 开发语言:C++
* 开发环境:Microsoft Visual Studio
* 时间: 2010.11.21
*/

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std ;

struct ActivityTime
{
public:
    ActivityTime (int nStart, int nEnd) 
        : m_nStart (nStart), m_nEnd (nEnd) 
    { }
    ActivityTime ()
        : m_nStart (0), m_nEnd (0)
    { }
    friend 
    bool operator < (const ActivityTime& lth, const ActivityTime& rth) 
    {
        return lth.m_nEnd < lth.m_nEnd ;
    }
public:
    int m_nStart ;
    int m_nEnd ;
} ;

class ActivityArrange 
{
public:
    ActivityArrange (const vector<ActivityTime>& vTimeList) 
    {
        m_vTimeList = vTimeList ;
        m_nCount = vTimeList.size () ;
        m_bvSelectFlag.resize (m_nCount, false) ;
    }
    // 活动安排
    void greedySelector () 
    {
        __sortTime () ;
        // 第一个活动一定入内
        m_bvSelectFlag[0] = true ;    
        int j = 0 ;
        for (int i = 1; i < m_nCount ; ++ i) {
            if (m_vTimeList[i].m_nStart > m_vTimeList[j].m_nEnd) {
                m_bvSelectFlag[i] = true ;
                j = i ;
            }
        }
        
        copy (m_bvSelectFlag.begin(), m_bvSelectFlag.end() ,ostream_iterator<bool> (cout, " "));
        cout << endl ;
    }

private:
    // 按照活动结束时间非递减排序
    void __sortTime () 
    {
        sort (m_vTimeList.begin(), m_vTimeList.end()) ;
        for (vector<ActivityTime>::iterator ite = m_vTimeList.begin() ;
                ite != m_vTimeList.end() ; 
                ++ ite) {
            cout << ite->m_nStart << ", "<< ite ->m_nEnd << endl ;
        }
    }

private:
    vector<ActivityTime>    m_vTimeList ;    // 活动时间安排列表
    vector<bool>            m_bvSelectFlag ;// 是否安排活动标志
    int    m_nCount ;    // 总活动个数
} ;

int main()
{
    vector<ActivityTime> vActiTimeList ;
    vActiTimeList.push_back (ActivityTime(1, 4)) ;
    vActiTimeList.push_back (ActivityTime(3, 5)) ;
    vActiTimeList.push_back (ActivityTime(0, 6)) ;
    vActiTimeList.push_back (ActivityTime(5, 7)) ;
    vActiTimeList.push_back (ActivityTime(3, 8)) ;
    vActiTimeList.push_back (ActivityTime(5, 9)) ;
    vActiTimeList.push_back (ActivityTime(6, 10)) ;
    vActiTimeList.push_back (ActivityTime(8, 11)) ;
    vActiTimeList.push_back (ActivityTime(8, 12)) ;
    vActiTimeList.push_back (ActivityTime(2, 13)) ;
    vActiTimeList.push_back (ActivityTime(12, 14)) ;

    ActivityArrange aa (vActiTimeList) ;
    aa.greedySelector () ;
    return 0 ;
}

这篇先到这儿,贪心算法未完待续。。。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值