【第一章:人工智能基础】03.算法分析与设计-(4)贪心算法(Greedy Algorithm)

第一章 人工智能基础

第三部分:算法分析与设计

第四节:贪心算法

内容:贪心选择性质,常见贪心算法(如活动选择问题、最小生成树)的分析。


一、贪心算法的定义

贪心算法是一种在每一步选择中都采取当前状态下最优解(即最有利)的策略,从而希望通过局部最优达到全局最优。

二、贪心算法的两个核心性质
  1. 贪心选择性质
    —— 全局最优解可以通过一系列局部最优选择构成。

  2. 最优子结构性质
    —— 问题的最优解包含其子问题的最优解。

并非所有问题都适合用贪心算法求解,通常需先证明这两个性质是否成立。


三、常见贪心算法实例

1. 活动选择问题(Activity Selection Problem)

问题描述:
给定 n 个活动,每个活动有起始时间 start[i] 和结束时间 end[i],要求在时间上互不重叠的前提下,选择最多数量的活动。

贪心策略:
按照结束时间从早到晚排序,每次选择第一个结束时间最早且与当前已选活动不冲突的活动。

示例代码:

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

2. 最小生成树(Minimum Spanning Tree,MST)

构建一棵连接图中所有节点、边权和最小的树。经典贪心算法:

  • Prim算法:每次选择连接“已选顶点”与“未选顶点”之间的最小边。

  • Kruskal算法:将边按权值升序排序,逐条加入图中,若不构成环则保留。

Kruskal 示例代码:

def kruskal(n, edges):
    parent = list(range(n))

    def find(u):
        while u != parent[u]:
            parent[u] = parent[parent[u]]
            u = parent[u]
        return u

    mst = []
    edges.sort(key=lambda x: x[2])  # edges: (u, v, weight)
    for u, v, w in edges:
        ru, rv = find(u), find(v)
        if ru != rv:
            parent[ru] = rv
            mst.append((u, v, w))
    return mst

四、贪心算法的适用场景

适合满足以下条件的问题:

  • 子问题结构相互独立

  • 总体最优包含局部最优

  • 每一步的最优选择不影响后续结果最优性

典型应用包括:

  • 区间调度

  • Huffman编码

  • 零钱找零(在某些币值组合中不适用)

  • 网络连通优化(最小生成树)


总结
特点内容
思想每一步都选择当前最优策略
优点简单、效率高(常为 O(n log n))
缺点不一定总是最优解
适用场景具有贪心选择性质和最优子结构的问题
常见算法活动选择、最小生成树、区间覆盖、任务调度、背包问题(部分)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值