首页 > 编程语言 >【算法】浅析贪心算法

【算法】浅析贪心算法

时间:2024-07-21 21:55:14浏览次数:17  
标签:剩余 找零 选择 算法 最优 浅析 贪心

贪心算法:高效解决问题的策略

1. 引言

在计算机科学和优化领域,贪心算法是一种常用的解决问题的策略。它以当前情况为基础,做出最优选择,从而希望最终结果也是最优的。本文将带你了解贪心算法的原理、使用方法及其在实际应用中的意义,并通过代码示例和图示帮助大家更好地理解。

2. 贪心算法简介

2.1 定义

贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下最优(即最有利)的选择,从而希望导致结果是全局最优的算法。

2.2 特点

(1)局部最优:贪心算法每次都选择当前最优解,而不考虑整体情况。
(2)不可回溯:一旦做出选择,就不可撤销。
(3)效率较高:贪心算法通常比动态规划等算法更简单、更快。

3. 贪心算法原理

贪心算法的核心思想是:在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

3.1 示例:找零问题

假设我们有1元、5元、10元、20元、50元和100元的纸币,现在需要找零n元,如何使用最少的纸币数量?
贪心算法的策略是:每次都选择面值最大的纸币,直到找零完成。

3.2 代码示例(Python)

def greedy_change(n):
    coins = [100, 50, 20, 10, 5, 1]
    count = 0
    for coin in coins:
        count += n // coin
        n %= coin
    return count
n = 620
print(f"找零{n}元,最少需要{greedy_change(n)}张纸币。")

输出结果:找零620元,最少需要7张纸币。

4. 图示理解

以下通过结构图和树形图来帮助大家理解贪心算法。

4.1 结构图

以找零问题为例,结构图如下:

结构图:
开始
  |
 100元
  |
 520元
  |
 50元
  |
 470元
  |
 20元
  |
...
  |
 0元 - 结束

4.2 结构图的描述

  1. 开始节点:表示算法的开始。
  2. 决策节点:表示在每一步中选择最大面额纸币的过程。例如,如果需要找零620元,第一个决策节点是选择100元纸币。
  3. 过程节点:表示每一步选择后剩余的找零金额。例如,选择一张100元后,剩余找零金额为520元。
  4. 结束节点:表示找零完成,没有剩余金额。
    结构图示例步骤:
  • 开始 → 选择100元 → 剩余520元
  • 剩余520元 → 选择50元 → 剩余470元
  • 剩余470元 → 选择20元 → 剩余450元
  • 剩余0元 → 结束

4.3 树状图

树状图:
        620元
       /     \
    100元    50元(非贪心选择)
    /          \
  520元      570元
   /           /
 50元      20元
  ...        ...

4.4 树状图的描述

  1. 根节点:表示开始找零的总金额,例如620元。
  2. 分支节点:表示每一次选择不同面额纸币的决策。每个分支节点会有多个子节点,代表剩余金额的不同情况。
  3. 叶节点:表示找零完成的状态,即剩余金额为0。
    树状图示例步骤:
  • 根节点(620元)
    • 选择100元(剩余520元)
      • 选择50元(剩余470元)
          • 找零完成(剩余0元)
    • 选择50元(这种情况不是贪心算法的选择,但可以展示在树状图中)

5. 贪心算法的使用

5.1 适用场景

贪心算法适用于具有“最优子结构”和“贪心选择性质”的问题。
(1)最优子结构:一个问题的最优解包含其子问题的最优解。
(2)贪心选择性质:局部最优解能导致全局最优解。

5.2 常见应用

  • 背包问题:如何将价值最大化地装入有限容量的背包。
  • 哈夫曼编码:一种用于数据压缩的编码方法。
  • 最小生成树:在图论中,连接所有顶点的边的最小权重之和。
  • 最短路径问题:在加权图中找到两点间的最短路径。

5.3 代码示例:活动选择问题

假设有一系列活动,每个活动都有开始和结束时间,如何最大化参与活动的个数?贪心算法的策略是:选择结束时间最早的活动,然后继续选择下一个不与之重叠的最早结束的活动。

def max_activities(activities):
    # 按结束时间排序
    activities.sort(key=lambda x: x[1])
    selected = [activities[0]]
    for start, end in activities:
        if start >= selected[-1][1]:
            selected.append([start, end])
    return selected

# 示例活动列表,格式为 (开始时间, 结束时间)
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10)]
print("选择的活动:", max_activities(activities))

6. 贪心算法的意义

  1. 简化问题求解过程
    贪心算法通过局部最优解来逼近全局最优解,使得问题求解过程更加简单。
  2. 提高算法效率
    相较于动态规划等算法,贪心算法通常具有更高的时间复杂度。
  3. 为其他算法提供思路
    贪心算法的思想可以与其他算法结合,如分治、动态规划等,从而解决更复杂的问题。

7. 总结

贪心算法作为一种高效解决问题的策略,在实际应用中具有广泛的意义。通过本文的介绍,相信大家对贪心算法的原理、使用和意义有了更深入的了解。在实际问题求解过程中,我们可以根据问题的特点,灵活运用贪心算法,提高问题求解的效率。然而,需要注意的是,贪心算法并不适用于所有问题,我们需要根据问题的性质来判断是否适用。

8. 扩展阅读

  • 动态规划:一种与贪心算法不同的算法,适用于需要考虑过去状态的问题。

  • 分治算法:将问题分解为更小的子问题,独立解决后再合并结果。

  • 回溯算法:尝试分步解决问题,如果某一步不满足要求则回溯到上一步。

标签:剩余,找零,选择,算法,最优,浅析,贪心
From: https://blog.csdn.net/Young_Pro/article/details/140578651

相关文章

  • 算法 - 求二进制数中1的个数
    转自: https://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html 一些简单的方法就不转了,转最后两个平行算法intBitCount4(unsignedintn){n=(n&0x55555555)+((n>>1)&0x55555555);n=(n&0x33333333)+((n>>2)&0x3333333......
  • 【机器学习】机器学习的基本知识点(包括背景、定义、具体内容、功能、使用场景、操作、
    引言机器学习是一门涉及多个领域的交叉学科,它主要研究如何让计算机模拟或实现人类的学习行为,以获取新的知识或技能,从而改善系统性能。它是人工智能的核心部分,并且与概率论、统计学、逼近论、凸分析、算法复杂度理论等多个学科相关。文章目录引言一、机器学习的背景二......
  • 文心一言 VS 讯飞星火 VS chatgpt (307)-- 算法导论22.2 5题
    五、证明:在广度优先搜索算法里,赋给结点u的u.d值与结点在邻接链表里出现的次序无关。使用图22-3作为例子,证明:BFS所计算出的广度优先树可以因邻接链表中的次序不同而不同。如果要写代码,请用go语言。文心一言:首先,我们来证明在广度优先搜索(BFS)算法中,赋给结点$u$的......
  • Java JVM——13. 垃圾回收相关算法
    1.生存还是死亡?在堆里存放着几乎所有的Java对象实例,在GC执行垃圾回收之前,首先需要区分出内存中哪些是存活对象,哪些是已经死亡的对象。只有被标记为己经死亡的对象,GC才会在执行垃圾回收时,释放掉其所占用的内存空间,因此这个过程我们称为垃圾标记阶段。那么在JVM中......
  • 《算法笔记》总结No.10——链表
        从第10期破例插叙一期单链表的实现,这个东东相当重要!考研的同学也可以看:相较于王道考研的伪码不太相同,专注于可以运行。如果是笔试中的伪码,意思正确即可~ 注:博主之前写过一个版本的顺序表和单链表的C++实现,和这篇的写法有所不同,不过内容也较全,大家可以先行阅读~......
  • 算法设计与数据结构系列【超详细、超全面、小白可入,期末复习】持续更新中...
    算法设计与数据结构系列【超详细、超全面、小白可入,期末复习】持续更新中…24.07.21代码采用语言:Java1、位运算(BitwiseOperation)常见操作:与(&)、或(I)、非(~)、异或(^)移位运算:>>和<<分别为左移和右移>>>运算符:用0填充高位,>>用符号位填充高位,没有<<<运算符真值表ab~a~b......
  • 基于协同过滤推荐算法+springboot+vue的校园二手商城(前后端分离)
    博主主页:猫头鹰源码博主简介:Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万+、专注Java技术领域和毕业设计项目实战主要内容:毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询文末联系获取项目介绍: 本系统为原创项目,采用前后端分......
  • 代码随想录算法训练营第16天 | 二叉树更加进阶
    2024年7月18日用层序遍历巧解题513.找树左下角的值层序遍历的板子一定要熟背。classSolution{publicintfindBottomLeftValue(TreeNoderoot){List<List<Integer>>res=newArrayList<>();//用根左右遍历,每次记录高度intheight=0;......
  • (7-4-03)RRT算法:基于Gazebo仿真的路径规划系统(3)
    (6)函数select_branch实现了RRT_*_FND算法中的选择分支策略,用于删除不再位于路径上的节点及其子节点。它接收当前达到的节点以及先前的路径作为输入,并根据路径更新图中的节点和边。随着节点的移除,函数会实时显示图的变化。最后,它返回更新后的路径。defselect_branch(G:Graph,......
  • 算法随笔——DP优化
    单调队列优化DP单调队列模板:inthead=1,tail=0; for(inti=1;i<=n;i++) { while(head<=tail&&head不满足条件)head++;//踢出队列 f[i]=f[q[head]]+...; while(head<=tail&&tail与i不满足单调性)tail--; q[++tail]=i; }优化思路则是......