zoukankan      html  css  js  c++  java
  • 贪心算法

    贪心算法概念

      根据局部最优解得到问题的整体最优解或整体最优解的近似解:只根据当前已有信息做当前最优选择(且选择了就不能改变)

    能利用贪心算法解决的问题有2个特性

    1.贪心选择

      原问题的整体最优解可以通过一步一步的局部最优选择得到;

    2.最优子结构

      问题的最优解包含其子问题的最优解;

      例如:北京-广州的最短路径问题(必须经过上海),则北京-上海、上海-广州的最短路径是问题的子问题,这个问题的最优解就必须考虑子问题北京-上海、上海-广州的最短路径的最优解

    使用贪心算法的步骤

    1.确定贪心策略(根据当前信息确定)

    2.得到局部最优解

    3.合成整体最优解

    例子1——最优装载问题

    问题描述:海盗船载重为load,每件宝贝的重量为wi,海盗如何把尽可能多的宝贝装上海盗船?

    贪心策略:每次选当前重量最轻的宝贝放上海盗船

    算法设计:1.对宝贝重量进行排序;sort()函数接收2个参数或者3个参数,可对数组或者vector排序,2个参数分别为首指针和尾后指针,第3个参数可以是一个谓词,头文件<algorithm>

         2.按照贪心策略每次选当前最轻的宝贝,直到海盗船装不下,设置计数器,最后计数器的值就是最后装入海盗船的宝贝数量

    例子2——部分的背包问题

    问题描述:

      背包载重为load,山洞中有n个宝贝,每个宝贝的重量为wi,价值为vi,单个宝贝可以分割,盗贼能盗取的最大价值是多少?

    贪心策略:

      因为单个宝贝可以分割,所以可以引入性价比,每次选当前性价比最高的宝贝放入背包

    算法设计:

      1.定义一个结构体,包含宝贝的重量、价值、性价比

      2.按照贪心策略每次选当前性价比最高的宝贝,直到背包装不下完整宝贝,此时,将性价比最高的那个宝贝进行分割,装入分割宝贝,使背包刚好装满

    注意:可分割的情况,所有数据请用double表示

    代码实现:

     1 struct item {
     2     double weight;
     3     double value;
     4     double ratio;
     5 };
     6 
     7 bool cmp(item& a, item& b)
     8 {
     9     return a.ratio > b.ratio;
    10 }
    11 
    12 double partBag(vector<double>& weight, vector<double>& value, double load)
    13 {
    14     int n = weight.size();
    15     vector<item> vec(n);
    16     for (int i = 0; i < n; ++i)
    17     {
    18         vec[i].weight = weight[i];
    19         vec[i].value = value[i];
    20         vec[i].ratio = value[i] / weight[i];
    21     }
    22     sort(vec.begin(), vec.end(), cmp);
    23     double curLoad = 0.0, maxiValue = 0.0, remainLoad = load;
    24     for (int i = 0; i < n; ++i)
    25     {
    26         if (remainLoad >= vec[i].weight)//全部装入
    27         {
    28             remainLoad -= vec[i].weight;
    29             maxiValue += vec[i].value;
    30         }
    31         else//部分装入
    32         {
    33             maxiValue += remainLoad*vec[i].ratio;
    34             break;
    35         }
    36     }
    37     return maxiValue;
    38 }

    测试例:

    1 int main()
    2 {
    3     vector<double> weight{ 4,2,9,5,5,8,5,4,5,5 }, value{ 3,8,18,6,8,20,5,6,7,15 };
    4     double load = 30.0;
    5     double maxiValue = partBag(weight, value, load);
    6     cout << "部分背包问题所能装的最大价值为:" << maxiValue << endl;
    7 
    8     return 0;
    9

    例子3——会议安排问题

    问题描述:如何在有限的时间内召开尽可能多的会议?

    贪心策略:因为最早开始时间+持续时间最短=最早结束时间,所以每次选当前来看结束时间最早且不会与已有会议相冲突的会议

    算法设计:1.定义一个结构体,包含会议的开始时间、结束时间

         2.对会议按结束时间排序

         3.按照贪心策略一步一步地选择会议,每安排上一个会议,便用变量last记录这个会议结束时间,下一次选择的会议的开始时间必须大于等于last

  • 相关阅读:
    常用API及异常
    支付宝支付流程以及二次封装alipay包 支付模块后台接口的实现 订单接口实现
    课程页前台组件 课程模块的实现 表的设计及数据录入 课程详情页前台组件 课程详情页后台实现
    celery使用
    登录、注册、页头页面 手机号验证接口 发送短信接口 注册接口 多方式登录接口 手机号登录接口 发送短信接口频率限制 异常处理修订 接口缓存
    redis基础使用 python操作redis django-redis使用
    短信接口的使用(腾讯云)
    主页设计:页面头部组件 页面底部组件 轮播图组件 主页组件 主页后台: home模块创建 路由分发 Banner表的model设计 数据库迁移 注册模块
    前台vue环境配置 vue项目的创建 项目目录的重构 全局样式文件 配置文件 axios配置 cookies配置 element-ui配置 bootstrap和jquery的配置
    thinkphp6使用最新版本composer后多应用模式提示路由不存在
  • 原文地址:https://www.cnblogs.com/Joezzz/p/9577520.html
Copyright © 2011-2022 走看看