zoukankan      html  css  js  c++  java
  • 算法导论13.贪心算法

    http://www.10086bank.com/201331592830749.html

    算法导论-13.贪心算法

    与动态规划类似,贪心算法也将问题化简为规模较小的子问题,并通过递归解决子问题来获取整个问题的解。不同的是,贪心问题不对子问题进行比较,而是只生成一个非空的子问题,而使选择在当时看上去是最优的(即“贪心”的含义)

    活动选择问题

    几个互相竞争的活动都要求以独占的方式占用某个公用资源(如选修课程对个人可支配时间的要求,或会议对会议室的要求),每个活动都有开始时间和结束时间。如何安排活动,使在总时间内开展的活动次数最多?形式化的,一组活动组成的集合 S=a1,a2...an ,每一个活动 ai 都有开始时间 si 和结束时间 fi 。求一组互相兼容的活动的最大子集合 S

    贪心算法:

    将所有活动按照结束时间排序,得到新的 S,首先选取结束时间最小 a1 的加入解 S,然后检查 a2 ,如果 a2 的开始时间大于当前已加入解的所有活动(目前就一个 a1)的结束时间,那么就舍弃之,否则将其加入解 S ,再检查 a3,以此类推。

    能够证明,贪心算法获取的是全局最优解:

    我们可以说,在排序后的 S,第一个活动 a1(结束时间最早的活动)一定在最优解 S 中。为什么呢?因为假设 S 不包含 a1,那么一定包含一个与 a1 不兼容的 ai ,是吧?(如果这都不能满足,直接向 S 中加入 a1 ,得到的新子集就比 S 多了一个元素,那么 S 就不是最优解了)然后,我们可以断言,从 S 去掉 ai 再加上 a1S 仍然是最优解。

    为什么呢?因为 a1 的结束时间是最早的,所以 ai 与 a1 不兼容的方式只能是:ai 的开始时间比 a1 结束时间早(但结束时间比 a1 结束时间晚),而且因为 S 中除了 ai 的其他活动都与 ai 兼容(理所当然,否则 S 连解都不是,何谈最优解?),这些其他活动都会出现在 ai 后面(也就是这些活动的开始时间比 ai 的结束时间晚),而不是前面。如果出现在前面呢? 拜托,如果这些活动在 ai 前面,那么这些活动的结束时间比 ai 的开始时间早,也就是比 a1 的结束时间早。这怎么可能呢?a1 就是S 中具有最早结束时间的活动了啊。

    原理说起来拗口,实现做起来却相当简单:

    class actvty{
    public:
        actvty(double start, double end, int id):_start(start),_end(end),_id(id){}
        const double getStart() const {return _start;}
        const double getEnd() const {return _end;}
        const int getId() const {return _id;}
        bool operator<(const actvty& tmp) const {return getEnd()<tmp.getEnd();}
    private:
        double _start;
        double _end;
        int _id;
    };
    
    std::vector<actvty> slctn(std::vector<actvty>& all){
        std::sort(all.begin(), all.end());
        std::vector<actvty> rslt;
        double start = 0;
        for (int i=0; i<all.size(); i++){
            if (all[i].getStart() >= start){
                rslt.push_back(all[i]);
                start = all[i].getEnd();
            }
        }
        return rslt;
    }

    练习16.1-3 假设用多个资源对一组活动进行调度,我们希望使用尽可能少的资源来满足所有活动要求。

    思路:和活动选择问题类似,只不过当一个活动不能被(当前开辟的资源)满足时,我们不是将它舍弃,而是新开辟一个资源供其使用。

    0-1背包问题

    窃贼在偷窃一家商店时发现有 n 件物品 S=a1,a2...an ,每一件物品 ai 都有其价值 vi 和重量 wi ,作为一个有尊严的窃贼,他曾发誓每次只偷最多 W 重量的货物,那么如何在不违背誓言的情况下,从赃物中获得最大的价值?

    贪心算法:

    将所有物品按照 vi/wi 值(姑且称为“单价”吧)排序,然后先拿单价最高的,然后拿单价次高的,如果拿到一个物品后超重了,那就舍弃它并继续上述过程,直到商店里所有剩下物品中的任意一件都会使盗贼的赃物超重。

    0-1背包问题是NP的,所以贪心算法不保证最优解。一个简单的例子就是:窃贼只偷取 10kg 物体,商店里只有两件物品,一件1kg,价值20元,单价20,另一件9.5kg,价值950元,单价10元。如果窃贼遵循贪心算法,就不能获得最优解了。

    习题16.2-4 某教授驾车从 A 地到 B 地,总里程数确定。油箱中的汽油能支持的里程也是确定的,途中有若干个加油站。教授希望加油的次数尽量少,请确定需要加油的加油站,支持教授的车驶完全程。(假设教授出发时邮箱是满的)。

    贪心算法:当途径某个加油站时,只有当油箱中的油已经不足以撑到下一个加油站时,才去加满油。

    这个算法可以证明是最优的,即假设加油站序列为 S=s1,s2...sn,贪心解中的第一个加油站为 si 一定在最优解中。如果 si 不在最优解中,那么最优解中一定有一个加油站 sp 在 si之前,否则车开不到 si+1 。假设最优解中的第二个加油站为 sq ,那么从最优解中去掉 sp 加上 sq 仍然是最优解。

    习题16.2-7 两个集合 A 和 B ,各有 n 个正整数,你可以按照自己的意愿对其进行排序。重新排序后,设 ai 为 A 中的第 i 个元素,bi 为 B 中的第 i 个元素。请排序元素,使 abii最大。

    思路:全部递增排序就是。证明也很简单,就是证明当 a1>b1 且 a2>b2 时(当然都是正整数啊),ab11>ab22 。

    ClickCounts: 137  CommentS: 0  
    feifei at 2013-3-15 9:28:30.749 do it

    The Next:数据结构的扩张(77)

  • 相关阅读:
    maven 设置日志级别
    浏览器工作原理:浅析浏览器中的页面
    浏览器工作原理:浅析浏览器中的页面
    解决uniapp的websocket连接在web和安卓正常,iOS连接不上的问题
    浏览器工作原理:浅析页面循环系统
    浏览器工作原理:浅析页面循环系统
    浏览器工作原理:浅析页面循环系统
    浅析如何使用WebSocket、SockJS、STOMP实现消息实时通讯功能:websocket/SocketJS/Stomp是什么及三者的关系、stomp协议格式、如何开启stomp、如何处理客服端发送的stomp、如何发消息给客服端、如何在任何地方发消息、如何给目标或指定用户发消息
    解决sockjs、stomp在uni-app端使用的坑
    浏览器工作原理:浅析页面循环系统
  • 原文地址:https://www.cnblogs.com/chinhi/p/3049212.html
Copyright © 2011-2022 走看看