当前位置: 首页 > article >正文

五大基础算法——贪心算法

贪心算法 是一种在每一步选择中都采取当前最优决策,希望通过局部最优解达到全局最优解的算法思想。它简单高效,但并非所有问题都适用。以下是贪心算法的核心概念、适用条件、经典问题及实现方法:


一、核心概念

  1. 局部最优解
    • 在每一步选择中,贪心算法只考虑当前状态下的最优解,而不考虑后续步骤的影响。
  2. 无后效性
    • 当前的选择不会影响后续选择的状态。
  3. 全局最优解
    • 通过一系列局部最优解,最终希望得到全局最优解。

二、适用条件

贪心算法适用于满足以下条件的问题:

  1. 贪心选择性质
    • 问题的全局最优解可以通过一系列局部最优解得到。
  2. 最优子结构
    • 问题的最优解包含其子问题的最优解。
  3. 无后效性
    • 当前的选择不会影响后续选择的状态。

三、经典问题与代码

1. 零钱兑换(硬币问题)

问题描述:给定不同面额的硬币和一个总金额,求最少需要多少枚硬币才能凑成总金额。

def coinChange(coins, amount):
    coins.sort(reverse=True)  # 从大到小排序
    count = 0
    for coin in coins:
        if amount == 0:
            break
        count += amount // coin
        amount %= coin
    return count if amount == 0 else -1

# 示例
coins = [1, 2, 5]
amount = 11
print(coinChange(coins, amount))  # 输出 3 (5+5+1)
2. 活动选择问题

问题描述:给定一组活动,每个活动有开始时间和结束时间,求最多能安排多少个互不冲突的活动。

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

# 示例
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (8, 9)]
print(activitySelection(activities))  # 输出 [(1, 4), (5, 7), (8, 9)]
3. 最小生成树(Kruskal算法)

问题描述:给定一个带权无向图,求其最小生成树。

def kruskal(graph):
    edges = sorted(graph['edges'], key=lambda x: x[2])  # 按权重排序
    parent = {node: node for node in graph['nodes']}
    result = []
    
    def find(u):
        while parent[u] != u:
            parent[u] = parent[parent[u]]  # 路径压缩
            u = parent[u]
        return u
    
    for u, v, w in edges:
        if find(u) != find(v):
            result.append((u, v, w))
            parent[find(u)] = find(v)
    return result

# 示例
graph = {
    'nodes': ['A', 'B', 'C', 'D'],
    'edges': [('A', 'B', 1), ('B', 'C', 2), ('C', 'D', 3), ('A', 'D', 4)]
}
print(kruskal(graph))  # 输出 [('A', 'B', 1), ('B', 'C', 2), ('C', 'D', 3)]

四、贪心算法的局限性

  1. 不保证全局最优
    • 贪心算法只能保证局部最优,不一定能得到全局最优解。
  2. 适用问题有限
    • 只有满足贪心选择性质和最优子结构的问题才能使用贪心算法。
  3. 需要证明正确性
    • 使用贪心算法时,必须证明其局部最优解能导致全局最优解。

五、适用问题特征

  • 问题可以分解为一系列子问题。
  • 子问题的最优解能组合成全局最优解。
  • 常见问题包括:区间调度、最小生成树、最短路径、零钱兑换等。

贪心算法是一种高效的算法思想,但需要仔细分析问题是否满足其适用条件。在实际应用中,通常需要结合其他算法(如动态规划)来解决更复杂的问题。


http://www.kler.cn/a/589017.html

相关文章:

  • 各省水资源平台 水资源遥测终端机都用什么协议
  • CSS中绝对定位
  • 【报错问题】在visual studio 终端使用npm -v后报错禁止运行脚本怎么处理
  • 大三下找C++开发实习的感受分享
  • 网络通信(传输层协议:TCP/IP ,UDP):
  • ADA-YOLO模型深度解析 | 自适应动态注意力驱动的目标检测新范式
  • 本地部署Deep Seek-R1,搭建个人知识库——笔记
  • 【Go每日一练】计算整数数组的最大子数组和
  • 深入解析大语言模型的 Function Call 实现—— 以 Qwen2.5为例
  • 02-Canvas-fabric.ActiveSelection
  • 浅谈Mysql数据库事务操作 用mybatis操作mysql事务 再在Springboot中使用Spring事务控制mysql事务回滚
  • 数学 :矩阵
  • 【Gitee】删除仓库的详细步骤
  • ArcGIS 水利制图符号库:提升水利工作效率的利器
  • 【QT:控件】
  • 第三百八十节 JavaFX教程 - JavaFX区域图
  • 【商城实战(38)】Spring Boot:从本地事务到分布式事务,商城数据一致性的守护之旅
  • 数据结构——单链表list
  • 【软考-架构】11.3、设计模式-新
  • 从技术创新到全球布局:MOVA割草机器人以尖端科技定义智能园艺