Python算法-贪心算法(Greedy Algorithm)

Python算法:贪心算法(Greedy Algorithm)深度解析

引言

贪心算法(Greedy Algorithm)是计算机科学中最基础的算法设计思想之一,其核心在于通过局部最优选择逐步构建全局最优解。尽管它并不总能保证得到绝对最优解,但在许多实际场景中(如任务调度、网络路由、数据压缩),贪心算法以其高效性和简洁性成为首选方案。本文将结合Python实现,系统讲解贪心算法的原理、应用场景及经典案例。

一、贪心算法的核心思想

1.1 基本定义

贪心算法通过一系列局部最优选择来构造问题的解。其决策过程具有以下特征:

  • 无后效性:每一步选择仅依赖当前状态,不依赖未来决策
  • 不可回溯性:一旦做出选择,后续步骤无法修改
  • 贪心选择性质:全局最优解可通过局部最优选择逐步构造

1.2 适用条件

贪心算法有效需满足两个关键条件:

  1. 贪心选择性质:局部最优选择能导向全局最优
  2. 最优子结构:问题的最优解包含其子问题的最优解

示例:活动选择问题中,选择最早结束的活动可留下更多时间给后续活动,符合贪心选择性质。

二、经典问题解析与Python实现

2.1 活动选择问题

问题描述:从多个活动中选择最多不重叠的活动
贪心策略:按结束时间排序,依次选择不冲突的活动

def activity_selection(start_times, end_times):# 按结束时间排序activities = sorted(zip(start_times, end_times), key=lambda x: x[1])selected = []last_end = 0for start, end in activities:if start >= last_end:selected.append((start, end))last_end = endreturn selected# 示例
start = [1, 3, 0, 5, 8, 5]
end = [2, 4, 6, 7, 9, 9]
print(activity_selection(start, end))  
# 输出:[(1, 2), (3, 4), (5, 7), (8, 9)]

2.2 分数背包问题

问题描述:在不超过背包容量的前提下,最大化物品总价值
贪心策略:优先选择单位价值最高的物品

def fractional_knapsack(weights, values, capacity):# 计算单位价值并排序items = sorted(zip(weights, values), key=lambda x: x[1]/x[0], reverse=True)total_value = 0for weight, value in items:if capacity <= 0:breaktake = min(weight, capacity)total_value += value * (take / weight)capacity -= takereturn total_value# 示例
weights = [10, 20, 30]
values = [60, 100, 120]
print(fractional_knapsack(weights, values, 50))  # 输出:240.0

2.3 霍夫曼编码

问题描述:通过构建前缀树实现数据压缩
贪心策略:合并频率最低的两个节点

import heapqclass Node:def __init__(self, freq, symbol, left=None, right=None):self.freq = freqself.symbol = symbolself.left = leftself.right = rightdef __lt__(self, other):return self.freq < other.freqdef huffman_coding(symbols, frequencies):heap = [Node(freq, symbol) for symbol, freq in zip(symbols, frequencies)]heapq.heapify(heap)while len(heap) > 1:left = heapq.heappop(heap)right = heapq.heappop(heap)merged = Node(left.freq + right.freq, left.symbol + right.symbol, left, right)heapq.heappush(heap, merged)# 生成编码codes = {}def traverse(node, code=''):if node is None:returnif node.left is None and node.right is None:codes[node.symbol] = codetraverse(node.left, code + '0')traverse(node.right, code + '1')traverse(heap[0])return codes# 示例
symbols = ['A', 'B', 'C', 'D']
frequencies = [5, 9, 12, 13]
print(huffman_coding(symbols, frequencies))
# 输出:{'A': '110', 'B': '111', 'C': '10', 'D': '0'}

三、贪心算法的优缺点分析

3.1 优势

  1. 时间复杂度低:通常为O(n log n)(排序开销)
  2. 实现简单:代码逻辑直观,易于调试
  3. 实时性高:适合需要快速决策的场景(如网络路由)

3.2 局限

  1. 无法保证全局最优:如0-1背包问题中,贪心选择可能失败
    # 反例:0-1背包问题
    weights = [25, 20, 15]
    values = [25, 20, 15]
    capacity = 30# 贪心选择单位价值最高(1.0)的物品,但总重量25超过容量
    # 正确解:选择后两个物品(总价值35)
    
  2. 依赖问题结构:需严格满足贪心选择性质

四、贪心算法与动态规划的对比

特性贪心算法动态规划
决策方式局部最优,不可回溯全局最优,可回溯
时间复杂度O(n log n)O(n²)或更高
适用场景具有贪心选择性质的问题具有最优子结构的问题
典型问题活动选择、霍夫曼编码0-1背包、最短路径

五、实际应用案例

5.1 网络路由

Dijkstra算法通过贪心策略选择当前最短路径节点,逐步构建全局最短路径树。

5.2 任务调度

操作系统中的进程调度(如SJF最短作业优先)采用贪心策略,减少平均等待时间。

5.3 数据压缩

JPEG图像压缩中的霍夫曼编码,通过贪心算法生成最优前缀码。

六、使用贪心算法的注意事项

  1. 验证问题适用性:通过数学证明或反例测试贪心策略的有效性
  2. 处理非标准场景:如硬币找零问题中,非标准面额需改用动态规划
  3. 结合其他算法:在复杂问题中,贪心算法常作为启发式方法与动态规划结合使用

七、总结

贪心算法以其高效性和简洁性,在算法设计中占据重要地位。通过掌握其核心思想(局部最优→全局最优)和经典案例(活动选择、霍夫曼编码),开发者可快速解决一类优化问题。然而,需时刻警惕其局限性——在缺乏贪心选择性质时,果断转向动态规划或回溯算法。未来,贪心算法将与机器学习结合,在智能决策领域发挥更大价值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/94557.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/94557.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

告别臃肿与广告:精选9款安卓电视桌面Launcher,还你清爽高效体验 (2025版)

[实测] 9款优秀安卓电视桌面Launcher推荐&#xff1a;告别原生臃肿&#xff0c;重塑清爽TV体验 引言&#xff1a;当前智能电视桌面的痛点 目前市面上许多智能电视或电视盒子的原生桌面&#xff08;Launcher&#xff09;系统&#xff0c;为了商业推广和内容聚合&#xff0c;往…

Docker Desktop紧急修复CVSS9.3高危容器逃逸漏洞

Docker公司修复了Windows和macOS版Docker Desktop应用程序中的一个高危漏洞&#xff08;CVE-2025-9074&#xff0c;CVSS评分9.3&#xff09;&#xff0c;攻击者可能利用该漏洞突破容器隔离限制。漏洞技术细节根据Docker官方文档披露&#xff0c;恶意容器能够访问Docker引擎并在…

携程旅游的 AI 网关落地实践

原创 董艺荃 Higress 2025年08月21日 16:32 陕西本文整理自携程旅游研发总监董艺荃在2025中国可信云大会上的分享&#xff0c;董艺荃 GitHub ID CH3CHO&#xff0c;同时也是 Higress 的 Maintainer。分享内容分为以下4部分。01 大规模应用 AI 技术过程中遇到了哪些问题02 网关…

CloudBase云开发MCP + CodeBuddy IDE:打造智能化全栈理财助手的完整实践

CloudBase云开发MCP CodeBuddy IDE&#xff1a;打造智能化全栈理财助手的完整实践 &#x1f31f; Hello&#xff0c;我是摘星&#xff01; &#x1f308; 在彩虹般绚烂的技术栈中&#xff0c;我是那个永不停歇的色彩收集者。 &#x1f98b; 每一个优化都是我培育的花朵&#x…

ESP8266学习

一&#xff0c;连接Wifi1.Esp8266连接手机热点ATATRST ATCWMODE1 ATCWJAP"ESP8266","123456789"手机查看连接信息2.Esp8266连接手机热点进入透传模式ATATRST ATCWMODE1 ATCWJAP"ESP8266","123456789"ATCIPMUX0 ATCIPSTART"TCP&qu…

Mac安装mitmproxy及操作对监控的请求

在 macOS 上安装和配置 mitmproxy 是一个相对简单的过程&#xff0c;可以使用常见的包管理工具如 Homebrew 或直接通过 Python 的包管理工具 pip。以下是详细的安装步骤&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Homebrew 是 macOS 上流行的包管理工具。它可以快速安…

c++ 数据结构-堆、优先队列 小总结

之前学习了一些堆、优先队列的知识点&#xff0c;在此做一个小总结。堆&#xff08;Heap&#xff09;堆&#xff08;Heap&#xff09;是一种特殊的完全二叉树数据结构&#xff0c;具有以下重要特性&#xff1a;结构特性堆是一棵完全二叉树&#xff0c;即除了最后一层外&#xf…

编写Linux下usb设备驱动方法:probe函数中要进行的工作

一. 简介 前一篇文章简单学习了 Linux下usb设备驱动实现流程&#xff0c;文章如下&#xff1a; 编写Linux下usb设备驱动方法&#xff1a;usb设备驱动实现流程-CSDN博客 本文来学习一下 usb设备驱动的 probe函数要完成的任务。 当usb主控制器检测到设备与 驱动相匹配时&…

动态规划:为什么暴力算法会有重复子问题

第一步&#xff1a;先明确 “子问题” 和 “重复子问题” 的定义 在算法中&#xff0c;“子问题” 不是泛指 “小一点的问题”&#xff0c;而是具有明确 “状态参数” 的、可独立求解的问题单元。 状态参数&#xff1a;描述子问题核心信息的变量&#xff08;比如 01 背包中的 “…

【网络】添加路由时,via和dev参数作用、直连路由

文章目录概述1、带via1.1 添加路由前的初始状态1.2. 执行添加路由的命令1.3. 添加路由后的状态2、不带 via (使用设备接口)&#xff0c;直连3、带via还是不带via ?4、dev xx的作用4.1 命令中带via时&#xff0c;建议不带 dev eth0 (让系统自动判断)4.2 命令中带via&#xff0c…

云原生---企业级Kubernetes

一、Kubernetes介绍 1.简介 kubernetes的本质是一组服务器集群&#xff0c;它可以在集群的每个节点上运行特定的程序&#xff0c;来对节点中的容器进行管理。目的是实现资源管理的自动化&#xff0c;主要提供了如下的主要功能&#xff1a; 自我修复&#xff1a;一旦某一个容器…

无人机三维路径规划首选算法:RRT_

无人机三维路径规划首选算法&#xff1a;RRT* 要判断哪种算法更适合无人机三维路径规划&#xff0c;需先明确无人机三维路径规划的核心需求&#xff0c;再结合各算法的底层逻辑与特性进行匹配。以下先梳理核心需求&#xff0c;再逐一分析算法特性&#xff0c;最终通过对比得出结…

CentOS 7 服务器初始化:从 0 到 1 的安全高效配置指南

前言 对于运维或开发人员而言&#xff0c;新到手的 CentOS 7 服务器绝非 “开箱即用”—— 默认的国外软件源下载缓慢、系统缺乏基础工具、防火墙未做安全配置&#xff0c;这些问题都会影响后续使用效率与服务器安全性。本文整理了 CentOS 7 服务器初始化的全套实操方案&#…

32.Attention-注意力机制

不是所有的信息都是有用的&#xff0c;或者说重要的。我们应该把注意力放在他该在的地方。 在人工智能领域&#xff0c;注意力机制被广泛应用。他可以帮助模型关注与当前任务相关的特征&#xff0c;而忽略不重要的特征&#xff0c;以提高准确率。注意力机制本质&#xff1a;即通…

如何设计 “用户共创型” IP 成长社群模型?​

“用户共创型” IP 成长社群的核心&#xff0c;是从 “IP 单向输出” 转向 “IP 与用户共生”&#xff0c;让用户从 “被动接收者” 变为 “主动参与者”&#xff0c;通过 “需求共建、内容共造、价值共享” 形成闭环&#xff0c;既强化用户归属感&#xff0c;又为 IP 注入持续…

Windows 命令行:mkdir 命令

专栏导航 上一篇&#xff1a;Windows 命令行&#xff1a;dir 命令 回到目录 下一篇&#xff1a;MFC 第一章概述 本节前言 本节&#xff0c;我们来讲解一个常见的命令&#xff0c;mkdir 命令。 学习本节知识&#xff0c;需要你首先懂得如何打开一个命令行界面&#xff0c;…

Linux系统编程——进程(函数)

回调函数&#xff1a;atexit()原型&#xff1a; int atexit(void (*function)(void));功能&#xff1a; 注册进程退出前执行的函数参数&#xff1a; function 函数指针&#xff0c;指向void返回值void参数的函数指针返回值 成功 返回0失败 …

均胜电子上半年毛利率持续提升,汽车智能化与机器人业务多点突破

8月25日&#xff0c;全球领先的智能汽车科技解决方案提供商均胜电子&#xff08;600699.SH&#xff09;发布2025上半年业绩&#xff0c;报告期内公司实现营业收入约303.47亿元&#xff0c;同比增长12.07%&#xff1b;营业利润总额约12.47亿元&#xff0c;归母净利润同比增长11.…

【QT入门到晋级】进程间通信(IPC)-共享内存

前言 前面分享了几种IPC通信技术&#xff0c;都有成熟的交互机制&#xff08;阻塞和非阻塞方式交互&#xff09;&#xff0c;而本文分享的共享内存&#xff0c;更像是系统提供了一张“白纸”&#xff0c;让多个进程自己构建管理及安全机制&#xff0c;而有些场景只需要简单的机…

自动化测试概念与 Web 自动化实战(基于 Selenium)

在软件测试领域&#xff0c;自动化测试是提升测试效率、保障回归测试质量的核心手段。尤其对于 C 开发的项目&#xff0c;自动化测试能有效减少重复手工操作&#xff0c;避免新增功能对历史功能的影响。本文从自动化基础概念入手&#xff0c;详解自动化分类、Web 自动化测试核心…