贪心算法(Java)

2023-05-16

贪心算法

文章目录

  • 贪心算法
    • 0、写在前面
    • 1、贪心算法的基本要素
      • 1.1 贪心选择性质
      • 1.2 最优子结构性质
      • 1.3 贪心算法与动态规划算法的差异
    • 2、贪心算法的特点
    • 3、贪心法的正确性证明
    • 4、活动安排问题
      • 4.1 问题描述
      • 4.2 贪心法的设计思想
      • 4.3 两个反例
    • 5、代码
    • 6、效率
    • 7、实例
    • 8、参考


在这里插入图片描述


0、写在前面

顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路径问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

1、贪心算法的基本要素

对于一个具体的问题,怎么知道是否可用贪心算法解此问题,以及能否得到问题的最优解呢?这个问题很难给予肯定的回答。

但是,从许多可以用贪心算法求解的问题中看到这类问题一般具有2个重要的性质:贪心选择性质和最优子结构性质

1.1 贪心选择性质

  • 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。

  • 动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。

  • 对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解

1.2 最优子结构性质

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

1.3 贪心算法与动态规划算法的差异

贪心算法和动态规划算法都要求问题具有最优子结构性质,这是2类算法的一个共同点。但是,对于具有最优子结构的问题应该选用贪心算法还是动态规划算法求解?

2、贪心算法的特点

设计要素:

  • 贪心法适用于组合优化问题.
    求解过程是多步判断过程,最终的判断序列对应于问题 的最优解.

  • 判断依据某种“短视的”贪心选择性质,性质的好坏决定了算法的成败.

  • 贪心法必须进行正确性证明

贪心法的优势:算法简单,时间和空间复杂性低

3、贪心法的正确性证明

数学归纳法

  1. 叙述一个描述算法正确性的命题P(n),n为算法步数或者问题规模
  2. 归纳基础:P(1) 或 P(n0)为真, n0为某个自然数
  3. 归纳步骤:P(k) -->P(k+1) 第一数学归纳法
    对于所有k(k<n)P(k)–> P(n) 第二数学归纳法

在这里插入图片描述

交换论证

  1. 分析算法的解的结构特征
  2. 从一个最优解逐步进行结构变换(替换成分、交换次序等)得到一个新的解(结构上与贪心算法的解更接近)
  3. 证明:上述变换最终得到算法的解,且变换在有限步结束,每步变换都保持解的最优性不降低.

4、活动安排问题

4.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相容。

4.2 贪心法的设计思想

在这里插入图片描述

4.3 两个反例

策略1:S={1,2,3},s1=0, f1=20, s2=2, f2=5, s3=8, f3=15

策略2:S={1,2,3},s1=0, f1=8, s2=7, f2=9, s3=8, f3=15

在这里插入图片描述

5、代码

活动安排

Note:各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排列

public static int greedySelector(int[] s,int[] f,boolean[] a) {
  int n=s.length;
  a[0]=true;
  int j=0;
  int count=1;
  for(int i=1;i<n;i++){
    if(s[i]>=f[j]){
    a[i]=true;
    j=i;
    count++;
    } else {
      a[i]=false;
    }
  }
  return count;
}

6、效率

  • 由于输入的活动以其完成时间的非减序排列,所以算法greedySelector每次总是选择具有最早完成时间的相容活动加入集合A中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也就是说,该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。

  • 算法greedySelector的效率极高。当输入的活动已按结束时间的非减序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。如果所给出的活动未按非减序排列,可以用O(nlogn)的时间重排。

7、实例

例:设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:

tp

算法greedySelector 的计算过程如左图所示。图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条表示的活动是当前正在检查相容性的活动。

A = {1, 4, 8,11}

在这里插入图片描述

  • 若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。

  • 贪心算法并不总能求得问题的整体最优解。但对于活动安排问题,贪心算法greedySelector却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。

算法的正确性证明

定理算法Select 执行到第 k 步, 选择 k 项活动 i1= 1, i2, …,
ik, 那么存在最优解 A 包含 i1=1, i2, … , ik .

根据定理:算法至多到第 n 步得到最优解

tp

归纳步骤:假设命题对 k 为真, 证明对 k+1 也为真.

在这里插入图片描述

tp

8、参考

  • 算法设计与分析(第4版)

结束!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

贪心算法(Java) 的相关文章

随机推荐

  • 符号三角形问题(Java)

    符号三角形问题 xff08 Java xff09 文章目录 符号三角形问题 xff08 Java xff09 1 前置介绍2 算法设计3 程序代码4 算法效率5 参考资料 1 前置介绍 符号三角形定义 如下图所示 xff0c 符号三角形是由
  • 装载问题 ——分支限界法(Java)

    装载问题 分支限界法 xff08 Java xff09 文章目录 装载问题 分支限界法 xff08 Java xff09 1 问题描述2 算法设计3 算法的改进4 程序代码5 参考资料 1 问题描述 有一批共n个集装箱要装上2艘载重量分别为
  • 装载问题 ——回溯法(Java)

    装载问题 回溯法 xff08 Java xff09 文章目录 装载问题 回溯法 xff08 Java xff09 1 问题描述1 1 装载问题1 2 转换问题 2 算法设计2 1 可行性约束函数2 2 上界函数2 3 解空间树2 4 剪枝函
  • 上传项目代码到Github|Gitee

    上传项目代码到Github Gitee 文章目录 上传项目代码到Github Gitee1 前置准备1 1 Git 安装1 2 在 Git 中设置用户名1 2 1 为计算机上的每个存储库设置 Git 用户名1 2 2 为一个仓库设置 Git
  • NoSQL数据库原理与应用综合项目——HBase篇

    NoSQL数据库原理与应用综合项目 HBase篇 文章目录 NoSQL数据库原理与应用综合项目 HBase篇 0 写在前面 1 本地数据或HDFS数据导入到HBase 2 Hbase数据库表操作 2 1 Java API 连接HBase 2
  • NoSQL数据库原理与应用综合项目——MongoDB篇

    NoSQL数据库原理与应用综合项目 MongoDB篇 文章目录 NoSQL数据库原理与应用综合项目 MongoDB篇 0 写在前面 1 本地数据或HDFS数据导入到MongoDB 2 MongoDB数据库表操作 2 1 Java API 连
  • NoSQL数据库原理与应用综合项目——Redis篇

    NoSQL数据库原理与应用综合项目 Redis篇 文章目录 NoSQL数据库原理与应用综合项目 Redis篇 0 写在前面 1 本地数据或HDFS数据导入到Redis 2 Redis数据库表操作 2 1 Java API 连接Redis 2
  • NoSQL数据库原理与应用综合项目——Neo4j篇

    NoSQL数据库原理与应用综合项目 Neo4j篇 文章目录 NoSQL数据库原理与应用综合项目 Neo4j篇 0 写在前面 1 本地数据或HDFS数据导入到Neo4j 2 Neo4j数据库表操作 2 1 使用Python连接Neo4j 2
  • Hadoop综合项目——二手房统计分析(起始篇)

    Hadoop综合项目 二手房统计分析 起始篇 文章目录 Hadoop综合项目 二手房统计分析 起始篇 0 写在前面 1 项目背景与功能 1 1 项目背景 1 2 项目功能 2 数据集和数据预处理 2 1 数据集 2 2 数据预处理 2 2
  • android -- 蓝牙 bluetooth (四)OPP文件传输

    在前面android 蓝牙 bluetooth xff08 一 xff09 入门文章结尾中提到了会按四个方面来写这系列的文章 xff0c 前面已写了蓝牙打开和蓝牙搜索 xff0c 这次一起来看下蓝牙文件分享的流程 xff0c 也就是蓝牙应用
  • Hadoop综合项目——二手房统计分析(MapReduce篇)

    Hadoop综合项目 二手房统计分析 MapReduce篇 文章目录 Hadoop综合项目 二手房统计分析 MapReduce篇 0 写在前面 1 MapReduce统计分析 1 1 统计四大一线城市房价的最值 1 2 按照城市分区统计二手
  • Hadoop综合项目——二手房统计分析(Hive篇)

    Hadoop综合项目 二手房统计分析 Hive篇 文章目录 Hadoop综合项目 二手房统计分析 Hive篇 0 写在前面 1 Hive统计分析 1 1 本地数据 HDFS数据导入到Hive 1 2 楼龄超过20年的二手房比例 1 3 四大
  • Hadoop综合项目——二手房统计分析(可视化篇)

    Hadoop综合项目 二手房统计分析 可视化篇 文章目录 Hadoop综合项目 二手房统计分析 可视化篇 0 写在前面 1 数据可视化 1 1 二手房四大一线城市总价Top5 1 2 统计各个楼龄段的二手房比例 1 3 统计各个城市二手房标
  • Git Bash Here和RStudio软件的问题解决

    Git Bash Here和RStudio软件的问题解决 文章目录 Git Bash Here和RStudio软件的问题解决0 写在前面1 Git软件在任务栏图标空白2 RStudio软件2 1 警告信息InormalizePath pat
  • 算法的复杂性分析

    算法的复杂性分析 文章目录 算法的复杂性分析0 算法评价的基本原则1 影响程序运行时间的因素2 算法复杂度2 1 算法的时间复杂度2 2 渐进表示法2 2 1 运行时间的上界2 2 运行时间的下界2 2 3 运行时间的准确界 3 总结4 参
  • 整数划分问题(Java递归)

    整数划分问题 xff08 Java递归 xff09 文章目录 整数划分问题 xff08 Java递归 xff09 0 问题描述1 递归式2 代码3 参考 0 问题描述 整数划分问题 将正整数n表示成一系列正整数之和 xff1a n 61 n
  • 快速排序(Java分治法)

    快速排序 xff08 Java分治法 xff09 文章目录 快速排序 xff08 Java分治法 xff09 0 分治策略1 思路步骤2 代码3 复杂度分析3 1 最好情况3 2 最坏情况3 3 平均情况3 4 性能影响因素 4 合并排序V
  • 动态规划算法

    动态规划算法 文章目录 动态规划算法0 动态规划的思想方法1 动态规划法的设计思想2 动态规划基本步骤3 动态规划算法设计步骤3 1 动态规划算法的基本要素 4 两种实现的比较5 备忘录方法6 备忘录方法与动态规划比较7 参考 0 动态规划
  • 最长公共子序列(LCS)

    最长公共子序列 xff08 LCS xff09 文章目录 最长公共子序列 xff08 LCS xff09 0 写在前面1 问题描述2 最长公共子序列的结构3 子问题的递归结构4 计算最优值5 算法的改进6 参考 0 写在前面 本文文字大都来
  • 贪心算法(Java)

    贪心算法 文章目录 贪心算法0 写在前面1 贪心算法的基本要素1 1 贪心选择性质1 2 最优子结构性质1 3 贪心算法与动态规划算法的差异 2 贪心算法的特点3 贪心法的正确性证明4 活动安排问题4 1 问题描述4 2 贪心法的设计思想4