欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > 【第一章:人工智能基础】03.算法分析与设计-(4)贪心算法(Greedy Algorithm)

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

2025/6/16 7:12:11 来源:https://blog.csdn.net/IT_ORACLE/article/details/148630574  浏览:    关键词:【第一章:人工智能基础】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 umst = []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] = rvmst.append((u, v, w))return mst

四、贪心算法的适用场景

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

  • 子问题结构相互独立

  • 总体最优包含局部最优

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

典型应用包括:

  • 区间调度

  • Huffman编码

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

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


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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com